All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/5] Improve RISC-V debugging support.
@ 2022-01-02 16:06 Konrad Schwarz
  2022-01-02 16:06 ` [PATCH v1 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
                   ` (4 more replies)
  0 siblings, 5 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-02 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt

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



^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v1 1/5] RISC-V: larger and more consistent register set for 'info registers'
  2022-01-02 16:06 [PATCH v1 0/5] Improve RISC-V debugging support Konrad Schwarz
@ 2022-01-02 16:06 ` Konrad Schwarz
  2022-01-02 16:06 ` [PATCH v1 2/5] RISC-V: monitor's print register functionality Konrad Schwarz
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-02 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt

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 <konrad.schwarz@siemens.com>
---
 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, sagark@eecs.berkeley.edu
  * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2021 Siemens AG, konrad.schwarz@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 */
+            CSR_SSCRATCH,
+            CSR_SEPC,
+            CSR_SCAUSE,
             CSR_STVAL,
+            CSR_SIP,
+
+/* Supervisor Protection and Translation */
+            CSR_SPTBR,
+            CSR_SATP,
+
+/* Hpervisor CSRs */
+            CSR_HSTATUS,
+            CSR_HEDELEG,
+            CSR_HIDELEG,
+            CSR_HIE,
+            CSR_HCOUNTEREN,
+            CSR_HGEIE,
             CSR_HTVAL,
+            CSR_HVIP,
+            CSR_HIP,
+            CSR_HTINST,
+            CSR_HGEIP,
+            CSR_HGATP,
+            CSR_HTIMEDELTA,
+            CSR_HTIMEDELTAH,
+
+/* Virtual CSRs */
+            CSR_VSSTATUS,
+            CSR_VSIE,
+            CSR_VSTVEC,
+            CSR_VSSCRATCH,
+            CSR_VSEPC,
+            CSR_VSCAUSE,
+            CSR_VSTVAL,
+            CSR_VSIP,
+            CSR_VSATP,
+
+            CSR_MTINST,
             CSR_MTVAL2,
-            CSR_MSCRATCH,
-            CSR_SSCRATCH,
-            CSR_SATP,
-            CSR_MMTE,
-            CSR_UPMBASE,
-            CSR_UPMMASK,
-            CSR_SPMBASE,
-            CSR_SPMMASK,
-            CSR_MPMBASE,
-            CSR_MPMMASK,
+
+#  if      0
+/* Enhanced Physical Memory Protection (ePMP) */
+            CSR_MSECCFG,
+            CSR_MSECCFGH,
+#  endif
+#  if      0
+/* Physical Memory Protection */
+            CSR_PMPCFG0,
+            CSR_PMPCFG1,
+            CSR_PMPCFG2,
+            CSR_PMPCFG3,
+            CSR_PMPADDR0,
+            CSR_PMPADDR1,
+            CSR_PMPADDR2,
+            CSR_PMPADDR3,
+            CSR_PMPADDR4,
+            CSR_PMPADDR5,
+            CSR_PMPADDR6,
+            CSR_PMPADDR7,
+            CSR_PMPADDR8,
+            CSR_PMPADDR9,
+            CSR_PMPADDR10,
+            CSR_PMPADDR11,
+            CSR_PMPADDR12,
+            CSR_PMPADDR13,
+            CSR_PMPADDR14,
+            CSR_PMPADDR15,
+#  endif
+
+#  if      0
+/* Debug/Trace Registers (shared with Debug Mode) */
+            CSR_TSELECT,
+            CSR_TDATA1,
+            CSR_TDATA2,
+            CSR_TDATA3,
+#  endif
+
+#  if      0
+/* Debug Mode Registers */
+            CSR_DCSR,
+            CSR_DPC,
+            CSR_DSCRATCH,
+#  endif
+
+#  if      0
+/* Performance Counters */
+            CSR_MHPMCOUNTER3,
+            CSR_MHPMCOUNTER4,
+            CSR_MHPMCOUNTER5,
+            CSR_MHPMCOUNTER6,
+            CSR_MHPMCOUNTER7,
+            CSR_MHPMCOUNTER8,
+            CSR_MHPMCOUNTER9,
+            CSR_MHPMCOUNTER10,
+            CSR_MHPMCOUNTER11,
+            CSR_MHPMCOUNTER12,
+            CSR_MHPMCOUNTER13,
+            CSR_MHPMCOUNTER14,
+            CSR_MHPMCOUNTER15,
+            CSR_MHPMCOUNTER16,
+            CSR_MHPMCOUNTER17,
+            CSR_MHPMCOUNTER18,
+            CSR_MHPMCOUNTER19,
+            CSR_MHPMCOUNTER20,
+            CSR_MHPMCOUNTER21,
+            CSR_MHPMCOUNTER22,
+            CSR_MHPMCOUNTER23,
+            CSR_MHPMCOUNTER24,
+            CSR_MHPMCOUNTER25,
+            CSR_MHPMCOUNTER26,
+            CSR_MHPMCOUNTER27,
+            CSR_MHPMCOUNTER28,
+            CSR_MHPMCOUNTER29,
+            CSR_MHPMCOUNTER30,
+            CSR_MHPMCOUNTER31,
+            CSR_MHPMEVENT3,
+            CSR_MHPMEVENT4,
+            CSR_MHPMEVENT5,
+            CSR_MHPMEVENT6,
+            CSR_MHPMEVENT7,
+            CSR_MHPMEVENT8,
+            CSR_MHPMEVENT9,
+            CSR_MHPMEVENT10,
+            CSR_MHPMEVENT11,
+            CSR_MHPMEVENT12,
+            CSR_MHPMEVENT13,
+            CSR_MHPMEVENT14,
+            CSR_MHPMEVENT15,
+            CSR_MHPMEVENT16,
+            CSR_MHPMEVENT17,
+            CSR_MHPMEVENT18,
+            CSR_MHPMEVENT19,
+            CSR_MHPMEVENT20,
+            CSR_MHPMEVENT21,
+            CSR_MHPMEVENT22,
+            CSR_MHPMEVENT23,
+            CSR_MHPMEVENT24,
+            CSR_MHPMEVENT25,
+            CSR_MHPMEVENT26,
+            CSR_MHPMEVENT27,
+            CSR_MHPMEVENT28,
+            CSR_MHPMEVENT29,
+            CSR_MHPMEVENT30,
+            CSR_MHPMEVENT31,
+            CSR_MHPMCOUNTER3H,
+            CSR_MHPMCOUNTER4H,
+            CSR_MHPMCOUNTER5H,
+            CSR_MHPMCOUNTER6H,
+            CSR_MHPMCOUNTER7H,
+            CSR_MHPMCOUNTER8H,
+            CSR_MHPMCOUNTER9H,
+            CSR_MHPMCOUNTER10H,
+            CSR_MHPMCOUNTER11H,
+            CSR_MHPMCOUNTER12H,
+            CSR_MHPMCOUNTER13H,
+            CSR_MHPMCOUNTER14H,
+            CSR_MHPMCOUNTER15H,
+            CSR_MHPMCOUNTER16H,
+            CSR_MHPMCOUNTER17H,
+            CSR_MHPMCOUNTER18H,
+            CSR_MHPMCOUNTER19H,
+            CSR_MHPMCOUNTER20H,
+            CSR_MHPMCOUNTER21H,
+            CSR_MHPMCOUNTER22H,
+            CSR_MHPMCOUNTER23H,
+            CSR_MHPMCOUNTER24H,
+            CSR_MHPMCOUNTER25H,
+            CSR_MHPMCOUNTER26H,
+            CSR_MHPMCOUNTER27H,
+            CSR_MHPMCOUNTER28H,
+            CSR_MHPMCOUNTER29H,
+            CSR_MHPMCOUNTER30H,
+            CSR_MHPMCOUNTER31H,
+#  endif
         };
 
         for (int i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
-- 
Konrad Schwarz



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v1 2/5] RISC-V: monitor's print register functionality
  2022-01-02 16:06 [PATCH v1 0/5] Improve RISC-V debugging support Konrad Schwarz
  2022-01-02 16:06 ` [PATCH v1 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
@ 2022-01-02 16:06 ` Konrad Schwarz
  2022-01-02 16:06 ` [PATCH v1 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations Konrad Schwarz
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-02 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt

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 <konrad.schwarz@siemens.com>
---
 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 <bmeng.cn@gmail.com>
+ * Copyright (c) 2021 Siemens AG, konrad.schwarz@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 = &RISCV_CPU (cs)->env;
+    riscv_csr_operations *op;
+    for (op = csr_ops; 1[&csr_ops] > op; ++op) {
+        if (!op->name) {
+            continue;
+        }
+        if (!strcmp(name, op->name)) {
+            if (RISCV_EXCP_NONE != riscv_csrrw_debug(env, op - csr_ops,
+                                 &ret_value,
+                                 0 /* new_value */,
+                                 0 /* write_mask */))
+                return -1;
+            *pval = ret_value;
+            return 0;
+        }
+    }
+    return -1;
+}
-- 
Konrad Schwarz



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v1 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations
  2022-01-02 16:06 [PATCH v1 0/5] Improve RISC-V debugging support Konrad Schwarz
  2022-01-02 16:06 ` [PATCH v1 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
  2022-01-02 16:06 ` [PATCH v1 2/5] RISC-V: monitor's print register functionality Konrad Schwarz
@ 2022-01-02 16:06 ` Konrad Schwarz
  2022-01-02 16:06 ` [PATCH v1 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
  2022-01-02 16:06 ` [PATCH v1 " Konrad Schwarz
  4 siblings, 0 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-02 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt

This is analog to the existing 'info mem' command and is implemented
using the same machinery.

Signed-off-by: Konrad Schwarz <konrad.schwarz@siemens.com>
---
 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.schwarz@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       "vaddr            paddr            "\
-                                "size             attr\n"
-#define PTE_HEADER_DELIMITER    "---------------- ---------------- "\
-                                "---------------- -------\n"
-#else
-#define PTE_HEADER_FIELDS       "vaddr    paddr            size     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);
+
+# define        VIRTUAL_WIDTH\
+        ((int) ((sizeof "ff" - sizeof "") * sizeof(target_ulong)))
+# define        PHYSICAL_WIDTH\
+        ((int) ((sizeof "ff" - sizeof "") * sizeof(hwaddr)))
+# define        ATTRIBUTE_WIDTH ((int) (sizeof "rwxugad" - sizeof ""))
+
+# define        VIRTUAL_COLUMN_WIDTH    (1 + VIRTUAL_WIDTH)
+# define        PHYSICAL_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' : '-',
-                   attr & PTE_G ? 'g' : '-',
-                   attr & PTE_A ? 'a' : '-',
-                   attr & PTE_D ? 'd' : '-');
+# if 4 == TARGET_LONG_SIZE
+#       define  TARGET_xFMT     PRIx32
+# elif 8 == TARGET_LONG_SIZE
+#       define  TARGET_xFMT     PRIx64
+# else
+#       error TARGET_LONG_SIZE not handled
+# endif
+
+    /* note: RISC-V physical addresses are actually xlen + 2 bits long
+    OTHO, QEMU wil probably never support addresses longer than 64 bits */
+    monitor_printf(mon,
+            "%-*.*" TARGET_xFMT
+            "%-*.*" PRIx64
+            "%-*.*" TARGET_xFMT
+            "%c%c%c%c%c%c%c\n",
+            VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, addr_canonical(va_bits, vaddr),
+            PHYSICAL_COLUMN_WIDTH, PHYSICAL_WIDTH, paddr,
+            VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, size,
+            attr & PTE_R ? 'r' : '-',
+            attr & PTE_W ? 'w' : '-',
+            attr & PTE_X ? 'x' : '-',
+            attr & PTE_U ? 'u' : '-',
+            attr & PTE_G ? 'g' : '-',
+            attr & PTE_A ? 'a' : '-',
+            attr & PTE_D ? 'd' : '-');
 }
 
 static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
                      int level, int ptidxbits, int ptesize, int va_bits,
+                     int guest,
                      target_ulong *vbase, hwaddr *pbase, hwaddr *last_paddr,
                      target_ulong *last_size, int *last_attr)
 {
@@ -89,7 +118,7 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
     target_ulong pte;
     int ptshift;
     int attr;
-    int idx;
+    int idx, idx_end;
 
     if (level < 0) {
         return;
@@ -98,7 +127,8 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
     ptshift = level * ptidxbits;
     pgsize = 1UL << (PGSHIFT + ptshift);
 
-    for (idx = 0; idx < (1UL << ptidxbits); idx++) {
+    for (idx = 0, idx_end = 1 << (ptidxbits + (guest ? 2 : 0));
+            idx_end > idx; idx++) {
         pte_addr = base + idx * ptesize;
         cpu_physical_memory_read(pte_addr, &pte, ptesize);
 
@@ -131,7 +161,9 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
             } else {
                 /* pointer to the next level of the page table */
                 walk_pte(mon, paddr, start, level - 1, ptidxbits, ptesize,
-                         va_bits, vbase, pbase, last_paddr,
+                         va_bits,
+                         0 /* guest */,
+                         vbase, pbase, last_paddr,
                          last_size, last_attr);
             }
         }
@@ -141,7 +173,9 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
 
 }
 
-static void mem_info_svxx(Monitor *mon, CPUArchState *env)
+static void mem_info_svxx(Monitor *mon, CPUArchState *env,
+        target_ulong const atp,
+        int guest, char const vaddr_char, char const paddr_char)
 {
     int levels, ptidxbits, ptesize, vm, va_bits;
     hwaddr base;
@@ -152,11 +186,11 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
     int last_attr;
 
     if (riscv_cpu_mxl(env) == MXL_RV32) {
-        base = (hwaddr)get_field(env->satp, SATP32_PPN) << PGSHIFT;
-        vm = get_field(env->satp, SATP32_MODE);
+        base = (hwaddr)get_field(atp, SATP32_PPN) << PGSHIFT;
+        vm = get_field(atp, SATP32_MODE);
     } else {
-        base = (hwaddr)get_field(env->satp, SATP64_PPN) << PGSHIFT;
-        vm = get_field(env->satp, SATP64_MODE);
+        base = (hwaddr)get_field(atp, SATP64_PPN) << PGSHIFT;
+        vm = get_field(atp, SATP64_MODE);
     }
 
     switch (vm) {
@@ -189,7 +223,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
     va_bits = PGSHIFT + levels * ptidxbits;
 
     /* print header */
-    print_pte_header(mon);
+    print_pte_header(mon, vaddr_char, paddr_char);
 
     vbase = -1;
     pbase = -1;
@@ -199,6 +233,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
 
     /* walk page tables, starting from address 0 */
     walk_pte(mon, base, 0, levels - 1, ptidxbits, ptesize, va_bits,
+             guest,
              &vbase, &pbase, &last_paddr, &last_size, &last_attr);
 
     /* don't forget the last one */
@@ -209,6 +244,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
 void hmp_info_mem(Monitor *mon, const QDict *qdict)
 {
     CPUArchState *env;
+    target_ulong atp;
 
     env = mon_get_cpu_env(mon);
     if (!env) {
@@ -221,19 +257,46 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
         return;
     }
 
+    atp = env->satp;
     if (riscv_cpu_mxl(env) == MXL_RV32) {
-        if (!(env->satp & SATP32_MODE)) {
+        if (!(atp & SATP32_MODE)) {
             monitor_printf(mon, "No translation or protection\n");
             return;
         }
     } else {
-        if (!(env->satp & SATP64_MODE)) {
+        if (!(atp & SATP64_MODE)) {
             monitor_printf(mon, "No translation or protection\n");
             return;
         }
     }
 
-    mem_info_svxx(mon, env);
+    mem_info_svxx(mon, env, atp, 0, 'v', 'p');
+}
+
+void hmp_info_gmem(Monitor *mon, const QDict *qdict)
+{
+    CPUArchState *env;
+    target_ulong atp;
+
+    env = mon_get_cpu_env(mon);
+    if (!env) {
+        monitor_printf(mon, "No CPU available\n");
+        return;
+    }
+
+    if (!riscv_has_ext(env, RVH)) {
+        monitor_printf(mon, "hypervisor extension not available\n");
+        return;
+    }
+
+    atp = env->hgatp;
+    if (!((MXL_RV32 == riscv_cpu_mxl(env) ? SATP32_MODE : SATP64_MODE)
+            & atp)) {
+        monitor_printf(mon, "No translation or protection\n");
+        return;
+    }
+
+    mem_info_svxx(mon, env, atp, 1, 'g', 'p');
 }
 
 static const MonitorDef monitor_defs[] = {
-- 
Konrad Schwarz



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v1 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-02 16:06 [PATCH v1 0/5] Improve RISC-V debugging support Konrad Schwarz
                   ` (2 preceding siblings ...)
  2022-01-02 16:06 ` [PATCH v1 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations Konrad Schwarz
@ 2022-01-02 16:06 ` Konrad Schwarz
  2022-01-03 12:54   ` Ralf Ramsauer
  2022-01-02 16:06 ` [PATCH v1 " Konrad Schwarz
  4 siblings, 1 reply; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-02 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt

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 <konrad.schwarz@siemens.com>
---
 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, sagark@eecs.berkeley.edu
  * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2021 Siemens AG, konrad.schwarz@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 0000000000..e8ec527f23
--- /dev/null
+++ b/target/riscv/csr32-op-gdbserver.h
@@ -0,0 +1,109 @@
+/* Copyright (c) 2021 Siemens AG, konrad.schwarz@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" },
+  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER28] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER29] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER30] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER31] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_CYCLEH] { .gdb_type = "uint32", .gdb_group = "user" },
+  [CSR_TIMEH] { .gdb_type = "uint32", .gdb_group = "user" },
+  [CSR_INSTRETH] { .gdb_type = "uint32", .gdb_group = "user" },
+  [CSR_HPMCOUNTER3H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER4H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER5H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER6H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER7H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER8H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER9H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER10H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER11H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER12H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER13H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER14H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER15H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER16H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER17H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER18H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER19H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER20H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER21H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER22H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER23H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER24H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER25H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER26H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER27H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER28H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER29H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER30H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER31H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_SSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "supervisor" },
+  [CSR_SEDELEG] { .gdb_type = "uint32", .gdb_group = "supervisor" },
+  [CSR_SIDELEG] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
+  [CSR_SIE] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
+  [CSR_STVEC] { .gdb_type = "stvec-fields", .gdb_group = "supervisor" },
+  [CSR_SCOUNTEREN] { .gdb_type = "scounteren-fields", .gdb_group = "supervisor" },
+  [CSR_SSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
+  [CSR_SEPC] { .gdb_type = "code_ptr", .gdb_group = "supervisor" },
+  [CSR_SCAUSE] { .gdb_type = "scause-fields", .gdb_group = "supervisor" },
+  [CSR_STVAL] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
+  [CSR_SIP] { .gdb_type = "sip-fields", .gdb_group = "supervisor" },
+  [CSR_SATP] { .gdb_type = "satp-fields", .gdb_group = "supervisor" },
+  [CSR_HSTATUS] { .gdb_type = "hstatus-fields", .gdb_group = "hypervisor" },
+  [CSR_HEDELEG] { .gdb_type = "hedeleg-fields", .gdb_group = "hypervisor" },
+  [CSR_HIDELEG] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
+  [CSR_HIE] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
+  [CSR_HCOUNTEREN] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HGEIE] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
+  [CSR_HGEIP] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
+  [CSR_HTVAL] { .gdb_type = "data_ptr", .gdb_group = "hypervisor" },
+  [CSR_HIP] { .gdb_type = "hip-fields", .gdb_group = "hypervisor" },
+  [CSR_HVIP] { .gdb_type = "hvip-fields", .gdb_group = "hypervisor" },
+  [CSR_HGATP] { .gdb_type = "hgatp-fields", .gdb_group = "hypervisor" },
+  [CSR_HTIMEDELTA] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HTIMEDELTAH] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HTINST] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
+  [CSR_VSSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSIE] { .gdb_type = "sie-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSTVEC] { .gdb_type = "stvec-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSEPC] { .gdb_type = "code_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSCAUSE] { .gdb_type = "scause-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSTVAL] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSIP] { .gdb_type = "sip-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSATP] { .gdb_type = "satp-fields", .gdb_group = "virtual-supervisor" },
diff --git a/target/riscv/csr64-op-gdbserver.h b/target/riscv/csr64-op-gdbserver.h
new file mode 100644
index 0000000000..fc4bc62d9e
--- /dev/null
+++ b/target/riscv/csr64-op-gdbserver.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2021 Siemens AG, konrad.schwarz@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 = "uint64", .gdb_group = "user" },
+  [CSR_TIME] { .gdb_type = "uint64", .gdb_group = "user" },
+  [CSR_INSTRET] { .gdb_type = "uint64", .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" },
+  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER28] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER29] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER30] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER31] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_SSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "supervisor" },
+  [CSR_SEDELEG] { .gdb_type = "uint64", .gdb_group = "supervisor" },
+  [CSR_SIDELEG] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
+  [CSR_SIE] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
+  [CSR_STVEC] { .gdb_type = "stvec-fields", .gdb_group = "supervisor" },
+  [CSR_SCOUNTEREN] { .gdb_type = "scounteren-fields", .gdb_group = "supervisor" },
+  [CSR_SSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
+  [CSR_SEPC] { .gdb_type = "code_ptr", .gdb_group = "supervisor" },
+  [CSR_SCAUSE] { .gdb_type = "scause-fields", .gdb_group = "supervisor" },
+  [CSR_STVAL] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
+  [CSR_SIP] { .gdb_type = "sip-fields", .gdb_group = "supervisor" },
+  [CSR_SATP] { .gdb_type = "satp-fields", .gdb_group = "supervisor" },
+  [CSR_HSTATUS] { .gdb_type = "hstatus-fields", .gdb_group = "hypervisor" },
+  [CSR_HEDELEG] { .gdb_type = "hedeleg-fields", .gdb_group = "hypervisor" },
+  [CSR_HIDELEG] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
+  [CSR_HIE] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
+  [CSR_HCOUNTEREN] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HGEIE] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
+  [CSR_HGEIP] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
+  [CSR_HTVAL] { .gdb_type = "data_ptr", .gdb_group = "hypervisor" },
+  [CSR_HIP] { .gdb_type = "hip-fields", .gdb_group = "hypervisor" },
+  [CSR_HVIP] { .gdb_type = "hvip-fields", .gdb_group = "hypervisor" },
+  [CSR_HGATP] { .gdb_type = "hgatp-fields", .gdb_group = "hypervisor" },
+  [CSR_HTIMEDELTA] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HTINST] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
+  [CSR_VSSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSIE] { .gdb_type = "sie-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSTVEC] { .gdb_type = "stvec-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSEPC] { .gdb_type = "code_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSCAUSE] { .gdb_type = "scause-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSTVAL] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSIP] { .gdb_type = "sip-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSATP] { .gdb_type = "satp-fields", .gdb_group = "virtual-supervisor" },
diff --git a/target/riscv/gdb_csr_types.c b/target/riscv/gdb_csr_types.c
new file mode 100644
index 0000000000..48b1db2b88
--- /dev/null
+++ b/target/riscv/gdb_csr_types.c
@@ -0,0 +1,333 @@
+/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
+
+#include "qemu/osdep.h"
+#include "gdb_csr_types.h"
+#define STR(X) #X
+
+char const riscv_gdb_csr_types[] =
+#ifdef TARGET_RISCV32
+   STR(
+<enum id="sstatus-fs-type" size="4">
+  <evalue name="off" value="0"/>
+  <evalue name="initial" value="1"/>
+  <evalue name="clean" value="2"/>
+  <evalue name="dirty" value="3"/>
+</enum><enum id="sstatus-xs-type" size="4">
+  <evalue name="off" value="0"/>
+  <evalue name="initial" value="1"/>
+  <evalue name="clean" value="2"/>
+  <evalue name="dirty" value="3"/>
+</enum><enum id="sstatus-uxl-type" size="4">
+  <evalue name="32" value="1"/>
+  <evalue name="64" value="2"/>
+  <evalue name="128" value="3"/>
+</enum><enum id="stvec-mode-type" size="4">
+  <evalue name="direct" value="0"/>
+  <evalue name="vectored" value="1"/>
+</enum><enum id="scause-exc-type" size="4">
+  <evalue name="instruction_address_misaligned" value="0"/>
+  <evalue name="instruction_access_fault" value="1"/>
+  <evalue name="illegal_instruction" value="2"/>
+  <evalue name="breakpoint" value="3"/>
+  <evalue name="load_address_misaligned" value="4"/>
+  <evalue name="load_access_fault" value="5"/>
+  <evalue name="store_address_misaligned" value="6"/>
+  <evalue name="store_access_fault" value="7"/>
+  <evalue name="enironment_call_from_U_mode" value="8"/>
+  <evalue name="enironment_call_from_S_mode" value="9"/>
+  <evalue name="enironment_call_from_VS_mode" value="10"/>
+  <evalue name="enironment_call_from_M_mode" value="11"/>
+  <evalue name="instruction_page_fault" value="12"/>
+  <evalue name="load_page_fault" value="13"/>
+  <evalue name="store_page_fault" value="15"/>
+  <evalue name="instruction_guest_page_fault" value="20"/>
+  <evalue name="load_guest_page_fault" value="21"/>
+  <evalue name="virtual_instruction" value="22"/>
+  <evalue name="store_guest_page_fault" value="23"/>
+</enum><enum id="satp-mode-type" size="4">
+  <evalue name="bare" value="0"/>
+  <evalue name="sv32" value="1"/>
+  <evalue name="sv39" value="8"/>
+  <evalue name="sv48" value="9"/>
+  <evalue name="sv57" value="10"/>
+  <evalue name="sv64" value="11"/>
+</enum><enum id="hgatp-mode-type" size="4">
+  <evalue name="bare" value="0"/>
+  <evalue name="sv32x4" value="1"/>
+  <evalue name="sv39x4" value="8"/>
+  <evalue name="sv48x4" value="9"/>
+  <evalue name="sv57x4" value="10"/>
+</enum><flags id="sstatus-fields" size="4">
+  <field name="sie" start="1" end="1"/>
+  <field name="mie" start="3" end="3"/>
+  <field name="spie" start="5" end="5"/>
+  <field name="ube" start="6" end="6"/>
+  <field name="mpie" start="7" end="7"/>
+  <field name="spp" start="8" end="8"/>
+  <field name="mpp" start="11" end="12"/>
+  <field name="fs" start="13" end="14" type="sstatus-fs-type"/>
+  <field name="xs" start="15" end="16" type="sstatus-xs-type"/>
+  <field name="mprv" start="17" end="17"/>
+  <field name="sum" start="18" end="18"/>
+  <field name="mxr" start="19" end="19"/>
+  <field name="tvm" start="20" end="20"/>
+  <field name="tw" start="21" end="21"/>
+  <field name="tsr" start="22" end="23"/>
+  <field name="uxl" start="32" end="33" type="sstatus-uxl-type"/>
+  <field name="sxl" start="34" end="35"/>
+  <field name="sbe" start="36" end="36"/>
+  <field name="mbe" start="37" end="37"/>
+  <field name="gva" start="38" end="38"/>
+  <field name="mpv" start="39" end="39"/>
+  <field name="sd" start="63" end="63"/>
+</flags><flags id="sie-fields" size="4">
+  <field name="ssie" start="1" end="1"/>
+  <field name="vssie" start="2" end="2"/>
+  <field name="msie" start="3" end="3"/>
+  <field name="stie" start="5" end="5"/>
+  <field name="vstie" start="6" end="6"/>
+  <field name="mtie" start="7" end="7"/>
+  <field name="seie" start="9" end="9"/>
+  <field name="vseie" start="10" end="10"/>
+  <field name="meie" start="11" end="11"/>
+  <field name="sgeie" start="12" end="12"/>
+</flags><flags id="stvec-fields" size="4">
+  <field name="mode" start="0" end="1" type="stvec-mode-type"/>
+  <field name="base" start="2" end="63"/>
+</flags><flags id="scounteren-fields" size="4">
+  <field name="cy" start="0" end="0"/>
+  <field name="tm" start="1" end="1"/>
+  <field name="ir" start="2" end="2"/>
+  <field name="hpm" start="3" end="31"/>
+</flags><flags id="scause-fields" size="4">
+  <field name="exc" start="0" end="30" type="scause-exc-type"/>
+  <field name="interrupt" start="31" end="31"/>
+</flags><flags id="sip-fields" size="4">
+  <field name="ssip" start="1" end="1"/>
+  <field name="vssip" start="2" end="2"/>
+  <field name="msip" start="3" end="3"/>
+  <field name="stip" start="5" end="5"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="mtip" start="7" end="7"/>
+  <field name="seip" start="9" end="9"/>
+  <field name="vseip" start="10" end="10"/>
+  <field name="meip" start="11" end="11"/>
+  <field name="sgeip" start="12" end="12"/>
+</flags><flags id="satp-fields" size="4">
+  <field name="ppn" start="0" end="43"/>
+  <field name="asid" start="44" end="59"/>
+  <field name="mode" start="60" end="63" type="satp-mode-type"/>
+</flags><flags id="hstatus-fields" size="4">
+  <field name="vsbe" start="5" end="5"/>
+  <field name="gva" start="6" end="6"/>
+  <field name="spv" start="7" end="7"/>
+  <field name="spvp" start="8" end="8"/>
+  <field name="hu" start="9" end="9"/>
+  <field name="vgein" start="12" end="17"/>
+  <field name="vtvm" start="20" end="20"/>
+  <field name="vtsr" start="22" end="22"/>
+  <field name="vsxl" start="32" end="33"/>
+</flags><flags id="hedeleg-fields" size="4">
+  <field name="instruction_address_misaligned" start="0" end="0"/>
+  <field name="instruction_access_fault" start="1" end="1"/>
+  <field name="illegal_instruction" start="2" end="2"/>
+  <field name="breakpoint" start="3" end="3"/>
+  <field name="load_address_misaligned" start="4" end="4"/>
+  <field name="load_access_fault" start="5" end="5"/>
+  <field name="store_address_misaligned" start="6" end="6"/>
+  <field name="store_access_fault" start="7" end="7"/>
+  <field name="enironment_call_from_U_mode" start="8" end="8"/>
+  <field name="enironment_call_from_S_mode" start="9" end="9"/>
+  <field name="enironment_call_from_VS_mode" start="10" end="10"/>
+  <field name="enironment_call_from_M_mode" start="11" end="11"/>
+  <field name="instruction_page_fault" start="12" end="12"/>
+  <field name="load_page_fault" start="13" end="13"/>
+  <field name="store_page_fault" start="15" end="15"/>
+  <field name="instruction_guest_page_fault" start="20" end="20"/>
+  <field name="load_guest_page_fault" start="21" end="21"/>
+  <field name="virtual_instruction" start="22" end="22"/>
+  <field name="store_guest_page_fault" start="23" end="23"/>
+</flags><flags id="hie-fields" size="4">
+  <field name="vssie" start="2" end="2"/>
+  <field name="vstie" start="6" end="6"/>
+  <field name="vseie" start="10" end="10"/>
+  <field name="sgeie" start="12" end="12"/>
+</flags><flags id="hip-fields" size="4">
+  <field name="vssip" start="2" end="2"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="vseip" start="10" end="10"/>
+  <field name="sgeip" start="12" end="12"/>
+</flags><flags id="hvip-fields" size="4">
+  <field name="vssip" start="2" end="2"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="vseip" start="10" end="10"/>
+</flags><flags id="hgatp-fields" size="4">
+  <field name="ppn" start="0" end="43"/>
+  <field name="vmid" start="44" end="57"/>
+  <field name="mode" start="60" end="63" type="hgatp-mode-type"/>
+</flags>
+)
+#elif defined TARGET_RISCV64
+   STR(
+<enum id="sstatus-fs-type" size="8">
+  <evalue name="off" value="0"/>
+  <evalue name="initial" value="1"/>
+  <evalue name="clean" value="2"/>
+  <evalue name="dirty" value="3"/>
+</enum><enum id="sstatus-xs-type" size="8">
+  <evalue name="off" value="0"/>
+  <evalue name="initial" value="1"/>
+  <evalue name="clean" value="2"/>
+  <evalue name="dirty" value="3"/>
+</enum><enum id="sstatus-uxl-type" size="8">
+  <evalue name="32" value="1"/>
+  <evalue name="64" value="2"/>
+  <evalue name="128" value="3"/>
+</enum><enum id="stvec-mode-type" size="8">
+  <evalue name="direct" value="0"/>
+  <evalue name="vectored" value="1"/>
+</enum><enum id="scause-exc-type" size="8">
+  <evalue name="instruction_address_misaligned" value="0"/>
+  <evalue name="instruction_access_fault" value="1"/>
+  <evalue name="illegal_instruction" value="2"/>
+  <evalue name="breakpoint" value="3"/>
+  <evalue name="load_address_misaligned" value="4"/>
+  <evalue name="load_access_fault" value="5"/>
+  <evalue name="store_address_misaligned" value="6"/>
+  <evalue name="store_access_fault" value="7"/>
+  <evalue name="enironment_call_from_U_mode" value="8"/>
+  <evalue name="enironment_call_from_S_mode" value="9"/>
+  <evalue name="enironment_call_from_VS_mode" value="10"/>
+  <evalue name="enironment_call_from_M_mode" value="11"/>
+  <evalue name="instruction_page_fault" value="12"/>
+  <evalue name="load_page_fault" value="13"/>
+  <evalue name="store_page_fault" value="15"/>
+  <evalue name="instruction_guest_page_fault" value="20"/>
+  <evalue name="load_guest_page_fault" value="21"/>
+  <evalue name="virtual_instruction" value="22"/>
+  <evalue name="store_guest_page_fault" value="23"/>
+</enum><enum id="satp-mode-type" size="8">
+  <evalue name="bare" value="0"/>
+  <evalue name="sv32" value="1"/>
+  <evalue name="sv39" value="8"/>
+  <evalue name="sv48" value="9"/>
+  <evalue name="sv57" value="10"/>
+  <evalue name="sv64" value="11"/>
+</enum><enum id="hgatp-mode-type" size="8">
+  <evalue name="bare" value="0"/>
+  <evalue name="sv32x4" value="1"/>
+  <evalue name="sv39x4" value="8"/>
+  <evalue name="sv48x4" value="9"/>
+  <evalue name="sv57x4" value="10"/>
+</enum><flags id="sstatus-fields" size="8">
+  <field name="sie" start="1" end="1"/>
+  <field name="mie" start="3" end="3"/>
+  <field name="spie" start="5" end="5"/>
+  <field name="ube" start="6" end="6"/>
+  <field name="mpie" start="7" end="7"/>
+  <field name="spp" start="8" end="8"/>
+  <field name="mpp" start="11" end="12"/>
+  <field name="fs" start="13" end="14" type="sstatus-fs-type"/>
+  <field name="xs" start="15" end="16" type="sstatus-xs-type"/>
+  <field name="mprv" start="17" end="17"/>
+  <field name="sum" start="18" end="18"/>
+  <field name="mxr" start="19" end="19"/>
+  <field name="tvm" start="20" end="20"/>
+  <field name="tw" start="21" end="21"/>
+  <field name="tsr" start="22" end="23"/>
+  <field name="uxl" start="32" end="33" type="sstatus-uxl-type"/>
+  <field name="sxl" start="34" end="35"/>
+  <field name="sbe" start="36" end="36"/>
+  <field name="mbe" start="37" end="37"/>
+  <field name="gva" start="38" end="38"/>
+  <field name="mpv" start="39" end="39"/>
+  <field name="sd" start="63" end="63"/>
+</flags><flags id="sie-fields" size="8">
+  <field name="ssie" start="1" end="1"/>
+  <field name="vssie" start="2" end="2"/>
+  <field name="msie" start="3" end="3"/>
+  <field name="stie" start="5" end="5"/>
+  <field name="vstie" start="6" end="6"/>
+  <field name="mtie" start="7" end="7"/>
+  <field name="seie" start="9" end="9"/>
+  <field name="vseie" start="10" end="10"/>
+  <field name="meie" start="11" end="11"/>
+  <field name="sgeie" start="12" end="12"/>
+</flags><flags id="stvec-fields" size="8">
+  <field name="mode" start="0" end="1" type="stvec-mode-type"/>
+  <field name="base" start="2" end="63"/>
+</flags><flags id="scounteren-fields" size="8">
+  <field name="cy" start="0" end="0"/>
+  <field name="tm" start="1" end="1"/>
+  <field name="ir" start="2" end="2"/>
+  <field name="hpm" start="3" end="31"/>
+</flags><flags id="scause-fields" size="8">
+  <field name="exc" start="0" end="62" type="scause-exc-type"/>
+  <field name="interrupt" start="63" end="63"/>
+</flags><flags id="sip-fields" size="8">
+  <field name="ssip" start="1" end="1"/>
+  <field name="vssip" start="2" end="2"/>
+  <field name="msip" start="3" end="3"/>
+  <field name="stip" start="5" end="5"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="mtip" start="7" end="7"/>
+  <field name="seip" start="9" end="9"/>
+  <field name="vseip" start="10" end="10"/>
+  <field name="meip" start="11" end="11"/>
+  <field name="sgeip" start="12" end="12"/>
+</flags><flags id="satp-fields" size="8">
+  <field name="ppn" start="0" end="43"/>
+  <field name="asid" start="44" end="59"/>
+  <field name="mode" start="60" end="63" type="satp-mode-type"/>
+</flags><flags id="hstatus-fields" size="8">
+  <field name="vsbe" start="5" end="5"/>
+  <field name="gva" start="6" end="6"/>
+  <field name="spv" start="7" end="7"/>
+  <field name="spvp" start="8" end="8"/>
+  <field name="hu" start="9" end="9"/>
+  <field name="vgein" start="12" end="17"/>
+  <field name="vtvm" start="20" end="20"/>
+  <field name="vtsr" start="22" end="22"/>
+  <field name="vsxl" start="32" end="33"/>
+</flags><flags id="hedeleg-fields" size="8">
+  <field name="instruction_address_misaligned" start="0" end="0"/>
+  <field name="instruction_access_fault" start="1" end="1"/>
+  <field name="illegal_instruction" start="2" end="2"/>
+  <field name="breakpoint" start="3" end="3"/>
+  <field name="load_address_misaligned" start="4" end="4"/>
+  <field name="load_access_fault" start="5" end="5"/>
+  <field name="store_address_misaligned" start="6" end="6"/>
+  <field name="store_access_fault" start="7" end="7"/>
+  <field name="enironment_call_from_U_mode" start="8" end="8"/>
+  <field name="enironment_call_from_S_mode" start="9" end="9"/>
+  <field name="enironment_call_from_VS_mode" start="10" end="10"/>
+  <field name="enironment_call_from_M_mode" start="11" end="11"/>
+  <field name="instruction_page_fault" start="12" end="12"/>
+  <field name="load_page_fault" start="13" end="13"/>
+  <field name="store_page_fault" start="15" end="15"/>
+  <field name="instruction_guest_page_fault" start="20" end="20"/>
+  <field name="load_guest_page_fault" start="21" end="21"/>
+  <field name="virtual_instruction" start="22" end="22"/>
+  <field name="store_guest_page_fault" start="23" end="23"/>
+</flags><flags id="hie-fields" size="8">
+  <field name="vssie" start="2" end="2"/>
+  <field name="vstie" start="6" end="6"/>
+  <field name="vseie" start="10" end="10"/>
+  <field name="sgeie" start="12" end="12"/>
+</flags><flags id="hip-fields" size="8">
+  <field name="vssip" start="2" end="2"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="vseip" start="10" end="10"/>
+  <field name="sgeip" start="12" end="12"/>
+</flags><flags id="hvip-fields" size="8">
+  <field name="vssip" start="2" end="2"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="vseip" start="10" end="10"/>
+</flags><flags id="hgatp-fields" size="8">
+  <field name="ppn" start="0" end="43"/>
+  <field name="vmid" start="44" end="57"/>
+  <field name="mode" start="60" end="63" type="hgatp-mode-type"/>
+</flags>
+)
+# endif
+;
diff --git a/target/riscv/gdb_csr_types.h b/target/riscv/gdb_csr_types.h
new file mode 100644
index 0000000000..e55c978ac8
--- /dev/null
+++ b/target/riscv/gdb_csr_types.h
@@ -0,0 +1,3 @@
+/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
+
+extern char const riscv_gdb_csr_types[];
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 23429179e2..9c3f68eeaf 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -2,6 +2,7 @@
  * RISC-V GDB Server Stub
  *
  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2021 Siemens AG, konrad.schwarz@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,
@@ -155,6 +156,9 @@ static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
     return 0;
 }
 
+#include "gdb_csr_types.h"
+#include "gdb_csr_type_group.h"
+
 static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
@@ -163,21 +167,33 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
     riscv_csr_predicate_fn predicate;
     int bitsize = 16 << env->misa_mxl_max;
     int i;
+    riscv_csr_operations *csr_op;
+    struct riscv_gdb_csr_tg const *csr_tg;
 
     g_string_printf(s, "<?xml version=\"1.0\"?>");
     g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
     g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
 
-    for (i = 0; i < CSR_TABLE_SIZE; i++) {
-        predicate = csr_ops[i].predicate;
+    g_string_append(s, riscv_gdb_csr_types);
+
+    for (i = 0, csr_op = csr_ops, csr_tg = riscv_gdb_csr_type_group;
+            i < CSR_TABLE_SIZE; ++csr_op, ++csr_tg, ++i) {
+        predicate = csr_op->predicate;
         if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
-            if (csr_ops[i].name) {
-                g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
+            if (csr_op->name) {
+                g_string_append_printf(s, "<reg name=\"%s\"", csr_op->name);
             } else {
                 g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
             }
             g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
-            g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
+            g_string_append_printf(s, " regnum=\"%d\"", base_reg + i);
+            if (csr_tg->gdb_type) {
+                g_string_append_printf(s, " type=\"%s\"", csr_tg->gdb_type);
+            }
+            if (csr_tg->gdb_group) {
+                g_string_append_printf(s, " group=\"%s\"", csr_tg->gdb_group);
+            }
+            g_string_append(s, " />\n");
         }
     }
 
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index d5e0bc93ea..e1945e54c4 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -25,7 +25,9 @@ riscv_softmmu_ss.add(files(
   'arch_dump.c',
   'pmp.c',
   'monitor.c',
-  'machine.c'
+  'machine.c',
+  'gdb_csr_types.c',
+  'gdb_csr_type_group.c'
 ))
 
 target_arch += {'riscv': riscv_ss}
-- 
Konrad Schwarz



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v1 5/5] RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register
  2022-01-02 16:06 [PATCH v1 0/5] Improve RISC-V debugging support Konrad Schwarz
                   ` (3 preceding siblings ...)
  2022-01-02 16:06 ` [PATCH v1 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
@ 2022-01-02 16:06 ` Konrad Schwarz
  4 siblings, 0 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-02 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt

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 <konrad.schwarz@siemens.com>
---
 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.  -->
 
+<!-- Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com -->
+
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
-<feature name="org.gnu.gdb.riscv.virtual">
-  <reg name="priv" bitsize="32"/>
+
+<feature	name="org.gnu.gdb.riscv.virtual" >
+
+<enum id="priv-current_priv-type" size="4" >
+	<evalue	name="user"	value="0" />
+	<evalue	name="supervisor"	value="1" />
+	<evalue	name="machine"	value="3" />
+</enum>
+
+
+<flags id="priv-fields"	size="4" >
+	<field	name="current_priv"	start="0"	end="1"
+		type="priv-current_priv-type" />
+	<field	name="v"	start="2"	end="2" />
+</flags>
+
+
+<reg	name="priv"
+		bitsize="32"
+		regnum="69"
+		save-restore="no"
+		type="priv-fields"
+		group="gdb-virtual"
+/>
+
+
 </feature>
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.  -->
 
+<!-- Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com -->
+
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
-<feature name="org.gnu.gdb.riscv.virtual">
-  <reg name="priv" bitsize="64"/>
+
+<feature	name="org.gnu.gdb.riscv.virtual" >
+
+<enum id="priv-current_priv-type" size="8" >
+	<evalue	name="user"	value="0" />
+	<evalue	name="supervisor"	value="1" />
+	<evalue	name="machine"	value="3" />
+</enum>
+
+
+<flags id="priv-fields"	size="8" >
+	<field	name="current_priv"	start="0"	end="1"
+		type="priv-current_priv-type" />
+	<field	name="v"	start="2"	end="2" />
+</flags>
+
+
+<reg	name="priv"
+		bitsize="64"
+		regnum="69"
+		save-restore="no"
+		type="priv-fields"
+		group="gdb-virtual"
+/>
+
+
 </feature>
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 = &cpu->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



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v1 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-02 16:06 ` [PATCH v1 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
@ 2022-01-03 12:54   ` Ralf Ramsauer
  2022-01-04 15:51     ` [PATCH v2 0/5] Improve RISC-V debugging support Konrad Schwarz
  0 siblings, 1 reply; 26+ messages in thread
From: Ralf Ramsauer @ 2022-01-03 12:54 UTC (permalink / raw)
  To: Konrad Schwarz, qemu-devel; +Cc: Palmer Dabbelt, Bin Meng, Alistair Francis



On 02/01/2022 17:06, Konrad Schwarz wrote:
> 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 <konrad.schwarz@siemens.com>
> ---
>   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, sagark@eecs.berkeley.edu
>    * Copyright (c) 2017-2018 SiFive, Inc.
> + * Copyright (c) 2021 Siemens AG, konrad.schwarz@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 0000000000..e8ec527f23
> --- /dev/null
> +++ b/target/riscv/csr32-op-gdbserver.h
> @@ -0,0 +1,109 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@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" },
> +  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER28] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER29] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER30] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER31] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_CYCLEH] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_TIMEH] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_INSTRETH] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER3H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER4H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER5H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER6H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER7H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER8H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER9H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER10H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER11H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER12H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER13H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER14H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER15H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER16H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER17H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER18H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER19H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER20H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER21H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER22H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER23H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER24H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER25H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER26H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER27H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER28H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER29H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER30H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER31H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_SSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "supervisor" },
> +  [CSR_SEDELEG] { .gdb_type = "uint32", .gdb_group = "supervisor" },
> +  [CSR_SIDELEG] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
> +  [CSR_SIE] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
> +  [CSR_STVEC] { .gdb_type = "stvec-fields", .gdb_group = "supervisor" },
> +  [CSR_SCOUNTEREN] { .gdb_type = "scounteren-fields", .gdb_group = "supervisor" },
> +  [CSR_SSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
> +  [CSR_SEPC] { .gdb_type = "code_ptr", .gdb_group = "supervisor" },
> +  [CSR_SCAUSE] { .gdb_type = "scause-fields", .gdb_group = "supervisor" },
> +  [CSR_STVAL] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
> +  [CSR_SIP] { .gdb_type = "sip-fields", .gdb_group = "supervisor" },
> +  [CSR_SATP] { .gdb_type = "satp-fields", .gdb_group = "supervisor" },
> +  [CSR_HSTATUS] { .gdb_type = "hstatus-fields", .gdb_group = "hypervisor" },
> +  [CSR_HEDELEG] { .gdb_type = "hedeleg-fields", .gdb_group = "hypervisor" },
> +  [CSR_HIDELEG] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
> +  [CSR_HIE] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
> +  [CSR_HCOUNTEREN] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HGEIE] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
> +  [CSR_HGEIP] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
> +  [CSR_HTVAL] { .gdb_type = "data_ptr", .gdb_group = "hypervisor" },
> +  [CSR_HIP] { .gdb_type = "hip-fields", .gdb_group = "hypervisor" },
> +  [CSR_HVIP] { .gdb_type = "hvip-fields", .gdb_group = "hypervisor" },
> +  [CSR_HGATP] { .gdb_type = "hgatp-fields", .gdb_group = "hypervisor" },
> +  [CSR_HTIMEDELTA] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HTIMEDELTAH] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HTINST] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
> +  [CSR_VSSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSIE] { .gdb_type = "sie-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSTVEC] { .gdb_type = "stvec-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSEPC] { .gdb_type = "code_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSCAUSE] { .gdb_type = "scause-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSTVAL] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSIP] { .gdb_type = "sip-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSATP] { .gdb_type = "satp-fields", .gdb_group = "virtual-supervisor" },
> diff --git a/target/riscv/csr64-op-gdbserver.h b/target/riscv/csr64-op-gdbserver.h
> new file mode 100644
> index 0000000000..fc4bc62d9e
> --- /dev/null
> +++ b/target/riscv/csr64-op-gdbserver.h
> @@ -0,0 +1,76 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@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 = "uint64", .gdb_group = "user" },
> +  [CSR_TIME] { .gdb_type = "uint64", .gdb_group = "user" },
> +  [CSR_INSTRET] { .gdb_type = "uint64", .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" },
> +  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER28] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER29] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER30] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER31] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_SSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "supervisor" },
> +  [CSR_SEDELEG] { .gdb_type = "uint64", .gdb_group = "supervisor" },
> +  [CSR_SIDELEG] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
> +  [CSR_SIE] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
> +  [CSR_STVEC] { .gdb_type = "stvec-fields", .gdb_group = "supervisor" },
> +  [CSR_SCOUNTEREN] { .gdb_type = "scounteren-fields", .gdb_group = "supervisor" },
> +  [CSR_SSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
> +  [CSR_SEPC] { .gdb_type = "code_ptr", .gdb_group = "supervisor" },
> +  [CSR_SCAUSE] { .gdb_type = "scause-fields", .gdb_group = "supervisor" },
> +  [CSR_STVAL] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
> +  [CSR_SIP] { .gdb_type = "sip-fields", .gdb_group = "supervisor" },
> +  [CSR_SATP] { .gdb_type = "satp-fields", .gdb_group = "supervisor" },
> +  [CSR_HSTATUS] { .gdb_type = "hstatus-fields", .gdb_group = "hypervisor" },
> +  [CSR_HEDELEG] { .gdb_type = "hedeleg-fields", .gdb_group = "hypervisor" },
> +  [CSR_HIDELEG] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
> +  [CSR_HIE] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
> +  [CSR_HCOUNTEREN] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HGEIE] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
> +  [CSR_HGEIP] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
> +  [CSR_HTVAL] { .gdb_type = "data_ptr", .gdb_group = "hypervisor" },
> +  [CSR_HIP] { .gdb_type = "hip-fields", .gdb_group = "hypervisor" },
> +  [CSR_HVIP] { .gdb_type = "hvip-fields", .gdb_group = "hypervisor" },
> +  [CSR_HGATP] { .gdb_type = "hgatp-fields", .gdb_group = "hypervisor" },
> +  [CSR_HTIMEDELTA] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HTINST] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
> +  [CSR_VSSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSIE] { .gdb_type = "sie-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSTVEC] { .gdb_type = "stvec-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSEPC] { .gdb_type = "code_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSCAUSE] { .gdb_type = "scause-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSTVAL] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSIP] { .gdb_type = "sip-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSATP] { .gdb_type = "satp-fields", .gdb_group = "virtual-supervisor" },
> diff --git a/target/riscv/gdb_csr_types.c b/target/riscv/gdb_csr_types.c
> new file mode 100644
> index 0000000000..48b1db2b88
> --- /dev/null
> +++ b/target/riscv/gdb_csr_types.c
> @@ -0,0 +1,333 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
> +
> +#include "qemu/osdep.h"
> +#include "gdb_csr_types.h"
> +#define STR(X) #X
> +
> +char const riscv_gdb_csr_types[] =
> +#ifdef TARGET_RISCV32
> +   STR(
> +<enum id="sstatus-fs-type" size="4">
> +  <evalue name="off" value="0"/>
> +  <evalue name="initial" value="1"/>
> +  <evalue name="clean" value="2"/>
> +  <evalue name="dirty" value="3"/>
> +</enum><enum id="sstatus-xs-type" size="4">
> +  <evalue name="off" value="0"/>
> +  <evalue name="initial" value="1"/>
> +  <evalue name="clean" value="2"/>
> +  <evalue name="dirty" value="3"/>
> +</enum><enum id="sstatus-uxl-type" size="4">
> +  <evalue name="32" value="1"/>
> +  <evalue name="64" value="2"/>
> +  <evalue name="128" value="3"/>
> +</enum><enum id="stvec-mode-type" size="4">
> +  <evalue name="direct" value="0"/>
> +  <evalue name="vectored" value="1"/>
> +</enum><enum id="scause-exc-type" size="4">
> +  <evalue name="instruction_address_misaligned" value="0"/>
> +  <evalue name="instruction_access_fault" value="1"/>
> +  <evalue name="illegal_instruction" value="2"/>
> +  <evalue name="breakpoint" value="3"/>
> +  <evalue name="load_address_misaligned" value="4"/>
> +  <evalue name="load_access_fault" value="5"/>
> +  <evalue name="store_address_misaligned" value="6"/>
> +  <evalue name="store_access_fault" value="7"/>
> +  <evalue name="enironment_call_from_U_mode" value="8"/>
> +  <evalue name="enironment_call_from_S_mode" value="9"/>
> +  <evalue name="enironment_call_from_VS_mode" value="10"/>
> +  <evalue name="enironment_call_from_M_mode" value="11"/>
> +  <evalue name="instruction_page_fault" value="12"/>
> +  <evalue name="load_page_fault" value="13"/>
> +  <evalue name="store_page_fault" value="15"/>
> +  <evalue name="instruction_guest_page_fault" value="20"/>
> +  <evalue name="load_guest_page_fault" value="21"/>
> +  <evalue name="virtual_instruction" value="22"/>
> +  <evalue name="store_guest_page_fault" value="23"/>
> +</enum><enum id="satp-mode-type" size="4">
> +  <evalue name="bare" value="0"/>
> +  <evalue name="sv32" value="1"/>
> +  <evalue name="sv39" value="8"/>
> +  <evalue name="sv48" value="9"/>
> +  <evalue name="sv57" value="10"/>
> +  <evalue name="sv64" value="11"/>
> +</enum><enum id="hgatp-mode-type" size="4">
> +  <evalue name="bare" value="0"/>
> +  <evalue name="sv32x4" value="1"/>
> +  <evalue name="sv39x4" value="8"/>
> +  <evalue name="sv48x4" value="9"/>
> +  <evalue name="sv57x4" value="10"/>
> +</enum><flags id="sstatus-fields" size="4">
> +  <field name="sie" start="1" end="1"/>
> +  <field name="mie" start="3" end="3"/>
> +  <field name="spie" start="5" end="5"/>
> +  <field name="ube" start="6" end="6"/>
> +  <field name="mpie" start="7" end="7"/>
> +  <field name="spp" start="8" end="8"/>
> +  <field name="mpp" start="11" end="12"/>
> +  <field name="fs" start="13" end="14" type="sstatus-fs-type"/>
> +  <field name="xs" start="15" end="16" type="sstatus-xs-type"/>
> +  <field name="mprv" start="17" end="17"/>
> +  <field name="sum" start="18" end="18"/>
> +  <field name="mxr" start="19" end="19"/>
> +  <field name="tvm" start="20" end="20"/>
> +  <field name="tw" start="21" end="21"/>
> +  <field name="tsr" start="22" end="23"/>
> +  <field name="uxl" start="32" end="33" type="sstatus-uxl-type"/>
> +  <field name="sxl" start="34" end="35"/>
> +  <field name="sbe" start="36" end="36"/>
> +  <field name="mbe" start="37" end="37"/>
> +  <field name="gva" start="38" end="38"/>
> +  <field name="mpv" start="39" end="39"/>
> +  <field name="sd" start="63" end="63"/>
> +</flags><flags id="sie-fields" size="4">
> +  <field name="ssie" start="1" end="1"/>
> +  <field name="vssie" start="2" end="2"/>
> +  <field name="msie" start="3" end="3"/>
> +  <field name="stie" start="5" end="5"/>
> +  <field name="vstie" start="6" end="6"/>
> +  <field name="mtie" start="7" end="7"/>
> +  <field name="seie" start="9" end="9"/>
> +  <field name="vseie" start="10" end="10"/>
> +  <field name="meie" start="11" end="11"/>
> +  <field name="sgeie" start="12" end="12"/>
> +</flags><flags id="stvec-fields" size="4">
> +  <field name="mode" start="0" end="1" type="stvec-mode-type"/>
> +  <field name="base" start="2" end="63"/>
> +</flags><flags id="scounteren-fields" size="4">
> +  <field name="cy" start="0" end="0"/>
> +  <field name="tm" start="1" end="1"/>
> +  <field name="ir" start="2" end="2"/>
> +  <field name="hpm" start="3" end="31"/>
> +</flags><flags id="scause-fields" size="4">
> +  <field name="exc" start="0" end="30" type="scause-exc-type"/>
> +  <field name="interrupt" start="31" end="31"/>
> +</flags><flags id="sip-fields" size="4">
> +  <field name="ssip" start="1" end="1"/>
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="msip" start="3" end="3"/>
> +  <field name="stip" start="5" end="5"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="mtip" start="7" end="7"/>
> +  <field name="seip" start="9" end="9"/>
> +  <field name="vseip" start="10" end="10"/>
> +  <field name="meip" start="11" end="11"/>
> +  <field name="sgeip" start="12" end="12"/>
> +</flags><flags id="satp-fields" size="4">
> +  <field name="ppn" start="0" end="43"/>
> +  <field name="asid" start="44" end="59"/>
> +  <field name="mode" start="60" end="63" type="satp-mode-type"/>
> +</flags><flags id="hstatus-fields" size="4">
> +  <field name="vsbe" start="5" end="5"/>
> +  <field name="gva" start="6" end="6"/>
> +  <field name="spv" start="7" end="7"/>
> +  <field name="spvp" start="8" end="8"/>
> +  <field name="hu" start="9" end="9"/>
> +  <field name="vgein" start="12" end="17"/>
> +  <field name="vtvm" start="20" end="20"/>
> +  <field name="vtsr" start="22" end="22"/>
> +  <field name="vsxl" start="32" end="33"/>
> +</flags><flags id="hedeleg-fields" size="4">
> +  <field name="instruction_address_misaligned" start="0" end="0"/>
> +  <field name="instruction_access_fault" start="1" end="1"/>
> +  <field name="illegal_instruction" start="2" end="2"/>
> +  <field name="breakpoint" start="3" end="3"/>
> +  <field name="load_address_misaligned" start="4" end="4"/>
> +  <field name="load_access_fault" start="5" end="5"/>
> +  <field name="store_address_misaligned" start="6" end="6"/>
> +  <field name="store_access_fault" start="7" end="7"/>
> +  <field name="enironment_call_from_U_mode" start="8" end="8"/>
> +  <field name="enironment_call_from_S_mode" start="9" end="9"/>
> +  <field name="enironment_call_from_VS_mode" start="10" end="10"/>
> +  <field name="enironment_call_from_M_mode" start="11" end="11"/>
> +  <field name="instruction_page_fault" start="12" end="12"/>
> +  <field name="load_page_fault" start="13" end="13"/>
> +  <field name="store_page_fault" start="15" end="15"/>
> +  <field name="instruction_guest_page_fault" start="20" end="20"/>
> +  <field name="load_guest_page_fault" start="21" end="21"/>
> +  <field name="virtual_instruction" start="22" end="22"/>
> +  <field name="store_guest_page_fault" start="23" end="23"/>
> +</flags><flags id="hie-fields" size="4">
> +  <field name="vssie" start="2" end="2"/>
> +  <field name="vstie" start="6" end="6"/>
> +  <field name="vseie" start="10" end="10"/>
> +  <field name="sgeie" start="12" end="12"/>
> +</flags><flags id="hip-fields" size="4">
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="vseip" start="10" end="10"/>
> +  <field name="sgeip" start="12" end="12"/>
> +</flags><flags id="hvip-fields" size="4">
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="vseip" start="10" end="10"/>
> +</flags><flags id="hgatp-fields" size="4">
> +  <field name="ppn" start="0" end="43"/>
> +  <field name="vmid" start="44" end="57"/>
> +  <field name="mode" start="60" end="63" type="hgatp-mode-type"/>
> +</flags>
> +)
> +#elif defined TARGET_RISCV64
> +   STR(
> +<enum id="sstatus-fs-type" size="8">
> +  <evalue name="off" value="0"/>
> +  <evalue name="initial" value="1"/>
> +  <evalue name="clean" value="2"/>
> +  <evalue name="dirty" value="3"/>
> +</enum><enum id="sstatus-xs-type" size="8">
> +  <evalue name="off" value="0"/>
> +  <evalue name="initial" value="1"/>
> +  <evalue name="clean" value="2"/>
> +  <evalue name="dirty" value="3"/>
> +</enum><enum id="sstatus-uxl-type" size="8">
> +  <evalue name="32" value="1"/>
> +  <evalue name="64" value="2"/>
> +  <evalue name="128" value="3"/>
> +</enum><enum id="stvec-mode-type" size="8">
> +  <evalue name="direct" value="0"/>
> +  <evalue name="vectored" value="1"/>
> +</enum><enum id="scause-exc-type" size="8">
> +  <evalue name="instruction_address_misaligned" value="0"/>
> +  <evalue name="instruction_access_fault" value="1"/>
> +  <evalue name="illegal_instruction" value="2"/>
> +  <evalue name="breakpoint" value="3"/>
> +  <evalue name="load_address_misaligned" value="4"/>
> +  <evalue name="load_access_fault" value="5"/>
> +  <evalue name="store_address_misaligned" value="6"/>
> +  <evalue name="store_access_fault" value="7"/>
> +  <evalue name="enironment_call_from_U_mode" value="8"/>
> +  <evalue name="enironment_call_from_S_mode" value="9"/>
> +  <evalue name="enironment_call_from_VS_mode" value="10"/>
> +  <evalue name="enironment_call_from_M_mode" value="11"/>
> +  <evalue name="instruction_page_fault" value="12"/>
> +  <evalue name="load_page_fault" value="13"/>
> +  <evalue name="store_page_fault" value="15"/>
> +  <evalue name="instruction_guest_page_fault" value="20"/>
> +  <evalue name="load_guest_page_fault" value="21"/>
> +  <evalue name="virtual_instruction" value="22"/>
> +  <evalue name="store_guest_page_fault" value="23"/>
> +</enum><enum id="satp-mode-type" size="8">
> +  <evalue name="bare" value="0"/>
> +  <evalue name="sv32" value="1"/>
> +  <evalue name="sv39" value="8"/>
> +  <evalue name="sv48" value="9"/>
> +  <evalue name="sv57" value="10"/>
> +  <evalue name="sv64" value="11"/>
> +</enum><enum id="hgatp-mode-type" size="8">
> +  <evalue name="bare" value="0"/>
> +  <evalue name="sv32x4" value="1"/>
> +  <evalue name="sv39x4" value="8"/>
> +  <evalue name="sv48x4" value="9"/>
> +  <evalue name="sv57x4" value="10"/>
> +</enum><flags id="sstatus-fields" size="8">
> +  <field name="sie" start="1" end="1"/>
> +  <field name="mie" start="3" end="3"/>
> +  <field name="spie" start="5" end="5"/>
> +  <field name="ube" start="6" end="6"/>
> +  <field name="mpie" start="7" end="7"/>
> +  <field name="spp" start="8" end="8"/>
> +  <field name="mpp" start="11" end="12"/>
> +  <field name="fs" start="13" end="14" type="sstatus-fs-type"/>
> +  <field name="xs" start="15" end="16" type="sstatus-xs-type"/>
> +  <field name="mprv" start="17" end="17"/>
> +  <field name="sum" start="18" end="18"/>
> +  <field name="mxr" start="19" end="19"/>
> +  <field name="tvm" start="20" end="20"/>
> +  <field name="tw" start="21" end="21"/>
> +  <field name="tsr" start="22" end="23"/>
> +  <field name="uxl" start="32" end="33" type="sstatus-uxl-type"/>
> +  <field name="sxl" start="34" end="35"/>
> +  <field name="sbe" start="36" end="36"/>
> +  <field name="mbe" start="37" end="37"/>
> +  <field name="gva" start="38" end="38"/>
> +  <field name="mpv" start="39" end="39"/>
> +  <field name="sd" start="63" end="63"/>
> +</flags><flags id="sie-fields" size="8">
> +  <field name="ssie" start="1" end="1"/>
> +  <field name="vssie" start="2" end="2"/>
> +  <field name="msie" start="3" end="3"/>
> +  <field name="stie" start="5" end="5"/>
> +  <field name="vstie" start="6" end="6"/>
> +  <field name="mtie" start="7" end="7"/>
> +  <field name="seie" start="9" end="9"/>
> +  <field name="vseie" start="10" end="10"/>
> +  <field name="meie" start="11" end="11"/>
> +  <field name="sgeie" start="12" end="12"/>
> +</flags><flags id="stvec-fields" size="8">
> +  <field name="mode" start="0" end="1" type="stvec-mode-type"/>
> +  <field name="base" start="2" end="63"/>
> +</flags><flags id="scounteren-fields" size="8">
> +  <field name="cy" start="0" end="0"/>
> +  <field name="tm" start="1" end="1"/>
> +  <field name="ir" start="2" end="2"/>
> +  <field name="hpm" start="3" end="31"/>
> +</flags><flags id="scause-fields" size="8">
> +  <field name="exc" start="0" end="62" type="scause-exc-type"/>
> +  <field name="interrupt" start="63" end="63"/>
> +</flags><flags id="sip-fields" size="8">
> +  <field name="ssip" start="1" end="1"/>
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="msip" start="3" end="3"/>
> +  <field name="stip" start="5" end="5"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="mtip" start="7" end="7"/>
> +  <field name="seip" start="9" end="9"/>
> +  <field name="vseip" start="10" end="10"/>
> +  <field name="meip" start="11" end="11"/>
> +  <field name="sgeip" start="12" end="12"/>
> +</flags><flags id="satp-fields" size="8">
> +  <field name="ppn" start="0" end="43"/>
> +  <field name="asid" start="44" end="59"/>
> +  <field name="mode" start="60" end="63" type="satp-mode-type"/>
> +</flags><flags id="hstatus-fields" size="8">
> +  <field name="vsbe" start="5" end="5"/>
> +  <field name="gva" start="6" end="6"/>
> +  <field name="spv" start="7" end="7"/>
> +  <field name="spvp" start="8" end="8"/>
> +  <field name="hu" start="9" end="9"/>
> +  <field name="vgein" start="12" end="17"/>
> +  <field name="vtvm" start="20" end="20"/>
> +  <field name="vtsr" start="22" end="22"/>
> +  <field name="vsxl" start="32" end="33"/>
> +</flags><flags id="hedeleg-fields" size="8">
> +  <field name="instruction_address_misaligned" start="0" end="0"/>
> +  <field name="instruction_access_fault" start="1" end="1"/>
> +  <field name="illegal_instruction" start="2" end="2"/>
> +  <field name="breakpoint" start="3" end="3"/>
> +  <field name="load_address_misaligned" start="4" end="4"/>
> +  <field name="load_access_fault" start="5" end="5"/>
> +  <field name="store_address_misaligned" start="6" end="6"/>
> +  <field name="store_access_fault" start="7" end="7"/>
> +  <field name="enironment_call_from_U_mode" start="8" end="8"/>
> +  <field name="enironment_call_from_S_mode" start="9" end="9"/>
> +  <field name="enironment_call_from_VS_mode" start="10" end="10"/>
> +  <field name="enironment_call_from_M_mode" start="11" end="11"/>
> +  <field name="instruction_page_fault" start="12" end="12"/>
> +  <field name="load_page_fault" start="13" end="13"/>
> +  <field name="store_page_fault" start="15" end="15"/>
> +  <field name="instruction_guest_page_fault" start="20" end="20"/>
> +  <field name="load_guest_page_fault" start="21" end="21"/>
> +  <field name="virtual_instruction" start="22" end="22"/>
> +  <field name="store_guest_page_fault" start="23" end="23"/>
> +</flags><flags id="hie-fields" size="8">
> +  <field name="vssie" start="2" end="2"/>
> +  <field name="vstie" start="6" end="6"/>
> +  <field name="vseie" start="10" end="10"/>
> +  <field name="sgeie" start="12" end="12"/>
> +</flags><flags id="hip-fields" size="8">
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="vseip" start="10" end="10"/>
> +  <field name="sgeip" start="12" end="12"/>
> +</flags><flags id="hvip-fields" size="8">
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="vseip" start="10" end="10"/>
> +</flags><flags id="hgatp-fields" size="8">
> +  <field name="ppn" start="0" end="43"/>
> +  <field name="vmid" start="44" end="57"/>
> +  <field name="mode" start="60" end="63" type="hgatp-mode-type"/>
> +</flags>
> +)
> +# endif
> +;
> diff --git a/target/riscv/gdb_csr_types.h b/target/riscv/gdb_csr_types.h
> new file mode 100644
> index 0000000000..e55c978ac8
> --- /dev/null
> +++ b/target/riscv/gdb_csr_types.h
> @@ -0,0 +1,3 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
> +
> +extern char const riscv_gdb_csr_types[];
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 23429179e2..9c3f68eeaf 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -2,6 +2,7 @@
>    * RISC-V GDB Server Stub
>    *
>    * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
> + * Copyright (c) 2021 Siemens AG, konrad.schwarz@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,
> @@ -155,6 +156,9 @@ static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
>       return 0;
>   }
>   
> +#include "gdb_csr_types.h"
> +#include "gdb_csr_type_group.h"

Just wanted to test this series, but this header, as well as the 
corresponding source file gdb_csr_type_group.c is missing.

configure fails with:
../target/riscv/meson.build:24:17: ERROR: File gdb_csr_type_group.c does 
not exist.

Thanks
   Ralf

> +
>   static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
>   {
>       RISCVCPU *cpu = RISCV_CPU(cs);
> @@ -163,21 +167,33 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
>       riscv_csr_predicate_fn predicate;
>       int bitsize = 16 << env->misa_mxl_max;
>       int i;
> +    riscv_csr_operations *csr_op;
> +    struct riscv_gdb_csr_tg const *csr_tg;
>   
>       g_string_printf(s, "<?xml version=\"1.0\"?>");
>       g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
>       g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
>   
> -    for (i = 0; i < CSR_TABLE_SIZE; i++) {
> -        predicate = csr_ops[i].predicate;
> +    g_string_append(s, riscv_gdb_csr_types);
> +
> +    for (i = 0, csr_op = csr_ops, csr_tg = riscv_gdb_csr_type_group;
> +            i < CSR_TABLE_SIZE; ++csr_op, ++csr_tg, ++i) {
> +        predicate = csr_op->predicate;
>           if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
> -            if (csr_ops[i].name) {
> -                g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
> +            if (csr_op->name) {
> +                g_string_append_printf(s, "<reg name=\"%s\"", csr_op->name);
>               } else {
>                   g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
>               }
>               g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
> -            g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
> +            g_string_append_printf(s, " regnum=\"%d\"", base_reg + i);
> +            if (csr_tg->gdb_type) {
> +                g_string_append_printf(s, " type=\"%s\"", csr_tg->gdb_type);
> +            }
> +            if (csr_tg->gdb_group) {
> +                g_string_append_printf(s, " group=\"%s\"", csr_tg->gdb_group);
> +            }
> +            g_string_append(s, " />\n");
>           }
>       }
>   
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index d5e0bc93ea..e1945e54c4 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -25,7 +25,9 @@ riscv_softmmu_ss.add(files(
>     'arch_dump.c',
>     'pmp.c',
>     'monitor.c',
> -  'machine.c'
> +  'machine.c',
> +  'gdb_csr_types.c',
> +  'gdb_csr_type_group.c'
>   ))
>   
>   target_arch += {'riscv': riscv_ss}


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 0/5] Improve RISC-V debugging support.
  2022-01-03 12:54   ` Ralf Ramsauer
@ 2022-01-04 15:51     ` Konrad Schwarz
  2022-01-04 15:51       ` [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
                         ` (4 more replies)
  0 siblings, 5 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-04 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt,
	Ralf Ramsauer

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



^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'
  2022-01-04 15:51     ` [PATCH v2 0/5] Improve RISC-V debugging support Konrad Schwarz
@ 2022-01-04 15:51       ` Konrad Schwarz
  2022-01-04 20:57         ` Richard Henderson
  2022-01-04 15:51       ` [PATCH v2 2/5] RISC-V: monitor's print register functionality Konrad Schwarz
                         ` (3 subsequent siblings)
  4 siblings, 1 reply; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-04 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt,
	Ralf Ramsauer

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 <konrad.schwarz@siemens.com>
---
 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, sagark@eecs.berkeley.edu
  * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2021 Siemens AG, konrad.schwarz@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 */
+            CSR_SSCRATCH,
+            CSR_SEPC,
+            CSR_SCAUSE,
             CSR_STVAL,
+            CSR_SIP,
+
+/* Supervisor Protection and Translation */
+            CSR_SPTBR,
+            CSR_SATP,
+
+/* Hpervisor CSRs */
+            CSR_HSTATUS,
+            CSR_HEDELEG,
+            CSR_HIDELEG,
+            CSR_HIE,
+            CSR_HCOUNTEREN,
+            CSR_HGEIE,
             CSR_HTVAL,
+            CSR_HVIP,
+            CSR_HIP,
+            CSR_HTINST,
+            CSR_HGEIP,
+            CSR_HGATP,
+            CSR_HTIMEDELTA,
+            CSR_HTIMEDELTAH,
+
+/* Virtual CSRs */
+            CSR_VSSTATUS,
+            CSR_VSIE,
+            CSR_VSTVEC,
+            CSR_VSSCRATCH,
+            CSR_VSEPC,
+            CSR_VSCAUSE,
+            CSR_VSTVAL,
+            CSR_VSIP,
+            CSR_VSATP,
+
+            CSR_MTINST,
             CSR_MTVAL2,
-            CSR_MSCRATCH,
-            CSR_SSCRATCH,
-            CSR_SATP,
-            CSR_MMTE,
-            CSR_UPMBASE,
-            CSR_UPMMASK,
-            CSR_SPMBASE,
-            CSR_SPMMASK,
-            CSR_MPMBASE,
-            CSR_MPMMASK,
+
+#  if      0
+/* Enhanced Physical Memory Protection (ePMP) */
+            CSR_MSECCFG,
+            CSR_MSECCFGH,
+#  endif
+#  if      0
+/* Physical Memory Protection */
+            CSR_PMPCFG0,
+            CSR_PMPCFG1,
+            CSR_PMPCFG2,
+            CSR_PMPCFG3,
+            CSR_PMPADDR0,
+            CSR_PMPADDR1,
+            CSR_PMPADDR2,
+            CSR_PMPADDR3,
+            CSR_PMPADDR4,
+            CSR_PMPADDR5,
+            CSR_PMPADDR6,
+            CSR_PMPADDR7,
+            CSR_PMPADDR8,
+            CSR_PMPADDR9,
+            CSR_PMPADDR10,
+            CSR_PMPADDR11,
+            CSR_PMPADDR12,
+            CSR_PMPADDR13,
+            CSR_PMPADDR14,
+            CSR_PMPADDR15,
+#  endif
+
+#  if      0
+/* Debug/Trace Registers (shared with Debug Mode) */
+            CSR_TSELECT,
+            CSR_TDATA1,
+            CSR_TDATA2,
+            CSR_TDATA3,
+#  endif
+
+#  if      0
+/* Debug Mode Registers */
+            CSR_DCSR,
+            CSR_DPC,
+            CSR_DSCRATCH,
+#  endif
+
+#  if      0
+/* Performance Counters */
+            CSR_MHPMCOUNTER3,
+            CSR_MHPMCOUNTER4,
+            CSR_MHPMCOUNTER5,
+            CSR_MHPMCOUNTER6,
+            CSR_MHPMCOUNTER7,
+            CSR_MHPMCOUNTER8,
+            CSR_MHPMCOUNTER9,
+            CSR_MHPMCOUNTER10,
+            CSR_MHPMCOUNTER11,
+            CSR_MHPMCOUNTER12,
+            CSR_MHPMCOUNTER13,
+            CSR_MHPMCOUNTER14,
+            CSR_MHPMCOUNTER15,
+            CSR_MHPMCOUNTER16,
+            CSR_MHPMCOUNTER17,
+            CSR_MHPMCOUNTER18,
+            CSR_MHPMCOUNTER19,
+            CSR_MHPMCOUNTER20,
+            CSR_MHPMCOUNTER21,
+            CSR_MHPMCOUNTER22,
+            CSR_MHPMCOUNTER23,
+            CSR_MHPMCOUNTER24,
+            CSR_MHPMCOUNTER25,
+            CSR_MHPMCOUNTER26,
+            CSR_MHPMCOUNTER27,
+            CSR_MHPMCOUNTER28,
+            CSR_MHPMCOUNTER29,
+            CSR_MHPMCOUNTER30,
+            CSR_MHPMCOUNTER31,
+            CSR_MHPMEVENT3,
+            CSR_MHPMEVENT4,
+            CSR_MHPMEVENT5,
+            CSR_MHPMEVENT6,
+            CSR_MHPMEVENT7,
+            CSR_MHPMEVENT8,
+            CSR_MHPMEVENT9,
+            CSR_MHPMEVENT10,
+            CSR_MHPMEVENT11,
+            CSR_MHPMEVENT12,
+            CSR_MHPMEVENT13,
+            CSR_MHPMEVENT14,
+            CSR_MHPMEVENT15,
+            CSR_MHPMEVENT16,
+            CSR_MHPMEVENT17,
+            CSR_MHPMEVENT18,
+            CSR_MHPMEVENT19,
+            CSR_MHPMEVENT20,
+            CSR_MHPMEVENT21,
+            CSR_MHPMEVENT22,
+            CSR_MHPMEVENT23,
+            CSR_MHPMEVENT24,
+            CSR_MHPMEVENT25,
+            CSR_MHPMEVENT26,
+            CSR_MHPMEVENT27,
+            CSR_MHPMEVENT28,
+            CSR_MHPMEVENT29,
+            CSR_MHPMEVENT30,
+            CSR_MHPMEVENT31,
+            CSR_MHPMCOUNTER3H,
+            CSR_MHPMCOUNTER4H,
+            CSR_MHPMCOUNTER5H,
+            CSR_MHPMCOUNTER6H,
+            CSR_MHPMCOUNTER7H,
+            CSR_MHPMCOUNTER8H,
+            CSR_MHPMCOUNTER9H,
+            CSR_MHPMCOUNTER10H,
+            CSR_MHPMCOUNTER11H,
+            CSR_MHPMCOUNTER12H,
+            CSR_MHPMCOUNTER13H,
+            CSR_MHPMCOUNTER14H,
+            CSR_MHPMCOUNTER15H,
+            CSR_MHPMCOUNTER16H,
+            CSR_MHPMCOUNTER17H,
+            CSR_MHPMCOUNTER18H,
+            CSR_MHPMCOUNTER19H,
+            CSR_MHPMCOUNTER20H,
+            CSR_MHPMCOUNTER21H,
+            CSR_MHPMCOUNTER22H,
+            CSR_MHPMCOUNTER23H,
+            CSR_MHPMCOUNTER24H,
+            CSR_MHPMCOUNTER25H,
+            CSR_MHPMCOUNTER26H,
+            CSR_MHPMCOUNTER27H,
+            CSR_MHPMCOUNTER28H,
+            CSR_MHPMCOUNTER29H,
+            CSR_MHPMCOUNTER30H,
+            CSR_MHPMCOUNTER31H,
+#  endif
         };
 
         for (int i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
-- 
Konrad Schwarz



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 2/5] RISC-V: monitor's print register functionality
  2022-01-04 15:51     ` [PATCH v2 0/5] Improve RISC-V debugging support Konrad Schwarz
  2022-01-04 15:51       ` [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
@ 2022-01-04 15:51       ` Konrad Schwarz
  2022-01-04 15:51       ` [PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations Konrad Schwarz
                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-04 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt,
	Ralf Ramsauer

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 <konrad.schwarz@siemens.com>
---
 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 <bmeng.cn@gmail.com>
+ * Copyright (c) 2021 Siemens AG, konrad.schwarz@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 = &RISCV_CPU (cs)->env;
+    riscv_csr_operations *op;
+    for (op = csr_ops; 1[&csr_ops] > op; ++op) {
+        if (!op->name) {
+            continue;
+        }
+        if (!strcmp(name, op->name)) {
+            if (RISCV_EXCP_NONE != riscv_csrrw_debug(env, op - csr_ops,
+                                 &ret_value,
+                                 0 /* new_value */,
+                                 0 /* write_mask */))
+                return -1;
+            *pval = ret_value;
+            return 0;
+        }
+    }
+    return -1;
+}
-- 
Konrad Schwarz



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations
  2022-01-04 15:51     ` [PATCH v2 0/5] Improve RISC-V debugging support Konrad Schwarz
  2022-01-04 15:51       ` [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
  2022-01-04 15:51       ` [PATCH v2 2/5] RISC-V: monitor's print register functionality Konrad Schwarz
@ 2022-01-04 15:51       ` Konrad Schwarz
  2022-01-04 22:03         ` Alistair Francis
  2022-01-04 15:51       ` [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
  2022-01-04 15:51       ` [PATCH v2 5/5] RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register Konrad Schwarz
  4 siblings, 1 reply; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-04 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt,
	Ralf Ramsauer

This is analog to the existing 'info mem' command and is implemented
using the same machinery.

Signed-off-by: Konrad Schwarz <konrad.schwarz@siemens.com>
---
 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.schwarz@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       "vaddr            paddr            "\
-                                "size             attr\n"
-#define PTE_HEADER_DELIMITER    "---------------- ---------------- "\
-                                "---------------- -------\n"
-#else
-#define PTE_HEADER_FIELDS       "vaddr    paddr            size     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);
+
+# define        VIRTUAL_WIDTH\
+        ((int) ((sizeof "ff" - sizeof "") * sizeof(target_ulong)))
+# define        PHYSICAL_WIDTH\
+        ((int) ((sizeof "ff" - sizeof "") * sizeof(hwaddr)))
+# define        ATTRIBUTE_WIDTH ((int) (sizeof "rwxugad" - sizeof ""))
+
+# define        VIRTUAL_COLUMN_WIDTH    (1 + VIRTUAL_WIDTH)
+# define        PHYSICAL_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' : '-',
-                   attr & PTE_G ? 'g' : '-',
-                   attr & PTE_A ? 'a' : '-',
-                   attr & PTE_D ? 'd' : '-');
+# if 4 == TARGET_LONG_SIZE
+#       define  TARGET_xFMT     PRIx32
+# elif 8 == TARGET_LONG_SIZE
+#       define  TARGET_xFMT     PRIx64
+# else
+#       error TARGET_LONG_SIZE not handled
+# endif
+
+    /* note: RISC-V physical addresses are actually xlen + 2 bits long
+    OTHO, QEMU wil probably never support addresses longer than 64 bits */
+    monitor_printf(mon,
+            "%-*.*" TARGET_xFMT
+            "%-*.*" PRIx64
+            "%-*.*" TARGET_xFMT
+            "%c%c%c%c%c%c%c\n",
+            VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, addr_canonical(va_bits, vaddr),
+            PHYSICAL_COLUMN_WIDTH, PHYSICAL_WIDTH, paddr,
+            VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, size,
+            attr & PTE_R ? 'r' : '-',
+            attr & PTE_W ? 'w' : '-',
+            attr & PTE_X ? 'x' : '-',
+            attr & PTE_U ? 'u' : '-',
+            attr & PTE_G ? 'g' : '-',
+            attr & PTE_A ? 'a' : '-',
+            attr & PTE_D ? 'd' : '-');
 }
 
 static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
                      int level, int ptidxbits, int ptesize, int va_bits,
+                     int guest,
                      target_ulong *vbase, hwaddr *pbase, hwaddr *last_paddr,
                      target_ulong *last_size, int *last_attr)
 {
@@ -89,7 +118,7 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
     target_ulong pte;
     int ptshift;
     int attr;
-    int idx;
+    int idx, idx_end;
 
     if (level < 0) {
         return;
@@ -98,7 +127,8 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
     ptshift = level * ptidxbits;
     pgsize = 1UL << (PGSHIFT + ptshift);
 
-    for (idx = 0; idx < (1UL << ptidxbits); idx++) {
+    for (idx = 0, idx_end = 1 << (ptidxbits + (guest ? 2 : 0));
+            idx_end > idx; idx++) {
         pte_addr = base + idx * ptesize;
         cpu_physical_memory_read(pte_addr, &pte, ptesize);
 
@@ -131,7 +161,9 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
             } else {
                 /* pointer to the next level of the page table */
                 walk_pte(mon, paddr, start, level - 1, ptidxbits, ptesize,
-                         va_bits, vbase, pbase, last_paddr,
+                         va_bits,
+                         0 /* guest */,
+                         vbase, pbase, last_paddr,
                          last_size, last_attr);
             }
         }
@@ -141,7 +173,9 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
 
 }
 
-static void mem_info_svxx(Monitor *mon, CPUArchState *env)
+static void mem_info_svxx(Monitor *mon, CPUArchState *env,
+        target_ulong const atp,
+        int guest, char const vaddr_char, char const paddr_char)
 {
     int levels, ptidxbits, ptesize, vm, va_bits;
     hwaddr base;
@@ -152,11 +186,11 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
     int last_attr;
 
     if (riscv_cpu_mxl(env) == MXL_RV32) {
-        base = (hwaddr)get_field(env->satp, SATP32_PPN) << PGSHIFT;
-        vm = get_field(env->satp, SATP32_MODE);
+        base = (hwaddr)get_field(atp, SATP32_PPN) << PGSHIFT;
+        vm = get_field(atp, SATP32_MODE);
     } else {
-        base = (hwaddr)get_field(env->satp, SATP64_PPN) << PGSHIFT;
-        vm = get_field(env->satp, SATP64_MODE);
+        base = (hwaddr)get_field(atp, SATP64_PPN) << PGSHIFT;
+        vm = get_field(atp, SATP64_MODE);
     }
 
     switch (vm) {
@@ -189,7 +223,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
     va_bits = PGSHIFT + levels * ptidxbits;
 
     /* print header */
-    print_pte_header(mon);
+    print_pte_header(mon, vaddr_char, paddr_char);
 
     vbase = -1;
     pbase = -1;
@@ -199,6 +233,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
 
     /* walk page tables, starting from address 0 */
     walk_pte(mon, base, 0, levels - 1, ptidxbits, ptesize, va_bits,
+             guest,
              &vbase, &pbase, &last_paddr, &last_size, &last_attr);
 
     /* don't forget the last one */
@@ -209,6 +244,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
 void hmp_info_mem(Monitor *mon, const QDict *qdict)
 {
     CPUArchState *env;
+    target_ulong atp;
 
     env = mon_get_cpu_env(mon);
     if (!env) {
@@ -221,19 +257,46 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
         return;
     }
 
+    atp = env->satp;
     if (riscv_cpu_mxl(env) == MXL_RV32) {
-        if (!(env->satp & SATP32_MODE)) {
+        if (!(atp & SATP32_MODE)) {
             monitor_printf(mon, "No translation or protection\n");
             return;
         }
     } else {
-        if (!(env->satp & SATP64_MODE)) {
+        if (!(atp & SATP64_MODE)) {
             monitor_printf(mon, "No translation or protection\n");
             return;
         }
     }
 
-    mem_info_svxx(mon, env);
+    mem_info_svxx(mon, env, atp, 0, 'v', 'p');
+}
+
+void hmp_info_gmem(Monitor *mon, const QDict *qdict)
+{
+    CPUArchState *env;
+    target_ulong atp;
+
+    env = mon_get_cpu_env(mon);
+    if (!env) {
+        monitor_printf(mon, "No CPU available\n");
+        return;
+    }
+
+    if (!riscv_has_ext(env, RVH)) {
+        monitor_printf(mon, "hypervisor extension not available\n");
+        return;
+    }
+
+    atp = env->hgatp;
+    if (!((MXL_RV32 == riscv_cpu_mxl(env) ? SATP32_MODE : SATP64_MODE)
+            & atp)) {
+        monitor_printf(mon, "No translation or protection\n");
+        return;
+    }
+
+    mem_info_svxx(mon, env, atp, 1, 'g', 'p');
 }
 
 static const MonitorDef monitor_defs[] = {
-- 
Konrad Schwarz



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-04 15:51     ` [PATCH v2 0/5] Improve RISC-V debugging support Konrad Schwarz
                         ` (2 preceding siblings ...)
  2022-01-04 15:51       ` [PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations Konrad Schwarz
@ 2022-01-04 15:51       ` Konrad Schwarz
  2022-01-04 22:11         ` Alistair Francis
                           ` (2 more replies)
  2022-01-04 15:51       ` [PATCH v2 5/5] RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register Konrad Schwarz
  4 siblings, 3 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-04 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt,
	Ralf Ramsauer

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 <konrad.schwarz@siemens.com>
---
 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, sagark@eecs.berkeley.edu
  * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2021 Siemens AG, konrad.schwarz@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 0000000000..e8ec527f23
--- /dev/null
+++ b/target/riscv/csr32-op-gdbserver.h
@@ -0,0 +1,109 @@
+/* Copyright (c) 2021 Siemens AG, konrad.schwarz@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" },
+  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER28] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER29] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER30] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER31] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_CYCLEH] { .gdb_type = "uint32", .gdb_group = "user" },
+  [CSR_TIMEH] { .gdb_type = "uint32", .gdb_group = "user" },
+  [CSR_INSTRETH] { .gdb_type = "uint32", .gdb_group = "user" },
+  [CSR_HPMCOUNTER3H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER4H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER5H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER6H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER7H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER8H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER9H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER10H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER11H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER12H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER13H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER14H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER15H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER16H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER17H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER18H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER19H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER20H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER21H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER22H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER23H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER24H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER25H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER26H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER27H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER28H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER29H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER30H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER31H] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_SSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "supervisor" },
+  [CSR_SEDELEG] { .gdb_type = "uint32", .gdb_group = "supervisor" },
+  [CSR_SIDELEG] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
+  [CSR_SIE] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
+  [CSR_STVEC] { .gdb_type = "stvec-fields", .gdb_group = "supervisor" },
+  [CSR_SCOUNTEREN] { .gdb_type = "scounteren-fields", .gdb_group = "supervisor" },
+  [CSR_SSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
+  [CSR_SEPC] { .gdb_type = "code_ptr", .gdb_group = "supervisor" },
+  [CSR_SCAUSE] { .gdb_type = "scause-fields", .gdb_group = "supervisor" },
+  [CSR_STVAL] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
+  [CSR_SIP] { .gdb_type = "sip-fields", .gdb_group = "supervisor" },
+  [CSR_SATP] { .gdb_type = "satp-fields", .gdb_group = "supervisor" },
+  [CSR_HSTATUS] { .gdb_type = "hstatus-fields", .gdb_group = "hypervisor" },
+  [CSR_HEDELEG] { .gdb_type = "hedeleg-fields", .gdb_group = "hypervisor" },
+  [CSR_HIDELEG] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
+  [CSR_HIE] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
+  [CSR_HCOUNTEREN] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HGEIE] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
+  [CSR_HGEIP] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
+  [CSR_HTVAL] { .gdb_type = "data_ptr", .gdb_group = "hypervisor" },
+  [CSR_HIP] { .gdb_type = "hip-fields", .gdb_group = "hypervisor" },
+  [CSR_HVIP] { .gdb_type = "hvip-fields", .gdb_group = "hypervisor" },
+  [CSR_HGATP] { .gdb_type = "hgatp-fields", .gdb_group = "hypervisor" },
+  [CSR_HTIMEDELTA] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HTIMEDELTAH] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HTINST] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
+  [CSR_VSSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSIE] { .gdb_type = "sie-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSTVEC] { .gdb_type = "stvec-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSEPC] { .gdb_type = "code_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSCAUSE] { .gdb_type = "scause-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSTVAL] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSIP] { .gdb_type = "sip-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSATP] { .gdb_type = "satp-fields", .gdb_group = "virtual-supervisor" },
diff --git a/target/riscv/csr64-op-gdbserver.h b/target/riscv/csr64-op-gdbserver.h
new file mode 100644
index 0000000000..fc4bc62d9e
--- /dev/null
+++ b/target/riscv/csr64-op-gdbserver.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2021 Siemens AG, konrad.schwarz@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 = "uint64", .gdb_group = "user" },
+  [CSR_TIME] { .gdb_type = "uint64", .gdb_group = "user" },
+  [CSR_INSTRET] { .gdb_type = "uint64", .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" },
+  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER28] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER29] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER30] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_HPMCOUNTER31] { .gdb_type = "int", .gdb_group = "user" },
+  [CSR_SSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "supervisor" },
+  [CSR_SEDELEG] { .gdb_type = "uint64", .gdb_group = "supervisor" },
+  [CSR_SIDELEG] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
+  [CSR_SIE] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
+  [CSR_STVEC] { .gdb_type = "stvec-fields", .gdb_group = "supervisor" },
+  [CSR_SCOUNTEREN] { .gdb_type = "scounteren-fields", .gdb_group = "supervisor" },
+  [CSR_SSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
+  [CSR_SEPC] { .gdb_type = "code_ptr", .gdb_group = "supervisor" },
+  [CSR_SCAUSE] { .gdb_type = "scause-fields", .gdb_group = "supervisor" },
+  [CSR_STVAL] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
+  [CSR_SIP] { .gdb_type = "sip-fields", .gdb_group = "supervisor" },
+  [CSR_SATP] { .gdb_type = "satp-fields", .gdb_group = "supervisor" },
+  [CSR_HSTATUS] { .gdb_type = "hstatus-fields", .gdb_group = "hypervisor" },
+  [CSR_HEDELEG] { .gdb_type = "hedeleg-fields", .gdb_group = "hypervisor" },
+  [CSR_HIDELEG] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
+  [CSR_HIE] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
+  [CSR_HCOUNTEREN] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HGEIE] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
+  [CSR_HGEIP] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
+  [CSR_HTVAL] { .gdb_type = "data_ptr", .gdb_group = "hypervisor" },
+  [CSR_HIP] { .gdb_type = "hip-fields", .gdb_group = "hypervisor" },
+  [CSR_HVIP] { .gdb_type = "hvip-fields", .gdb_group = "hypervisor" },
+  [CSR_HGATP] { .gdb_type = "hgatp-fields", .gdb_group = "hypervisor" },
+  [CSR_HTIMEDELTA] { .gdb_type = "int", .gdb_group = "hypervisor" },
+  [CSR_HTINST] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
+  [CSR_VSSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSIE] { .gdb_type = "sie-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSTVEC] { .gdb_type = "stvec-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSEPC] { .gdb_type = "code_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSCAUSE] { .gdb_type = "scause-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSTVAL] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
+  [CSR_VSIP] { .gdb_type = "sip-fields", .gdb_group = "virtual-supervisor" },
+  [CSR_VSATP] { .gdb_type = "satp-fields", .gdb_group = "virtual-supervisor" },
diff --git a/target/riscv/gdb_csr_type_group.c b/target/riscv/gdb_csr_type_group.c
new file mode 100644
index 0000000000..af394de302
--- /dev/null
+++ b/target/riscv/gdb_csr_type_group.c
@@ -0,0 +1,16 @@
+/* Copyright 2021 Siemens AG */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "gdb_csr_type_group.h"
+
+struct riscv_gdb_csr_tg const riscv_gdb_csr_type_group[] = {
+
+#if !defined(CONFIG_USER_ONLY)
+#  ifdef TARGET_RISCV64
+#    include "csr64-op-gdbserver.h"
+#  elif defined TARGET_RISCV64
+#    include "csr32-op-gdbserver.h"
+#  endif
+#endif /* !CONFIG_USER_ONLY */
+
+};
diff --git a/target/riscv/gdb_csr_type_group.h b/target/riscv/gdb_csr_type_group.h
new file mode 100644
index 0000000000..e044913bd7
--- /dev/null
+++ b/target/riscv/gdb_csr_type_group.h
@@ -0,0 +1,3 @@
+extern struct riscv_gdb_csr_tg {
+    char const *gdb_type, *gdb_group;
+} const riscv_gdb_csr_type_group[CSR_TABLE_SIZE];
diff --git a/target/riscv/gdb_csr_types.c b/target/riscv/gdb_csr_types.c
new file mode 100644
index 0000000000..48b1db2b88
--- /dev/null
+++ b/target/riscv/gdb_csr_types.c
@@ -0,0 +1,333 @@
+/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
+
+#include "qemu/osdep.h"
+#include "gdb_csr_types.h"
+#define STR(X) #X
+
+char const riscv_gdb_csr_types[] =
+#ifdef TARGET_RISCV32
+   STR(
+<enum id="sstatus-fs-type" size="4">
+  <evalue name="off" value="0"/>
+  <evalue name="initial" value="1"/>
+  <evalue name="clean" value="2"/>
+  <evalue name="dirty" value="3"/>
+</enum><enum id="sstatus-xs-type" size="4">
+  <evalue name="off" value="0"/>
+  <evalue name="initial" value="1"/>
+  <evalue name="clean" value="2"/>
+  <evalue name="dirty" value="3"/>
+</enum><enum id="sstatus-uxl-type" size="4">
+  <evalue name="32" value="1"/>
+  <evalue name="64" value="2"/>
+  <evalue name="128" value="3"/>
+</enum><enum id="stvec-mode-type" size="4">
+  <evalue name="direct" value="0"/>
+  <evalue name="vectored" value="1"/>
+</enum><enum id="scause-exc-type" size="4">
+  <evalue name="instruction_address_misaligned" value="0"/>
+  <evalue name="instruction_access_fault" value="1"/>
+  <evalue name="illegal_instruction" value="2"/>
+  <evalue name="breakpoint" value="3"/>
+  <evalue name="load_address_misaligned" value="4"/>
+  <evalue name="load_access_fault" value="5"/>
+  <evalue name="store_address_misaligned" value="6"/>
+  <evalue name="store_access_fault" value="7"/>
+  <evalue name="enironment_call_from_U_mode" value="8"/>
+  <evalue name="enironment_call_from_S_mode" value="9"/>
+  <evalue name="enironment_call_from_VS_mode" value="10"/>
+  <evalue name="enironment_call_from_M_mode" value="11"/>
+  <evalue name="instruction_page_fault" value="12"/>
+  <evalue name="load_page_fault" value="13"/>
+  <evalue name="store_page_fault" value="15"/>
+  <evalue name="instruction_guest_page_fault" value="20"/>
+  <evalue name="load_guest_page_fault" value="21"/>
+  <evalue name="virtual_instruction" value="22"/>
+  <evalue name="store_guest_page_fault" value="23"/>
+</enum><enum id="satp-mode-type" size="4">
+  <evalue name="bare" value="0"/>
+  <evalue name="sv32" value="1"/>
+  <evalue name="sv39" value="8"/>
+  <evalue name="sv48" value="9"/>
+  <evalue name="sv57" value="10"/>
+  <evalue name="sv64" value="11"/>
+</enum><enum id="hgatp-mode-type" size="4">
+  <evalue name="bare" value="0"/>
+  <evalue name="sv32x4" value="1"/>
+  <evalue name="sv39x4" value="8"/>
+  <evalue name="sv48x4" value="9"/>
+  <evalue name="sv57x4" value="10"/>
+</enum><flags id="sstatus-fields" size="4">
+  <field name="sie" start="1" end="1"/>
+  <field name="mie" start="3" end="3"/>
+  <field name="spie" start="5" end="5"/>
+  <field name="ube" start="6" end="6"/>
+  <field name="mpie" start="7" end="7"/>
+  <field name="spp" start="8" end="8"/>
+  <field name="mpp" start="11" end="12"/>
+  <field name="fs" start="13" end="14" type="sstatus-fs-type"/>
+  <field name="xs" start="15" end="16" type="sstatus-xs-type"/>
+  <field name="mprv" start="17" end="17"/>
+  <field name="sum" start="18" end="18"/>
+  <field name="mxr" start="19" end="19"/>
+  <field name="tvm" start="20" end="20"/>
+  <field name="tw" start="21" end="21"/>
+  <field name="tsr" start="22" end="23"/>
+  <field name="uxl" start="32" end="33" type="sstatus-uxl-type"/>
+  <field name="sxl" start="34" end="35"/>
+  <field name="sbe" start="36" end="36"/>
+  <field name="mbe" start="37" end="37"/>
+  <field name="gva" start="38" end="38"/>
+  <field name="mpv" start="39" end="39"/>
+  <field name="sd" start="63" end="63"/>
+</flags><flags id="sie-fields" size="4">
+  <field name="ssie" start="1" end="1"/>
+  <field name="vssie" start="2" end="2"/>
+  <field name="msie" start="3" end="3"/>
+  <field name="stie" start="5" end="5"/>
+  <field name="vstie" start="6" end="6"/>
+  <field name="mtie" start="7" end="7"/>
+  <field name="seie" start="9" end="9"/>
+  <field name="vseie" start="10" end="10"/>
+  <field name="meie" start="11" end="11"/>
+  <field name="sgeie" start="12" end="12"/>
+</flags><flags id="stvec-fields" size="4">
+  <field name="mode" start="0" end="1" type="stvec-mode-type"/>
+  <field name="base" start="2" end="63"/>
+</flags><flags id="scounteren-fields" size="4">
+  <field name="cy" start="0" end="0"/>
+  <field name="tm" start="1" end="1"/>
+  <field name="ir" start="2" end="2"/>
+  <field name="hpm" start="3" end="31"/>
+</flags><flags id="scause-fields" size="4">
+  <field name="exc" start="0" end="30" type="scause-exc-type"/>
+  <field name="interrupt" start="31" end="31"/>
+</flags><flags id="sip-fields" size="4">
+  <field name="ssip" start="1" end="1"/>
+  <field name="vssip" start="2" end="2"/>
+  <field name="msip" start="3" end="3"/>
+  <field name="stip" start="5" end="5"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="mtip" start="7" end="7"/>
+  <field name="seip" start="9" end="9"/>
+  <field name="vseip" start="10" end="10"/>
+  <field name="meip" start="11" end="11"/>
+  <field name="sgeip" start="12" end="12"/>
+</flags><flags id="satp-fields" size="4">
+  <field name="ppn" start="0" end="43"/>
+  <field name="asid" start="44" end="59"/>
+  <field name="mode" start="60" end="63" type="satp-mode-type"/>
+</flags><flags id="hstatus-fields" size="4">
+  <field name="vsbe" start="5" end="5"/>
+  <field name="gva" start="6" end="6"/>
+  <field name="spv" start="7" end="7"/>
+  <field name="spvp" start="8" end="8"/>
+  <field name="hu" start="9" end="9"/>
+  <field name="vgein" start="12" end="17"/>
+  <field name="vtvm" start="20" end="20"/>
+  <field name="vtsr" start="22" end="22"/>
+  <field name="vsxl" start="32" end="33"/>
+</flags><flags id="hedeleg-fields" size="4">
+  <field name="instruction_address_misaligned" start="0" end="0"/>
+  <field name="instruction_access_fault" start="1" end="1"/>
+  <field name="illegal_instruction" start="2" end="2"/>
+  <field name="breakpoint" start="3" end="3"/>
+  <field name="load_address_misaligned" start="4" end="4"/>
+  <field name="load_access_fault" start="5" end="5"/>
+  <field name="store_address_misaligned" start="6" end="6"/>
+  <field name="store_access_fault" start="7" end="7"/>
+  <field name="enironment_call_from_U_mode" start="8" end="8"/>
+  <field name="enironment_call_from_S_mode" start="9" end="9"/>
+  <field name="enironment_call_from_VS_mode" start="10" end="10"/>
+  <field name="enironment_call_from_M_mode" start="11" end="11"/>
+  <field name="instruction_page_fault" start="12" end="12"/>
+  <field name="load_page_fault" start="13" end="13"/>
+  <field name="store_page_fault" start="15" end="15"/>
+  <field name="instruction_guest_page_fault" start="20" end="20"/>
+  <field name="load_guest_page_fault" start="21" end="21"/>
+  <field name="virtual_instruction" start="22" end="22"/>
+  <field name="store_guest_page_fault" start="23" end="23"/>
+</flags><flags id="hie-fields" size="4">
+  <field name="vssie" start="2" end="2"/>
+  <field name="vstie" start="6" end="6"/>
+  <field name="vseie" start="10" end="10"/>
+  <field name="sgeie" start="12" end="12"/>
+</flags><flags id="hip-fields" size="4">
+  <field name="vssip" start="2" end="2"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="vseip" start="10" end="10"/>
+  <field name="sgeip" start="12" end="12"/>
+</flags><flags id="hvip-fields" size="4">
+  <field name="vssip" start="2" end="2"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="vseip" start="10" end="10"/>
+</flags><flags id="hgatp-fields" size="4">
+  <field name="ppn" start="0" end="43"/>
+  <field name="vmid" start="44" end="57"/>
+  <field name="mode" start="60" end="63" type="hgatp-mode-type"/>
+</flags>
+)
+#elif defined TARGET_RISCV64
+   STR(
+<enum id="sstatus-fs-type" size="8">
+  <evalue name="off" value="0"/>
+  <evalue name="initial" value="1"/>
+  <evalue name="clean" value="2"/>
+  <evalue name="dirty" value="3"/>
+</enum><enum id="sstatus-xs-type" size="8">
+  <evalue name="off" value="0"/>
+  <evalue name="initial" value="1"/>
+  <evalue name="clean" value="2"/>
+  <evalue name="dirty" value="3"/>
+</enum><enum id="sstatus-uxl-type" size="8">
+  <evalue name="32" value="1"/>
+  <evalue name="64" value="2"/>
+  <evalue name="128" value="3"/>
+</enum><enum id="stvec-mode-type" size="8">
+  <evalue name="direct" value="0"/>
+  <evalue name="vectored" value="1"/>
+</enum><enum id="scause-exc-type" size="8">
+  <evalue name="instruction_address_misaligned" value="0"/>
+  <evalue name="instruction_access_fault" value="1"/>
+  <evalue name="illegal_instruction" value="2"/>
+  <evalue name="breakpoint" value="3"/>
+  <evalue name="load_address_misaligned" value="4"/>
+  <evalue name="load_access_fault" value="5"/>
+  <evalue name="store_address_misaligned" value="6"/>
+  <evalue name="store_access_fault" value="7"/>
+  <evalue name="enironment_call_from_U_mode" value="8"/>
+  <evalue name="enironment_call_from_S_mode" value="9"/>
+  <evalue name="enironment_call_from_VS_mode" value="10"/>
+  <evalue name="enironment_call_from_M_mode" value="11"/>
+  <evalue name="instruction_page_fault" value="12"/>
+  <evalue name="load_page_fault" value="13"/>
+  <evalue name="store_page_fault" value="15"/>
+  <evalue name="instruction_guest_page_fault" value="20"/>
+  <evalue name="load_guest_page_fault" value="21"/>
+  <evalue name="virtual_instruction" value="22"/>
+  <evalue name="store_guest_page_fault" value="23"/>
+</enum><enum id="satp-mode-type" size="8">
+  <evalue name="bare" value="0"/>
+  <evalue name="sv32" value="1"/>
+  <evalue name="sv39" value="8"/>
+  <evalue name="sv48" value="9"/>
+  <evalue name="sv57" value="10"/>
+  <evalue name="sv64" value="11"/>
+</enum><enum id="hgatp-mode-type" size="8">
+  <evalue name="bare" value="0"/>
+  <evalue name="sv32x4" value="1"/>
+  <evalue name="sv39x4" value="8"/>
+  <evalue name="sv48x4" value="9"/>
+  <evalue name="sv57x4" value="10"/>
+</enum><flags id="sstatus-fields" size="8">
+  <field name="sie" start="1" end="1"/>
+  <field name="mie" start="3" end="3"/>
+  <field name="spie" start="5" end="5"/>
+  <field name="ube" start="6" end="6"/>
+  <field name="mpie" start="7" end="7"/>
+  <field name="spp" start="8" end="8"/>
+  <field name="mpp" start="11" end="12"/>
+  <field name="fs" start="13" end="14" type="sstatus-fs-type"/>
+  <field name="xs" start="15" end="16" type="sstatus-xs-type"/>
+  <field name="mprv" start="17" end="17"/>
+  <field name="sum" start="18" end="18"/>
+  <field name="mxr" start="19" end="19"/>
+  <field name="tvm" start="20" end="20"/>
+  <field name="tw" start="21" end="21"/>
+  <field name="tsr" start="22" end="23"/>
+  <field name="uxl" start="32" end="33" type="sstatus-uxl-type"/>
+  <field name="sxl" start="34" end="35"/>
+  <field name="sbe" start="36" end="36"/>
+  <field name="mbe" start="37" end="37"/>
+  <field name="gva" start="38" end="38"/>
+  <field name="mpv" start="39" end="39"/>
+  <field name="sd" start="63" end="63"/>
+</flags><flags id="sie-fields" size="8">
+  <field name="ssie" start="1" end="1"/>
+  <field name="vssie" start="2" end="2"/>
+  <field name="msie" start="3" end="3"/>
+  <field name="stie" start="5" end="5"/>
+  <field name="vstie" start="6" end="6"/>
+  <field name="mtie" start="7" end="7"/>
+  <field name="seie" start="9" end="9"/>
+  <field name="vseie" start="10" end="10"/>
+  <field name="meie" start="11" end="11"/>
+  <field name="sgeie" start="12" end="12"/>
+</flags><flags id="stvec-fields" size="8">
+  <field name="mode" start="0" end="1" type="stvec-mode-type"/>
+  <field name="base" start="2" end="63"/>
+</flags><flags id="scounteren-fields" size="8">
+  <field name="cy" start="0" end="0"/>
+  <field name="tm" start="1" end="1"/>
+  <field name="ir" start="2" end="2"/>
+  <field name="hpm" start="3" end="31"/>
+</flags><flags id="scause-fields" size="8">
+  <field name="exc" start="0" end="62" type="scause-exc-type"/>
+  <field name="interrupt" start="63" end="63"/>
+</flags><flags id="sip-fields" size="8">
+  <field name="ssip" start="1" end="1"/>
+  <field name="vssip" start="2" end="2"/>
+  <field name="msip" start="3" end="3"/>
+  <field name="stip" start="5" end="5"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="mtip" start="7" end="7"/>
+  <field name="seip" start="9" end="9"/>
+  <field name="vseip" start="10" end="10"/>
+  <field name="meip" start="11" end="11"/>
+  <field name="sgeip" start="12" end="12"/>
+</flags><flags id="satp-fields" size="8">
+  <field name="ppn" start="0" end="43"/>
+  <field name="asid" start="44" end="59"/>
+  <field name="mode" start="60" end="63" type="satp-mode-type"/>
+</flags><flags id="hstatus-fields" size="8">
+  <field name="vsbe" start="5" end="5"/>
+  <field name="gva" start="6" end="6"/>
+  <field name="spv" start="7" end="7"/>
+  <field name="spvp" start="8" end="8"/>
+  <field name="hu" start="9" end="9"/>
+  <field name="vgein" start="12" end="17"/>
+  <field name="vtvm" start="20" end="20"/>
+  <field name="vtsr" start="22" end="22"/>
+  <field name="vsxl" start="32" end="33"/>
+</flags><flags id="hedeleg-fields" size="8">
+  <field name="instruction_address_misaligned" start="0" end="0"/>
+  <field name="instruction_access_fault" start="1" end="1"/>
+  <field name="illegal_instruction" start="2" end="2"/>
+  <field name="breakpoint" start="3" end="3"/>
+  <field name="load_address_misaligned" start="4" end="4"/>
+  <field name="load_access_fault" start="5" end="5"/>
+  <field name="store_address_misaligned" start="6" end="6"/>
+  <field name="store_access_fault" start="7" end="7"/>
+  <field name="enironment_call_from_U_mode" start="8" end="8"/>
+  <field name="enironment_call_from_S_mode" start="9" end="9"/>
+  <field name="enironment_call_from_VS_mode" start="10" end="10"/>
+  <field name="enironment_call_from_M_mode" start="11" end="11"/>
+  <field name="instruction_page_fault" start="12" end="12"/>
+  <field name="load_page_fault" start="13" end="13"/>
+  <field name="store_page_fault" start="15" end="15"/>
+  <field name="instruction_guest_page_fault" start="20" end="20"/>
+  <field name="load_guest_page_fault" start="21" end="21"/>
+  <field name="virtual_instruction" start="22" end="22"/>
+  <field name="store_guest_page_fault" start="23" end="23"/>
+</flags><flags id="hie-fields" size="8">
+  <field name="vssie" start="2" end="2"/>
+  <field name="vstie" start="6" end="6"/>
+  <field name="vseie" start="10" end="10"/>
+  <field name="sgeie" start="12" end="12"/>
+</flags><flags id="hip-fields" size="8">
+  <field name="vssip" start="2" end="2"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="vseip" start="10" end="10"/>
+  <field name="sgeip" start="12" end="12"/>
+</flags><flags id="hvip-fields" size="8">
+  <field name="vssip" start="2" end="2"/>
+  <field name="vstip" start="6" end="6"/>
+  <field name="vseip" start="10" end="10"/>
+</flags><flags id="hgatp-fields" size="8">
+  <field name="ppn" start="0" end="43"/>
+  <field name="vmid" start="44" end="57"/>
+  <field name="mode" start="60" end="63" type="hgatp-mode-type"/>
+</flags>
+)
+# endif
+;
diff --git a/target/riscv/gdb_csr_types.h b/target/riscv/gdb_csr_types.h
new file mode 100644
index 0000000000..e55c978ac8
--- /dev/null
+++ b/target/riscv/gdb_csr_types.h
@@ -0,0 +1,3 @@
+/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
+
+extern char const riscv_gdb_csr_types[];
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 23429179e2..9c3f68eeaf 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -2,6 +2,7 @@
  * RISC-V GDB Server Stub
  *
  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2021 Siemens AG, konrad.schwarz@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,
@@ -155,6 +156,9 @@ static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
     return 0;
 }
 
+#include "gdb_csr_types.h"
+#include "gdb_csr_type_group.h"
+
 static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
@@ -163,21 +167,33 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
     riscv_csr_predicate_fn predicate;
     int bitsize = 16 << env->misa_mxl_max;
     int i;
+    riscv_csr_operations *csr_op;
+    struct riscv_gdb_csr_tg const *csr_tg;
 
     g_string_printf(s, "<?xml version=\"1.0\"?>");
     g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
     g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
 
-    for (i = 0; i < CSR_TABLE_SIZE; i++) {
-        predicate = csr_ops[i].predicate;
+    g_string_append(s, riscv_gdb_csr_types);
+
+    for (i = 0, csr_op = csr_ops, csr_tg = riscv_gdb_csr_type_group;
+            i < CSR_TABLE_SIZE; ++csr_op, ++csr_tg, ++i) {
+        predicate = csr_op->predicate;
         if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
-            if (csr_ops[i].name) {
-                g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
+            if (csr_op->name) {
+                g_string_append_printf(s, "<reg name=\"%s\"", csr_op->name);
             } else {
                 g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
             }
             g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
-            g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
+            g_string_append_printf(s, " regnum=\"%d\"", base_reg + i);
+            if (csr_tg->gdb_type) {
+                g_string_append_printf(s, " type=\"%s\"", csr_tg->gdb_type);
+            }
+            if (csr_tg->gdb_group) {
+                g_string_append_printf(s, " group=\"%s\"", csr_tg->gdb_group);
+            }
+            g_string_append(s, " />\n");
         }
     }
 
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index d5e0bc93ea..e1945e54c4 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -25,7 +25,9 @@ riscv_softmmu_ss.add(files(
   'arch_dump.c',
   'pmp.c',
   'monitor.c',
-  'machine.c'
+  'machine.c',
+  'gdb_csr_types.c',
+  'gdb_csr_type_group.c'
 ))
 
 target_arch += {'riscv': riscv_ss}
-- 
Konrad Schwarz



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 5/5] RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register
  2022-01-04 15:51     ` [PATCH v2 0/5] Improve RISC-V debugging support Konrad Schwarz
                         ` (3 preceding siblings ...)
  2022-01-04 15:51       ` [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
@ 2022-01-04 15:51       ` Konrad Schwarz
  4 siblings, 0 replies; 26+ messages in thread
From: Konrad Schwarz @ 2022-01-04 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Konrad Schwarz, Alistair Francis, Bin Meng, Palmer Dabbelt,
	Ralf Ramsauer

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 <konrad.schwarz@siemens.com>
---
 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.  -->
 
+<!-- Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com -->
+
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
-<feature name="org.gnu.gdb.riscv.virtual">
-  <reg name="priv" bitsize="32"/>
+
+<feature	name="org.gnu.gdb.riscv.virtual" >
+
+<enum id="priv-current_priv-type" size="4" >
+	<evalue	name="user"	value="0" />
+	<evalue	name="supervisor"	value="1" />
+	<evalue	name="machine"	value="3" />
+</enum>
+
+
+<flags id="priv-fields"	size="4" >
+	<field	name="current_priv"	start="0"	end="1"
+		type="priv-current_priv-type" />
+	<field	name="v"	start="2"	end="2" />
+</flags>
+
+
+<reg	name="priv"
+		bitsize="32"
+		regnum="69"
+		save-restore="no"
+		type="priv-fields"
+		group="gdb-virtual"
+/>
+
+
 </feature>
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.  -->
 
+<!-- Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com -->
+
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
-<feature name="org.gnu.gdb.riscv.virtual">
-  <reg name="priv" bitsize="64"/>
+
+<feature	name="org.gnu.gdb.riscv.virtual" >
+
+<enum id="priv-current_priv-type" size="8" >
+	<evalue	name="user"	value="0" />
+	<evalue	name="supervisor"	value="1" />
+	<evalue	name="machine"	value="3" />
+</enum>
+
+
+<flags id="priv-fields"	size="8" >
+	<field	name="current_priv"	start="0"	end="1"
+		type="priv-current_priv-type" />
+	<field	name="v"	start="2"	end="2" />
+</flags>
+
+
+<reg	name="priv"
+		bitsize="64"
+		regnum="69"
+		save-restore="no"
+		type="priv-fields"
+		group="gdb-virtual"
+/>
+
+
 </feature>
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 = &cpu->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



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'
  2022-01-04 15:51       ` [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
@ 2022-01-04 20:57         ` Richard Henderson
  2022-01-05 12:38           ` Schwarz, Konrad
  0 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2022-01-04 20:57 UTC (permalink / raw)
  To: Konrad Schwarz, qemu-devel
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, Ralf Ramsauer

On 1/4/22 7:51 AM, Konrad Schwarz wrote:
>           static const int dump_csrs[] = {
> +
> +#  if 0
> +            CSR_USTATUS,
> +            CSR_UIE,
> +            CSR_UTVEC,

Adding huge sections of #if 0 code is not acceptable.


r~


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations
  2022-01-04 15:51       ` [PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations Konrad Schwarz
@ 2022-01-04 22:03         ` Alistair Francis
  2022-01-05 13:09           ` Schwarz, Konrad
  0 siblings, 1 reply; 26+ messages in thread
From: Alistair Francis @ 2022-01-04 22:03 UTC (permalink / raw)
  To: Konrad Schwarz
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis,
	qemu-devel@nongnu.org Developers, Ralf Ramsauer

On Wed, Jan 5, 2022 at 1:55 AM Konrad Schwarz
<konrad.schwarz@siemens.com> wrote:
>
> This is analog to the existing 'info mem' command and is implemented
> using the same machinery.
>
> Signed-off-by: Konrad Schwarz <konrad.schwarz@siemens.com>

Hello and thanks for the patches

> ---
>  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

I don't think we want RISC-V specific commands. Could we not just
extend `info mem` instead?

> +
> +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.schwarz@siemens.com

Generally you would only add a copyright claim for a very large
change. Adding a single function prototype doesn't really cut it.

>   *
>   * 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       "vaddr            paddr            "\
> -                                "size             attr\n"
> -#define PTE_HEADER_DELIMITER    "---------------- ---------------- "\
> -                                "---------------- -------\n"
> -#else
> -#define PTE_HEADER_FIELDS       "vaddr    paddr            size     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);
> +
> +# define        VIRTUAL_WIDTH\
> +        ((int) ((sizeof "ff" - sizeof "") * sizeof(target_ulong)))
> +# define        PHYSICAL_WIDTH\
> +        ((int) ((sizeof "ff" - sizeof "") * sizeof(hwaddr)))
> +# define        ATTRIBUTE_WIDTH ((int) (sizeof "rwxugad" - sizeof ""))
> +
> +# define        VIRTUAL_COLUMN_WIDTH    (1 + VIRTUAL_WIDTH)
> +# define        PHYSICAL_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' : '-',
> -                   attr & PTE_G ? 'g' : '-',
> -                   attr & PTE_A ? 'a' : '-',
> -                   attr & PTE_D ? 'd' : '-');
> +# if 4 == TARGET_LONG_SIZE
> +#       define  TARGET_xFMT     PRIx32
> +# elif 8 == TARGET_LONG_SIZE
> +#       define  TARGET_xFMT     PRIx64
> +# else
> +#       error TARGET_LONG_SIZE not handled
> +# endif

You can just use TCG_PRIlx instead

Alistair

> +
> +    /* note: RISC-V physical addresses are actually xlen + 2 bits long
> +    OTHO, QEMU wil probably never support addresses longer than 64 bits */
> +    monitor_printf(mon,
> +            "%-*.*" TARGET_xFMT
> +            "%-*.*" PRIx64
> +            "%-*.*" TARGET_xFMT
> +            "%c%c%c%c%c%c%c\n",
> +            VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, addr_canonical(va_bits, vaddr),
> +            PHYSICAL_COLUMN_WIDTH, PHYSICAL_WIDTH, paddr,
> +            VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, size,
> +            attr & PTE_R ? 'r' : '-',
> +            attr & PTE_W ? 'w' : '-',
> +            attr & PTE_X ? 'x' : '-',
> +            attr & PTE_U ? 'u' : '-',
> +            attr & PTE_G ? 'g' : '-',
> +            attr & PTE_A ? 'a' : '-',
> +            attr & PTE_D ? 'd' : '-');
>  }
>
>  static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
>                       int level, int ptidxbits, int ptesize, int va_bits,
> +                     int guest,
>                       target_ulong *vbase, hwaddr *pbase, hwaddr *last_paddr,
>                       target_ulong *last_size, int *last_attr)
>  {
> @@ -89,7 +118,7 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
>      target_ulong pte;
>      int ptshift;
>      int attr;
> -    int idx;
> +    int idx, idx_end;
>
>      if (level < 0) {
>          return;
> @@ -98,7 +127,8 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
>      ptshift = level * ptidxbits;
>      pgsize = 1UL << (PGSHIFT + ptshift);
>
> -    for (idx = 0; idx < (1UL << ptidxbits); idx++) {
> +    for (idx = 0, idx_end = 1 << (ptidxbits + (guest ? 2 : 0));
> +            idx_end > idx; idx++) {
>          pte_addr = base + idx * ptesize;
>          cpu_physical_memory_read(pte_addr, &pte, ptesize);
>
> @@ -131,7 +161,9 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
>              } else {
>                  /* pointer to the next level of the page table */
>                  walk_pte(mon, paddr, start, level - 1, ptidxbits, ptesize,
> -                         va_bits, vbase, pbase, last_paddr,
> +                         va_bits,
> +                         0 /* guest */,
> +                         vbase, pbase, last_paddr,
>                           last_size, last_attr);
>              }
>          }
> @@ -141,7 +173,9 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
>
>  }
>
> -static void mem_info_svxx(Monitor *mon, CPUArchState *env)
> +static void mem_info_svxx(Monitor *mon, CPUArchState *env,
> +        target_ulong const atp,
> +        int guest, char const vaddr_char, char const paddr_char)
>  {
>      int levels, ptidxbits, ptesize, vm, va_bits;
>      hwaddr base;
> @@ -152,11 +186,11 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
>      int last_attr;
>
>      if (riscv_cpu_mxl(env) == MXL_RV32) {
> -        base = (hwaddr)get_field(env->satp, SATP32_PPN) << PGSHIFT;
> -        vm = get_field(env->satp, SATP32_MODE);
> +        base = (hwaddr)get_field(atp, SATP32_PPN) << PGSHIFT;
> +        vm = get_field(atp, SATP32_MODE);
>      } else {
> -        base = (hwaddr)get_field(env->satp, SATP64_PPN) << PGSHIFT;
> -        vm = get_field(env->satp, SATP64_MODE);
> +        base = (hwaddr)get_field(atp, SATP64_PPN) << PGSHIFT;
> +        vm = get_field(atp, SATP64_MODE);
>      }
>
>      switch (vm) {
> @@ -189,7 +223,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
>      va_bits = PGSHIFT + levels * ptidxbits;
>
>      /* print header */
> -    print_pte_header(mon);
> +    print_pte_header(mon, vaddr_char, paddr_char);
>
>      vbase = -1;
>      pbase = -1;
> @@ -199,6 +233,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
>
>      /* walk page tables, starting from address 0 */
>      walk_pte(mon, base, 0, levels - 1, ptidxbits, ptesize, va_bits,
> +             guest,
>               &vbase, &pbase, &last_paddr, &last_size, &last_attr);
>
>      /* don't forget the last one */
> @@ -209,6 +244,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
>  void hmp_info_mem(Monitor *mon, const QDict *qdict)
>  {
>      CPUArchState *env;
> +    target_ulong atp;
>
>      env = mon_get_cpu_env(mon);
>      if (!env) {
> @@ -221,19 +257,46 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
>          return;
>      }
>
> +    atp = env->satp;
>      if (riscv_cpu_mxl(env) == MXL_RV32) {
> -        if (!(env->satp & SATP32_MODE)) {
> +        if (!(atp & SATP32_MODE)) {
>              monitor_printf(mon, "No translation or protection\n");
>              return;
>          }
>      } else {
> -        if (!(env->satp & SATP64_MODE)) {
> +        if (!(atp & SATP64_MODE)) {
>              monitor_printf(mon, "No translation or protection\n");
>              return;
>          }
>      }
>
> -    mem_info_svxx(mon, env);
> +    mem_info_svxx(mon, env, atp, 0, 'v', 'p');
> +}
> +
> +void hmp_info_gmem(Monitor *mon, const QDict *qdict)
> +{
> +    CPUArchState *env;
> +    target_ulong atp;
> +
> +    env = mon_get_cpu_env(mon);
> +    if (!env) {
> +        monitor_printf(mon, "No CPU available\n");
> +        return;
> +    }
> +
> +    if (!riscv_has_ext(env, RVH)) {
> +        monitor_printf(mon, "hypervisor extension not available\n");
> +        return;
> +    }
> +
> +    atp = env->hgatp;
> +    if (!((MXL_RV32 == riscv_cpu_mxl(env) ? SATP32_MODE : SATP64_MODE)
> +            & atp)) {
> +        monitor_printf(mon, "No translation or protection\n");
> +        return;
> +    }
> +
> +    mem_info_svxx(mon, env, atp, 1, 'g', 'p');
>  }
>
>  static const MonitorDef monitor_defs[] = {
> --
> Konrad Schwarz
>
>


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-04 15:51       ` [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
@ 2022-01-04 22:11         ` Alistair Francis
  2022-01-05 13:25           ` Schwarz, Konrad
  2022-01-04 23:01         ` Richard Henderson
  2022-01-05 18:43         ` Alex Bennée
  2 siblings, 1 reply; 26+ messages in thread
From: Alistair Francis @ 2022-01-04 22:11 UTC (permalink / raw)
  To: Konrad Schwarz
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis,
	qemu-devel@nongnu.org Developers, Ralf Ramsauer

On Wed, Jan 5, 2022 at 1:56 AM Konrad Schwarz
<konrad.schwarz@siemens.com> wrote:
>
> 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 <konrad.schwarz@siemens.com>
> ---
>  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, sagark@eecs.berkeley.edu
>   * Copyright (c) 2017-2018 SiFive, Inc.
> + * Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com

Please don't add these to existing files. In this case you have just
added a newline to this file

>   *
>   * 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 0000000000..e8ec527f23
> --- /dev/null
> +++ b/target/riscv/csr32-op-gdbserver.h
> @@ -0,0 +1,109 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */

All of these files should have the usual file boiler plate

> +
> +  [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" },
> +  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER28] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER29] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER30] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER31] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_CYCLEH] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_TIMEH] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_INSTRETH] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER3H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER4H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER5H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER6H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER7H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER8H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER9H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER10H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER11H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER12H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER13H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER14H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER15H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER16H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER17H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER18H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER19H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER20H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER21H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER22H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER23H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER24H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER25H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER26H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER27H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER28H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER29H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER30H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER31H] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_SSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "supervisor" },
> +  [CSR_SEDELEG] { .gdb_type = "uint32", .gdb_group = "supervisor" },
> +  [CSR_SIDELEG] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
> +  [CSR_SIE] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
> +  [CSR_STVEC] { .gdb_type = "stvec-fields", .gdb_group = "supervisor" },
> +  [CSR_SCOUNTEREN] { .gdb_type = "scounteren-fields", .gdb_group = "supervisor" },
> +  [CSR_SSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
> +  [CSR_SEPC] { .gdb_type = "code_ptr", .gdb_group = "supervisor" },
> +  [CSR_SCAUSE] { .gdb_type = "scause-fields", .gdb_group = "supervisor" },
> +  [CSR_STVAL] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
> +  [CSR_SIP] { .gdb_type = "sip-fields", .gdb_group = "supervisor" },
> +  [CSR_SATP] { .gdb_type = "satp-fields", .gdb_group = "supervisor" },
> +  [CSR_HSTATUS] { .gdb_type = "hstatus-fields", .gdb_group = "hypervisor" },
> +  [CSR_HEDELEG] { .gdb_type = "hedeleg-fields", .gdb_group = "hypervisor" },
> +  [CSR_HIDELEG] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
> +  [CSR_HIE] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
> +  [CSR_HCOUNTEREN] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HGEIE] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
> +  [CSR_HGEIP] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
> +  [CSR_HTVAL] { .gdb_type = "data_ptr", .gdb_group = "hypervisor" },
> +  [CSR_HIP] { .gdb_type = "hip-fields", .gdb_group = "hypervisor" },
> +  [CSR_HVIP] { .gdb_type = "hvip-fields", .gdb_group = "hypervisor" },
> +  [CSR_HGATP] { .gdb_type = "hgatp-fields", .gdb_group = "hypervisor" },
> +  [CSR_HTIMEDELTA] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HTIMEDELTAH] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HTINST] { .gdb_type = "uint32", .gdb_group = "hypervisor" },
> +  [CSR_VSSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSIE] { .gdb_type = "sie-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSTVEC] { .gdb_type = "stvec-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSEPC] { .gdb_type = "code_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSCAUSE] { .gdb_type = "scause-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSTVAL] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSIP] { .gdb_type = "sip-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSATP] { .gdb_type = "satp-fields", .gdb_group = "virtual-supervisor" },
> diff --git a/target/riscv/csr64-op-gdbserver.h b/target/riscv/csr64-op-gdbserver.h
> new file mode 100644
> index 0000000000..fc4bc62d9e
> --- /dev/null
> +++ b/target/riscv/csr64-op-gdbserver.h
> @@ -0,0 +1,76 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@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 = "uint64", .gdb_group = "user" },
> +  [CSR_TIME] { .gdb_type = "uint64", .gdb_group = "user" },
> +  [CSR_INSTRET] { .gdb_type = "uint64", .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" },
> +  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER28] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER29] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER30] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER31] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_SSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "supervisor" },
> +  [CSR_SEDELEG] { .gdb_type = "uint64", .gdb_group = "supervisor" },
> +  [CSR_SIDELEG] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
> +  [CSR_SIE] { .gdb_type = "sie-fields", .gdb_group = "supervisor" },
> +  [CSR_STVEC] { .gdb_type = "stvec-fields", .gdb_group = "supervisor" },
> +  [CSR_SCOUNTEREN] { .gdb_type = "scounteren-fields", .gdb_group = "supervisor" },
> +  [CSR_SSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
> +  [CSR_SEPC] { .gdb_type = "code_ptr", .gdb_group = "supervisor" },
> +  [CSR_SCAUSE] { .gdb_type = "scause-fields", .gdb_group = "supervisor" },
> +  [CSR_STVAL] { .gdb_type = "data_ptr", .gdb_group = "supervisor" },
> +  [CSR_SIP] { .gdb_type = "sip-fields", .gdb_group = "supervisor" },
> +  [CSR_SATP] { .gdb_type = "satp-fields", .gdb_group = "supervisor" },
> +  [CSR_HSTATUS] { .gdb_type = "hstatus-fields", .gdb_group = "hypervisor" },
> +  [CSR_HEDELEG] { .gdb_type = "hedeleg-fields", .gdb_group = "hypervisor" },
> +  [CSR_HIDELEG] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
> +  [CSR_HIE] { .gdb_type = "hie-fields", .gdb_group = "hypervisor" },
> +  [CSR_HCOUNTEREN] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HGEIE] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
> +  [CSR_HGEIP] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
> +  [CSR_HTVAL] { .gdb_type = "data_ptr", .gdb_group = "hypervisor" },
> +  [CSR_HIP] { .gdb_type = "hip-fields", .gdb_group = "hypervisor" },
> +  [CSR_HVIP] { .gdb_type = "hvip-fields", .gdb_group = "hypervisor" },
> +  [CSR_HGATP] { .gdb_type = "hgatp-fields", .gdb_group = "hypervisor" },
> +  [CSR_HTIMEDELTA] { .gdb_type = "int", .gdb_group = "hypervisor" },
> +  [CSR_HTINST] { .gdb_type = "uint64", .gdb_group = "hypervisor" },
> +  [CSR_VSSTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSIE] { .gdb_type = "sie-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSTVEC] { .gdb_type = "stvec-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSSCRATCH] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSEPC] { .gdb_type = "code_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSCAUSE] { .gdb_type = "scause-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSTVAL] { .gdb_type = "data_ptr", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSIP] { .gdb_type = "sip-fields", .gdb_group = "virtual-supervisor" },
> +  [CSR_VSATP] { .gdb_type = "satp-fields", .gdb_group = "virtual-supervisor" },
> diff --git a/target/riscv/gdb_csr_type_group.c b/target/riscv/gdb_csr_type_group.c
> new file mode 100644
> index 0000000000..af394de302
> --- /dev/null
> +++ b/target/riscv/gdb_csr_type_group.c
> @@ -0,0 +1,16 @@
> +/* Copyright 2021 Siemens AG */
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +#include "gdb_csr_type_group.h"
> +
> +struct riscv_gdb_csr_tg const riscv_gdb_csr_type_group[] = {
> +
> +#if !defined(CONFIG_USER_ONLY)
> +#  ifdef TARGET_RISCV64
> +#    include "csr64-op-gdbserver.h"
> +#  elif defined TARGET_RISCV64
> +#    include "csr32-op-gdbserver.h"

This doesn't look right. `if defined TARGET_RISCV64` -> `include
"csr32-op-gdbserver.h"`?

Also this should be dynamic instead of based on the build time CPU, as
the user could use a 32-bit CPU on a 64-bit target build.

> +#  endif
> +#endif /* !CONFIG_USER_ONLY */
> +
> +};
> diff --git a/target/riscv/gdb_csr_type_group.h b/target/riscv/gdb_csr_type_group.h
> new file mode 100644
> index 0000000000..e044913bd7
> --- /dev/null
> +++ b/target/riscv/gdb_csr_type_group.h
> @@ -0,0 +1,3 @@
> +extern struct riscv_gdb_csr_tg {
> +    char const *gdb_type, *gdb_group;
> +} const riscv_gdb_csr_type_group[CSR_TABLE_SIZE];

I feel like all of the header files could be combined into one single
file and instead of using macros just pick the struct.

Alistair

> diff --git a/target/riscv/gdb_csr_types.c b/target/riscv/gdb_csr_types.c
> new file mode 100644
> index 0000000000..48b1db2b88
> --- /dev/null
> +++ b/target/riscv/gdb_csr_types.c
> @@ -0,0 +1,333 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
> +
> +#include "qemu/osdep.h"
> +#include "gdb_csr_types.h"
> +#define STR(X) #X
> +
> +char const riscv_gdb_csr_types[] =
> +#ifdef TARGET_RISCV32
> +   STR(
> +<enum id="sstatus-fs-type" size="4">
> +  <evalue name="off" value="0"/>
> +  <evalue name="initial" value="1"/>
> +  <evalue name="clean" value="2"/>
> +  <evalue name="dirty" value="3"/>
> +</enum><enum id="sstatus-xs-type" size="4">
> +  <evalue name="off" value="0"/>
> +  <evalue name="initial" value="1"/>
> +  <evalue name="clean" value="2"/>
> +  <evalue name="dirty" value="3"/>
> +</enum><enum id="sstatus-uxl-type" size="4">
> +  <evalue name="32" value="1"/>
> +  <evalue name="64" value="2"/>
> +  <evalue name="128" value="3"/>
> +</enum><enum id="stvec-mode-type" size="4">
> +  <evalue name="direct" value="0"/>
> +  <evalue name="vectored" value="1"/>
> +</enum><enum id="scause-exc-type" size="4">
> +  <evalue name="instruction_address_misaligned" value="0"/>
> +  <evalue name="instruction_access_fault" value="1"/>
> +  <evalue name="illegal_instruction" value="2"/>
> +  <evalue name="breakpoint" value="3"/>
> +  <evalue name="load_address_misaligned" value="4"/>
> +  <evalue name="load_access_fault" value="5"/>
> +  <evalue name="store_address_misaligned" value="6"/>
> +  <evalue name="store_access_fault" value="7"/>
> +  <evalue name="enironment_call_from_U_mode" value="8"/>
> +  <evalue name="enironment_call_from_S_mode" value="9"/>
> +  <evalue name="enironment_call_from_VS_mode" value="10"/>
> +  <evalue name="enironment_call_from_M_mode" value="11"/>
> +  <evalue name="instruction_page_fault" value="12"/>
> +  <evalue name="load_page_fault" value="13"/>
> +  <evalue name="store_page_fault" value="15"/>
> +  <evalue name="instruction_guest_page_fault" value="20"/>
> +  <evalue name="load_guest_page_fault" value="21"/>
> +  <evalue name="virtual_instruction" value="22"/>
> +  <evalue name="store_guest_page_fault" value="23"/>
> +</enum><enum id="satp-mode-type" size="4">
> +  <evalue name="bare" value="0"/>
> +  <evalue name="sv32" value="1"/>
> +  <evalue name="sv39" value="8"/>
> +  <evalue name="sv48" value="9"/>
> +  <evalue name="sv57" value="10"/>
> +  <evalue name="sv64" value="11"/>
> +</enum><enum id="hgatp-mode-type" size="4">
> +  <evalue name="bare" value="0"/>
> +  <evalue name="sv32x4" value="1"/>
> +  <evalue name="sv39x4" value="8"/>
> +  <evalue name="sv48x4" value="9"/>
> +  <evalue name="sv57x4" value="10"/>
> +</enum><flags id="sstatus-fields" size="4">
> +  <field name="sie" start="1" end="1"/>
> +  <field name="mie" start="3" end="3"/>
> +  <field name="spie" start="5" end="5"/>
> +  <field name="ube" start="6" end="6"/>
> +  <field name="mpie" start="7" end="7"/>
> +  <field name="spp" start="8" end="8"/>
> +  <field name="mpp" start="11" end="12"/>
> +  <field name="fs" start="13" end="14" type="sstatus-fs-type"/>
> +  <field name="xs" start="15" end="16" type="sstatus-xs-type"/>
> +  <field name="mprv" start="17" end="17"/>
> +  <field name="sum" start="18" end="18"/>
> +  <field name="mxr" start="19" end="19"/>
> +  <field name="tvm" start="20" end="20"/>
> +  <field name="tw" start="21" end="21"/>
> +  <field name="tsr" start="22" end="23"/>
> +  <field name="uxl" start="32" end="33" type="sstatus-uxl-type"/>
> +  <field name="sxl" start="34" end="35"/>
> +  <field name="sbe" start="36" end="36"/>
> +  <field name="mbe" start="37" end="37"/>
> +  <field name="gva" start="38" end="38"/>
> +  <field name="mpv" start="39" end="39"/>
> +  <field name="sd" start="63" end="63"/>
> +</flags><flags id="sie-fields" size="4">
> +  <field name="ssie" start="1" end="1"/>
> +  <field name="vssie" start="2" end="2"/>
> +  <field name="msie" start="3" end="3"/>
> +  <field name="stie" start="5" end="5"/>
> +  <field name="vstie" start="6" end="6"/>
> +  <field name="mtie" start="7" end="7"/>
> +  <field name="seie" start="9" end="9"/>
> +  <field name="vseie" start="10" end="10"/>
> +  <field name="meie" start="11" end="11"/>
> +  <field name="sgeie" start="12" end="12"/>
> +</flags><flags id="stvec-fields" size="4">
> +  <field name="mode" start="0" end="1" type="stvec-mode-type"/>
> +  <field name="base" start="2" end="63"/>
> +</flags><flags id="scounteren-fields" size="4">
> +  <field name="cy" start="0" end="0"/>
> +  <field name="tm" start="1" end="1"/>
> +  <field name="ir" start="2" end="2"/>
> +  <field name="hpm" start="3" end="31"/>
> +</flags><flags id="scause-fields" size="4">
> +  <field name="exc" start="0" end="30" type="scause-exc-type"/>
> +  <field name="interrupt" start="31" end="31"/>
> +</flags><flags id="sip-fields" size="4">
> +  <field name="ssip" start="1" end="1"/>
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="msip" start="3" end="3"/>
> +  <field name="stip" start="5" end="5"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="mtip" start="7" end="7"/>
> +  <field name="seip" start="9" end="9"/>
> +  <field name="vseip" start="10" end="10"/>
> +  <field name="meip" start="11" end="11"/>
> +  <field name="sgeip" start="12" end="12"/>
> +</flags><flags id="satp-fields" size="4">
> +  <field name="ppn" start="0" end="43"/>
> +  <field name="asid" start="44" end="59"/>
> +  <field name="mode" start="60" end="63" type="satp-mode-type"/>
> +</flags><flags id="hstatus-fields" size="4">
> +  <field name="vsbe" start="5" end="5"/>
> +  <field name="gva" start="6" end="6"/>
> +  <field name="spv" start="7" end="7"/>
> +  <field name="spvp" start="8" end="8"/>
> +  <field name="hu" start="9" end="9"/>
> +  <field name="vgein" start="12" end="17"/>
> +  <field name="vtvm" start="20" end="20"/>
> +  <field name="vtsr" start="22" end="22"/>
> +  <field name="vsxl" start="32" end="33"/>
> +</flags><flags id="hedeleg-fields" size="4">
> +  <field name="instruction_address_misaligned" start="0" end="0"/>
> +  <field name="instruction_access_fault" start="1" end="1"/>
> +  <field name="illegal_instruction" start="2" end="2"/>
> +  <field name="breakpoint" start="3" end="3"/>
> +  <field name="load_address_misaligned" start="4" end="4"/>
> +  <field name="load_access_fault" start="5" end="5"/>
> +  <field name="store_address_misaligned" start="6" end="6"/>
> +  <field name="store_access_fault" start="7" end="7"/>
> +  <field name="enironment_call_from_U_mode" start="8" end="8"/>
> +  <field name="enironment_call_from_S_mode" start="9" end="9"/>
> +  <field name="enironment_call_from_VS_mode" start="10" end="10"/>
> +  <field name="enironment_call_from_M_mode" start="11" end="11"/>
> +  <field name="instruction_page_fault" start="12" end="12"/>
> +  <field name="load_page_fault" start="13" end="13"/>
> +  <field name="store_page_fault" start="15" end="15"/>
> +  <field name="instruction_guest_page_fault" start="20" end="20"/>
> +  <field name="load_guest_page_fault" start="21" end="21"/>
> +  <field name="virtual_instruction" start="22" end="22"/>
> +  <field name="store_guest_page_fault" start="23" end="23"/>
> +</flags><flags id="hie-fields" size="4">
> +  <field name="vssie" start="2" end="2"/>
> +  <field name="vstie" start="6" end="6"/>
> +  <field name="vseie" start="10" end="10"/>
> +  <field name="sgeie" start="12" end="12"/>
> +</flags><flags id="hip-fields" size="4">
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="vseip" start="10" end="10"/>
> +  <field name="sgeip" start="12" end="12"/>
> +</flags><flags id="hvip-fields" size="4">
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="vseip" start="10" end="10"/>
> +</flags><flags id="hgatp-fields" size="4">
> +  <field name="ppn" start="0" end="43"/>
> +  <field name="vmid" start="44" end="57"/>
> +  <field name="mode" start="60" end="63" type="hgatp-mode-type"/>
> +</flags>
> +)
> +#elif defined TARGET_RISCV64
> +   STR(
> +<enum id="sstatus-fs-type" size="8">
> +  <evalue name="off" value="0"/>
> +  <evalue name="initial" value="1"/>
> +  <evalue name="clean" value="2"/>
> +  <evalue name="dirty" value="3"/>
> +</enum><enum id="sstatus-xs-type" size="8">
> +  <evalue name="off" value="0"/>
> +  <evalue name="initial" value="1"/>
> +  <evalue name="clean" value="2"/>
> +  <evalue name="dirty" value="3"/>
> +</enum><enum id="sstatus-uxl-type" size="8">
> +  <evalue name="32" value="1"/>
> +  <evalue name="64" value="2"/>
> +  <evalue name="128" value="3"/>
> +</enum><enum id="stvec-mode-type" size="8">
> +  <evalue name="direct" value="0"/>
> +  <evalue name="vectored" value="1"/>
> +</enum><enum id="scause-exc-type" size="8">
> +  <evalue name="instruction_address_misaligned" value="0"/>
> +  <evalue name="instruction_access_fault" value="1"/>
> +  <evalue name="illegal_instruction" value="2"/>
> +  <evalue name="breakpoint" value="3"/>
> +  <evalue name="load_address_misaligned" value="4"/>
> +  <evalue name="load_access_fault" value="5"/>
> +  <evalue name="store_address_misaligned" value="6"/>
> +  <evalue name="store_access_fault" value="7"/>
> +  <evalue name="enironment_call_from_U_mode" value="8"/>
> +  <evalue name="enironment_call_from_S_mode" value="9"/>
> +  <evalue name="enironment_call_from_VS_mode" value="10"/>
> +  <evalue name="enironment_call_from_M_mode" value="11"/>
> +  <evalue name="instruction_page_fault" value="12"/>
> +  <evalue name="load_page_fault" value="13"/>
> +  <evalue name="store_page_fault" value="15"/>
> +  <evalue name="instruction_guest_page_fault" value="20"/>
> +  <evalue name="load_guest_page_fault" value="21"/>
> +  <evalue name="virtual_instruction" value="22"/>
> +  <evalue name="store_guest_page_fault" value="23"/>
> +</enum><enum id="satp-mode-type" size="8">
> +  <evalue name="bare" value="0"/>
> +  <evalue name="sv32" value="1"/>
> +  <evalue name="sv39" value="8"/>
> +  <evalue name="sv48" value="9"/>
> +  <evalue name="sv57" value="10"/>
> +  <evalue name="sv64" value="11"/>
> +</enum><enum id="hgatp-mode-type" size="8">
> +  <evalue name="bare" value="0"/>
> +  <evalue name="sv32x4" value="1"/>
> +  <evalue name="sv39x4" value="8"/>
> +  <evalue name="sv48x4" value="9"/>
> +  <evalue name="sv57x4" value="10"/>
> +</enum><flags id="sstatus-fields" size="8">
> +  <field name="sie" start="1" end="1"/>
> +  <field name="mie" start="3" end="3"/>
> +  <field name="spie" start="5" end="5"/>
> +  <field name="ube" start="6" end="6"/>
> +  <field name="mpie" start="7" end="7"/>
> +  <field name="spp" start="8" end="8"/>
> +  <field name="mpp" start="11" end="12"/>
> +  <field name="fs" start="13" end="14" type="sstatus-fs-type"/>
> +  <field name="xs" start="15" end="16" type="sstatus-xs-type"/>
> +  <field name="mprv" start="17" end="17"/>
> +  <field name="sum" start="18" end="18"/>
> +  <field name="mxr" start="19" end="19"/>
> +  <field name="tvm" start="20" end="20"/>
> +  <field name="tw" start="21" end="21"/>
> +  <field name="tsr" start="22" end="23"/>
> +  <field name="uxl" start="32" end="33" type="sstatus-uxl-type"/>
> +  <field name="sxl" start="34" end="35"/>
> +  <field name="sbe" start="36" end="36"/>
> +  <field name="mbe" start="37" end="37"/>
> +  <field name="gva" start="38" end="38"/>
> +  <field name="mpv" start="39" end="39"/>
> +  <field name="sd" start="63" end="63"/>
> +</flags><flags id="sie-fields" size="8">
> +  <field name="ssie" start="1" end="1"/>
> +  <field name="vssie" start="2" end="2"/>
> +  <field name="msie" start="3" end="3"/>
> +  <field name="stie" start="5" end="5"/>
> +  <field name="vstie" start="6" end="6"/>
> +  <field name="mtie" start="7" end="7"/>
> +  <field name="seie" start="9" end="9"/>
> +  <field name="vseie" start="10" end="10"/>
> +  <field name="meie" start="11" end="11"/>
> +  <field name="sgeie" start="12" end="12"/>
> +</flags><flags id="stvec-fields" size="8">
> +  <field name="mode" start="0" end="1" type="stvec-mode-type"/>
> +  <field name="base" start="2" end="63"/>
> +</flags><flags id="scounteren-fields" size="8">
> +  <field name="cy" start="0" end="0"/>
> +  <field name="tm" start="1" end="1"/>
> +  <field name="ir" start="2" end="2"/>
> +  <field name="hpm" start="3" end="31"/>
> +</flags><flags id="scause-fields" size="8">
> +  <field name="exc" start="0" end="62" type="scause-exc-type"/>
> +  <field name="interrupt" start="63" end="63"/>
> +</flags><flags id="sip-fields" size="8">
> +  <field name="ssip" start="1" end="1"/>
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="msip" start="3" end="3"/>
> +  <field name="stip" start="5" end="5"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="mtip" start="7" end="7"/>
> +  <field name="seip" start="9" end="9"/>
> +  <field name="vseip" start="10" end="10"/>
> +  <field name="meip" start="11" end="11"/>
> +  <field name="sgeip" start="12" end="12"/>
> +</flags><flags id="satp-fields" size="8">
> +  <field name="ppn" start="0" end="43"/>
> +  <field name="asid" start="44" end="59"/>
> +  <field name="mode" start="60" end="63" type="satp-mode-type"/>
> +</flags><flags id="hstatus-fields" size="8">
> +  <field name="vsbe" start="5" end="5"/>
> +  <field name="gva" start="6" end="6"/>
> +  <field name="spv" start="7" end="7"/>
> +  <field name="spvp" start="8" end="8"/>
> +  <field name="hu" start="9" end="9"/>
> +  <field name="vgein" start="12" end="17"/>
> +  <field name="vtvm" start="20" end="20"/>
> +  <field name="vtsr" start="22" end="22"/>
> +  <field name="vsxl" start="32" end="33"/>
> +</flags><flags id="hedeleg-fields" size="8">
> +  <field name="instruction_address_misaligned" start="0" end="0"/>
> +  <field name="instruction_access_fault" start="1" end="1"/>
> +  <field name="illegal_instruction" start="2" end="2"/>
> +  <field name="breakpoint" start="3" end="3"/>
> +  <field name="load_address_misaligned" start="4" end="4"/>
> +  <field name="load_access_fault" start="5" end="5"/>
> +  <field name="store_address_misaligned" start="6" end="6"/>
> +  <field name="store_access_fault" start="7" end="7"/>
> +  <field name="enironment_call_from_U_mode" start="8" end="8"/>
> +  <field name="enironment_call_from_S_mode" start="9" end="9"/>
> +  <field name="enironment_call_from_VS_mode" start="10" end="10"/>
> +  <field name="enironment_call_from_M_mode" start="11" end="11"/>
> +  <field name="instruction_page_fault" start="12" end="12"/>
> +  <field name="load_page_fault" start="13" end="13"/>
> +  <field name="store_page_fault" start="15" end="15"/>
> +  <field name="instruction_guest_page_fault" start="20" end="20"/>
> +  <field name="load_guest_page_fault" start="21" end="21"/>
> +  <field name="virtual_instruction" start="22" end="22"/>
> +  <field name="store_guest_page_fault" start="23" end="23"/>
> +</flags><flags id="hie-fields" size="8">
> +  <field name="vssie" start="2" end="2"/>
> +  <field name="vstie" start="6" end="6"/>
> +  <field name="vseie" start="10" end="10"/>
> +  <field name="sgeie" start="12" end="12"/>
> +</flags><flags id="hip-fields" size="8">
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="vseip" start="10" end="10"/>
> +  <field name="sgeip" start="12" end="12"/>
> +</flags><flags id="hvip-fields" size="8">
> +  <field name="vssip" start="2" end="2"/>
> +  <field name="vstip" start="6" end="6"/>
> +  <field name="vseip" start="10" end="10"/>
> +</flags><flags id="hgatp-fields" size="8">
> +  <field name="ppn" start="0" end="43"/>
> +  <field name="vmid" start="44" end="57"/>
> +  <field name="mode" start="60" end="63" type="hgatp-mode-type"/>
> +</flags>
> +)
> +# endif
> +;
> diff --git a/target/riscv/gdb_csr_types.h b/target/riscv/gdb_csr_types.h
> new file mode 100644
> index 0000000000..e55c978ac8
> --- /dev/null
> +++ b/target/riscv/gdb_csr_types.h
> @@ -0,0 +1,3 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
> +
> +extern char const riscv_gdb_csr_types[];
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 23429179e2..9c3f68eeaf 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -2,6 +2,7 @@
>   * RISC-V GDB Server Stub
>   *
>   * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
> + * Copyright (c) 2021 Siemens AG, konrad.schwarz@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,
> @@ -155,6 +156,9 @@ static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n)
>      return 0;
>  }
>
> +#include "gdb_csr_types.h"
> +#include "gdb_csr_type_group.h"
> +
>  static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
>  {
>      RISCVCPU *cpu = RISCV_CPU(cs);
> @@ -163,21 +167,33 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
>      riscv_csr_predicate_fn predicate;
>      int bitsize = 16 << env->misa_mxl_max;
>      int i;
> +    riscv_csr_operations *csr_op;
> +    struct riscv_gdb_csr_tg const *csr_tg;
>
>      g_string_printf(s, "<?xml version=\"1.0\"?>");
>      g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
>      g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
>
> -    for (i = 0; i < CSR_TABLE_SIZE; i++) {
> -        predicate = csr_ops[i].predicate;
> +    g_string_append(s, riscv_gdb_csr_types);
> +
> +    for (i = 0, csr_op = csr_ops, csr_tg = riscv_gdb_csr_type_group;
> +            i < CSR_TABLE_SIZE; ++csr_op, ++csr_tg, ++i) {
> +        predicate = csr_op->predicate;
>          if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
> -            if (csr_ops[i].name) {
> -                g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
> +            if (csr_op->name) {
> +                g_string_append_printf(s, "<reg name=\"%s\"", csr_op->name);
>              } else {
>                  g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
>              }
>              g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
> -            g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
> +            g_string_append_printf(s, " regnum=\"%d\"", base_reg + i);
> +            if (csr_tg->gdb_type) {
> +                g_string_append_printf(s, " type=\"%s\"", csr_tg->gdb_type);
> +            }
> +            if (csr_tg->gdb_group) {
> +                g_string_append_printf(s, " group=\"%s\"", csr_tg->gdb_group);
> +            }
> +            g_string_append(s, " />\n");
>          }
>      }
>
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index d5e0bc93ea..e1945e54c4 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -25,7 +25,9 @@ riscv_softmmu_ss.add(files(
>    'arch_dump.c',
>    'pmp.c',
>    'monitor.c',
> -  'machine.c'
> +  'machine.c',
> +  'gdb_csr_types.c',
> +  'gdb_csr_type_group.c'
>  ))
>
>  target_arch += {'riscv': riscv_ss}
> --
> Konrad Schwarz
>
>


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-04 15:51       ` [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
  2022-01-04 22:11         ` Alistair Francis
@ 2022-01-04 23:01         ` Richard Henderson
  2022-01-05 14:04           ` Schwarz, Konrad
  2022-01-05 18:43         ` Alex Bennée
  2 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2022-01-04 23:01 UTC (permalink / raw)
  To: Konrad Schwarz, qemu-devel
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, Ralf Ramsauer

On 1/4/22 7:51 AM, Konrad Schwarz wrote:
> +++ b/target/riscv/csr32-op-gdbserver.h
...
> +++ b/target/riscv/csr64-op-gdbserver.h

There is a *lot* of overlap between these two files.
Why not add this data to the main csr_ops array?
That would put all the info for each csr in one place.

> +  [CSR_CYCLE] { .gdb_type = "uint64", .gdb_group = "user" },

I think you should be able to use "unsigned long" as a proxy for the native register size.

> +char const riscv_gdb_csr_types[] =
> +#ifdef TARGET_RISCV32
...
> +#elif defined TARGET_RISCV64
...
> +# endif
> +;

Ideally we shouldn't use ifdefs for this -- we should choose one or the other depending on 
the startup env->misa_mxl_max.  We are still using an ifdef for the main 
riscv-*-virtual.xml, but that could be considered a bug to fix.


r~


^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'
  2022-01-04 20:57         ` Richard Henderson
@ 2022-01-05 12:38           ` Schwarz, Konrad
  2022-01-05 18:21             ` Alex Bennée
  0 siblings, 1 reply; 26+ messages in thread
From: Schwarz, Konrad @ 2022-01-05 12:38 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, Ralf Ramsauer

> -----Original Message-----
> From: Richard Henderson <richard.henderson@linaro.org>
> Sent: Tuesday, January 4, 2022 21:57
> Subject: Re: [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'
> 
> On 1/4/22 7:51 AM, Konrad Schwarz wrote:
> >           static const int dump_csrs[] = {
> > +
> > +#  if 0
> > +            CSR_USTATUS,
> > +            CSR_UIE,
> > +            CSR_UTVEC,
> 
> Adding huge sections of #if 0 code is not acceptable.

I'm not sure on how to solve the dilemma of

* transgressing on QEMUs coding guidelines on the one side
  (large sections of commented out code)

* having `info registers' output a huge swath of CSRs,
  swamping the user and making the command impractical

I feel that providing some control at compile
time via `# if' conditional compilation is preferrable to just dumping
everything.  I could of course only list the CSRs that
are interesting to me, currently, but I thought it
would be better to list (almost) all of them and give at least
programmers an easy way to enable the blocks of CSRs
that are of interest to them.

Obviously, the best solution would be to extend the command to
add a filter argument, similar to GDB's `info registers'
(i.e. info registers XXX), but I don't know how to do that in QEMU and
it would work differently from other target architectures.

What would you suggest?

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations
  2022-01-04 22:03         ` Alistair Francis
@ 2022-01-05 13:09           ` Schwarz, Konrad
  0 siblings, 0 replies; 26+ messages in thread
From: Schwarz, Konrad @ 2022-01-05 13:09 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis,
	qemu-devel@nongnu.org Developers, Ralf Ramsauer

> -----Original Message-----
> From: Alistair Francis <alistair23@gmail.com>
> Sent: Tuesday, January 4, 2022 23:03
> On Wed, Jan 5, 2022 at 1:55 AM Konrad Schwarz
> <konrad.schwarz@siemens.com> wrote:
> >
> > This is analog to the existing 'info mem' command and is implemented
> > using the same machinery.

> >  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
> 
> I don't think we want RISC-V specific commands. Could we not just
> extend `info mem` instead?

Considering that the similar commands `info tlb' and `info mem'
are target dependent (i.e. specific to I386, SH4, SPARC,
PCC, XTENSA and M68K, respectively to I386 and RISC-V),
I honestly do not see a problem here.

Obviously, other architectures are free to add their own implementation
of the `info gmem' functionality, so the list of architectures
supporting this command might grow in future.  The command itself
is not specific to RISC-V.

PS: I will be taking your other points to heart on the re-roll,
I just wanted to get this out of the way before attempting it.

Regards,
Konrad

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-04 22:11         ` Alistair Francis
@ 2022-01-05 13:25           ` Schwarz, Konrad
  0 siblings, 0 replies; 26+ messages in thread
From: Schwarz, Konrad @ 2022-01-05 13:25 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis,
	qemu-devel@nongnu.org Developers, Ralf Ramsauer

Hi,

> -----Original Message-----
> From: Alistair Francis <alistair23@gmail.com>
> Sent: Tuesday, January 4, 2022 23:12
> To: Schwarz, Konrad (T CED SES-DE) <konrad.schwarz@siemens.com>
> Subject: Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
> 
> On Wed, Jan 5, 2022 at 1:56 AM Konrad Schwarz
> <konrad.schwarz@siemens.com> wrote:
> > 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, sagark@eecs.berkeley.edu
> >   * Copyright (c) 2017-2018 SiFive, Inc.
> > + * Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com
> 
> Please don't add these to existing files. In this case you have just
> added a newline to this file

Sorry, I don't know how that slipped through.
I originally didn't have any copyright messages, to which my company objected,
and I guess I overcompensated.
 
> diff --git a/target/riscv/csr32-op-gdbserver.h b/target/riscv/csr32-op-gdbserver.h
> > new file mode 100644
> > index 0000000000..e8ec527f23
> > --- /dev/null
> > +++ b/target/riscv/csr32-op-gdbserver.h
> > @@ -0,0 +1,109 @@
> > +/* Copyright (c) 2021 Siemens AG, konrad.schwarz@siemens.com */
> 
> All of these files should have the usual file boiler plate

OK, I'll try to figure out something.

> > +#if !defined(CONFIG_USER_ONLY)
> > +#  ifdef TARGET_RISCV64
> > +#    include "csr64-op-gdbserver.h"
> > +#  elif defined TARGET_RISCV64
> > +#    include "csr32-op-gdbserver.h"
> 
> This doesn't look right. `if defined TARGET_RISCV64` -> `include
> "csr32-op-gdbserver.h"`?

You are quite right. 

> Also this should be dynamic instead of based on the build time CPU, as
> the user could use a 32-bit CPU on a 64-bit target build.

I'm not sure.  The machine itself is still a 64-bit machine; its CSRs are 64 bits long.
`csr.c', which implements the CSRs contains an instance of # ifdef TARGET_RISCV64,
so that part of the implementation is not dynamic either.

Also, someone who is developing 32-bit system software can easily
sidestep the issue by using the 32-bit target.

Regards
Konrad

^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-04 23:01         ` Richard Henderson
@ 2022-01-05 14:04           ` Schwarz, Konrad
  2022-01-05 20:20             ` Richard Henderson
  0 siblings, 1 reply; 26+ messages in thread
From: Schwarz, Konrad @ 2022-01-05 14:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, Ralf Ramsauer

Hi,

> -----Original Message-----
> From: Richard Henderson <richard.henderson@linaro.org>
> Sent: Wednesday, January 5, 2022 0:02
> To: Schwarz, Konrad (T CED SES-DE) <konrad.schwarz@siemens.com>; qemu-devel@nongnu.org
> Cc: Alistair Francis <alistair.francis@wdc.com>; Bin Meng <bin.meng@windriver.com>; Palmer Dabbelt
> <palmer@dabbelt.com>; Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
> Subject: Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
> 
> On 1/4/22 7:51 AM, Konrad Schwarz wrote:
> > +++ b/target/riscv/csr32-op-gdbserver.h
> ...
> > +++ b/target/riscv/csr64-op-gdbserver.h
> 
> There is a *lot* of overlap between these two files.
> Why not add this data to the main csr_ops array?
> That would put all the info for each csr in one place.

So the problem is that these files are generated -- somewhat ironically
via XSLT from complete GDB target descriptions, which are themselves
generated from a mixture of AWK and shell scripts that I have in a
different project and which you would probably not want to have
contributed.  Those scripts generate a variety of other definitions
for C and assembly besides the GDB XML target descriptions, so would
probably need to be reduced for just QEMU usage.

I did actually originally add the data directly to the csr_ops array.
Because of the large number of CSRs and the generational aspect,
it was infeasible (for me at least) to create an editing merge script to
intermingle the existing definitions and the new data.  I tried to
work around this by using C99's designated initializer syntax,
adding in the new data at the end of the table, and using specific
enough initializers to not disturb the existing data.

However, this did not work out: despite using very specific initializers,
the previously initialized CSR structures in the csr_ops array
were reset to their default values, i.e., 0, breaking the code.
This was not the way I expected this feature to work in C99 and
my reading of the C99 standard does not support this either.  But
that’s what GCC does, at least on my machine.

This is also the reason the overlap is not handled more elegantly:
GDB target description XML doesn't support alternates for different
machine word lengths and so I lose that information when transforming
from the 64 and 32-bit target description sources.
 
> > +  [CSR_CYCLE] { .gdb_type = "uint64", .gdb_group = "user" },
> 
> I think you should be able to use "unsigned long" as a proxy for the native register size.

`unsigned long' is not listed in section `G.3 Predefined Target Types'
of the GDB manual.

I also have to say that GDB does not handle the target descriptions
correctly in all cases.  In particular, I suspect a bug when
a field crosses a 32-bit boundary: GDB is showing twice the
field value.  I'm pretty sure my target description is correct
for this case, I've rechecked several times.  Also, GDB
is not picking up all of the new CSRs for some reason, but
I'm sure is reading the target description from QEMU.

Since target descriptions are rare in practice, a bug would
not surprise me; for example, the DTD for target descriptions
supplied with GDB is wrong: it is missing the `enum' element
(which was probably added later) and the xsi:include element.

Ultimately, this is a chicken and egg problem: bugs in GDB can
only be flushed out if it gets interesting
target descriptions to read.

> 
> > +char const riscv_gdb_csr_types[] =
> > +#ifdef TARGET_RISCV32
> ...
> > +#elif defined TARGET_RISCV64
> ...
> > +# endif
> > +;
> 
> Ideally we shouldn't use ifdefs for this -- we should choose one or the other depending on
> the startup env->misa_mxl_max.  We are still using an ifdef for the main
> riscv-*-virtual.xml, but that could be considered a bug to fix.

As I wrote Alistair, I'm not sure this reasoning is correct.  Even if a 64-bit
machine is running in 32-bit mode, the machine itself remains a 64-bit machine,
and it's CSRs are so too.  We can have the situation of a 64-bit kernel and 32-bit
user-mode process; would we want the CSRs to change when switching between the two?
Even if we did, the GDB remote protocol does not have the ability to say "API change,
please reread the target description" (AFAIK).  And in any case, users can easily side-step
the issue by using a 32-bit target QEMU if they are only interested in 32-bit code.

Regards
Konrad

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'
  2022-01-05 12:38           ` Schwarz, Konrad
@ 2022-01-05 18:21             ` Alex Bennée
  0 siblings, 0 replies; 26+ messages in thread
From: Alex Bennée @ 2022-01-05 18:21 UTC (permalink / raw)
  To: Schwarz, Konrad
  Cc: Bin Meng, Richard Henderson, Ralf Ramsauer, qemu-devel,
	Palmer Dabbelt, Alistair Francis


"Schwarz, Konrad" <konrad.schwarz@siemens.com> writes:

>> -----Original Message-----
>> From: Richard Henderson <richard.henderson@linaro.org>
>> Sent: Tuesday, January 4, 2022 21:57
>> Subject: Re: [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'
>> 
>> On 1/4/22 7:51 AM, Konrad Schwarz wrote:
>> >           static const int dump_csrs[] = {
>> > +
>> > +#  if 0
>> > +            CSR_USTATUS,
>> > +            CSR_UIE,
>> > +            CSR_UTVEC,
>> 
>> Adding huge sections of #if 0 code is not acceptable.
>
> I'm not sure on how to solve the dilemma of
>
> * transgressing on QEMUs coding guidelines on the one side
>   (large sections of commented out code)
>
> * having `info registers' output a huge swath of CSRs,
>   swamping the user and making the command impractical
>
> I feel that providing some control at compile
> time via `# if' conditional compilation is preferrable to just dumping
> everything.  I could of course only list the CSRs that
> are interesting to me, currently, but I thought it
> would be better to list (almost) all of them and give at least
> programmers an easy way to enable the blocks of CSRs
> that are of interest to them.
>
> Obviously, the best solution would be to extend the command to
> add a filter argument, similar to GDB's `info registers'
> (i.e. info registers XXX), but I don't know how to do that in QEMU and
> it would work differently from other target architectures.

This is a problem that needs solving not only for "info registers" but
also things like "-d cpu", gdbserver and (eventually) TCG plugins.

My (so far unrealised) vision is to have a architecture independent
sub-system that we can register (sic) registers. The frontends would
replace their existing qemu_log and gdbserver hooks with a group aware
registering function to the sub-system. For example:

  register_reg("x0", REG_CORE, get_gen_reg, set_gen_reg, offsetof(CPUARMState, xregs[0]))
  register_reg(ri->name, REG_SYSTEM, get_cpreg, set_cpreg, ri);

and so on. This would then provide a common point for the register value
consumers to request values and sets. So we could have options like:

  (hmp) info registers fpu
  -d cpu:pc
  qemu_plugin_get_regset("x0-x7");

and avoid having too much per-architecture special casing. I'd also like
to get rid of custom gdb XML generation in the frontends (e.g.
arm_gen_dynamic_svereg_xml) and make that common functionality.

> What would you suggest?

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-04 15:51       ` [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
  2022-01-04 22:11         ` Alistair Francis
  2022-01-04 23:01         ` Richard Henderson
@ 2022-01-05 18:43         ` Alex Bennée
  2022-01-05 19:24           ` Schwarz, Konrad
  2 siblings, 1 reply; 26+ messages in thread
From: Alex Bennée @ 2022-01-05 18:43 UTC (permalink / raw)
  To: Konrad Schwarz
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, Ralf Ramsauer, qemu-devel


Konrad Schwarz <konrad.schwarz@siemens.com> writes:

> 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 <konrad.schwarz@siemens.com>
<snip>

Not withstanding my general comments (wish) to eventually get rid of
per-arch XML generation:

>  static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
>  {
>      RISCVCPU *cpu = RISCV_CPU(cs);
> @@ -163,21 +167,33 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
>      riscv_csr_predicate_fn predicate;
>      int bitsize = 16 << env->misa_mxl_max;
>      int i;
> +    riscv_csr_operations *csr_op;
> +    struct riscv_gdb_csr_tg const *csr_tg;
>  
>      g_string_printf(s, "<?xml version=\"1.0\"?>");
>      g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
>      g_string_append_printf(s, "<feature>      name=\"org.gnu.gdb.riscv.csr\">");

With these changes does it still match the org.gnu.gdb.riscv.csr
register description in gdb? Previously for custom XML I've used the
org.qemu.ARCH.REGS form to distinguish between something GDB expects and
something we invented (changed since 797920b952ea).

>  
> -    for (i = 0; i < CSR_TABLE_SIZE; i++) {
> -        predicate = csr_ops[i].predicate;
> +    g_string_append(s, riscv_gdb_csr_types);
> +
> +    for (i = 0, csr_op = csr_ops, csr_tg = riscv_gdb_csr_type_group;
> +            i < CSR_TABLE_SIZE; ++csr_op, ++csr_tg, ++i) {
> +        predicate = csr_op->predicate;
>          if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
> -            if (csr_ops[i].name) {
> -                g_string_append_printf(s, "<reg name=\"%s\"", csr_ops[i].name);
> +            if (csr_op->name) {
> +                g_string_append_printf(s, "<reg name=\"%s\"", csr_op->name);
>              } else {
>                  g_string_append_printf(s, "<reg name=\"csr%03x\"", i);
>              }
>              g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
> -            g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
> +            g_string_append_printf(s, " regnum=\"%d\"", base_reg + i);
> +            if (csr_tg->gdb_type) {
> +                g_string_append_printf(s, " type=\"%s\"", csr_tg->gdb_type);
> +            }
> +            if (csr_tg->gdb_group) {
> +                g_string_append_printf(s, " group=\"%s\"", csr_tg->gdb_group);
> +            }
> +            g_string_append(s, " />\n");
>          }
>      }
<snip>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 26+ messages in thread

* RE: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-05 18:43         ` Alex Bennée
@ 2022-01-05 19:24           ` Schwarz, Konrad
  2022-01-05 19:34             ` Alex Bennée
  0 siblings, 1 reply; 26+ messages in thread
From: Schwarz, Konrad @ 2022-01-05 19:24 UTC (permalink / raw)
  To: Alex Bennée
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, Ralf Ramsauer, qemu-devel



> -----Original Message-----
> From: Alex Bennée <alex.bennee@linaro.org>

> Konrad Schwarz <konrad.schwarz@siemens.com> writes:
> 

> >  static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
> >  {
> >      RISCVCPU *cpu = RISCV_CPU(cs);
> > @@ -163,21 +167,33 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
> >      riscv_csr_predicate_fn predicate;
> >      int bitsize = 16 << env->misa_mxl_max;
> >      int i;
> > +    riscv_csr_operations *csr_op;
> > +    struct riscv_gdb_csr_tg const *csr_tg;
> >
> >      g_string_printf(s, "<?xml version=\"1.0\"?>");
> >      g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
> >      g_string_append_printf(s, "<feature>      name=\"org.gnu.gdb.riscv.csr\">");
> 
> With these changes does it still match the org.gnu.gdb.riscv.csr
> register description in gdb? Previously for custom XML I've used the
> org.qemu.ARCH.REGS form to distinguish between something GDB expects and
> something we invented (changed since 797920b952ea).

I don't expect it to match -- but why should it?
The whole point of target descriptions is for GDBserver to inform
GDB of the precise set and layout of pre-defined register classes.
The class `org.gnu.gdb.riscv.csr' is known to a RISC-V capable
GDB as the class of all CSRs; a specific RISC-V core might
have vendor-specific CSRs, but they would still be included
in `org.gnu.gdb.riscv.csr'.

Section G.5 in the GDB manual makes this clear:
"You can add additional registers to any of the standard features --
GDB will display them just as they were added to an
unrecognized feature."

--
Konrad

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-05 19:24           ` Schwarz, Konrad
@ 2022-01-05 19:34             ` Alex Bennée
  0 siblings, 0 replies; 26+ messages in thread
From: Alex Bennée @ 2022-01-05 19:34 UTC (permalink / raw)
  To: Schwarz, Konrad
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, Ralf Ramsauer, qemu-devel


"Schwarz, Konrad" <konrad.schwarz@siemens.com> writes:

>> -----Original Message-----
>> From: Alex Bennée <alex.bennee@linaro.org>
>
>> Konrad Schwarz <konrad.schwarz@siemens.com> writes:
>> 
>
>> >  static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
>> >  {
>> >      RISCVCPU *cpu = RISCV_CPU(cs);
>> > @@ -163,21 +167,33 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
>> >      riscv_csr_predicate_fn predicate;
>> >      int bitsize = 16 << env->misa_mxl_max;
>> >      int i;
>> > +    riscv_csr_operations *csr_op;
>> > +    struct riscv_gdb_csr_tg const *csr_tg;
>> >
>> >      g_string_printf(s, "<?xml version=\"1.0\"?>");
>> >      g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">");
>> >      g_string_append_printf(s, "<feature>      name=\"org.gnu.gdb.riscv.csr\">");
>> 
>> With these changes does it still match the org.gnu.gdb.riscv.csr
>> register description in gdb? Previously for custom XML I've used the
>> org.qemu.ARCH.REGS form to distinguish between something GDB expects and
>> something we invented (changed since 797920b952ea).
>
> I don't expect it to match -- but why should it?
> The whole point of target descriptions is for GDBserver to inform
> GDB of the precise set and layout of pre-defined register classes.
> The class `org.gnu.gdb.riscv.csr' is known to a RISC-V capable
> GDB as the class of all CSRs; a specific RISC-V core might
> have vendor-specific CSRs, but they would still be included
> in `org.gnu.gdb.riscv.csr'.

Certainly for ARM's SVE there is special handling code in gdb to deal
with the control of the vector length. As long as GDB doesn't make any
such assumptions for RISC-V then go right ahead.

>
> Section G.5 in the GDB manual makes this clear:
> "You can add additional registers to any of the standard features --
> GDB will display them just as they were added to an
> unrecognized feature."


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver
  2022-01-05 14:04           ` Schwarz, Konrad
@ 2022-01-05 20:20             ` Richard Henderson
  0 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2022-01-05 20:20 UTC (permalink / raw)
  To: Schwarz, Konrad, qemu-devel
  Cc: Palmer Dabbelt, Bin Meng, Alistair Francis, Ralf Ramsauer

On 1/5/22 6:04 AM, Schwarz, Konrad wrote:
> So the problem is that these files are generated -- somewhat ironically
> via XSLT from complete GDB target descriptions, which are themselves
> generated from a mixture of AWK and shell scripts that I have in a
> different project and which you would probably not want to have
> contributed.  Those scripts generate a variety of other definitions
> for C and assembly besides the GDB XML target descriptions, so would
> probably need to be reduced for just QEMU usage.

You may be right that we don't want your original scripts, but that also  implies that the 
fact your files are generated is irrelevant to us.  Why should we care?  I think it makes 
more sense to manually edit csr.c and be done with it.

>  I tried to
> work around this by using C99's designated initializer syntax,
> adding in the new data at the end of the table, and using specific
> enough initializers to not disturb the existing data.
> 
> However, this did not work out: despite using very specific initializers,
> the previously initialized CSR structures in the csr_ops array
> were reset to their default values, i.e., 0, breaking the code.
> This was not the way I expected this feature to work in C99 and
> my reading of the C99 standard does not support this either.  But
> that’s what GCC does, at least on my machine.

I'm sure your syntax was incorrect.  You probably used

>>> +  [CSR_CYCLE] { .gdb_type = "uint64", .gdb_group = "user" },

which does indeed overwrite the entire entry in the array.  You could have used

     [CSR_CYCLE].gdb_type = "uint64"

which will just set the one field.

That said, I don't think that we want this distributed initialization.

>> I think you should be able to use "unsigned long" as a proxy for the native register size.
> 
> `unsigned long' is not listed in section `G.3 Predefined Target Types'
> of the GDB manual.

Hmm.  I didn't look at the docs; I looked at gdbtypes.h and saw the existence of 
builtin_unsigned_long.  I suppose this might not be plumbed into the xml.

In which case, since we're generating everything dynamically anyway, we could just as 
easily make NULL map to "uint<XLEN>" when generating the xml.  Or instead of a string, 
perhaps some enum which distinguishes data_ptr/code_ptr/uint<xlen>/uint<min(n,xlen)> which 
is then filled in during generation.

> I also have to say that GDB does not handle the target descriptions
> correctly in all cases.  In particular, I suspect a bug when
> a field crosses a 32-bit boundary: GDB is showing twice the
> field value.

I wonder if this is an issue of using "uint32" for the field type?  You could, for the 
moment, drop all of the bitfield descriptions and leave the interpretation to the user. 
Giving an accurate integral value for the register as a whole is more helpful than giving 
inaccurate field values.

> As I wrote Alistair, I'm not sure this reasoning is correct.  Even if a 64-bit
> machine is running in 32-bit mode, the machine itself remains a 64-bit machine,
> and it's CSRs are so too.

And that's where we're mis-communicating.

We're working toward having exactly one qemu-system-riscv binary, which will emulate both 
RV32 and RV64 (and RV128) cpus, selected by -cpu foo.  At which point there will be no 
CONFIG_RISCV32 define at all.  The way to distinguish the three cases is 
cpu->env.misa_mxl_max.

> We can have the situation of a 64-bit kernel and 32-bit
> user-mode process; would we want the CSRs to change when switching between the two?

Well ideally yes...

> Even if we did, the GDB remote protocol does not have the ability to say "API change,
> please reread the target description" (AFAIK).

... but as you rightly note, gdb can't handle it.


r~


^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2022-01-05 20:22 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-02 16:06 [PATCH v1 0/5] Improve RISC-V debugging support Konrad Schwarz
2022-01-02 16:06 ` [PATCH v1 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
2022-01-02 16:06 ` [PATCH v1 2/5] RISC-V: monitor's print register functionality Konrad Schwarz
2022-01-02 16:06 ` [PATCH v1 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations Konrad Schwarz
2022-01-02 16:06 ` [PATCH v1 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
2022-01-03 12:54   ` Ralf Ramsauer
2022-01-04 15:51     ` [PATCH v2 0/5] Improve RISC-V debugging support Konrad Schwarz
2022-01-04 15:51       ` [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers' Konrad Schwarz
2022-01-04 20:57         ` Richard Henderson
2022-01-05 12:38           ` Schwarz, Konrad
2022-01-05 18:21             ` Alex Bennée
2022-01-04 15:51       ` [PATCH v2 2/5] RISC-V: monitor's print register functionality Konrad Schwarz
2022-01-04 15:51       ` [PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations Konrad Schwarz
2022-01-04 22:03         ` Alistair Francis
2022-01-05 13:09           ` Schwarz, Konrad
2022-01-04 15:51       ` [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver Konrad Schwarz
2022-01-04 22:11         ` Alistair Francis
2022-01-05 13:25           ` Schwarz, Konrad
2022-01-04 23:01         ` Richard Henderson
2022-01-05 14:04           ` Schwarz, Konrad
2022-01-05 20:20             ` Richard Henderson
2022-01-05 18:43         ` Alex Bennée
2022-01-05 19:24           ` Schwarz, Konrad
2022-01-05 19:34             ` Alex Bennée
2022-01-04 15:51       ` [PATCH v2 5/5] RISC-V: Add `v' (virtualization mode) bit to the `priv' virtual debug register Konrad Schwarz
2022-01-02 16:06 ` [PATCH v1 " Konrad Schwarz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.