All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v3 0/2] Proposing custom CSR handling logic
@ 2021-06-10 14:44 ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 14+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-06-10 14:44 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: dylan, alankao, wangjunqiang, bin.meng, Ruinaldn ChuanTzu Tsai,
	alistair23

From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>

The changes from V2 :
* Making custom CSR operation table become registerable.
* Re-use the riscv_csrrw() code instead of ducplication.
* Splitting custom CPU bits into seperated files.
* Splitting the AX25 CPU from the feature patch
* Adding custom/vendor value "holder."
    In previous patche

- - - -

Sorry for the late update. COVID really hit us hard lately.

I really appreciate the comments and suggestions from Bin and Alistair, and I
am very willing to answer the doubts.

For the questions regarding the hash table for CSR operations, that is because
we might have heterogeneous architecture with harts having diffrent CSR
extensions/features.
For instance, there are FLUSH32 and FLUSH64 CSR on the application cores
on the U54-MC and U74-MC series from SiFive, yet for the monitor cores (S51 and
S7), there are no such custom/vendor CSRs. Though I cannot disclose too much
for the time being, we Andes Technology have similar design choice on our
platforms; and thus, a mechanism for dynamically registering CSR operation
functions will become a substrate for further extension.

And one day if those CSRs become standardized, ones can easily pull-and-plug
the structures into `csr_ops` table.

The write_stub() is useful and necessary if such a CSR conducts some hardware 
behaviors which are hard to implement in QEMU's world view, such as cache
policies or something would fail-over in user's code, for instance, the
I/O feature probing code. And that's why we keep it inside our toolbox.

Adding TINFO is a bit in the twilight zone. It's officially documented in the
RISC-V Debug Spec, yet we Andes has our own customization (which might
come out of the shadow one day) on it and thus we decice to add the csrno in
the general parts (cpu_bits.h) and add the handling function in csr_andes.inc.c
for our further development.

For now, this patch with previously submitted Andes AE350 board support 
https://mail.gnu.org/archive/html/qemu-riscv/2021-03/msg00096.html 
could execute mainline U-boot (proper) and OpenSBI (with test payload)
successfully.


Cordially yours,
Ruinland ChuanTzu Tsai


Ruinaldn ChuanTzu Tsai (2):
  Adding Andes AX25 CPU model
  Adding preliminary custom/vendor CSR handling mechanism

 target/riscv/andes_cpu_bits.h  | 113 ++++++++++++++++++++++++
 target/riscv/cpu.c             |  37 ++++++++
 target/riscv/cpu.h             |  29 ++++++-
 target/riscv/cpu_bits.h        |   3 +
 target/riscv/csr.c             |  46 ++++++++--
 target/riscv/csr_andes.inc.c   | 153 +++++++++++++++++++++++++++++++++
 target/riscv/custom_cpu_bits.h |   3 +
 7 files changed, 375 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.inc.c
 create mode 100644 target/riscv/custom_cpu_bits.h

-- 
2.31.1



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

* [RFC PATCH v3 0/2] Proposing custom CSR handling logic
@ 2021-06-10 14:44 ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 14+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-06-10 14:44 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: alistair23, wangjunqiang, bin.meng, alankao, dylan,
	Ruinaldn ChuanTzu Tsai

From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>

The changes from V2 :
* Making custom CSR operation table become registerable.
* Re-use the riscv_csrrw() code instead of ducplication.
* Splitting custom CPU bits into seperated files.
* Splitting the AX25 CPU from the feature patch
* Adding custom/vendor value "holder."
    In previous patche

- - - -

Sorry for the late update. COVID really hit us hard lately.

I really appreciate the comments and suggestions from Bin and Alistair, and I
am very willing to answer the doubts.

For the questions regarding the hash table for CSR operations, that is because
we might have heterogeneous architecture with harts having diffrent CSR
extensions/features.
For instance, there are FLUSH32 and FLUSH64 CSR on the application cores
on the U54-MC and U74-MC series from SiFive, yet for the monitor cores (S51 and
S7), there are no such custom/vendor CSRs. Though I cannot disclose too much
for the time being, we Andes Technology have similar design choice on our
platforms; and thus, a mechanism for dynamically registering CSR operation
functions will become a substrate for further extension.

And one day if those CSRs become standardized, ones can easily pull-and-plug
the structures into `csr_ops` table.

The write_stub() is useful and necessary if such a CSR conducts some hardware 
behaviors which are hard to implement in QEMU's world view, such as cache
policies or something would fail-over in user's code, for instance, the
I/O feature probing code. And that's why we keep it inside our toolbox.

Adding TINFO is a bit in the twilight zone. It's officially documented in the
RISC-V Debug Spec, yet we Andes has our own customization (which might
come out of the shadow one day) on it and thus we decice to add the csrno in
the general parts (cpu_bits.h) and add the handling function in csr_andes.inc.c
for our further development.

For now, this patch with previously submitted Andes AE350 board support 
https://mail.gnu.org/archive/html/qemu-riscv/2021-03/msg00096.html 
could execute mainline U-boot (proper) and OpenSBI (with test payload)
successfully.


Cordially yours,
Ruinland ChuanTzu Tsai


Ruinaldn ChuanTzu Tsai (2):
  Adding Andes AX25 CPU model
  Adding preliminary custom/vendor CSR handling mechanism

 target/riscv/andes_cpu_bits.h  | 113 ++++++++++++++++++++++++
 target/riscv/cpu.c             |  37 ++++++++
 target/riscv/cpu.h             |  29 ++++++-
 target/riscv/cpu_bits.h        |   3 +
 target/riscv/csr.c             |  46 ++++++++--
 target/riscv/csr_andes.inc.c   | 153 +++++++++++++++++++++++++++++++++
 target/riscv/custom_cpu_bits.h |   3 +
 7 files changed, 375 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.inc.c
 create mode 100644 target/riscv/custom_cpu_bits.h

-- 
2.31.1



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

* [RFC PATCH v3 1/2] Adding Andes AX25 CPU model
  2021-06-10 14:44 ` Ruinland Chuan-Tzu Tsai
@ 2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 14+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-06-10 14:44 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: dylan, alankao, wangjunqiang, bin.meng, Ruinaldn ChuanTzu Tsai,
	alistair23

From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>

Adding the skeleton of Andes Technology AX25 CPU model for the future commits,
which will utilize custom/vendor CSR handling mechaism.
---
 target/riscv/cpu.c | 8 ++++++++
 target/riscv/cpu.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ddea8fbeeb..4ae21cbf9b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -159,6 +159,13 @@ static void rv64_base_cpu_init(Object *obj)
     set_misa(env, RV64);
 }
 
+static void ax25_cpu_init(Object *obj)
+{
+    CPURISCVState *env = &RISCV_CPU(obj)->env;
+    set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+    set_priv_version(env, PRIV_VERSION_1_10_0);
+}
+
 static void rv64_sifive_u_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -705,6 +712,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
 #elif defined(TARGET_RISCV64)
     DEFINE_CPU(TYPE_RISCV_CPU_BASE64,           rv64_base_cpu_init),
+    DEFINE_CPU(TYPE_RISCV_CPU_AX25,             ax25_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64_sifive_e_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64_sifive_u_cpu_init),
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0edb2826a2..bff9af7f3f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -37,6 +37,7 @@
 #define TYPE_RISCV_CPU_ANY              RISCV_CPU_TYPE_NAME("any")
 #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
 #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
+#define TYPE_RISCV_CPU_AX25             RISCV_CPU_TYPE_NAME("andes-ax25")
 #define TYPE_RISCV_CPU_IBEX             RISCV_CPU_TYPE_NAME("lowrisc-ibex")
 #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
 #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
-- 
2.31.1



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

* [RFC PATCH v3 1/2] Adding Andes AX25 CPU model
@ 2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 14+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-06-10 14:44 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: alistair23, wangjunqiang, bin.meng, alankao, dylan,
	Ruinaldn ChuanTzu Tsai

From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>

Adding the skeleton of Andes Technology AX25 CPU model for the future commits,
which will utilize custom/vendor CSR handling mechaism.
---
 target/riscv/cpu.c | 8 ++++++++
 target/riscv/cpu.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ddea8fbeeb..4ae21cbf9b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -159,6 +159,13 @@ static void rv64_base_cpu_init(Object *obj)
     set_misa(env, RV64);
 }
 
+static void ax25_cpu_init(Object *obj)
+{
+    CPURISCVState *env = &RISCV_CPU(obj)->env;
+    set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+    set_priv_version(env, PRIV_VERSION_1_10_0);
+}
+
 static void rv64_sifive_u_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -705,6 +712,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
 #elif defined(TARGET_RISCV64)
     DEFINE_CPU(TYPE_RISCV_CPU_BASE64,           rv64_base_cpu_init),
+    DEFINE_CPU(TYPE_RISCV_CPU_AX25,             ax25_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64_sifive_e_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64_sifive_u_cpu_init),
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0edb2826a2..bff9af7f3f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -37,6 +37,7 @@
 #define TYPE_RISCV_CPU_ANY              RISCV_CPU_TYPE_NAME("any")
 #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
 #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
+#define TYPE_RISCV_CPU_AX25             RISCV_CPU_TYPE_NAME("andes-ax25")
 #define TYPE_RISCV_CPU_IBEX             RISCV_CPU_TYPE_NAME("lowrisc-ibex")
 #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
 #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
-- 
2.31.1



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

* [RFC PATCH v3 2/2] Adding preliminary custom/vendor CSR handling mechanism
  2021-06-10 14:44 ` Ruinland Chuan-Tzu Tsai
@ 2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 14+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-06-10 14:44 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: dylan, alankao, wangjunqiang, bin.meng, Ruinaldn ChuanTzu Tsai,
	alistair23

From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>

For now we add a custom CSR handling mechanism to handle non-standard CSR read
or write.

The write_stub() and read_zero() are provided for quick placeholder usage if
such CSRs' behavior are expected to fail-over in its user code.

For demonstration, we modify Andes Technology AX25 to showcase how the such
mechanism works and how the UITB and MMSC_CFG CSR could be emulated.
---
 target/riscv/andes_cpu_bits.h  | 113 ++++++++++++++++++++++++
 target/riscv/cpu.c             |  29 +++++++
 target/riscv/cpu.h             |  20 ++++-
 target/riscv/cpu_bits.h        |   3 +
 target/riscv/csr.c             |  46 ++++++++--
 target/riscv/csr_andes.inc.c   | 153 +++++++++++++++++++++++++++++++++
 target/riscv/custom_cpu_bits.h |   3 +
 7 files changed, 358 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.inc.c
 create mode 100644 target/riscv/custom_cpu_bits.h

diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
new file mode 100644
index 0000000000..8dee58a2c2
--- /dev/null
+++ b/target/riscv/andes_cpu_bits.h
@@ -0,0 +1,113 @@
+/* ========= AndeStar V5 machine mode CSRs ========= */
+/* Configuration Registers */
+#define CSR_MICM_CFG            0xfc0
+#define CSR_MDCM_CFG            0xfc1
+#define CSR_MMSC_CFG            0xfc2
+#define CSR_MMSC_CFG2           0xfc3
+#define CSR_MVEC_CFG            0xfc7
+
+/* Crash Debug CSRs */
+#define CSR_MCRASH_STATESAVE    0xfc8
+#define CSR_MSTATUS_CRASHSAVE   0xfc9
+
+/* Memory CSRs */
+#define CSR_MILMB               0x7c0
+#define CSR_MDLMB               0x7c1
+#define CSR_MECC_CODE           0x7C2
+#define CSR_MNVEC               0x7c3
+#define CSR_MCACHE_CTL          0x7ca
+#define CSR_MCCTLBEGINADDR      0x7cb
+#define CSR_MCCTLCOMMAND        0x7cc
+#define CSR_MCCTLDATA           0x7cd
+#define CSR_MPPIB               0x7f0
+#define CSR_MFIOB               0x7f1
+
+/* Hardware Stack Protection & Recording */
+#define CSR_MHSP_CTL            0x7c6
+#define CSR_MSP_BOUND           0x7c7
+#define CSR_MSP_BASE            0x7c8
+#define CSR_MXSTATUS            0x7c4
+#define CSR_MDCAUSE             0x7c9
+#define CSR_MSLIDELEG           0x7d5
+#define CSR_MSAVESTATUS         0x7d6
+#define CSR_MSAVEEPC1           0x7d7
+#define CSR_MSAVECAUSE1         0x7d8
+#define CSR_MSAVEEPC2           0x7d9
+#define CSR_MSAVECAUSE2         0x7da
+#define CSR_MSAVEDCAUSE1        0x7db
+#define CSR_MSAVEDCAUSE2        0x7dc
+
+/* Control CSRs */
+#define CSR_MPFT_CTL            0x7c5
+#define CSR_MMISC_CTL           0x7d0
+#define CSR_MCLK_CTL            0x7df
+
+/* Counter related CSRs */
+#define CSR_MCOUNTERWEN         0x7ce
+#define CSR_MCOUNTERINTEN       0x7cf
+#define CSR_MCOUNTERMASK_M      0x7d1
+#define CSR_MCOUNTERMASK_S      0x7d2
+#define CSR_MCOUNTERMASK_U      0x7d3
+#define CSR_MCOUNTEROVF         0x7d4
+
+/* Enhanced CLIC CSRs */
+#define CSR_MIRQ_ENTRY          0x7ec
+#define CSR_MINTSEL_JAL         0x7ed
+#define CSR_PUSHMCAUSE          0x7ee
+#define CSR_PUSHMEPC            0x7ef
+#define CSR_PUSHMXSTATUS        0x7eb
+
+/* Andes Physical Memory Attribute(PMA) CSRs */
+#define CSR_PMACFG0             0xbc0
+#define CSR_PMACFG1             0xbc1
+#define CSR_PMACFG2             0xbc2
+#define CSR_PMACFG3             0xbc3
+#define CSR_PMAADDR0            0xbd0
+#define CSR_PMAADDR1            0xbd1
+#define CSR_PMAADDR2            0xbd2
+#define CSR_PMAADDR3            0xbd2
+#define CSR_PMAADDR4            0xbd4
+#define CSR_PMAADDR5            0xbd5
+#define CSR_PMAADDR6            0xbd6
+#define CSR_PMAADDR7            0xbd7
+#define CSR_PMAADDR8            0xbd8
+#define CSR_PMAADDR9            0xbd9
+#define CSR_PMAADDR10           0xbda
+#define CSR_PMAADDR11           0xbdb
+#define CSR_PMAADDR12           0xbdc
+#define CSR_PMAADDR13           0xbdd
+#define CSR_PMAADDR14           0xbde
+#define CSR_PMAADDR15           0xbdf
+
+/* ========= AndeStar V5 supervisor mode CSRs ========= */
+/* Supervisor trap registers */
+#define CSR_SLIE                0x9c4
+#define CSR_SLIP                0x9c5
+#define CSR_SDCAUSE             0x9c9
+
+/* Supervisor counter registers */
+#define CSR_SCOUNTERINTEN       0x9cf
+#define CSR_SCOUNTERMASK_M      0x9d1
+#define CSR_SCOUNTERMASK_S      0x9d2
+#define CSR_SCOUNTERMASK_U      0x9d3
+#define CSR_SCOUNTEROVF         0x9d4
+#define CSR_SCOUNTINHIBIT       0x9e0
+#define CSR_SHPMEVENT3          0x9e3
+#define CSR_SHPMEVENT4          0x9e4
+#define CSR_SHPMEVENT5          0x9e5
+#define CSR_SHPMEVENT6          0x9e6
+
+/* Supervisor control registers */
+#define CSR_SCCTLDATA           0x9cd
+#define CSR_SMISC_CTL           0x9d0
+
+/* ========= AndeStar V5 user mode CSRs ========= */
+/* User mode control registers */
+#define CSR_UITB                0x800
+#define CSR_UCODE               0x801
+#define CSR_UDCAUSE             0x809
+#define CSR_UCCTLBEGINADDR      0x80b
+#define CSR_UCCTLCOMMAND        0x80c
+#define CSR_WFE                 0x810
+#define CSR_SLEEPVALUE          0x811
+#define CSR_TXEVT               0x812
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4ae21cbf9b..460839d006 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -144,6 +144,30 @@ static void set_resetvec(CPURISCVState *env, int resetvec)
 #endif
 }
 
+#if defined(TARGET_RISCV64)
+// Currently we only have ax25 using this function, to ease Wunused-function,
+// we put it in TARGET_RISCV64.
+static void setup_custom_csr(CPURISCVState *env,
+                             riscv_custom_csr_operations csr_map_struct[]
+                             ) {
+
+    env->custom_csr_map = g_hash_table_new_full(
+        g_direct_hash, g_direct_equal, NULL, NULL);
+
+    int i;
+
+    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
+        if (csr_map_struct[i].csrno != 0) {
+            g_hash_table_insert(env->custom_csr_map,
+                GINT_TO_POINTER(csr_map_struct[i].csrno),
+                &csr_map_struct[i].csr_opset);
+        } else {
+            break;
+        }
+    }
+}
+#endif
+
 static void riscv_any_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -164,6 +188,11 @@ static void ax25_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
     set_priv_version(env, PRIV_VERSION_1_10_0);
+
+    /* setup custom csr handler hash table */
+    setup_custom_csr(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
+
 }
 
 static void rv64_sifive_u_cpu_init(Object *obj)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index bff9af7f3f..231505f403 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -112,6 +112,7 @@ FIELD(VTYPE, VEDIV, 5, 2)
 FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
 FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
+
 struct CPURISCVState {
     target_ulong gpr[32];
     uint64_t fpr[32]; /* assume both F and D extensions */
@@ -240,6 +241,14 @@ struct CPURISCVState {
 
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *timer; /* Internal timer */
+
+    // The reason why we have an opset map for custom CSRs and a seperated
+    // storage map is that we might have heterogeneous architecture, in which
+    // different harts have different custom CSRs.
+    /* Custom CSR opset map */
+    GHashTable *custom_csr_map;
+    /* Custom CSR val holder */
+    void *custom_csr_val;
 };
 
 OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
@@ -486,17 +495,26 @@ typedef struct {
     riscv_csr_op_fn op;
 } riscv_csr_operations;
 
+typedef struct {
+    int csrno;
+    riscv_csr_operations csr_opset;
+    } riscv_custom_csr_operations;
+
 /* CSR function table constants */
 enum {
-    CSR_TABLE_SIZE = 0x1000
+    CSR_TABLE_SIZE = 0x1000,
+    MAX_CUSTOM_CSR_NUM = 100
 };
 
 /* CSR function table */
+extern int andes_custom_csr_size;
+extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 
 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
 
+
 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index caf4599207..e8dfebd1b0 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -259,6 +259,7 @@
 #define CSR_TDATA1          0x7a1
 #define CSR_TDATA2          0x7a2
 #define CSR_TDATA3          0x7a3
+#define CSR_TINFO           0x7a4
 
 /* Debug Mode Registers */
 #define CSR_DCSR            0x7b0
@@ -593,3 +594,5 @@
 #define MIE_SSIE                           (1 << IRQ_S_SOFT)
 #define MIE_USIE                           (1 << IRQ_U_SOFT)
 #endif
+
+#include "custom_cpu_bits.h"
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fd2e6363f3..6ea2b5e4b0 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -523,6 +523,14 @@ static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
     return 0;
 }
 
+
+// XXX: This is just a write stub for developing custom CSR handler,
+// if the behavior of writting such CSR is not presentable in QEMU and doesn't
+// affect the functionality, just stub it.
+static int write_stub(CPURISCVState *env, int csrno, target_ulong val) {
+    return 0;
+}
+
 static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
 {
     if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
@@ -1264,6 +1272,15 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
 
 #endif
 
+
+/* Custom CSR related routines and data structures */
+
+static gpointer is_custom_csr(CPURISCVState *env, int csrno) {
+    gpointer ret;
+    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
+    return ret;
+    }
+
 /*
  * riscv_csrrw - read and/or update control and status register
  *
@@ -1279,6 +1296,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
     int ret;
     target_ulong old_value;
     RISCVCPU *cpu = env_archcpu(env);
+    riscv_csr_operations *csrop;
 
     /* check privileges and return -1 if check fails */
 #if !defined(CONFIG_USER_ONLY)
@@ -1307,27 +1325,37 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
         return -RISCV_EXCP_ILLEGAL_INST;
     }
 
+    /* try handle_custom_csr */
+    riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
+        is_custom_csr(env, csrno);
+    if(NULL != custom_csr_opset) {
+        csrop = custom_csr_opset;
+        }
+    else {
+        csrop = &csr_ops[csrno];
+        }
+
     /* check predicate */
-    if (!csr_ops[csrno].predicate) {
+    if (!csrop->predicate) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
-    ret = csr_ops[csrno].predicate(env, csrno);
+    ret = csrop->predicate(env, csrno);
     if (ret < 0) {
         return ret;
     }
 
     /* execute combined read/write operation if it exists */
-    if (csr_ops[csrno].op) {
-        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
+    if (csrop->op) {
+        return csrop->op(env, csrno, ret_value, new_value, write_mask);
     }
 
     /* if no accessor exists then return failure */
-    if (!csr_ops[csrno].read) {
+    if (!csrop->read) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
 
     /* read old value */
-    ret = csr_ops[csrno].read(env, csrno, &old_value);
+    ret = csrop->read(env, csrno, &old_value);
     if (ret < 0) {
         return ret;
     }
@@ -1335,8 +1363,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
     /* write value if writable and write mask set, otherwise drop writes */
     if (write_mask) {
         new_value = (old_value & ~write_mask) | (new_value & write_mask);
-        if (csr_ops[csrno].write) {
-            ret = csr_ops[csrno].write(env, csrno, new_value);
+        if (csrop->write) {
+            ret = csrop->write(env, csrno, new_value);
             if (ret < 0) {
                 return ret;
             }
@@ -1369,6 +1397,8 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
     return ret;
 }
 
+#include "csr_andes.inc.c"
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     /* User Floating-Point CSRs */
diff --git a/target/riscv/csr_andes.inc.c b/target/riscv/csr_andes.inc.c
new file mode 100644
index 0000000000..6af7c91096
--- /dev/null
+++ b/target/riscv/csr_andes.inc.c
@@ -0,0 +1,153 @@
+/* Andes Custom Registers */
+
+struct andes_csr_val {
+    target_long uitb;
+};
+
+int andes_custom_csr_size = sizeof(struct andes_csr_val);
+
+static int write_uitb(CPURISCVState *env, int csrno, target_ulong val) {
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    andes_csr->uitb = val;
+    return 0;
+}
+
+static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val) {
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    *val = andes_csr->uitb;
+    return 0;
+}
+
+static int read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    /* enable pma probe */
+    *val = 0x40000000;
+    return 0;
+}
+
+riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
+#if !defined(CONFIG_USER_ONLY)
+    /* ==================== AndeStar V5 machine mode CSRs ==================== */
+    /* Configuration Registers */
+    {CSR_MICM_CFG,         { "micm_cfg",          any, read_zero, write_stub} },
+    {CSR_MDCM_CFG,         { "mdcm_cfg",          any, read_zero, write_stub} },
+    {CSR_MMSC_CFG,         { "mmsc_cfg",          any, read_mmsc_cfg, write_stub} },
+    {CSR_MMSC_CFG2,        { "mmsc_cfg2",         any, read_zero, write_stub} },
+    {CSR_MVEC_CFG,         { "mvec_cfg",          any, read_zero, write_stub} },
+
+    /* Crash Debug CSRs */
+    {CSR_MCRASH_STATESAVE,  { "mcrash_statesave",  any, read_zero, write_stub} },
+    {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
+
+    /* Memory CSRs */
+    {CSR_MILMB,            { "milmb",             any, read_zero, write_stub} },
+    {CSR_MDLMB,            { "mdlmb",             any, read_zero, write_stub} },
+    {CSR_MECC_CODE,        { "mecc_code",         any, read_zero, write_stub} },
+    {CSR_MNVEC,            { "mnvec",             any, read_zero, write_stub} },
+    {CSR_MCACHE_CTL,       { "mcache_ctl",        any, read_zero, write_stub} },
+    {CSR_MCCTLBEGINADDR,   { "mcctlbeginaddr",    any, read_zero, write_stub} },
+    {CSR_MCCTLCOMMAND,     { "mcctlcommand",      any, read_zero, write_stub} },
+    {CSR_MCCTLDATA,        { "mcctldata",         any, read_zero, write_stub} },
+    {CSR_MPPIB,            { "mppib",             any, read_zero, write_stub} },
+    {CSR_MFIOB,            { "mfiob",             any, read_zero, write_stub} },
+
+    /* Hardware Stack Protection & Recording */
+    {CSR_MHSP_CTL,         { "mhsp_ctl",          any, read_zero, write_stub} },
+    {CSR_MSP_BOUND,        { "msp_bound",         any, read_zero, write_stub} },
+    {CSR_MSP_BASE,         { "msp_base",          any, read_zero, write_stub} },
+    {CSR_MXSTATUS,         { "mxstatus",          any, read_zero, write_stub} },
+    {CSR_MDCAUSE,          { "mdcause",           any, read_zero, write_stub} },
+    {CSR_MSLIDELEG,        { "mslideleg",         any, read_zero, write_stub} },
+    {CSR_MSAVESTATUS,      { "msavestatus",       any, read_zero, write_stub} },
+    {CSR_MSAVEEPC1,        { "msaveepc1",         any, read_zero, write_stub} },
+    {CSR_MSAVECAUSE1,      { "msavecause1",       any, read_zero, write_stub} },
+    {CSR_MSAVEEPC2,        { "msaveepc2",         any, read_zero, write_stub} },
+    {CSR_MSAVECAUSE2,      { "msavecause2",       any, read_zero, write_stub} },
+    {CSR_MSAVEDCAUSE1,     { "msavedcause1",      any, read_zero, write_stub} },
+    {CSR_MSAVEDCAUSE2,     { "msavedcause2",      any, read_zero, write_stub} },
+
+    /* Control CSRs */
+    {CSR_MPFT_CTL,         { "mpft_ctl",          any, read_zero, write_stub} },
+    {CSR_MMISC_CTL,        { "mmisc_ctl",         any, read_zero, write_stub} },
+    {CSR_MCLK_CTL,         { "mclk_ctl",          any, read_zero, write_stub} },
+
+    /* Counter related CSRs */
+    {CSR_MCOUNTERWEN,      { "mcounterwen",       any, read_zero, write_stub} },
+    {CSR_MCOUNTERINTEN,    { "mcounterinten",     any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_M,   { "mcountermask_m",    any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_S,   { "mcountermask_s",    any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_U,   { "mcountermask_u",    any, read_zero, write_stub} },
+    {CSR_MCOUNTEROVF,      { "mcounterovf",       any, read_zero, write_stub} },
+
+    /* Enhanced CLIC CSRs */
+    {CSR_MIRQ_ENTRY,       { "mirq_entry",        any, read_zero, write_stub} },
+    {CSR_MINTSEL_JAL,      { "mintsel_jal",       any, read_zero, write_stub} },
+    {CSR_PUSHMCAUSE,       { "pushmcause",        any, read_zero, write_stub} },
+    {CSR_PUSHMEPC,         { "pushmepc",          any, read_zero, write_stub} },
+    {CSR_PUSHMXSTATUS,     { "pushmxstatus",      any, read_zero, write_stub} },
+
+    /* Andes Physical Memory Attribute(PMA) CSRs */
+    {CSR_PMACFG0,          { "pmacfg0",           any, read_zero, write_stub} },
+    {CSR_PMACFG1,          { "pmacfg1",           any, read_zero, write_stub} },
+    {CSR_PMACFG2,          { "pmacfg2",           any, read_zero, write_stub} },
+    {CSR_PMACFG3,          { "pmacfg3",           any, read_zero, write_stub} },
+    {CSR_PMAADDR0,         { "pmaaddr0",          any, read_zero, write_stub} },
+    {CSR_PMAADDR1,         { "pmaaddr1",          any, read_zero, write_stub} },
+    {CSR_PMAADDR2,         { "pmaaddr2",          any, read_zero, write_stub} },
+    {CSR_PMAADDR3,         { "pmaaddr3",          any, read_zero, write_stub} },
+    {CSR_PMAADDR4,         { "pmaaddr4",          any, read_zero, write_stub} },
+    {CSR_PMAADDR5,         { "pmaaddr5",          any, read_zero, write_stub} },
+    {CSR_PMAADDR6,         { "pmaaddr6",          any, read_zero, write_stub} },
+    {CSR_PMAADDR7,         { "pmaaddr7",          any, read_zero, write_stub} },
+    {CSR_PMAADDR8,         { "pmaaddr8",          any, read_zero, write_stub} },
+    {CSR_PMAADDR9,         { "pmaaddr9",          any, read_zero, write_stub} },
+    {CSR_PMAADDR10,        { "pmaaddr10",         any, read_zero, write_stub} },
+    {CSR_PMAADDR11,        { "pmaaddr11",         any, read_zero, write_stub} },
+    {CSR_PMAADDR12,        { "pmaaddr12",         any, read_zero, write_stub} },
+    {CSR_PMAADDR13,        { "pmaaddr13",         any, read_zero, write_stub} },
+    {CSR_PMAADDR14,        { "pmaaddr14",         any, read_zero, write_stub} },
+    {CSR_PMAADDR15,        { "pmaaddr15",         any, read_zero, write_stub} },
+
+    /* Debug/Trace Registers (shared with Debug Mode) */
+    {CSR_TSELECT,          { "tselect",           any, read_zero, write_stub} },
+    {CSR_TDATA1,           { "tdata1",            any, read_zero, write_stub} },
+    {CSR_TDATA2,           { "tdata2",            any, read_zero, write_stub} },
+    {CSR_TDATA3,           { "tdata3",            any, read_zero, write_stub} },
+    {CSR_TINFO,            { "tinfo",             any, read_zero, write_stub} },
+
+    /* ================== AndeStar V5 supervisor mode CSRs ================== */
+    /* Supervisor trap registers */
+    {CSR_SLIE,             { "slie",              any, read_zero, write_stub} },
+    {CSR_SLIP,             { "slip",              any, read_zero, write_stub} },
+    {CSR_SDCAUSE,          { "sdcause",           any, read_zero, write_stub} },
+
+    /* Supervisor counter registers */
+    {CSR_SCOUNTERINTEN,    { "scounterinten",     any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_M,   { "scountermask_m",    any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_S,   { "scountermask_s",    any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_U,   { "scountermask_u",    any, read_zero, write_stub} },
+    {CSR_SCOUNTEROVF,      { "scounterovf",       any, read_zero, write_stub} },
+    {CSR_SCOUNTINHIBIT,    { "scountinhibit",     any, read_zero, write_stub} },
+    {CSR_SHPMEVENT3,       { "shpmevent3",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT4,       { "shpmevent4",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT5,       { "shpmevent5",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT6,       { "shpmevent6",        any, read_zero, write_stub} },
+
+    /* Supervisor control registers */
+    {CSR_SCCTLDATA,        { "scctldata",         any, read_zero, write_stub} },
+    {CSR_SMISC_CTL,        { "smisc_ctl",         any, read_zero, write_stub} },
+
+    /* ===================== AndeStar V5 user mode CSRs ===================== */
+    /* User mode control registers */
+    {CSR_UITB,             { "uitb",              any, read_uitb, write_uitb} },
+    {CSR_UCODE,            { "ucode",             any, read_zero, write_stub} },
+    {CSR_UDCAUSE,          { "udcause",           any, read_zero, write_stub} },
+    {CSR_UCCTLBEGINADDR,   { "ucctlbeginaddr",    any, read_zero, write_stub} },
+    {CSR_UCCTLCOMMAND,     { "ucctlcommand",      any, read_zero, write_stub} },
+    {CSR_WFE,              { "wfe",               any, read_zero, write_stub} },
+    {CSR_SLEEPVALUE,       { "sleepvalue",        any, read_zero, write_stub} },
+    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
+    {0, { "", NULL, NULL, NULL } },
+#endif
+    };
+
diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
new file mode 100644
index 0000000000..072c97728a
--- /dev/null
+++ b/target/riscv/custom_cpu_bits.h
@@ -0,0 +1,3 @@
+//XXX Maybe we should introduce a configure option to toggle different vendor
+// CSR bits definition ?
+#include "andes_cpu_bits.h"
-- 
2.31.1



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

* [RFC PATCH v3 2/2] Adding preliminary custom/vendor CSR handling mechanism
@ 2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 14+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-06-10 14:44 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: alistair23, wangjunqiang, bin.meng, alankao, dylan,
	Ruinaldn ChuanTzu Tsai

From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>

For now we add a custom CSR handling mechanism to handle non-standard CSR read
or write.

The write_stub() and read_zero() are provided for quick placeholder usage if
such CSRs' behavior are expected to fail-over in its user code.

For demonstration, we modify Andes Technology AX25 to showcase how the such
mechanism works and how the UITB and MMSC_CFG CSR could be emulated.
---
 target/riscv/andes_cpu_bits.h  | 113 ++++++++++++++++++++++++
 target/riscv/cpu.c             |  29 +++++++
 target/riscv/cpu.h             |  20 ++++-
 target/riscv/cpu_bits.h        |   3 +
 target/riscv/csr.c             |  46 ++++++++--
 target/riscv/csr_andes.inc.c   | 153 +++++++++++++++++++++++++++++++++
 target/riscv/custom_cpu_bits.h |   3 +
 7 files changed, 358 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.inc.c
 create mode 100644 target/riscv/custom_cpu_bits.h

diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
new file mode 100644
index 0000000000..8dee58a2c2
--- /dev/null
+++ b/target/riscv/andes_cpu_bits.h
@@ -0,0 +1,113 @@
+/* ========= AndeStar V5 machine mode CSRs ========= */
+/* Configuration Registers */
+#define CSR_MICM_CFG            0xfc0
+#define CSR_MDCM_CFG            0xfc1
+#define CSR_MMSC_CFG            0xfc2
+#define CSR_MMSC_CFG2           0xfc3
+#define CSR_MVEC_CFG            0xfc7
+
+/* Crash Debug CSRs */
+#define CSR_MCRASH_STATESAVE    0xfc8
+#define CSR_MSTATUS_CRASHSAVE   0xfc9
+
+/* Memory CSRs */
+#define CSR_MILMB               0x7c0
+#define CSR_MDLMB               0x7c1
+#define CSR_MECC_CODE           0x7C2
+#define CSR_MNVEC               0x7c3
+#define CSR_MCACHE_CTL          0x7ca
+#define CSR_MCCTLBEGINADDR      0x7cb
+#define CSR_MCCTLCOMMAND        0x7cc
+#define CSR_MCCTLDATA           0x7cd
+#define CSR_MPPIB               0x7f0
+#define CSR_MFIOB               0x7f1
+
+/* Hardware Stack Protection & Recording */
+#define CSR_MHSP_CTL            0x7c6
+#define CSR_MSP_BOUND           0x7c7
+#define CSR_MSP_BASE            0x7c8
+#define CSR_MXSTATUS            0x7c4
+#define CSR_MDCAUSE             0x7c9
+#define CSR_MSLIDELEG           0x7d5
+#define CSR_MSAVESTATUS         0x7d6
+#define CSR_MSAVEEPC1           0x7d7
+#define CSR_MSAVECAUSE1         0x7d8
+#define CSR_MSAVEEPC2           0x7d9
+#define CSR_MSAVECAUSE2         0x7da
+#define CSR_MSAVEDCAUSE1        0x7db
+#define CSR_MSAVEDCAUSE2        0x7dc
+
+/* Control CSRs */
+#define CSR_MPFT_CTL            0x7c5
+#define CSR_MMISC_CTL           0x7d0
+#define CSR_MCLK_CTL            0x7df
+
+/* Counter related CSRs */
+#define CSR_MCOUNTERWEN         0x7ce
+#define CSR_MCOUNTERINTEN       0x7cf
+#define CSR_MCOUNTERMASK_M      0x7d1
+#define CSR_MCOUNTERMASK_S      0x7d2
+#define CSR_MCOUNTERMASK_U      0x7d3
+#define CSR_MCOUNTEROVF         0x7d4
+
+/* Enhanced CLIC CSRs */
+#define CSR_MIRQ_ENTRY          0x7ec
+#define CSR_MINTSEL_JAL         0x7ed
+#define CSR_PUSHMCAUSE          0x7ee
+#define CSR_PUSHMEPC            0x7ef
+#define CSR_PUSHMXSTATUS        0x7eb
+
+/* Andes Physical Memory Attribute(PMA) CSRs */
+#define CSR_PMACFG0             0xbc0
+#define CSR_PMACFG1             0xbc1
+#define CSR_PMACFG2             0xbc2
+#define CSR_PMACFG3             0xbc3
+#define CSR_PMAADDR0            0xbd0
+#define CSR_PMAADDR1            0xbd1
+#define CSR_PMAADDR2            0xbd2
+#define CSR_PMAADDR3            0xbd2
+#define CSR_PMAADDR4            0xbd4
+#define CSR_PMAADDR5            0xbd5
+#define CSR_PMAADDR6            0xbd6
+#define CSR_PMAADDR7            0xbd7
+#define CSR_PMAADDR8            0xbd8
+#define CSR_PMAADDR9            0xbd9
+#define CSR_PMAADDR10           0xbda
+#define CSR_PMAADDR11           0xbdb
+#define CSR_PMAADDR12           0xbdc
+#define CSR_PMAADDR13           0xbdd
+#define CSR_PMAADDR14           0xbde
+#define CSR_PMAADDR15           0xbdf
+
+/* ========= AndeStar V5 supervisor mode CSRs ========= */
+/* Supervisor trap registers */
+#define CSR_SLIE                0x9c4
+#define CSR_SLIP                0x9c5
+#define CSR_SDCAUSE             0x9c9
+
+/* Supervisor counter registers */
+#define CSR_SCOUNTERINTEN       0x9cf
+#define CSR_SCOUNTERMASK_M      0x9d1
+#define CSR_SCOUNTERMASK_S      0x9d2
+#define CSR_SCOUNTERMASK_U      0x9d3
+#define CSR_SCOUNTEROVF         0x9d4
+#define CSR_SCOUNTINHIBIT       0x9e0
+#define CSR_SHPMEVENT3          0x9e3
+#define CSR_SHPMEVENT4          0x9e4
+#define CSR_SHPMEVENT5          0x9e5
+#define CSR_SHPMEVENT6          0x9e6
+
+/* Supervisor control registers */
+#define CSR_SCCTLDATA           0x9cd
+#define CSR_SMISC_CTL           0x9d0
+
+/* ========= AndeStar V5 user mode CSRs ========= */
+/* User mode control registers */
+#define CSR_UITB                0x800
+#define CSR_UCODE               0x801
+#define CSR_UDCAUSE             0x809
+#define CSR_UCCTLBEGINADDR      0x80b
+#define CSR_UCCTLCOMMAND        0x80c
+#define CSR_WFE                 0x810
+#define CSR_SLEEPVALUE          0x811
+#define CSR_TXEVT               0x812
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4ae21cbf9b..460839d006 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -144,6 +144,30 @@ static void set_resetvec(CPURISCVState *env, int resetvec)
 #endif
 }
 
+#if defined(TARGET_RISCV64)
+// Currently we only have ax25 using this function, to ease Wunused-function,
+// we put it in TARGET_RISCV64.
+static void setup_custom_csr(CPURISCVState *env,
+                             riscv_custom_csr_operations csr_map_struct[]
+                             ) {
+
+    env->custom_csr_map = g_hash_table_new_full(
+        g_direct_hash, g_direct_equal, NULL, NULL);
+
+    int i;
+
+    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
+        if (csr_map_struct[i].csrno != 0) {
+            g_hash_table_insert(env->custom_csr_map,
+                GINT_TO_POINTER(csr_map_struct[i].csrno),
+                &csr_map_struct[i].csr_opset);
+        } else {
+            break;
+        }
+    }
+}
+#endif
+
 static void riscv_any_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -164,6 +188,11 @@ static void ax25_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
     set_priv_version(env, PRIV_VERSION_1_10_0);
+
+    /* setup custom csr handler hash table */
+    setup_custom_csr(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
+
 }
 
 static void rv64_sifive_u_cpu_init(Object *obj)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index bff9af7f3f..231505f403 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -112,6 +112,7 @@ FIELD(VTYPE, VEDIV, 5, 2)
 FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
 FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
+
 struct CPURISCVState {
     target_ulong gpr[32];
     uint64_t fpr[32]; /* assume both F and D extensions */
@@ -240,6 +241,14 @@ struct CPURISCVState {
 
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *timer; /* Internal timer */
+
+    // The reason why we have an opset map for custom CSRs and a seperated
+    // storage map is that we might have heterogeneous architecture, in which
+    // different harts have different custom CSRs.
+    /* Custom CSR opset map */
+    GHashTable *custom_csr_map;
+    /* Custom CSR val holder */
+    void *custom_csr_val;
 };
 
 OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
@@ -486,17 +495,26 @@ typedef struct {
     riscv_csr_op_fn op;
 } riscv_csr_operations;
 
+typedef struct {
+    int csrno;
+    riscv_csr_operations csr_opset;
+    } riscv_custom_csr_operations;
+
 /* CSR function table constants */
 enum {
-    CSR_TABLE_SIZE = 0x1000
+    CSR_TABLE_SIZE = 0x1000,
+    MAX_CUSTOM_CSR_NUM = 100
 };
 
 /* CSR function table */
+extern int andes_custom_csr_size;
+extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 
 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
 
+
 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index caf4599207..e8dfebd1b0 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -259,6 +259,7 @@
 #define CSR_TDATA1          0x7a1
 #define CSR_TDATA2          0x7a2
 #define CSR_TDATA3          0x7a3
+#define CSR_TINFO           0x7a4
 
 /* Debug Mode Registers */
 #define CSR_DCSR            0x7b0
@@ -593,3 +594,5 @@
 #define MIE_SSIE                           (1 << IRQ_S_SOFT)
 #define MIE_USIE                           (1 << IRQ_U_SOFT)
 #endif
+
+#include "custom_cpu_bits.h"
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fd2e6363f3..6ea2b5e4b0 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -523,6 +523,14 @@ static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
     return 0;
 }
 
+
+// XXX: This is just a write stub for developing custom CSR handler,
+// if the behavior of writting such CSR is not presentable in QEMU and doesn't
+// affect the functionality, just stub it.
+static int write_stub(CPURISCVState *env, int csrno, target_ulong val) {
+    return 0;
+}
+
 static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
 {
     if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
@@ -1264,6 +1272,15 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
 
 #endif
 
+
+/* Custom CSR related routines and data structures */
+
+static gpointer is_custom_csr(CPURISCVState *env, int csrno) {
+    gpointer ret;
+    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
+    return ret;
+    }
+
 /*
  * riscv_csrrw - read and/or update control and status register
  *
@@ -1279,6 +1296,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
     int ret;
     target_ulong old_value;
     RISCVCPU *cpu = env_archcpu(env);
+    riscv_csr_operations *csrop;
 
     /* check privileges and return -1 if check fails */
 #if !defined(CONFIG_USER_ONLY)
@@ -1307,27 +1325,37 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
         return -RISCV_EXCP_ILLEGAL_INST;
     }
 
+    /* try handle_custom_csr */
+    riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
+        is_custom_csr(env, csrno);
+    if(NULL != custom_csr_opset) {
+        csrop = custom_csr_opset;
+        }
+    else {
+        csrop = &csr_ops[csrno];
+        }
+
     /* check predicate */
-    if (!csr_ops[csrno].predicate) {
+    if (!csrop->predicate) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
-    ret = csr_ops[csrno].predicate(env, csrno);
+    ret = csrop->predicate(env, csrno);
     if (ret < 0) {
         return ret;
     }
 
     /* execute combined read/write operation if it exists */
-    if (csr_ops[csrno].op) {
-        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
+    if (csrop->op) {
+        return csrop->op(env, csrno, ret_value, new_value, write_mask);
     }
 
     /* if no accessor exists then return failure */
-    if (!csr_ops[csrno].read) {
+    if (!csrop->read) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
 
     /* read old value */
-    ret = csr_ops[csrno].read(env, csrno, &old_value);
+    ret = csrop->read(env, csrno, &old_value);
     if (ret < 0) {
         return ret;
     }
@@ -1335,8 +1363,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
     /* write value if writable and write mask set, otherwise drop writes */
     if (write_mask) {
         new_value = (old_value & ~write_mask) | (new_value & write_mask);
-        if (csr_ops[csrno].write) {
-            ret = csr_ops[csrno].write(env, csrno, new_value);
+        if (csrop->write) {
+            ret = csrop->write(env, csrno, new_value);
             if (ret < 0) {
                 return ret;
             }
@@ -1369,6 +1397,8 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
     return ret;
 }
 
+#include "csr_andes.inc.c"
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     /* User Floating-Point CSRs */
diff --git a/target/riscv/csr_andes.inc.c b/target/riscv/csr_andes.inc.c
new file mode 100644
index 0000000000..6af7c91096
--- /dev/null
+++ b/target/riscv/csr_andes.inc.c
@@ -0,0 +1,153 @@
+/* Andes Custom Registers */
+
+struct andes_csr_val {
+    target_long uitb;
+};
+
+int andes_custom_csr_size = sizeof(struct andes_csr_val);
+
+static int write_uitb(CPURISCVState *env, int csrno, target_ulong val) {
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    andes_csr->uitb = val;
+    return 0;
+}
+
+static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val) {
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    *val = andes_csr->uitb;
+    return 0;
+}
+
+static int read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    /* enable pma probe */
+    *val = 0x40000000;
+    return 0;
+}
+
+riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
+#if !defined(CONFIG_USER_ONLY)
+    /* ==================== AndeStar V5 machine mode CSRs ==================== */
+    /* Configuration Registers */
+    {CSR_MICM_CFG,         { "micm_cfg",          any, read_zero, write_stub} },
+    {CSR_MDCM_CFG,         { "mdcm_cfg",          any, read_zero, write_stub} },
+    {CSR_MMSC_CFG,         { "mmsc_cfg",          any, read_mmsc_cfg, write_stub} },
+    {CSR_MMSC_CFG2,        { "mmsc_cfg2",         any, read_zero, write_stub} },
+    {CSR_MVEC_CFG,         { "mvec_cfg",          any, read_zero, write_stub} },
+
+    /* Crash Debug CSRs */
+    {CSR_MCRASH_STATESAVE,  { "mcrash_statesave",  any, read_zero, write_stub} },
+    {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
+
+    /* Memory CSRs */
+    {CSR_MILMB,            { "milmb",             any, read_zero, write_stub} },
+    {CSR_MDLMB,            { "mdlmb",             any, read_zero, write_stub} },
+    {CSR_MECC_CODE,        { "mecc_code",         any, read_zero, write_stub} },
+    {CSR_MNVEC,            { "mnvec",             any, read_zero, write_stub} },
+    {CSR_MCACHE_CTL,       { "mcache_ctl",        any, read_zero, write_stub} },
+    {CSR_MCCTLBEGINADDR,   { "mcctlbeginaddr",    any, read_zero, write_stub} },
+    {CSR_MCCTLCOMMAND,     { "mcctlcommand",      any, read_zero, write_stub} },
+    {CSR_MCCTLDATA,        { "mcctldata",         any, read_zero, write_stub} },
+    {CSR_MPPIB,            { "mppib",             any, read_zero, write_stub} },
+    {CSR_MFIOB,            { "mfiob",             any, read_zero, write_stub} },
+
+    /* Hardware Stack Protection & Recording */
+    {CSR_MHSP_CTL,         { "mhsp_ctl",          any, read_zero, write_stub} },
+    {CSR_MSP_BOUND,        { "msp_bound",         any, read_zero, write_stub} },
+    {CSR_MSP_BASE,         { "msp_base",          any, read_zero, write_stub} },
+    {CSR_MXSTATUS,         { "mxstatus",          any, read_zero, write_stub} },
+    {CSR_MDCAUSE,          { "mdcause",           any, read_zero, write_stub} },
+    {CSR_MSLIDELEG,        { "mslideleg",         any, read_zero, write_stub} },
+    {CSR_MSAVESTATUS,      { "msavestatus",       any, read_zero, write_stub} },
+    {CSR_MSAVEEPC1,        { "msaveepc1",         any, read_zero, write_stub} },
+    {CSR_MSAVECAUSE1,      { "msavecause1",       any, read_zero, write_stub} },
+    {CSR_MSAVEEPC2,        { "msaveepc2",         any, read_zero, write_stub} },
+    {CSR_MSAVECAUSE2,      { "msavecause2",       any, read_zero, write_stub} },
+    {CSR_MSAVEDCAUSE1,     { "msavedcause1",      any, read_zero, write_stub} },
+    {CSR_MSAVEDCAUSE2,     { "msavedcause2",      any, read_zero, write_stub} },
+
+    /* Control CSRs */
+    {CSR_MPFT_CTL,         { "mpft_ctl",          any, read_zero, write_stub} },
+    {CSR_MMISC_CTL,        { "mmisc_ctl",         any, read_zero, write_stub} },
+    {CSR_MCLK_CTL,         { "mclk_ctl",          any, read_zero, write_stub} },
+
+    /* Counter related CSRs */
+    {CSR_MCOUNTERWEN,      { "mcounterwen",       any, read_zero, write_stub} },
+    {CSR_MCOUNTERINTEN,    { "mcounterinten",     any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_M,   { "mcountermask_m",    any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_S,   { "mcountermask_s",    any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_U,   { "mcountermask_u",    any, read_zero, write_stub} },
+    {CSR_MCOUNTEROVF,      { "mcounterovf",       any, read_zero, write_stub} },
+
+    /* Enhanced CLIC CSRs */
+    {CSR_MIRQ_ENTRY,       { "mirq_entry",        any, read_zero, write_stub} },
+    {CSR_MINTSEL_JAL,      { "mintsel_jal",       any, read_zero, write_stub} },
+    {CSR_PUSHMCAUSE,       { "pushmcause",        any, read_zero, write_stub} },
+    {CSR_PUSHMEPC,         { "pushmepc",          any, read_zero, write_stub} },
+    {CSR_PUSHMXSTATUS,     { "pushmxstatus",      any, read_zero, write_stub} },
+
+    /* Andes Physical Memory Attribute(PMA) CSRs */
+    {CSR_PMACFG0,          { "pmacfg0",           any, read_zero, write_stub} },
+    {CSR_PMACFG1,          { "pmacfg1",           any, read_zero, write_stub} },
+    {CSR_PMACFG2,          { "pmacfg2",           any, read_zero, write_stub} },
+    {CSR_PMACFG3,          { "pmacfg3",           any, read_zero, write_stub} },
+    {CSR_PMAADDR0,         { "pmaaddr0",          any, read_zero, write_stub} },
+    {CSR_PMAADDR1,         { "pmaaddr1",          any, read_zero, write_stub} },
+    {CSR_PMAADDR2,         { "pmaaddr2",          any, read_zero, write_stub} },
+    {CSR_PMAADDR3,         { "pmaaddr3",          any, read_zero, write_stub} },
+    {CSR_PMAADDR4,         { "pmaaddr4",          any, read_zero, write_stub} },
+    {CSR_PMAADDR5,         { "pmaaddr5",          any, read_zero, write_stub} },
+    {CSR_PMAADDR6,         { "pmaaddr6",          any, read_zero, write_stub} },
+    {CSR_PMAADDR7,         { "pmaaddr7",          any, read_zero, write_stub} },
+    {CSR_PMAADDR8,         { "pmaaddr8",          any, read_zero, write_stub} },
+    {CSR_PMAADDR9,         { "pmaaddr9",          any, read_zero, write_stub} },
+    {CSR_PMAADDR10,        { "pmaaddr10",         any, read_zero, write_stub} },
+    {CSR_PMAADDR11,        { "pmaaddr11",         any, read_zero, write_stub} },
+    {CSR_PMAADDR12,        { "pmaaddr12",         any, read_zero, write_stub} },
+    {CSR_PMAADDR13,        { "pmaaddr13",         any, read_zero, write_stub} },
+    {CSR_PMAADDR14,        { "pmaaddr14",         any, read_zero, write_stub} },
+    {CSR_PMAADDR15,        { "pmaaddr15",         any, read_zero, write_stub} },
+
+    /* Debug/Trace Registers (shared with Debug Mode) */
+    {CSR_TSELECT,          { "tselect",           any, read_zero, write_stub} },
+    {CSR_TDATA1,           { "tdata1",            any, read_zero, write_stub} },
+    {CSR_TDATA2,           { "tdata2",            any, read_zero, write_stub} },
+    {CSR_TDATA3,           { "tdata3",            any, read_zero, write_stub} },
+    {CSR_TINFO,            { "tinfo",             any, read_zero, write_stub} },
+
+    /* ================== AndeStar V5 supervisor mode CSRs ================== */
+    /* Supervisor trap registers */
+    {CSR_SLIE,             { "slie",              any, read_zero, write_stub} },
+    {CSR_SLIP,             { "slip",              any, read_zero, write_stub} },
+    {CSR_SDCAUSE,          { "sdcause",           any, read_zero, write_stub} },
+
+    /* Supervisor counter registers */
+    {CSR_SCOUNTERINTEN,    { "scounterinten",     any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_M,   { "scountermask_m",    any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_S,   { "scountermask_s",    any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_U,   { "scountermask_u",    any, read_zero, write_stub} },
+    {CSR_SCOUNTEROVF,      { "scounterovf",       any, read_zero, write_stub} },
+    {CSR_SCOUNTINHIBIT,    { "scountinhibit",     any, read_zero, write_stub} },
+    {CSR_SHPMEVENT3,       { "shpmevent3",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT4,       { "shpmevent4",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT5,       { "shpmevent5",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT6,       { "shpmevent6",        any, read_zero, write_stub} },
+
+    /* Supervisor control registers */
+    {CSR_SCCTLDATA,        { "scctldata",         any, read_zero, write_stub} },
+    {CSR_SMISC_CTL,        { "smisc_ctl",         any, read_zero, write_stub} },
+
+    /* ===================== AndeStar V5 user mode CSRs ===================== */
+    /* User mode control registers */
+    {CSR_UITB,             { "uitb",              any, read_uitb, write_uitb} },
+    {CSR_UCODE,            { "ucode",             any, read_zero, write_stub} },
+    {CSR_UDCAUSE,          { "udcause",           any, read_zero, write_stub} },
+    {CSR_UCCTLBEGINADDR,   { "ucctlbeginaddr",    any, read_zero, write_stub} },
+    {CSR_UCCTLCOMMAND,     { "ucctlcommand",      any, read_zero, write_stub} },
+    {CSR_WFE,              { "wfe",               any, read_zero, write_stub} },
+    {CSR_SLEEPVALUE,       { "sleepvalue",        any, read_zero, write_stub} },
+    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
+    {0, { "", NULL, NULL, NULL } },
+#endif
+    };
+
diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
new file mode 100644
index 0000000000..072c97728a
--- /dev/null
+++ b/target/riscv/custom_cpu_bits.h
@@ -0,0 +1,3 @@
+//XXX Maybe we should introduce a configure option to toggle different vendor
+// CSR bits definition ?
+#include "andes_cpu_bits.h"
-- 
2.31.1



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

* Re: [RFC PATCH v3 2/2] Adding preliminary custom/vendor CSR handling mechanism
  2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
@ 2021-06-10 16:19     ` Richard Henderson
  -1 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2021-06-10 16:19 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, qemu-devel, qemu-riscv
  Cc: bin.meng, alistair23, wangjunqiang, dylan, alankao

On 6/10/21 7:44 AM, Ruinland Chuan-Tzu Tsai wrote:
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,113 @@
> +/* ========= AndeStar V5 machine mode CSRs ========= */

> --- /dev/null
> +++ b/target/riscv/csr_andes.inc.c
> @@ -0,0 +1,153 @@
> +/* Andes Custom Registers */

> --- /dev/null
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -0,0 +1,3 @@
> +//XXX Maybe we should introduce a configure option to toggle different vendor
> +// CSR bits definition ?
> +#include "andes_cpu_bits.h"

All new files must have copyright+license boilerplate.


r~


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

* Re: [RFC PATCH v3 2/2] Adding preliminary custom/vendor CSR handling mechanism
@ 2021-06-10 16:19     ` Richard Henderson
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2021-06-10 16:19 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, qemu-devel, qemu-riscv
  Cc: dylan, alankao, wangjunqiang, bin.meng, alistair23

On 6/10/21 7:44 AM, Ruinland Chuan-Tzu Tsai wrote:
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,113 @@
> +/* ========= AndeStar V5 machine mode CSRs ========= */

> --- /dev/null
> +++ b/target/riscv/csr_andes.inc.c
> @@ -0,0 +1,153 @@
> +/* Andes Custom Registers */

> --- /dev/null
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -0,0 +1,3 @@
> +//XXX Maybe we should introduce a configure option to toggle different vendor
> +// CSR bits definition ?
> +#include "andes_cpu_bits.h"

All new files must have copyright+license boilerplate.


r~


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

* Re: [RFC PATCH v3 1/2] Adding Andes AX25 CPU model
  2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
@ 2021-06-10 22:49     ` Alistair Francis
  -1 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2021-06-10 22:49 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: Dylan Jhong, open list:RISC-V, Alan Quey-Liang Kao((((((((((),
	wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers

On Fri, Jun 11, 2021 at 12:44 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>
>
> Adding the skeleton of Andes Technology AX25 CPU model for the future commits,
> which will utilize custom/vendor CSR handling mechaism.

You are missing a SoB line.

See https://wiki.qemu.org/Contribute/SubmitAPatch for more details.

Alistair

> ---
>  target/riscv/cpu.c | 8 ++++++++
>  target/riscv/cpu.h | 1 +
>  2 files changed, 9 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ddea8fbeeb..4ae21cbf9b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -159,6 +159,13 @@ static void rv64_base_cpu_init(Object *obj)
>      set_misa(env, RV64);
>  }
>
> +static void ax25_cpu_init(Object *obj)
> +{
> +    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> +    set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
> +
>  static void rv64_sifive_u_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> @@ -705,6 +712,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
>  #elif defined(TARGET_RISCV64)
>      DEFINE_CPU(TYPE_RISCV_CPU_BASE64,           rv64_base_cpu_init),
> +    DEFINE_CPU(TYPE_RISCV_CPU_AX25,             ax25_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64_sifive_e_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64_sifive_u_cpu_init),
>  #endif
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 0edb2826a2..bff9af7f3f 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -37,6 +37,7 @@
>  #define TYPE_RISCV_CPU_ANY              RISCV_CPU_TYPE_NAME("any")
>  #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
>  #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
> +#define TYPE_RISCV_CPU_AX25             RISCV_CPU_TYPE_NAME("andes-ax25")
>  #define TYPE_RISCV_CPU_IBEX             RISCV_CPU_TYPE_NAME("lowrisc-ibex")
>  #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
>  #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
> --
> 2.31.1
>


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

* Re: [RFC PATCH v3 1/2] Adding Andes AX25 CPU model
@ 2021-06-10 22:49     ` Alistair Francis
  0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2021-06-10 22:49 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Alan Quey-Liang Kao((((((((((),
	Dylan Jhong

On Fri, Jun 11, 2021 at 12:44 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>
>
> Adding the skeleton of Andes Technology AX25 CPU model for the future commits,
> which will utilize custom/vendor CSR handling mechaism.

You are missing a SoB line.

See https://wiki.qemu.org/Contribute/SubmitAPatch for more details.

Alistair

> ---
>  target/riscv/cpu.c | 8 ++++++++
>  target/riscv/cpu.h | 1 +
>  2 files changed, 9 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ddea8fbeeb..4ae21cbf9b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -159,6 +159,13 @@ static void rv64_base_cpu_init(Object *obj)
>      set_misa(env, RV64);
>  }
>
> +static void ax25_cpu_init(Object *obj)
> +{
> +    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> +    set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
> +
>  static void rv64_sifive_u_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> @@ -705,6 +712,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
>  #elif defined(TARGET_RISCV64)
>      DEFINE_CPU(TYPE_RISCV_CPU_BASE64,           rv64_base_cpu_init),
> +    DEFINE_CPU(TYPE_RISCV_CPU_AX25,             ax25_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64_sifive_e_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64_sifive_u_cpu_init),
>  #endif
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 0edb2826a2..bff9af7f3f 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -37,6 +37,7 @@
>  #define TYPE_RISCV_CPU_ANY              RISCV_CPU_TYPE_NAME("any")
>  #define TYPE_RISCV_CPU_BASE32           RISCV_CPU_TYPE_NAME("rv32")
>  #define TYPE_RISCV_CPU_BASE64           RISCV_CPU_TYPE_NAME("rv64")
> +#define TYPE_RISCV_CPU_AX25             RISCV_CPU_TYPE_NAME("andes-ax25")
>  #define TYPE_RISCV_CPU_IBEX             RISCV_CPU_TYPE_NAME("lowrisc-ibex")
>  #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
>  #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
> --
> 2.31.1
>


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

* Re: [RFC PATCH v3 2/2] Adding preliminary custom/vendor CSR handling mechanism
  2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
@ 2021-06-10 22:57     ` Alistair Francis
  -1 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2021-06-10 22:57 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: Dylan Jhong, open list:RISC-V, Alan Quey-Liang Kao((((((((((),
	wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers

On Fri, Jun 11, 2021 at 12:44 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>
>
> For now we add a custom CSR handling mechanism to handle non-standard CSR read
> or write.
>
> The write_stub() and read_zero() are provided for quick placeholder usage if
> such CSRs' behavior are expected to fail-over in its user code.
>
> For demonstration, we modify Andes Technology AX25 to showcase how the such
> mechanism works and how the UITB and MMSC_CFG CSR could be emulated.

Thanks for the patch!

This patch probably needs to be split into at least 2 different
patches. One adding the implementation and a second one adding the
Andes custom CSRs.

You also should run checkpatch on all patches:
https://wiki.qemu.org/Contribute/SubmitAPatch#Use_the_QEMU_coding_style

You are missing a SoB line here.

> ---
>  target/riscv/andes_cpu_bits.h  | 113 ++++++++++++++++++++++++
>  target/riscv/cpu.c             |  29 +++++++
>  target/riscv/cpu.h             |  20 ++++-
>  target/riscv/cpu_bits.h        |   3 +
>  target/riscv/csr.c             |  46 ++++++++--
>  target/riscv/csr_andes.inc.c   | 153 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_cpu_bits.h |   3 +
>  7 files changed, 358 insertions(+), 9 deletions(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.inc.c
>  create mode 100644 target/riscv/custom_cpu_bits.h
>
> diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> new file mode 100644
> index 0000000000..8dee58a2c2
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,113 @@
> +/* ========= AndeStar V5 machine mode CSRs ========= */
> +/* Configuration Registers */
> +#define CSR_MICM_CFG            0xfc0
> +#define CSR_MDCM_CFG            0xfc1
> +#define CSR_MMSC_CFG            0xfc2
> +#define CSR_MMSC_CFG2           0xfc3
> +#define CSR_MVEC_CFG            0xfc7
> +
> +/* Crash Debug CSRs */
> +#define CSR_MCRASH_STATESAVE    0xfc8
> +#define CSR_MSTATUS_CRASHSAVE   0xfc9
> +
> +/* Memory CSRs */
> +#define CSR_MILMB               0x7c0
> +#define CSR_MDLMB               0x7c1
> +#define CSR_MECC_CODE           0x7C2
> +#define CSR_MNVEC               0x7c3
> +#define CSR_MCACHE_CTL          0x7ca
> +#define CSR_MCCTLBEGINADDR      0x7cb
> +#define CSR_MCCTLCOMMAND        0x7cc
> +#define CSR_MCCTLDATA           0x7cd
> +#define CSR_MPPIB               0x7f0
> +#define CSR_MFIOB               0x7f1
> +
> +/* Hardware Stack Protection & Recording */
> +#define CSR_MHSP_CTL            0x7c6
> +#define CSR_MSP_BOUND           0x7c7
> +#define CSR_MSP_BASE            0x7c8
> +#define CSR_MXSTATUS            0x7c4
> +#define CSR_MDCAUSE             0x7c9
> +#define CSR_MSLIDELEG           0x7d5
> +#define CSR_MSAVESTATUS         0x7d6
> +#define CSR_MSAVEEPC1           0x7d7
> +#define CSR_MSAVECAUSE1         0x7d8
> +#define CSR_MSAVEEPC2           0x7d9
> +#define CSR_MSAVECAUSE2         0x7da
> +#define CSR_MSAVEDCAUSE1        0x7db
> +#define CSR_MSAVEDCAUSE2        0x7dc
> +
> +/* Control CSRs */
> +#define CSR_MPFT_CTL            0x7c5
> +#define CSR_MMISC_CTL           0x7d0
> +#define CSR_MCLK_CTL            0x7df
> +
> +/* Counter related CSRs */
> +#define CSR_MCOUNTERWEN         0x7ce
> +#define CSR_MCOUNTERINTEN       0x7cf
> +#define CSR_MCOUNTERMASK_M      0x7d1
> +#define CSR_MCOUNTERMASK_S      0x7d2
> +#define CSR_MCOUNTERMASK_U      0x7d3
> +#define CSR_MCOUNTEROVF         0x7d4
> +
> +/* Enhanced CLIC CSRs */
> +#define CSR_MIRQ_ENTRY          0x7ec
> +#define CSR_MINTSEL_JAL         0x7ed
> +#define CSR_PUSHMCAUSE          0x7ee
> +#define CSR_PUSHMEPC            0x7ef
> +#define CSR_PUSHMXSTATUS        0x7eb
> +
> +/* Andes Physical Memory Attribute(PMA) CSRs */
> +#define CSR_PMACFG0             0xbc0
> +#define CSR_PMACFG1             0xbc1
> +#define CSR_PMACFG2             0xbc2
> +#define CSR_PMACFG3             0xbc3
> +#define CSR_PMAADDR0            0xbd0
> +#define CSR_PMAADDR1            0xbd1
> +#define CSR_PMAADDR2            0xbd2
> +#define CSR_PMAADDR3            0xbd2
> +#define CSR_PMAADDR4            0xbd4
> +#define CSR_PMAADDR5            0xbd5
> +#define CSR_PMAADDR6            0xbd6
> +#define CSR_PMAADDR7            0xbd7
> +#define CSR_PMAADDR8            0xbd8
> +#define CSR_PMAADDR9            0xbd9
> +#define CSR_PMAADDR10           0xbda
> +#define CSR_PMAADDR11           0xbdb
> +#define CSR_PMAADDR12           0xbdc
> +#define CSR_PMAADDR13           0xbdd
> +#define CSR_PMAADDR14           0xbde
> +#define CSR_PMAADDR15           0xbdf
> +
> +/* ========= AndeStar V5 supervisor mode CSRs ========= */
> +/* Supervisor trap registers */
> +#define CSR_SLIE                0x9c4
> +#define CSR_SLIP                0x9c5
> +#define CSR_SDCAUSE             0x9c9
> +
> +/* Supervisor counter registers */
> +#define CSR_SCOUNTERINTEN       0x9cf
> +#define CSR_SCOUNTERMASK_M      0x9d1
> +#define CSR_SCOUNTERMASK_S      0x9d2
> +#define CSR_SCOUNTERMASK_U      0x9d3
> +#define CSR_SCOUNTEROVF         0x9d4
> +#define CSR_SCOUNTINHIBIT       0x9e0
> +#define CSR_SHPMEVENT3          0x9e3
> +#define CSR_SHPMEVENT4          0x9e4
> +#define CSR_SHPMEVENT5          0x9e5
> +#define CSR_SHPMEVENT6          0x9e6
> +
> +/* Supervisor control registers */
> +#define CSR_SCCTLDATA           0x9cd
> +#define CSR_SMISC_CTL           0x9d0
> +
> +/* ========= AndeStar V5 user mode CSRs ========= */
> +/* User mode control registers */
> +#define CSR_UITB                0x800
> +#define CSR_UCODE               0x801
> +#define CSR_UDCAUSE             0x809
> +#define CSR_UCCTLBEGINADDR      0x80b
> +#define CSR_UCCTLCOMMAND        0x80c
> +#define CSR_WFE                 0x810
> +#define CSR_SLEEPVALUE          0x811
> +#define CSR_TXEVT               0x812

These CSRs should be added in a separate patch.

> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 4ae21cbf9b..460839d006 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -144,6 +144,30 @@ static void set_resetvec(CPURISCVState *env, int resetvec)
>  #endif
>  }
>
> +#if defined(TARGET_RISCV64)

We won't add any new code using `#if defined(TARGET_RISCV64)` This
should apply for RV32 and RV64.

> +// Currently we only have ax25 using this function, to ease Wunused-function,
> +// we put it in TARGET_RISCV64.

Don't use C++ comments

> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[]
> +                             ) {
> +
> +    env->custom_csr_map = g_hash_table_new_full(
> +        g_direct_hash, g_direct_equal, NULL, NULL);
> +
> +    int i;

This should be at the top of the block.

> +
> +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> +        if (csr_map_struct[i].csrno != 0) {
> +            g_hash_table_insert(env->custom_csr_map,
> +                GINT_TO_POINTER(csr_map_struct[i].csrno),
> +                &csr_map_struct[i].csr_opset);
> +        } else {
> +            break;
> +        }
> +    }
> +}
> +#endif
> +
>  static void riscv_any_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> @@ -164,6 +188,11 @@ static void ax25_cpu_init(Object *obj)
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
>      set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>      set_priv_version(env, PRIV_VERSION_1_10_0);
> +
> +    /* setup custom csr handler hash table */
> +    setup_custom_csr(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> +
>  }
>
>  static void rv64_sifive_u_cpu_init(Object *obj)
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index bff9af7f3f..231505f403 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -112,6 +112,7 @@ FIELD(VTYPE, VEDIV, 5, 2)
>  FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
>  FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
>
> +

Don't add a new line here.

>  struct CPURISCVState {
>      target_ulong gpr[32];
>      uint64_t fpr[32]; /* assume both F and D extensions */
> @@ -240,6 +241,14 @@ struct CPURISCVState {
>
>      /* Fields from here on are preserved across CPU reset. */
>      QEMUTimer *timer; /* Internal timer */
> +
> +    // The reason why we have an opset map for custom CSRs and a seperated
> +    // storage map is that we might have heterogeneous architecture, in which
> +    // different harts have different custom CSRs.

Again wrong comment format.

> +    /* Custom CSR opset map */
> +    GHashTable *custom_csr_map;
> +    /* Custom CSR val holder */
> +    void *custom_csr_val;
>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -486,17 +495,26 @@ typedef struct {
>      riscv_csr_op_fn op;
>  } riscv_csr_operations;
>
> +typedef struct {
> +    int csrno;
> +    riscv_csr_operations csr_opset;
> +    } riscv_custom_csr_operations;
> +
>  /* CSR function table constants */
>  enum {
> -    CSR_TABLE_SIZE = 0x1000
> +    CSR_TABLE_SIZE = 0x1000,
> +    MAX_CUSTOM_CSR_NUM = 100
>  };
>
>  /* CSR function table */
> +extern int andes_custom_csr_size;
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>
>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> +
>  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>
>  #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf4599207..e8dfebd1b0 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -259,6 +259,7 @@
>  #define CSR_TDATA1          0x7a1
>  #define CSR_TDATA2          0x7a2
>  #define CSR_TDATA3          0x7a3
> +#define CSR_TINFO           0x7a4

Why is this being added?

This should be a seperate patch.

>
>  /* Debug Mode Registers */
>  #define CSR_DCSR            0x7b0
> @@ -593,3 +594,5 @@
>  #define MIE_SSIE                           (1 << IRQ_S_SOFT)
>  #define MIE_USIE                           (1 << IRQ_U_SOFT)
>  #endif
> +
> +#include "custom_cpu_bits.h"
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fd2e6363f3..6ea2b5e4b0 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -523,6 +523,14 @@ static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
>      return 0;
>  }
>
> +
> +// XXX: This is just a write stub for developing custom CSR handler,
> +// if the behavior of writting such CSR is not presentable in QEMU and doesn't
> +// affect the functionality, just stub it.
> +static int write_stub(CPURISCVState *env, int csrno, target_ulong val) {
> +    return 0;
> +}
> +
>  static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
>  {
>      if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
> @@ -1264,6 +1272,15 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>
>  #endif
>
> +
> +/* Custom CSR related routines and data structures */
> +
> +static gpointer is_custom_csr(CPURISCVState *env, int csrno) {
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;

You don't need ret here.

> +    }
> +
>  /*
>   * riscv_csrrw - read and/or update control and status register
>   *
> @@ -1279,6 +1296,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      int ret;
>      target_ulong old_value;
>      RISCVCPU *cpu = env_archcpu(env);
> +    riscv_csr_operations *csrop;
>
>      /* check privileges and return -1 if check fails */
>  #if !defined(CONFIG_USER_ONLY)
> @@ -1307,27 +1325,37 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
> +    /* try handle_custom_csr */
> +    riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +        is_custom_csr(env, csrno);
> +    if(NULL != custom_csr_opset) {
> +        csrop = custom_csr_opset;
> +        }
> +    else {
> +        csrop = &csr_ops[csrno];
> +        }

I suspect that most CPUs won't have any custom CSRs. As the CSRs are
accessed pretty regularly we want to ensure that a CPU without custom
CSRs won't be slowed down.

Couldn't we set custom_csr_map to NULL by default and only initilise
it if CSRs are added?

Alistair

> +
>      /* check predicate */
> -    if (!csr_ops[csrno].predicate) {
> +    if (!csrop->predicate) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> -    ret = csr_ops[csrno].predicate(env, csrno);
> +    ret = csrop->predicate(env, csrno);
>      if (ret < 0) {
>          return ret;
>      }
>
>      /* execute combined read/write operation if it exists */
> -    if (csr_ops[csrno].op) {
> -        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> +    if (csrop->op) {
> +        return csrop->op(env, csrno, ret_value, new_value, write_mask);
>      }
>
>      /* if no accessor exists then return failure */
> -    if (!csr_ops[csrno].read) {
> +    if (!csrop->read) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
>      /* read old value */
> -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> +    ret = csrop->read(env, csrno, &old_value);
>      if (ret < 0) {
>          return ret;
>      }
> @@ -1335,8 +1363,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      /* write value if writable and write mask set, otherwise drop writes */
>      if (write_mask) {
>          new_value = (old_value & ~write_mask) | (new_value & write_mask);
> -        if (csr_ops[csrno].write) {
> -            ret = csr_ops[csrno].write(env, csrno, new_value);
> +        if (csrop->write) {
> +            ret = csrop->write(env, csrno, new_value);
>              if (ret < 0) {
>                  return ret;
>              }
> @@ -1369,6 +1397,8 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      return ret;
>  }
>
> +#include "csr_andes.inc.c"
> +
>  /* Control and Status Register function table */
>  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      /* User Floating-Point CSRs */
> diff --git a/target/riscv/csr_andes.inc.c b/target/riscv/csr_andes.inc.c
> new file mode 100644
> index 0000000000..6af7c91096
> --- /dev/null
> +++ b/target/riscv/csr_andes.inc.c
> @@ -0,0 +1,153 @@
> +/* Andes Custom Registers */
> +
> +struct andes_csr_val {
> +    target_long uitb;
> +};
> +
> +int andes_custom_csr_size = sizeof(struct andes_csr_val);
> +
> +static int write_uitb(CPURISCVState *env, int csrno, target_ulong val) {
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    andes_csr->uitb = val;
> +    return 0;
> +}
> +
> +static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val) {
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    *val = andes_csr->uitb;
> +    return 0;
> +}
> +
> +static int read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    /* enable pma probe */
> +    *val = 0x40000000;
> +    return 0;
> +}
> +
> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> +#if !defined(CONFIG_USER_ONLY)
> +    /* ==================== AndeStar V5 machine mode CSRs ==================== */
> +    /* Configuration Registers */
> +    {CSR_MICM_CFG,         { "micm_cfg",          any, read_zero, write_stub} },
> +    {CSR_MDCM_CFG,         { "mdcm_cfg",          any, read_zero, write_stub} },
> +    {CSR_MMSC_CFG,         { "mmsc_cfg",          any, read_mmsc_cfg, write_stub} },
> +    {CSR_MMSC_CFG2,        { "mmsc_cfg2",         any, read_zero, write_stub} },
> +    {CSR_MVEC_CFG,         { "mvec_cfg",          any, read_zero, write_stub} },
> +
> +    /* Crash Debug CSRs */
> +    {CSR_MCRASH_STATESAVE,  { "mcrash_statesave",  any, read_zero, write_stub} },
> +    {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
> +
> +    /* Memory CSRs */
> +    {CSR_MILMB,            { "milmb",             any, read_zero, write_stub} },
> +    {CSR_MDLMB,            { "mdlmb",             any, read_zero, write_stub} },
> +    {CSR_MECC_CODE,        { "mecc_code",         any, read_zero, write_stub} },
> +    {CSR_MNVEC,            { "mnvec",             any, read_zero, write_stub} },
> +    {CSR_MCACHE_CTL,       { "mcache_ctl",        any, read_zero, write_stub} },
> +    {CSR_MCCTLBEGINADDR,   { "mcctlbeginaddr",    any, read_zero, write_stub} },
> +    {CSR_MCCTLCOMMAND,     { "mcctlcommand",      any, read_zero, write_stub} },
> +    {CSR_MCCTLDATA,        { "mcctldata",         any, read_zero, write_stub} },
> +    {CSR_MPPIB,            { "mppib",             any, read_zero, write_stub} },
> +    {CSR_MFIOB,            { "mfiob",             any, read_zero, write_stub} },
> +
> +    /* Hardware Stack Protection & Recording */
> +    {CSR_MHSP_CTL,         { "mhsp_ctl",          any, read_zero, write_stub} },
> +    {CSR_MSP_BOUND,        { "msp_bound",         any, read_zero, write_stub} },
> +    {CSR_MSP_BASE,         { "msp_base",          any, read_zero, write_stub} },
> +    {CSR_MXSTATUS,         { "mxstatus",          any, read_zero, write_stub} },
> +    {CSR_MDCAUSE,          { "mdcause",           any, read_zero, write_stub} },
> +    {CSR_MSLIDELEG,        { "mslideleg",         any, read_zero, write_stub} },
> +    {CSR_MSAVESTATUS,      { "msavestatus",       any, read_zero, write_stub} },
> +    {CSR_MSAVEEPC1,        { "msaveepc1",         any, read_zero, write_stub} },
> +    {CSR_MSAVECAUSE1,      { "msavecause1",       any, read_zero, write_stub} },
> +    {CSR_MSAVEEPC2,        { "msaveepc2",         any, read_zero, write_stub} },
> +    {CSR_MSAVECAUSE2,      { "msavecause2",       any, read_zero, write_stub} },
> +    {CSR_MSAVEDCAUSE1,     { "msavedcause1",      any, read_zero, write_stub} },
> +    {CSR_MSAVEDCAUSE2,     { "msavedcause2",      any, read_zero, write_stub} },
> +
> +    /* Control CSRs */
> +    {CSR_MPFT_CTL,         { "mpft_ctl",          any, read_zero, write_stub} },
> +    {CSR_MMISC_CTL,        { "mmisc_ctl",         any, read_zero, write_stub} },
> +    {CSR_MCLK_CTL,         { "mclk_ctl",          any, read_zero, write_stub} },
> +
> +    /* Counter related CSRs */
> +    {CSR_MCOUNTERWEN,      { "mcounterwen",       any, read_zero, write_stub} },
> +    {CSR_MCOUNTERINTEN,    { "mcounterinten",     any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_M,   { "mcountermask_m",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_S,   { "mcountermask_s",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_U,   { "mcountermask_u",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTEROVF,      { "mcounterovf",       any, read_zero, write_stub} },
> +
> +    /* Enhanced CLIC CSRs */
> +    {CSR_MIRQ_ENTRY,       { "mirq_entry",        any, read_zero, write_stub} },
> +    {CSR_MINTSEL_JAL,      { "mintsel_jal",       any, read_zero, write_stub} },
> +    {CSR_PUSHMCAUSE,       { "pushmcause",        any, read_zero, write_stub} },
> +    {CSR_PUSHMEPC,         { "pushmepc",          any, read_zero, write_stub} },
> +    {CSR_PUSHMXSTATUS,     { "pushmxstatus",      any, read_zero, write_stub} },
> +
> +    /* Andes Physical Memory Attribute(PMA) CSRs */
> +    {CSR_PMACFG0,          { "pmacfg0",           any, read_zero, write_stub} },
> +    {CSR_PMACFG1,          { "pmacfg1",           any, read_zero, write_stub} },
> +    {CSR_PMACFG2,          { "pmacfg2",           any, read_zero, write_stub} },
> +    {CSR_PMACFG3,          { "pmacfg3",           any, read_zero, write_stub} },
> +    {CSR_PMAADDR0,         { "pmaaddr0",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR1,         { "pmaaddr1",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR2,         { "pmaaddr2",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR3,         { "pmaaddr3",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR4,         { "pmaaddr4",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR5,         { "pmaaddr5",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR6,         { "pmaaddr6",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR7,         { "pmaaddr7",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR8,         { "pmaaddr8",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR9,         { "pmaaddr9",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR10,        { "pmaaddr10",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR11,        { "pmaaddr11",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR12,        { "pmaaddr12",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR13,        { "pmaaddr13",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR14,        { "pmaaddr14",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR15,        { "pmaaddr15",         any, read_zero, write_stub} },
> +
> +    /* Debug/Trace Registers (shared with Debug Mode) */
> +    {CSR_TSELECT,          { "tselect",           any, read_zero, write_stub} },
> +    {CSR_TDATA1,           { "tdata1",            any, read_zero, write_stub} },
> +    {CSR_TDATA2,           { "tdata2",            any, read_zero, write_stub} },
> +    {CSR_TDATA3,           { "tdata3",            any, read_zero, write_stub} },
> +    {CSR_TINFO,            { "tinfo",             any, read_zero, write_stub} },
> +
> +    /* ================== AndeStar V5 supervisor mode CSRs ================== */
> +    /* Supervisor trap registers */
> +    {CSR_SLIE,             { "slie",              any, read_zero, write_stub} },
> +    {CSR_SLIP,             { "slip",              any, read_zero, write_stub} },
> +    {CSR_SDCAUSE,          { "sdcause",           any, read_zero, write_stub} },
> +
> +    /* Supervisor counter registers */
> +    {CSR_SCOUNTERINTEN,    { "scounterinten",     any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_M,   { "scountermask_m",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_S,   { "scountermask_s",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_U,   { "scountermask_u",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTEROVF,      { "scounterovf",       any, read_zero, write_stub} },
> +    {CSR_SCOUNTINHIBIT,    { "scountinhibit",     any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT3,       { "shpmevent3",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT4,       { "shpmevent4",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT5,       { "shpmevent5",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT6,       { "shpmevent6",        any, read_zero, write_stub} },
> +
> +    /* Supervisor control registers */
> +    {CSR_SCCTLDATA,        { "scctldata",         any, read_zero, write_stub} },
> +    {CSR_SMISC_CTL,        { "smisc_ctl",         any, read_zero, write_stub} },
> +
> +    /* ===================== AndeStar V5 user mode CSRs ===================== */
> +    /* User mode control registers */
> +    {CSR_UITB,             { "uitb",              any, read_uitb, write_uitb} },
> +    {CSR_UCODE,            { "ucode",             any, read_zero, write_stub} },
> +    {CSR_UDCAUSE,          { "udcause",           any, read_zero, write_stub} },
> +    {CSR_UCCTLBEGINADDR,   { "ucctlbeginaddr",    any, read_zero, write_stub} },
> +    {CSR_UCCTLCOMMAND,     { "ucctlcommand",      any, read_zero, write_stub} },
> +    {CSR_WFE,              { "wfe",               any, read_zero, write_stub} },
> +    {CSR_SLEEPVALUE,       { "sleepvalue",        any, read_zero, write_stub} },
> +    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
> +    {0, { "", NULL, NULL, NULL } },
> +#endif
> +    };
> +
> diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
> new file mode 100644
> index 0000000000..072c97728a
> --- /dev/null
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -0,0 +1,3 @@
> +//XXX Maybe we should introduce a configure option to toggle different vendor
> +// CSR bits definition ?
> +#include "andes_cpu_bits.h"
> --
> 2.31.1
>


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

* Re: [RFC PATCH v3 2/2] Adding preliminary custom/vendor CSR handling mechanism
@ 2021-06-10 22:57     ` Alistair Francis
  0 siblings, 0 replies; 14+ messages in thread
From: Alistair Francis @ 2021-06-10 22:57 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Alan Quey-Liang Kao((((((((((),
	Dylan Jhong

On Fri, Jun 11, 2021 at 12:44 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>
>
> For now we add a custom CSR handling mechanism to handle non-standard CSR read
> or write.
>
> The write_stub() and read_zero() are provided for quick placeholder usage if
> such CSRs' behavior are expected to fail-over in its user code.
>
> For demonstration, we modify Andes Technology AX25 to showcase how the such
> mechanism works and how the UITB and MMSC_CFG CSR could be emulated.

Thanks for the patch!

This patch probably needs to be split into at least 2 different
patches. One adding the implementation and a second one adding the
Andes custom CSRs.

You also should run checkpatch on all patches:
https://wiki.qemu.org/Contribute/SubmitAPatch#Use_the_QEMU_coding_style

You are missing a SoB line here.

> ---
>  target/riscv/andes_cpu_bits.h  | 113 ++++++++++++++++++++++++
>  target/riscv/cpu.c             |  29 +++++++
>  target/riscv/cpu.h             |  20 ++++-
>  target/riscv/cpu_bits.h        |   3 +
>  target/riscv/csr.c             |  46 ++++++++--
>  target/riscv/csr_andes.inc.c   | 153 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_cpu_bits.h |   3 +
>  7 files changed, 358 insertions(+), 9 deletions(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.inc.c
>  create mode 100644 target/riscv/custom_cpu_bits.h
>
> diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> new file mode 100644
> index 0000000000..8dee58a2c2
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,113 @@
> +/* ========= AndeStar V5 machine mode CSRs ========= */
> +/* Configuration Registers */
> +#define CSR_MICM_CFG            0xfc0
> +#define CSR_MDCM_CFG            0xfc1
> +#define CSR_MMSC_CFG            0xfc2
> +#define CSR_MMSC_CFG2           0xfc3
> +#define CSR_MVEC_CFG            0xfc7
> +
> +/* Crash Debug CSRs */
> +#define CSR_MCRASH_STATESAVE    0xfc8
> +#define CSR_MSTATUS_CRASHSAVE   0xfc9
> +
> +/* Memory CSRs */
> +#define CSR_MILMB               0x7c0
> +#define CSR_MDLMB               0x7c1
> +#define CSR_MECC_CODE           0x7C2
> +#define CSR_MNVEC               0x7c3
> +#define CSR_MCACHE_CTL          0x7ca
> +#define CSR_MCCTLBEGINADDR      0x7cb
> +#define CSR_MCCTLCOMMAND        0x7cc
> +#define CSR_MCCTLDATA           0x7cd
> +#define CSR_MPPIB               0x7f0
> +#define CSR_MFIOB               0x7f1
> +
> +/* Hardware Stack Protection & Recording */
> +#define CSR_MHSP_CTL            0x7c6
> +#define CSR_MSP_BOUND           0x7c7
> +#define CSR_MSP_BASE            0x7c8
> +#define CSR_MXSTATUS            0x7c4
> +#define CSR_MDCAUSE             0x7c9
> +#define CSR_MSLIDELEG           0x7d5
> +#define CSR_MSAVESTATUS         0x7d6
> +#define CSR_MSAVEEPC1           0x7d7
> +#define CSR_MSAVECAUSE1         0x7d8
> +#define CSR_MSAVEEPC2           0x7d9
> +#define CSR_MSAVECAUSE2         0x7da
> +#define CSR_MSAVEDCAUSE1        0x7db
> +#define CSR_MSAVEDCAUSE2        0x7dc
> +
> +/* Control CSRs */
> +#define CSR_MPFT_CTL            0x7c5
> +#define CSR_MMISC_CTL           0x7d0
> +#define CSR_MCLK_CTL            0x7df
> +
> +/* Counter related CSRs */
> +#define CSR_MCOUNTERWEN         0x7ce
> +#define CSR_MCOUNTERINTEN       0x7cf
> +#define CSR_MCOUNTERMASK_M      0x7d1
> +#define CSR_MCOUNTERMASK_S      0x7d2
> +#define CSR_MCOUNTERMASK_U      0x7d3
> +#define CSR_MCOUNTEROVF         0x7d4
> +
> +/* Enhanced CLIC CSRs */
> +#define CSR_MIRQ_ENTRY          0x7ec
> +#define CSR_MINTSEL_JAL         0x7ed
> +#define CSR_PUSHMCAUSE          0x7ee
> +#define CSR_PUSHMEPC            0x7ef
> +#define CSR_PUSHMXSTATUS        0x7eb
> +
> +/* Andes Physical Memory Attribute(PMA) CSRs */
> +#define CSR_PMACFG0             0xbc0
> +#define CSR_PMACFG1             0xbc1
> +#define CSR_PMACFG2             0xbc2
> +#define CSR_PMACFG3             0xbc3
> +#define CSR_PMAADDR0            0xbd0
> +#define CSR_PMAADDR1            0xbd1
> +#define CSR_PMAADDR2            0xbd2
> +#define CSR_PMAADDR3            0xbd2
> +#define CSR_PMAADDR4            0xbd4
> +#define CSR_PMAADDR5            0xbd5
> +#define CSR_PMAADDR6            0xbd6
> +#define CSR_PMAADDR7            0xbd7
> +#define CSR_PMAADDR8            0xbd8
> +#define CSR_PMAADDR9            0xbd9
> +#define CSR_PMAADDR10           0xbda
> +#define CSR_PMAADDR11           0xbdb
> +#define CSR_PMAADDR12           0xbdc
> +#define CSR_PMAADDR13           0xbdd
> +#define CSR_PMAADDR14           0xbde
> +#define CSR_PMAADDR15           0xbdf
> +
> +/* ========= AndeStar V5 supervisor mode CSRs ========= */
> +/* Supervisor trap registers */
> +#define CSR_SLIE                0x9c4
> +#define CSR_SLIP                0x9c5
> +#define CSR_SDCAUSE             0x9c9
> +
> +/* Supervisor counter registers */
> +#define CSR_SCOUNTERINTEN       0x9cf
> +#define CSR_SCOUNTERMASK_M      0x9d1
> +#define CSR_SCOUNTERMASK_S      0x9d2
> +#define CSR_SCOUNTERMASK_U      0x9d3
> +#define CSR_SCOUNTEROVF         0x9d4
> +#define CSR_SCOUNTINHIBIT       0x9e0
> +#define CSR_SHPMEVENT3          0x9e3
> +#define CSR_SHPMEVENT4          0x9e4
> +#define CSR_SHPMEVENT5          0x9e5
> +#define CSR_SHPMEVENT6          0x9e6
> +
> +/* Supervisor control registers */
> +#define CSR_SCCTLDATA           0x9cd
> +#define CSR_SMISC_CTL           0x9d0
> +
> +/* ========= AndeStar V5 user mode CSRs ========= */
> +/* User mode control registers */
> +#define CSR_UITB                0x800
> +#define CSR_UCODE               0x801
> +#define CSR_UDCAUSE             0x809
> +#define CSR_UCCTLBEGINADDR      0x80b
> +#define CSR_UCCTLCOMMAND        0x80c
> +#define CSR_WFE                 0x810
> +#define CSR_SLEEPVALUE          0x811
> +#define CSR_TXEVT               0x812

These CSRs should be added in a separate patch.

> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 4ae21cbf9b..460839d006 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -144,6 +144,30 @@ static void set_resetvec(CPURISCVState *env, int resetvec)
>  #endif
>  }
>
> +#if defined(TARGET_RISCV64)

We won't add any new code using `#if defined(TARGET_RISCV64)` This
should apply for RV32 and RV64.

> +// Currently we only have ax25 using this function, to ease Wunused-function,
> +// we put it in TARGET_RISCV64.

Don't use C++ comments

> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[]
> +                             ) {
> +
> +    env->custom_csr_map = g_hash_table_new_full(
> +        g_direct_hash, g_direct_equal, NULL, NULL);
> +
> +    int i;

This should be at the top of the block.

> +
> +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> +        if (csr_map_struct[i].csrno != 0) {
> +            g_hash_table_insert(env->custom_csr_map,
> +                GINT_TO_POINTER(csr_map_struct[i].csrno),
> +                &csr_map_struct[i].csr_opset);
> +        } else {
> +            break;
> +        }
> +    }
> +}
> +#endif
> +
>  static void riscv_any_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> @@ -164,6 +188,11 @@ static void ax25_cpu_init(Object *obj)
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
>      set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>      set_priv_version(env, PRIV_VERSION_1_10_0);
> +
> +    /* setup custom csr handler hash table */
> +    setup_custom_csr(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> +
>  }
>
>  static void rv64_sifive_u_cpu_init(Object *obj)
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index bff9af7f3f..231505f403 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -112,6 +112,7 @@ FIELD(VTYPE, VEDIV, 5, 2)
>  FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
>  FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
>
> +

Don't add a new line here.

>  struct CPURISCVState {
>      target_ulong gpr[32];
>      uint64_t fpr[32]; /* assume both F and D extensions */
> @@ -240,6 +241,14 @@ struct CPURISCVState {
>
>      /* Fields from here on are preserved across CPU reset. */
>      QEMUTimer *timer; /* Internal timer */
> +
> +    // The reason why we have an opset map for custom CSRs and a seperated
> +    // storage map is that we might have heterogeneous architecture, in which
> +    // different harts have different custom CSRs.

Again wrong comment format.

> +    /* Custom CSR opset map */
> +    GHashTable *custom_csr_map;
> +    /* Custom CSR val holder */
> +    void *custom_csr_val;
>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -486,17 +495,26 @@ typedef struct {
>      riscv_csr_op_fn op;
>  } riscv_csr_operations;
>
> +typedef struct {
> +    int csrno;
> +    riscv_csr_operations csr_opset;
> +    } riscv_custom_csr_operations;
> +
>  /* CSR function table constants */
>  enum {
> -    CSR_TABLE_SIZE = 0x1000
> +    CSR_TABLE_SIZE = 0x1000,
> +    MAX_CUSTOM_CSR_NUM = 100
>  };
>
>  /* CSR function table */
> +extern int andes_custom_csr_size;
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>
>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> +
>  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>
>  #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf4599207..e8dfebd1b0 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -259,6 +259,7 @@
>  #define CSR_TDATA1          0x7a1
>  #define CSR_TDATA2          0x7a2
>  #define CSR_TDATA3          0x7a3
> +#define CSR_TINFO           0x7a4

Why is this being added?

This should be a seperate patch.

>
>  /* Debug Mode Registers */
>  #define CSR_DCSR            0x7b0
> @@ -593,3 +594,5 @@
>  #define MIE_SSIE                           (1 << IRQ_S_SOFT)
>  #define MIE_USIE                           (1 << IRQ_U_SOFT)
>  #endif
> +
> +#include "custom_cpu_bits.h"
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fd2e6363f3..6ea2b5e4b0 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -523,6 +523,14 @@ static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
>      return 0;
>  }
>
> +
> +// XXX: This is just a write stub for developing custom CSR handler,
> +// if the behavior of writting such CSR is not presentable in QEMU and doesn't
> +// affect the functionality, just stub it.
> +static int write_stub(CPURISCVState *env, int csrno, target_ulong val) {
> +    return 0;
> +}
> +
>  static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
>  {
>      if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
> @@ -1264,6 +1272,15 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>
>  #endif
>
> +
> +/* Custom CSR related routines and data structures */
> +
> +static gpointer is_custom_csr(CPURISCVState *env, int csrno) {
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;

You don't need ret here.

> +    }
> +
>  /*
>   * riscv_csrrw - read and/or update control and status register
>   *
> @@ -1279,6 +1296,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      int ret;
>      target_ulong old_value;
>      RISCVCPU *cpu = env_archcpu(env);
> +    riscv_csr_operations *csrop;
>
>      /* check privileges and return -1 if check fails */
>  #if !defined(CONFIG_USER_ONLY)
> @@ -1307,27 +1325,37 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
> +    /* try handle_custom_csr */
> +    riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +        is_custom_csr(env, csrno);
> +    if(NULL != custom_csr_opset) {
> +        csrop = custom_csr_opset;
> +        }
> +    else {
> +        csrop = &csr_ops[csrno];
> +        }

I suspect that most CPUs won't have any custom CSRs. As the CSRs are
accessed pretty regularly we want to ensure that a CPU without custom
CSRs won't be slowed down.

Couldn't we set custom_csr_map to NULL by default and only initilise
it if CSRs are added?

Alistair

> +
>      /* check predicate */
> -    if (!csr_ops[csrno].predicate) {
> +    if (!csrop->predicate) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> -    ret = csr_ops[csrno].predicate(env, csrno);
> +    ret = csrop->predicate(env, csrno);
>      if (ret < 0) {
>          return ret;
>      }
>
>      /* execute combined read/write operation if it exists */
> -    if (csr_ops[csrno].op) {
> -        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> +    if (csrop->op) {
> +        return csrop->op(env, csrno, ret_value, new_value, write_mask);
>      }
>
>      /* if no accessor exists then return failure */
> -    if (!csr_ops[csrno].read) {
> +    if (!csrop->read) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
>      /* read old value */
> -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> +    ret = csrop->read(env, csrno, &old_value);
>      if (ret < 0) {
>          return ret;
>      }
> @@ -1335,8 +1363,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      /* write value if writable and write mask set, otherwise drop writes */
>      if (write_mask) {
>          new_value = (old_value & ~write_mask) | (new_value & write_mask);
> -        if (csr_ops[csrno].write) {
> -            ret = csr_ops[csrno].write(env, csrno, new_value);
> +        if (csrop->write) {
> +            ret = csrop->write(env, csrno, new_value);
>              if (ret < 0) {
>                  return ret;
>              }
> @@ -1369,6 +1397,8 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      return ret;
>  }
>
> +#include "csr_andes.inc.c"
> +
>  /* Control and Status Register function table */
>  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      /* User Floating-Point CSRs */
> diff --git a/target/riscv/csr_andes.inc.c b/target/riscv/csr_andes.inc.c
> new file mode 100644
> index 0000000000..6af7c91096
> --- /dev/null
> +++ b/target/riscv/csr_andes.inc.c
> @@ -0,0 +1,153 @@
> +/* Andes Custom Registers */
> +
> +struct andes_csr_val {
> +    target_long uitb;
> +};
> +
> +int andes_custom_csr_size = sizeof(struct andes_csr_val);
> +
> +static int write_uitb(CPURISCVState *env, int csrno, target_ulong val) {
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    andes_csr->uitb = val;
> +    return 0;
> +}
> +
> +static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val) {
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    *val = andes_csr->uitb;
> +    return 0;
> +}
> +
> +static int read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    /* enable pma probe */
> +    *val = 0x40000000;
> +    return 0;
> +}
> +
> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> +#if !defined(CONFIG_USER_ONLY)
> +    /* ==================== AndeStar V5 machine mode CSRs ==================== */
> +    /* Configuration Registers */
> +    {CSR_MICM_CFG,         { "micm_cfg",          any, read_zero, write_stub} },
> +    {CSR_MDCM_CFG,         { "mdcm_cfg",          any, read_zero, write_stub} },
> +    {CSR_MMSC_CFG,         { "mmsc_cfg",          any, read_mmsc_cfg, write_stub} },
> +    {CSR_MMSC_CFG2,        { "mmsc_cfg2",         any, read_zero, write_stub} },
> +    {CSR_MVEC_CFG,         { "mvec_cfg",          any, read_zero, write_stub} },
> +
> +    /* Crash Debug CSRs */
> +    {CSR_MCRASH_STATESAVE,  { "mcrash_statesave",  any, read_zero, write_stub} },
> +    {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
> +
> +    /* Memory CSRs */
> +    {CSR_MILMB,            { "milmb",             any, read_zero, write_stub} },
> +    {CSR_MDLMB,            { "mdlmb",             any, read_zero, write_stub} },
> +    {CSR_MECC_CODE,        { "mecc_code",         any, read_zero, write_stub} },
> +    {CSR_MNVEC,            { "mnvec",             any, read_zero, write_stub} },
> +    {CSR_MCACHE_CTL,       { "mcache_ctl",        any, read_zero, write_stub} },
> +    {CSR_MCCTLBEGINADDR,   { "mcctlbeginaddr",    any, read_zero, write_stub} },
> +    {CSR_MCCTLCOMMAND,     { "mcctlcommand",      any, read_zero, write_stub} },
> +    {CSR_MCCTLDATA,        { "mcctldata",         any, read_zero, write_stub} },
> +    {CSR_MPPIB,            { "mppib",             any, read_zero, write_stub} },
> +    {CSR_MFIOB,            { "mfiob",             any, read_zero, write_stub} },
> +
> +    /* Hardware Stack Protection & Recording */
> +    {CSR_MHSP_CTL,         { "mhsp_ctl",          any, read_zero, write_stub} },
> +    {CSR_MSP_BOUND,        { "msp_bound",         any, read_zero, write_stub} },
> +    {CSR_MSP_BASE,         { "msp_base",          any, read_zero, write_stub} },
> +    {CSR_MXSTATUS,         { "mxstatus",          any, read_zero, write_stub} },
> +    {CSR_MDCAUSE,          { "mdcause",           any, read_zero, write_stub} },
> +    {CSR_MSLIDELEG,        { "mslideleg",         any, read_zero, write_stub} },
> +    {CSR_MSAVESTATUS,      { "msavestatus",       any, read_zero, write_stub} },
> +    {CSR_MSAVEEPC1,        { "msaveepc1",         any, read_zero, write_stub} },
> +    {CSR_MSAVECAUSE1,      { "msavecause1",       any, read_zero, write_stub} },
> +    {CSR_MSAVEEPC2,        { "msaveepc2",         any, read_zero, write_stub} },
> +    {CSR_MSAVECAUSE2,      { "msavecause2",       any, read_zero, write_stub} },
> +    {CSR_MSAVEDCAUSE1,     { "msavedcause1",      any, read_zero, write_stub} },
> +    {CSR_MSAVEDCAUSE2,     { "msavedcause2",      any, read_zero, write_stub} },
> +
> +    /* Control CSRs */
> +    {CSR_MPFT_CTL,         { "mpft_ctl",          any, read_zero, write_stub} },
> +    {CSR_MMISC_CTL,        { "mmisc_ctl",         any, read_zero, write_stub} },
> +    {CSR_MCLK_CTL,         { "mclk_ctl",          any, read_zero, write_stub} },
> +
> +    /* Counter related CSRs */
> +    {CSR_MCOUNTERWEN,      { "mcounterwen",       any, read_zero, write_stub} },
> +    {CSR_MCOUNTERINTEN,    { "mcounterinten",     any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_M,   { "mcountermask_m",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_S,   { "mcountermask_s",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_U,   { "mcountermask_u",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTEROVF,      { "mcounterovf",       any, read_zero, write_stub} },
> +
> +    /* Enhanced CLIC CSRs */
> +    {CSR_MIRQ_ENTRY,       { "mirq_entry",        any, read_zero, write_stub} },
> +    {CSR_MINTSEL_JAL,      { "mintsel_jal",       any, read_zero, write_stub} },
> +    {CSR_PUSHMCAUSE,       { "pushmcause",        any, read_zero, write_stub} },
> +    {CSR_PUSHMEPC,         { "pushmepc",          any, read_zero, write_stub} },
> +    {CSR_PUSHMXSTATUS,     { "pushmxstatus",      any, read_zero, write_stub} },
> +
> +    /* Andes Physical Memory Attribute(PMA) CSRs */
> +    {CSR_PMACFG0,          { "pmacfg0",           any, read_zero, write_stub} },
> +    {CSR_PMACFG1,          { "pmacfg1",           any, read_zero, write_stub} },
> +    {CSR_PMACFG2,          { "pmacfg2",           any, read_zero, write_stub} },
> +    {CSR_PMACFG3,          { "pmacfg3",           any, read_zero, write_stub} },
> +    {CSR_PMAADDR0,         { "pmaaddr0",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR1,         { "pmaaddr1",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR2,         { "pmaaddr2",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR3,         { "pmaaddr3",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR4,         { "pmaaddr4",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR5,         { "pmaaddr5",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR6,         { "pmaaddr6",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR7,         { "pmaaddr7",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR8,         { "pmaaddr8",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR9,         { "pmaaddr9",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR10,        { "pmaaddr10",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR11,        { "pmaaddr11",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR12,        { "pmaaddr12",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR13,        { "pmaaddr13",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR14,        { "pmaaddr14",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR15,        { "pmaaddr15",         any, read_zero, write_stub} },
> +
> +    /* Debug/Trace Registers (shared with Debug Mode) */
> +    {CSR_TSELECT,          { "tselect",           any, read_zero, write_stub} },
> +    {CSR_TDATA1,           { "tdata1",            any, read_zero, write_stub} },
> +    {CSR_TDATA2,           { "tdata2",            any, read_zero, write_stub} },
> +    {CSR_TDATA3,           { "tdata3",            any, read_zero, write_stub} },
> +    {CSR_TINFO,            { "tinfo",             any, read_zero, write_stub} },
> +
> +    /* ================== AndeStar V5 supervisor mode CSRs ================== */
> +    /* Supervisor trap registers */
> +    {CSR_SLIE,             { "slie",              any, read_zero, write_stub} },
> +    {CSR_SLIP,             { "slip",              any, read_zero, write_stub} },
> +    {CSR_SDCAUSE,          { "sdcause",           any, read_zero, write_stub} },
> +
> +    /* Supervisor counter registers */
> +    {CSR_SCOUNTERINTEN,    { "scounterinten",     any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_M,   { "scountermask_m",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_S,   { "scountermask_s",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_U,   { "scountermask_u",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTEROVF,      { "scounterovf",       any, read_zero, write_stub} },
> +    {CSR_SCOUNTINHIBIT,    { "scountinhibit",     any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT3,       { "shpmevent3",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT4,       { "shpmevent4",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT5,       { "shpmevent5",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT6,       { "shpmevent6",        any, read_zero, write_stub} },
> +
> +    /* Supervisor control registers */
> +    {CSR_SCCTLDATA,        { "scctldata",         any, read_zero, write_stub} },
> +    {CSR_SMISC_CTL,        { "smisc_ctl",         any, read_zero, write_stub} },
> +
> +    /* ===================== AndeStar V5 user mode CSRs ===================== */
> +    /* User mode control registers */
> +    {CSR_UITB,             { "uitb",              any, read_uitb, write_uitb} },
> +    {CSR_UCODE,            { "ucode",             any, read_zero, write_stub} },
> +    {CSR_UDCAUSE,          { "udcause",           any, read_zero, write_stub} },
> +    {CSR_UCCTLBEGINADDR,   { "ucctlbeginaddr",    any, read_zero, write_stub} },
> +    {CSR_UCCTLCOMMAND,     { "ucctlcommand",      any, read_zero, write_stub} },
> +    {CSR_WFE,              { "wfe",               any, read_zero, write_stub} },
> +    {CSR_SLEEPVALUE,       { "sleepvalue",        any, read_zero, write_stub} },
> +    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
> +    {0, { "", NULL, NULL, NULL } },
> +#endif
> +    };
> +
> diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
> new file mode 100644
> index 0000000000..072c97728a
> --- /dev/null
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -0,0 +1,3 @@
> +//XXX Maybe we should introduce a configure option to toggle different vendor
> +// CSR bits definition ?
> +#include "andes_cpu_bits.h"
> --
> 2.31.1
>


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

* Re: [RFC PATCH v3 1/2] Adding Andes AX25 CPU model
  2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
@ 2021-06-10 23:22     ` Bin Meng
  -1 siblings, 0 replies; 14+ messages in thread
From: Bin Meng @ 2021-06-10 23:22 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: Dylan Jhong, open list:RISC-V, Alan Kao, wangjunqiang, Bin Meng,
	qemu-devel@nongnu.org Developers, Alistair Francis

Hi Ruinland,

On Thu, Jun 10, 2021 at 10:45 PM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>
>
> Adding the skeleton of Andes Technology AX25 CPU model for the future commits,
> which will utilize custom/vendor CSR handling mechaism.

typo: mechanism

> ---
>  target/riscv/cpu.c | 8 ++++++++
>  target/riscv/cpu.h | 1 +
>  2 files changed, 9 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ddea8fbeeb..4ae21cbf9b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -159,6 +159,13 @@ static void rv64_base_cpu_init(Object *obj)
>      set_misa(env, RV64);
>  }
>
> +static void ax25_cpu_init(Object *obj)
> +{
> +    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> +    set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
> +
>  static void rv64_sifive_u_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> @@ -705,6 +712,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
>  #elif defined(TARGET_RISCV64)
>      DEFINE_CPU(TYPE_RISCV_CPU_BASE64,           rv64_base_cpu_init),
> +    DEFINE_CPU(TYPE_RISCV_CPU_AX25,             ax25_cpu_init),

What about the 32-bit variant of A25, and the SMP variant of A25MP/AX25MP?

Also how about the latest A45 (RV32) and AX45 (RV64)?

How should we name these? I think we may need to name this using the
SMP variant name, no?

>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64_sifive_e_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64_sifive_u_cpu_init),
>  #endif

Regards,
Bin


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

* Re: [RFC PATCH v3 1/2] Adding Andes AX25 CPU model
@ 2021-06-10 23:22     ` Bin Meng
  0 siblings, 0 replies; 14+ messages in thread
From: Bin Meng @ 2021-06-10 23:22 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, Dylan Jhong,
	Alan Kao, wangjunqiang, Bin Meng, Alistair Francis

Hi Ruinland,

On Thu, Jun 10, 2021 at 10:45 PM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinaldn ChuanTzu Tsai <ruinland@andestech.com>
>
> Adding the skeleton of Andes Technology AX25 CPU model for the future commits,
> which will utilize custom/vendor CSR handling mechaism.

typo: mechanism

> ---
>  target/riscv/cpu.c | 8 ++++++++
>  target/riscv/cpu.h | 1 +
>  2 files changed, 9 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ddea8fbeeb..4ae21cbf9b 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -159,6 +159,13 @@ static void rv64_base_cpu_init(Object *obj)
>      set_misa(env, RV64);
>  }
>
> +static void ax25_cpu_init(Object *obj)
> +{
> +    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> +    set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
> +
>  static void rv64_sifive_u_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> @@ -705,6 +712,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
>  #elif defined(TARGET_RISCV64)
>      DEFINE_CPU(TYPE_RISCV_CPU_BASE64,           rv64_base_cpu_init),
> +    DEFINE_CPU(TYPE_RISCV_CPU_AX25,             ax25_cpu_init),

What about the 32-bit variant of A25, and the SMP variant of A25MP/AX25MP?

Also how about the latest A45 (RV32) and AX45 (RV64)?

How should we name these? I think we may need to name this using the
SMP variant name, no?

>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64_sifive_e_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64_sifive_u_cpu_init),
>  #endif

Regards,
Bin


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

end of thread, other threads:[~2021-06-10 23:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-10 14:44 [RFC PATCH v3 0/2] Proposing custom CSR handling logic Ruinland Chuan-Tzu Tsai
2021-06-10 14:44 ` Ruinland Chuan-Tzu Tsai
2021-06-10 14:44 ` [RFC PATCH v3 1/2] Adding Andes AX25 CPU model Ruinland Chuan-Tzu Tsai
2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
2021-06-10 22:49   ` Alistair Francis
2021-06-10 22:49     ` Alistair Francis
2021-06-10 23:22   ` Bin Meng
2021-06-10 23:22     ` Bin Meng
2021-06-10 14:44 ` [RFC PATCH v3 2/2] Adding preliminary custom/vendor CSR handling mechanism Ruinland Chuan-Tzu Tsai
2021-06-10 14:44   ` Ruinland Chuan-Tzu Tsai
2021-06-10 16:19   ` Richard Henderson
2021-06-10 16:19     ` Richard Henderson
2021-06-10 22:57   ` Alistair Francis
2021-06-10 22:57     ` Alistair Francis

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.