[PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'
Display more CSRs in the 'info registers' command and group them according to function. The number of CSRs in RISC-V is so large to make it impractical for all CSRs to be displayed by 'info registers'. The code uses conditional compilation directives around register groups; advanced users can enable/disable register groups as required. Signed-off-by: Konrad Schwarz --- target/riscv/cpu.c | 327 + 1 file changed, 303 insertions(+), 24 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index f812998123..eb9518fc16 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -3,6 +3,7 @@ * * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu * Copyright (c) 2017-2018 SiFive, Inc. + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -244,40 +245,318 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) #ifndef CONFIG_USER_ONLY { static const int dump_csrs[] = { + +# if 0 +CSR_USTATUS, +CSR_UIE, +CSR_UTVEC, + +/* User Trap Handling */ +CSR_USCRATCH, +CSR_UEPC, +CSR_UCAUSE, +CSR_UTVAL, +CSR_UIP, +# endif + +/* User Floating-Point CSRs */ +CSR_FFLAGS, +CSR_FRM, +CSR_FCSR, + +/* User Vector CSRs */ +CSR_VSTART, +CSR_VXSAT, +CSR_VXRM, +CSR_VL, +CSR_VTYPE, + +# if 0 +/* User Timers and Counters */ +CSR_CYCLE, +CSR_TIME, +CSR_INSTRET, +CSR_HPMCOUNTER3, +CSR_HPMCOUNTER4, +CSR_HPMCOUNTER5, +CSR_HPMCOUNTER6, +CSR_HPMCOUNTER7, +CSR_HPMCOUNTER8, +CSR_HPMCOUNTER9, +CSR_HPMCOUNTER10, +CSR_HPMCOUNTER11, +CSR_HPMCOUNTER12, +CSR_HPMCOUNTER13, +CSR_HPMCOUNTER14, +CSR_HPMCOUNTER15, +CSR_HPMCOUNTER16, +CSR_HPMCOUNTER17, +CSR_HPMCOUNTER18, +CSR_HPMCOUNTER19, +CSR_HPMCOUNTER20, +CSR_HPMCOUNTER21, +CSR_HPMCOUNTER22, +CSR_HPMCOUNTER23, +CSR_HPMCOUNTER24, +CSR_HPMCOUNTER25, +CSR_HPMCOUNTER26, +CSR_HPMCOUNTER27, +CSR_HPMCOUNTER28, +CSR_HPMCOUNTER29, +CSR_HPMCOUNTER30, +CSR_HPMCOUNTER31, +CSR_CYCLEH, +CSR_TIMEH, +CSR_INSTRETH, +CSR_HPMCOUNTER3H, +CSR_HPMCOUNTER4H, +CSR_HPMCOUNTER5H, +CSR_HPMCOUNTER6H, +CSR_HPMCOUNTER7H, +CSR_HPMCOUNTER8H, +CSR_HPMCOUNTER9H, +CSR_HPMCOUNTER10H, +CSR_HPMCOUNTER11H, +CSR_HPMCOUNTER12H, +CSR_HPMCOUNTER13H, +CSR_HPMCOUNTER14H, +CSR_HPMCOUNTER15H, +CSR_HPMCOUNTER16H, +CSR_HPMCOUNTER17H, +CSR_HPMCOUNTER18H, +CSR_HPMCOUNTER19H, +CSR_HPMCOUNTER20H, +CSR_HPMCOUNTER21H, +CSR_HPMCOUNTER22H, +CSR_HPMCOUNTER23H, +CSR_HPMCOUNTER24H, +CSR_HPMCOUNTER25H, +CSR_HPMCOUNTER26H, +CSR_HPMCOUNTER27H, +CSR_HPMCOUNTER28H, +CSR_HPMCOUNTER29H, +CSR_HPMCOUNTER30H, +CSR_HPMCOUNTER31H, +# endif + +# if 0 +/* Machine Timers and Counters */ +CSR_MCYCLE, +CSR_MINSTRET, +CSR_MCYCLEH, +CSR_MINSTRETH, +# endif + +/* Machine Information Registers */ +CSR_MVENDORID, +CSR_MARCHID, +CSR_MIMPID, CSR_MHARTID, + +/* Machine Trap Setup */ CSR_MSTATUS, -CSR_MSTATUSH, -CSR_HSTATUS, -CSR_VSSTATUS, -CSR_MIP, -CSR_MIE, -CSR_MIDELEG, -CSR_HIDELEG, +CSR_MISA, CSR_MEDELEG, -CSR_HEDELEG, +CSR_MIDELEG, +CSR_MIE, CSR_MTVEC, -CSR_STVEC, -CSR_VSTVEC, +CSR_MCOUNTEREN, + +# if defined TARGET_RISCV32 +/* 32-bit only */ +CSR_MSTATUSH, +# endif + +/* Machine Trap Handling */ +CSR_MSCRATCH, CSR_MEPC, -CSR_SEPC, -CSR_VSEPC, CSR_MCAUSE, -CSR_SCAUSE, -CSR_VSCAUSE, CSR_MTVAL, +CSR_MIP, + +/* Supervisor Trap Setup */ +CSR_SSTATUS, +CSR_SEDELEG, +CSR_SIDELEG, +CSR_SIE, +CSR_STVEC, +CSR_SCOUNTEREN, + +/* Supervisor Trap Handling
[PATCH v2 0/5] Improve RISC-V debugging support.
Added the files missing in v1 of this patch. -- >8 -- 1) Make the QEMU monitor `info registers' command more informative 2) Implement the QEMU monitor `print $register' 3) Introduce a new command `info gmem' to the QEMU monitor, which displays a RISC-V hypervisor's guest's 2nd level paging tables similarly to the existing `info mem' command. 4) Improve QEMU RISC-V target descriptions for GDB. In particular, add type information for many control and status registers. 5) Extend the virtual `priv' register with hypervisor virtualization status. Konrad Schwarz (5): RISC-V: larger and more consistent register set for 'info registers' RISC-V: monitor's print register functionality RISC-V: 'info gmem' to show hypervisor guest -> physical address translations RISC-V: Typed CSRs in gdbserver RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register gdb-xml/riscv-32bit-virtual.xml | 30 ++- gdb-xml/riscv-64bit-virtual.xml | 30 ++- hmp-commands-info.hx | 16 ++ include/monitor/hmp-target.h | 2 + target/riscv/cpu.c| 327 ++--- target/riscv/csr.c| 2 + target/riscv/csr32-op-gdbserver.h | 109 ++ target/riscv/csr64-op-gdbserver.h | 76 +++ target/riscv/gdb_csr_type_group.c | 16 ++ target/riscv/gdb_csr_type_group.h | 3 + target/riscv/gdb_csr_types.c | 333 ++ target/riscv/gdb_csr_types.h | 3 + target/riscv/gdbstub.c| 31 ++- target/riscv/meson.build | 4 +- target/riscv/monitor.c| 204 ++ 15 files changed, 1115 insertions(+), 71 deletions(-) create mode 100644 target/riscv/csr32-op-gdbserver.h create mode 100644 target/riscv/csr64-op-gdbserver.h create mode 100644 target/riscv/gdb_csr_type_group.c create mode 100644 target/riscv/gdb_csr_type_group.h create mode 100644 target/riscv/gdb_csr_types.c create mode 100644 target/riscv/gdb_csr_types.h base-commit: 8627edfb3f1fca24a96a0954148885c3241c10f8 -- Konrad Schwarz
[PATCH v2 5/5] RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register
The RISC-V Debug Support specification suggests debuggers provide "virtual debug registers" to show state not directly visible in the ISA, and defines one such register, `priv', which encodes the processor's current operating mode in the two least significant bits. GDB represents virtual debug registers in the `org.gnu.gdb.riscv.virtual' feature of RISC-V target descriptions. This patch adds the `v' (hypervisor virtualization mode) bit to `priv' as specified by section 4.9.1 of version 1.0 of the RISC-V Debug Support specification. Signed-off-by: Konrad Schwarz --- gdb-xml/riscv-32bit-virtual.xml | 30 -- gdb-xml/riscv-64bit-virtual.xml | 30 -- target/riscv/gdbstub.c | 5 - 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/gdb-xml/riscv-32bit-virtual.xml b/gdb-xml/riscv-32bit-virtual.xml index 905f1c555d..7dad42cd67 100644 --- a/gdb-xml/riscv-32bit-virtual.xml +++ b/gdb-xml/riscv-32bit-virtual.xml @@ -5,7 +5,33 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> + + - - + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/riscv-64bit-virtual.xml b/gdb-xml/riscv-64bit-virtual.xml index 62d86c237b..02c234670d 100644 --- a/gdb-xml/riscv-64bit-virtual.xml +++ b/gdb-xml/riscv-64bit-virtual.xml @@ -5,7 +5,33 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> + + - - + + + + + + + + + + + + + + + + + + + diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c index 9c3f68eeaf..b3fa9f864e 100644 --- a/target/riscv/gdbstub.c +++ b/target/riscv/gdbstub.c @@ -136,7 +136,10 @@ static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n) #ifdef CONFIG_USER_ONLY return gdb_get_regl(buf, 0); #else -return gdb_get_regl(buf, cs->priv); + RISCVCPU *const cpu = RISCV_CPU(cs); + CPURISCVState *const env = >env; +return gdb_get_regl(buf, riscv_cpu_virt_enabled(env) << 2 | cs->priv); + /* per RISCV Debug Spec 1.0, 4.9.1 */ #endif } return 0; -- Konrad Schwarz
[PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
GDB target descriptions support typed registers; such that `info register X' displays not only the hex value of register `X', but also the individual bitfields the register comprises (if any), using textual labels if possible. This patch includes type information for GDB for a large subset of the RISC-V Control and Status Registers (CSRs). Signed-off-by: Konrad Schwarz --- target/riscv/csr.c| 2 + target/riscv/csr32-op-gdbserver.h | 109 ++ target/riscv/csr64-op-gdbserver.h | 76 +++ target/riscv/gdb_csr_type_group.c | 16 ++ target/riscv/gdb_csr_type_group.h | 3 + target/riscv/gdb_csr_types.c | 333 ++ target/riscv/gdb_csr_types.h | 3 + target/riscv/gdbstub.c| 26 ++- target/riscv/meson.build | 4 +- 9 files changed, 566 insertions(+), 6 deletions(-) create mode 100644 target/riscv/csr32-op-gdbserver.h create mode 100644 target/riscv/csr64-op-gdbserver.h create mode 100644 target/riscv/gdb_csr_type_group.c create mode 100644 target/riscv/gdb_csr_type_group.h create mode 100644 target/riscv/gdb_csr_types.c create mode 100644 target/riscv/gdb_csr_types.h diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 9f41954894..557b4afe0e 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -3,6 +3,7 @@ * * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu * Copyright (c) 2017-2018 SiFive, Inc. + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -2094,5 +2095,6 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32, read_zero }, [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32, read_zero }, [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32, read_zero }, + #endif /* !CONFIG_USER_ONLY */ }; diff --git a/target/riscv/csr32-op-gdbserver.h b/target/riscv/csr32-op-gdbserver.h new file mode 100644 index 00..e8ec527f23 --- /dev/null +++ b/target/riscv/csr32-op-gdbserver.h @@ -0,0 +1,109 @@ +/* Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com */ + + [CSR_USTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "user" }, + [CSR_UIE] { .gdb_type = "sie-fields", .gdb_group = "user" }, + [CSR_UTVEC] { .gdb_type = "code_ptr", .gdb_group = "user" }, + [CSR_USCRATCH] { .gdb_type = "data_ptr", .gdb_group = "user" }, + [CSR_UEPC] { .gdb_type = "code_ptr", .gdb_group = "user" }, + [CSR_UCAUSE] { .gdb_type = "scause-fields", .gdb_group = "user" }, + [CSR_UTVAL] { .gdb_type = "data_ptr", .gdb_group = "user" }, + [CSR_UIP] { .gdb_type = "code_ptr", .gdb_group = "user" }, + [CSR_CYCLE] { .gdb_type = "uint32", .gdb_group = "user" }, + [CSR_TIME] { .gdb_type = "uint32", .gdb_group = "user" }, + [CSR_INSTRET] { .gdb_type = "uint32", .gdb_group = "user" }, + [CSR_HPMCOUNTER3] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER4] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER5] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER6] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER7] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER8] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER9] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER10] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER11] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER12] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER13] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER14] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER15] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER16] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER17] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER18] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER19] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER20] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER21] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER22] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER23] { .gdb_type = "int", .gdb_group
[PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations
This is analog to the existing 'info mem' command and is implemented using the same machinery. Signed-off-by: Konrad Schwarz --- hmp-commands-info.hx | 16 + include/monitor/hmp-target.h | 2 + target/riscv/monitor.c | 135 +-- 3 files changed, 117 insertions(+), 36 deletions(-) diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 407a1da800..fa519f0129 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -237,6 +237,22 @@ SRST Show the active virtual memory mappings. ERST +#if defined TARGET_RISCV +{ +.name = "gmem", +.args_type = "", +.params = "", +.help = "show the hypervisor guest's physical address" + " translation", +.cmd= hmp_info_gmem, +}, +#endif + +SRST + ``info gmem`` +Show the hypervisor guest's physical address translation. +ERST + { .name = "mtree", .args_type = "flatview:-f,dispatch_tree:-d,owner:-o,disabled:-D", diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h index ffdc15a34b..9f2dd976f6 100644 --- a/include/monitor/hmp-target.h +++ b/include/monitor/hmp-target.h @@ -2,6 +2,7 @@ * QEMU monitor * * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,6 +46,7 @@ CPUArchState *mon_get_cpu_env(Monitor *mon); CPUState *mon_get_cpu(Monitor *mon); void hmp_info_mem(Monitor *mon, const QDict *qdict); +void hmp_info_gmem(Monitor *mon, const QDict *qdict); void hmp_info_tlb(Monitor *mon, const QDict *qdict); void hmp_mce(Monitor *mon, const QDict *qdict); void hmp_info_local_apic(Monitor *mon, const QDict *qdict); diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c index 3f74ea9934..ad58bdf9ca 100644 --- a/target/riscv/monitor.c +++ b/target/riscv/monitor.c @@ -25,16 +25,6 @@ #include "monitor/monitor.h" #include "monitor/hmp-target.h" -#ifdef TARGET_RISCV64 -#define PTE_HEADER_FIELDS "vaddrpaddr"\ -"size attr\n" -#define PTE_HEADER_DELIMITER" "\ -" ---\n" -#else -#define PTE_HEADER_FIELDS "vaddrpaddrsize attr\n" -#define PTE_HEADER_DELIMITER" ---\n" -#endif - /* Perform linear address sign extension */ static target_ulong addr_canonical(int va_bits, target_ulong addr) { @@ -47,10 +37,34 @@ static target_ulong addr_canonical(int va_bits, target_ulong addr) return addr; } -static void print_pte_header(Monitor *mon) +static void print_pte_header(Monitor *mon, +char const vaddr_char, char const paddr_char) { -monitor_printf(mon, PTE_HEADER_FIELDS); -monitor_printf(mon, PTE_HEADER_DELIMITER); + +# defineVIRTUAL_WIDTH\ +((int) ((sizeof "ff" - sizeof "") * sizeof(target_ulong))) +# definePHYSICAL_WIDTH\ +((int) ((sizeof "ff" - sizeof "") * sizeof(hwaddr))) +# defineATTRIBUTE_WIDTH ((int) (sizeof "rwxugad" - sizeof "")) + +# defineVIRTUAL_COLUMN_WIDTH(1 + VIRTUAL_WIDTH) +# definePHYSICAL_COLUMN_WIDTH (1 + PHYSICAL_WIDTH) + +static char const dashes[PHYSICAL_WIDTH] = ""; + +monitor_printf(mon, +"%c%-*s%c%-*s%-*s%-*s\n" +"%-*.*s%-*.*s%-*.*s%-*.*s\n", + +vaddr_char, VIRTUAL_COLUMN_WIDTH - 1, "addr", +paddr_char, PHYSICAL_COLUMN_WIDTH - 1, "addr", +VIRTUAL_COLUMN_WIDTH, "size", +ATTRIBUTE_WIDTH, "attr", + +VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, dashes, +PHYSICAL_COLUMN_WIDTH, PHYSICAL_WIDTH, dashes, +VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, dashes, +ATTRIBUTE_WIDTH, ATTRIBUTE_WIDTH, dashes); } static void print_pte(Monitor *mon, int va_bits, target_ulong vaddr, @@ -65,21 +79,36 @@ static void print_pte(Monitor *mon, int va_bits, target_ulong vaddr, return; } -monitor_printf(mon, TARGET_FMT_lx " " TARGET_FMT_plx " " TARGET_FMT_lx - " %c%c%c%c%c%c%c\n", - addr_canonical(va_bits, vaddr), - paddr, size, - attr & PTE_R ? 'r' : '-', - attr & PTE_W ? 'w' : '-', - attr & PTE_X ? 'x' : '-', - attr & PTE_U ? 'u'
[PATCH v2 2/5] RISC-V: monitor's print register functionality
Enable the print (p) command to display both general-purpose and Contral and Status (CSR) registers. General purpose registers can be named using the xN form or their ABI names (zero, ra, sp, a0, s1, t2). Signed-off-by: Konrad Schwarz --- target/riscv/monitor.c | 69 ++ 1 file changed, 69 insertions(+) diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c index 7efb4b62c1..3f74ea9934 100644 --- a/target/riscv/monitor.c +++ b/target/riscv/monitor.c @@ -2,6 +2,7 @@ * QEMU monitor for RISC-V * * Copyright (c) 2019 Bin Meng + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com * * RISC-V specific monitor commands implementation * @@ -234,3 +235,71 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict) mem_info_svxx(mon, env); } + +static const MonitorDef monitor_defs[] = { +# define MONITORDEF_RISCV_GPR(NO, ALIAS)\ +{ "x" #NO #ALIAS, offsetof(CPURISCVState, gpr[NO]) }, + +MONITORDEF_RISCV_GPR(0, |zero) +MONITORDEF_RISCV_GPR(1, |ra) +MONITORDEF_RISCV_GPR(2, |sp) +MONITORDEF_RISCV_GPR(3, |gp) +MONITORDEF_RISCV_GPR(4, |tp) +MONITORDEF_RISCV_GPR(5, |t0) +MONITORDEF_RISCV_GPR(6, |t1) +MONITORDEF_RISCV_GPR(7, |t2) +MONITORDEF_RISCV_GPR(8, |s0|fp) +MONITORDEF_RISCV_GPR(9, |s1) +MONITORDEF_RISCV_GPR(10, |a0) +MONITORDEF_RISCV_GPR(11, |a1) +MONITORDEF_RISCV_GPR(12, |a2) +MONITORDEF_RISCV_GPR(13, |a3) +MONITORDEF_RISCV_GPR(14, |a4) +MONITORDEF_RISCV_GPR(15, |a5) +MONITORDEF_RISCV_GPR(16, |a6) +MONITORDEF_RISCV_GPR(17, |a7) +MONITORDEF_RISCV_GPR(18, |s2) +MONITORDEF_RISCV_GPR(19, |s3) +MONITORDEF_RISCV_GPR(20, |s4) +MONITORDEF_RISCV_GPR(21, |s5) +MONITORDEF_RISCV_GPR(22, |s6) +MONITORDEF_RISCV_GPR(23, |s7) +MONITORDEF_RISCV_GPR(24, |s8) +MONITORDEF_RISCV_GPR(25, |s9) +MONITORDEF_RISCV_GPR(26, |s10) +MONITORDEF_RISCV_GPR(27, |s11) +MONITORDEF_RISCV_GPR(28, |t3) +MONITORDEF_RISCV_GPR(29, |t4) +MONITORDEF_RISCV_GPR(30, |t5) +MONITORDEF_RISCV_GPR(31, |t6) + +{ }, +}; + +const MonitorDef *target_monitor_defs(void) +{ +return monitor_defs; +} + +int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval) +{ + +target_ulong ret_value; +CPURISCVState *const env = _CPU (cs)->env; +riscv_csr_operations *op; +for (op = csr_ops; 1[_ops] > op; ++op) { +if (!op->name) { +continue; +} +if (!strcmp(name, op->name)) { +if (RISCV_EXCP_NONE != riscv_csrrw_debug(env, op - csr_ops, + _value, + 0 /* new_value */, + 0 /* write_mask */)) +return -1; +*pval = ret_value; +return 0; +} +} +return -1; +} -- Konrad Schwarz
[PATCH v1 0/5] Improve RISC-V debugging support.
1) Make the QEMU monitor `info registers' command more informative 2) Implement the QEMU monitor `print $register' 3) Introduce a new command `info gmem' to the QEMU monitor, which displays a RISC-V hypervisor's guest's 2nd level paging tables similarly to the existing `info mem' command. 4) Improve QEMU RISC-V target descriptions for GDB. In particular, add type information for many control and status registers. 5) Extend the virtual `priv' register with hypervisor virtualization status. Konrad Schwarz (5): RISC-V: larger and more consistent register set for 'info registers' RISC-V: monitor's print register functionality RISC-V: 'info gmem' to show hypervisor guest -> physical address translations RISC-V: Typed CSRs in gdbserver RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register gdb-xml/riscv-32bit-virtual.xml | 30 ++- gdb-xml/riscv-64bit-virtual.xml | 30 ++- hmp-commands-info.hx | 16 ++ include/monitor/hmp-target.h | 2 + target/riscv/cpu.c| 327 ++--- target/riscv/csr.c| 2 + target/riscv/csr32-op-gdbserver.h | 109 ++ target/riscv/csr64-op-gdbserver.h | 76 +++ target/riscv/gdb_csr_types.c | 333 ++ target/riscv/gdb_csr_types.h | 3 + target/riscv/gdbstub.c| 31 ++- target/riscv/meson.build | 4 +- target/riscv/monitor.c| 204 ++ 13 files changed, 1096 insertions(+), 71 deletions(-) create mode 100644 target/riscv/csr32-op-gdbserver.h create mode 100644 target/riscv/csr64-op-gdbserver.h create mode 100644 target/riscv/gdb_csr_types.c create mode 100644 target/riscv/gdb_csr_types.h base-commit: 8627edfb3f1fca24a96a0954148885c3241c10f8 -- Konrad Schwarz
[PATCH v1 4/5] RISC-V: Typed CSRs in gdbserver
GDB target descriptions support typed registers; such that `info register X' displays not only the hex value of register `X', but also the individual bitfields the register comprises (if any), using textual labels if possible. This patch includes type information for GDB for a large subset of the RISC-V Control and Status Registers (CSRs). Signed-off-by: Konrad Schwarz --- target/riscv/csr.c| 2 + target/riscv/csr32-op-gdbserver.h | 109 ++ target/riscv/csr64-op-gdbserver.h | 76 +++ target/riscv/gdb_csr_types.c | 333 ++ target/riscv/gdb_csr_types.h | 3 + target/riscv/gdbstub.c| 26 ++- target/riscv/meson.build | 4 +- 7 files changed, 547 insertions(+), 6 deletions(-) create mode 100644 target/riscv/csr32-op-gdbserver.h create mode 100644 target/riscv/csr64-op-gdbserver.h create mode 100644 target/riscv/gdb_csr_types.c create mode 100644 target/riscv/gdb_csr_types.h diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 9f41954894..557b4afe0e 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -3,6 +3,7 @@ * * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu * Copyright (c) 2017-2018 SiFive, Inc. + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -2094,5 +2095,6 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32, read_zero }, [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32, read_zero }, [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32, read_zero }, + #endif /* !CONFIG_USER_ONLY */ }; diff --git a/target/riscv/csr32-op-gdbserver.h b/target/riscv/csr32-op-gdbserver.h new file mode 100644 index 00..e8ec527f23 --- /dev/null +++ b/target/riscv/csr32-op-gdbserver.h @@ -0,0 +1,109 @@ +/* Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com */ + + [CSR_USTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "user" }, + [CSR_UIE] { .gdb_type = "sie-fields", .gdb_group = "user" }, + [CSR_UTVEC] { .gdb_type = "code_ptr", .gdb_group = "user" }, + [CSR_USCRATCH] { .gdb_type = "data_ptr", .gdb_group = "user" }, + [CSR_UEPC] { .gdb_type = "code_ptr", .gdb_group = "user" }, + [CSR_UCAUSE] { .gdb_type = "scause-fields", .gdb_group = "user" }, + [CSR_UTVAL] { .gdb_type = "data_ptr", .gdb_group = "user" }, + [CSR_UIP] { .gdb_type = "code_ptr", .gdb_group = "user" }, + [CSR_CYCLE] { .gdb_type = "uint32", .gdb_group = "user" }, + [CSR_TIME] { .gdb_type = "uint32", .gdb_group = "user" }, + [CSR_INSTRET] { .gdb_type = "uint32", .gdb_group = "user" }, + [CSR_HPMCOUNTER3] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER4] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER5] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER6] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER7] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER8] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER9] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER10] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER11] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER12] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER13] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER14] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER15] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER16] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER17] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER18] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER19] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER20] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER21] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER22] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER23] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER24] { .gdb_type = "int", .gdb_group = "user" }, + [CSR_HPMCOUNTER25] { .gdb_type = "int", .gdb_group = "user" }, +
[PATCH v1 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations
This is analog to the existing 'info mem' command and is implemented using the same machinery. Signed-off-by: Konrad Schwarz --- hmp-commands-info.hx | 16 + include/monitor/hmp-target.h | 2 + target/riscv/monitor.c | 135 +-- 3 files changed, 117 insertions(+), 36 deletions(-) diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 407a1da800..fa519f0129 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -237,6 +237,22 @@ SRST Show the active virtual memory mappings. ERST +#if defined TARGET_RISCV +{ +.name = "gmem", +.args_type = "", +.params = "", +.help = "show the hypervisor guest's physical address" + " translation", +.cmd= hmp_info_gmem, +}, +#endif + +SRST + ``info gmem`` +Show the hypervisor guest's physical address translation. +ERST + { .name = "mtree", .args_type = "flatview:-f,dispatch_tree:-d,owner:-o,disabled:-D", diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h index ffdc15a34b..9f2dd976f6 100644 --- a/include/monitor/hmp-target.h +++ b/include/monitor/hmp-target.h @@ -2,6 +2,7 @@ * QEMU monitor * * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,6 +46,7 @@ CPUArchState *mon_get_cpu_env(Monitor *mon); CPUState *mon_get_cpu(Monitor *mon); void hmp_info_mem(Monitor *mon, const QDict *qdict); +void hmp_info_gmem(Monitor *mon, const QDict *qdict); void hmp_info_tlb(Monitor *mon, const QDict *qdict); void hmp_mce(Monitor *mon, const QDict *qdict); void hmp_info_local_apic(Monitor *mon, const QDict *qdict); diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c index 3f74ea9934..ad58bdf9ca 100644 --- a/target/riscv/monitor.c +++ b/target/riscv/monitor.c @@ -25,16 +25,6 @@ #include "monitor/monitor.h" #include "monitor/hmp-target.h" -#ifdef TARGET_RISCV64 -#define PTE_HEADER_FIELDS "vaddrpaddr"\ -"size attr\n" -#define PTE_HEADER_DELIMITER" "\ -" ---\n" -#else -#define PTE_HEADER_FIELDS "vaddrpaddrsize attr\n" -#define PTE_HEADER_DELIMITER" ---\n" -#endif - /* Perform linear address sign extension */ static target_ulong addr_canonical(int va_bits, target_ulong addr) { @@ -47,10 +37,34 @@ static target_ulong addr_canonical(int va_bits, target_ulong addr) return addr; } -static void print_pte_header(Monitor *mon) +static void print_pte_header(Monitor *mon, +char const vaddr_char, char const paddr_char) { -monitor_printf(mon, PTE_HEADER_FIELDS); -monitor_printf(mon, PTE_HEADER_DELIMITER); + +# defineVIRTUAL_WIDTH\ +((int) ((sizeof "ff" - sizeof "") * sizeof(target_ulong))) +# definePHYSICAL_WIDTH\ +((int) ((sizeof "ff" - sizeof "") * sizeof(hwaddr))) +# defineATTRIBUTE_WIDTH ((int) (sizeof "rwxugad" - sizeof "")) + +# defineVIRTUAL_COLUMN_WIDTH(1 + VIRTUAL_WIDTH) +# definePHYSICAL_COLUMN_WIDTH (1 + PHYSICAL_WIDTH) + +static char const dashes[PHYSICAL_WIDTH] = ""; + +monitor_printf(mon, +"%c%-*s%c%-*s%-*s%-*s\n" +"%-*.*s%-*.*s%-*.*s%-*.*s\n", + +vaddr_char, VIRTUAL_COLUMN_WIDTH - 1, "addr", +paddr_char, PHYSICAL_COLUMN_WIDTH - 1, "addr", +VIRTUAL_COLUMN_WIDTH, "size", +ATTRIBUTE_WIDTH, "attr", + +VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, dashes, +PHYSICAL_COLUMN_WIDTH, PHYSICAL_WIDTH, dashes, +VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, dashes, +ATTRIBUTE_WIDTH, ATTRIBUTE_WIDTH, dashes); } static void print_pte(Monitor *mon, int va_bits, target_ulong vaddr, @@ -65,21 +79,36 @@ static void print_pte(Monitor *mon, int va_bits, target_ulong vaddr, return; } -monitor_printf(mon, TARGET_FMT_lx " " TARGET_FMT_plx " " TARGET_FMT_lx - " %c%c%c%c%c%c%c\n", - addr_canonical(va_bits, vaddr), - paddr, size, - attr & PTE_R ? 'r' : '-', - attr & PTE_W ? 'w' : '-', - attr & PTE_X ? 'x' : '-', - attr & PTE_U ? 'u'
[PATCH v1 2/5] RISC-V: monitor's print register functionality
Enable the print (p) command to display both general-purpose and Contral and Status (CSR) registers. General purpose registers can be named using the xN form or their ABI names (zero, ra, sp, a0, s1, t2). Signed-off-by: Konrad Schwarz --- target/riscv/monitor.c | 69 ++ 1 file changed, 69 insertions(+) diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c index 7efb4b62c1..3f74ea9934 100644 --- a/target/riscv/monitor.c +++ b/target/riscv/monitor.c @@ -2,6 +2,7 @@ * QEMU monitor for RISC-V * * Copyright (c) 2019 Bin Meng + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com * * RISC-V specific monitor commands implementation * @@ -234,3 +235,71 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict) mem_info_svxx(mon, env); } + +static const MonitorDef monitor_defs[] = { +# define MONITORDEF_RISCV_GPR(NO, ALIAS)\ +{ "x" #NO #ALIAS, offsetof(CPURISCVState, gpr[NO]) }, + +MONITORDEF_RISCV_GPR(0, |zero) +MONITORDEF_RISCV_GPR(1, |ra) +MONITORDEF_RISCV_GPR(2, |sp) +MONITORDEF_RISCV_GPR(3, |gp) +MONITORDEF_RISCV_GPR(4, |tp) +MONITORDEF_RISCV_GPR(5, |t0) +MONITORDEF_RISCV_GPR(6, |t1) +MONITORDEF_RISCV_GPR(7, |t2) +MONITORDEF_RISCV_GPR(8, |s0|fp) +MONITORDEF_RISCV_GPR(9, |s1) +MONITORDEF_RISCV_GPR(10, |a0) +MONITORDEF_RISCV_GPR(11, |a1) +MONITORDEF_RISCV_GPR(12, |a2) +MONITORDEF_RISCV_GPR(13, |a3) +MONITORDEF_RISCV_GPR(14, |a4) +MONITORDEF_RISCV_GPR(15, |a5) +MONITORDEF_RISCV_GPR(16, |a6) +MONITORDEF_RISCV_GPR(17, |a7) +MONITORDEF_RISCV_GPR(18, |s2) +MONITORDEF_RISCV_GPR(19, |s3) +MONITORDEF_RISCV_GPR(20, |s4) +MONITORDEF_RISCV_GPR(21, |s5) +MONITORDEF_RISCV_GPR(22, |s6) +MONITORDEF_RISCV_GPR(23, |s7) +MONITORDEF_RISCV_GPR(24, |s8) +MONITORDEF_RISCV_GPR(25, |s9) +MONITORDEF_RISCV_GPR(26, |s10) +MONITORDEF_RISCV_GPR(27, |s11) +MONITORDEF_RISCV_GPR(28, |t3) +MONITORDEF_RISCV_GPR(29, |t4) +MONITORDEF_RISCV_GPR(30, |t5) +MONITORDEF_RISCV_GPR(31, |t6) + +{ }, +}; + +const MonitorDef *target_monitor_defs(void) +{ +return monitor_defs; +} + +int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval) +{ + +target_ulong ret_value; +CPURISCVState *const env = _CPU (cs)->env; +riscv_csr_operations *op; +for (op = csr_ops; 1[_ops] > op; ++op) { +if (!op->name) { +continue; +} +if (!strcmp(name, op->name)) { +if (RISCV_EXCP_NONE != riscv_csrrw_debug(env, op - csr_ops, + _value, + 0 /* new_value */, + 0 /* write_mask */)) +return -1; +*pval = ret_value; +return 0; +} +} +return -1; +} -- Konrad Schwarz
[PATCH v1 5/5] RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register
The RISC-V Debug Support specification suggests debuggers provide "virtual debug registers" to show state not directly visible in the ISA, and defines one such register, `priv', which encodes the processor's current operating mode in the two least significant bits. GDB represents virtual debug registers in the `org.gnu.gdb.riscv.virtual' feature of RISC-V target descriptions. This patch adds the `v' (hypervisor virtualization mode) bit to `priv' as specified by section 4.9.1 of version 1.0 of the RISC-V Debug Support specification. Signed-off-by: Konrad Schwarz --- gdb-xml/riscv-32bit-virtual.xml | 30 -- gdb-xml/riscv-64bit-virtual.xml | 30 -- target/riscv/gdbstub.c | 5 - 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/gdb-xml/riscv-32bit-virtual.xml b/gdb-xml/riscv-32bit-virtual.xml index 905f1c555d..7dad42cd67 100644 --- a/gdb-xml/riscv-32bit-virtual.xml +++ b/gdb-xml/riscv-32bit-virtual.xml @@ -5,7 +5,33 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> + + - - + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/riscv-64bit-virtual.xml b/gdb-xml/riscv-64bit-virtual.xml index 62d86c237b..02c234670d 100644 --- a/gdb-xml/riscv-64bit-virtual.xml +++ b/gdb-xml/riscv-64bit-virtual.xml @@ -5,7 +5,33 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> + + - - + + + + + + + + + + + + + + + + + + + diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c index 9c3f68eeaf..b3fa9f864e 100644 --- a/target/riscv/gdbstub.c +++ b/target/riscv/gdbstub.c @@ -136,7 +136,10 @@ static int riscv_gdb_get_virtual(CPURISCVState *cs, GByteArray *buf, int n) #ifdef CONFIG_USER_ONLY return gdb_get_regl(buf, 0); #else -return gdb_get_regl(buf, cs->priv); + RISCVCPU *const cpu = RISCV_CPU(cs); + CPURISCVState *const env = >env; +return gdb_get_regl(buf, riscv_cpu_virt_enabled(env) << 2 | cs->priv); + /* per RISCV Debug Spec 1.0, 4.9.1 */ #endif } return 0; -- Konrad Schwarz
[PATCH v1 1/5] RISC-V: larger and more consistent register set for 'info registers'
Display more CSRs in the 'info registers' command and group them according to function. The number of CSRs in RISC-V is so large to make it impractical for all CSRs to be displayed by 'info registers'. The code uses conditional compilation directives around register groups; advanced users can enable/disable register groups as required. Signed-off-by: Konrad Schwarz --- target/riscv/cpu.c | 327 + 1 file changed, 303 insertions(+), 24 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index f812998123..eb9518fc16 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -3,6 +3,7 @@ * * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu * Copyright (c) 2017-2018 SiFive, Inc. + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -244,40 +245,318 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags) #ifndef CONFIG_USER_ONLY { static const int dump_csrs[] = { + +# if 0 +CSR_USTATUS, +CSR_UIE, +CSR_UTVEC, + +/* User Trap Handling */ +CSR_USCRATCH, +CSR_UEPC, +CSR_UCAUSE, +CSR_UTVAL, +CSR_UIP, +# endif + +/* User Floating-Point CSRs */ +CSR_FFLAGS, +CSR_FRM, +CSR_FCSR, + +/* User Vector CSRs */ +CSR_VSTART, +CSR_VXSAT, +CSR_VXRM, +CSR_VL, +CSR_VTYPE, + +# if 0 +/* User Timers and Counters */ +CSR_CYCLE, +CSR_TIME, +CSR_INSTRET, +CSR_HPMCOUNTER3, +CSR_HPMCOUNTER4, +CSR_HPMCOUNTER5, +CSR_HPMCOUNTER6, +CSR_HPMCOUNTER7, +CSR_HPMCOUNTER8, +CSR_HPMCOUNTER9, +CSR_HPMCOUNTER10, +CSR_HPMCOUNTER11, +CSR_HPMCOUNTER12, +CSR_HPMCOUNTER13, +CSR_HPMCOUNTER14, +CSR_HPMCOUNTER15, +CSR_HPMCOUNTER16, +CSR_HPMCOUNTER17, +CSR_HPMCOUNTER18, +CSR_HPMCOUNTER19, +CSR_HPMCOUNTER20, +CSR_HPMCOUNTER21, +CSR_HPMCOUNTER22, +CSR_HPMCOUNTER23, +CSR_HPMCOUNTER24, +CSR_HPMCOUNTER25, +CSR_HPMCOUNTER26, +CSR_HPMCOUNTER27, +CSR_HPMCOUNTER28, +CSR_HPMCOUNTER29, +CSR_HPMCOUNTER30, +CSR_HPMCOUNTER31, +CSR_CYCLEH, +CSR_TIMEH, +CSR_INSTRETH, +CSR_HPMCOUNTER3H, +CSR_HPMCOUNTER4H, +CSR_HPMCOUNTER5H, +CSR_HPMCOUNTER6H, +CSR_HPMCOUNTER7H, +CSR_HPMCOUNTER8H, +CSR_HPMCOUNTER9H, +CSR_HPMCOUNTER10H, +CSR_HPMCOUNTER11H, +CSR_HPMCOUNTER12H, +CSR_HPMCOUNTER13H, +CSR_HPMCOUNTER14H, +CSR_HPMCOUNTER15H, +CSR_HPMCOUNTER16H, +CSR_HPMCOUNTER17H, +CSR_HPMCOUNTER18H, +CSR_HPMCOUNTER19H, +CSR_HPMCOUNTER20H, +CSR_HPMCOUNTER21H, +CSR_HPMCOUNTER22H, +CSR_HPMCOUNTER23H, +CSR_HPMCOUNTER24H, +CSR_HPMCOUNTER25H, +CSR_HPMCOUNTER26H, +CSR_HPMCOUNTER27H, +CSR_HPMCOUNTER28H, +CSR_HPMCOUNTER29H, +CSR_HPMCOUNTER30H, +CSR_HPMCOUNTER31H, +# endif + +# if 0 +/* Machine Timers and Counters */ +CSR_MCYCLE, +CSR_MINSTRET, +CSR_MCYCLEH, +CSR_MINSTRETH, +# endif + +/* Machine Information Registers */ +CSR_MVENDORID, +CSR_MARCHID, +CSR_MIMPID, CSR_MHARTID, + +/* Machine Trap Setup */ CSR_MSTATUS, -CSR_MSTATUSH, -CSR_HSTATUS, -CSR_VSSTATUS, -CSR_MIP, -CSR_MIE, -CSR_MIDELEG, -CSR_HIDELEG, +CSR_MISA, CSR_MEDELEG, -CSR_HEDELEG, +CSR_MIDELEG, +CSR_MIE, CSR_MTVEC, -CSR_STVEC, -CSR_VSTVEC, +CSR_MCOUNTEREN, + +# if defined TARGET_RISCV32 +/* 32-bit only */ +CSR_MSTATUSH, +# endif + +/* Machine Trap Handling */ +CSR_MSCRATCH, CSR_MEPC, -CSR_SEPC, -CSR_VSEPC, CSR_MCAUSE, -CSR_SCAUSE, -CSR_VSCAUSE, CSR_MTVAL, +CSR_MIP, + +/* Supervisor Trap Setup */ +CSR_SSTATUS, +CSR_SEDELEG, +CSR_SIDELEG, +CSR_SIE, +CSR_STVEC, +CSR_SCOUNTEREN, + +/* Supervisor Trap Handling