[PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'

2022-01-04 Thread Konrad Schwarz
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.

2022-01-04 Thread Konrad Schwarz
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

2022-01-04 Thread Konrad Schwarz
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

2022-01-04 Thread Konrad Schwarz
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

2022-01-04 Thread Konrad Schwarz
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

2022-01-04 Thread Konrad Schwarz
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.

2022-01-02 Thread Konrad Schwarz
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

2022-01-02 Thread Konrad Schwarz
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

2022-01-02 Thread Konrad Schwarz
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

2022-01-02 Thread Konrad Schwarz
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

2022-01-02 Thread Konrad Schwarz
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'

2022-01-02 Thread Konrad Schwarz
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