All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
  To: alistair23, wangjunqiang, bmeng.cn
  Cc: ycliang, alankao, dylan, qemu-devel, Ruinland Chuan-Tzu Tsai, qemu-riscv

Hi Alistair, Bin and all :

Sorry for bumping this stale topic.
As our last discussion, I have removed Kconfigs and meson options.
The custom CSR logic is in-built by default and whether a custom CSR
is presented on the accessing hart will be checked at runtime.

Changes from V4 :
Remove Kconfigs and meson options.
Make custom CSR handling logic self-contained.
Use g_hash_table_new instead of g_hash_table_new_full.

The performance slowdown could be easily tested with a simple program
running on linux-user mode :

/* test_csr.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

int main (int ac, char *av[]) {
   struct  timeval start;
   struct  timeval end;
   gettimeofday(&start,NULL);
   unsigned int loop_n = 999999 ;
   unsigned char i;
   unsigned char o;
   do {
       for(i=0; i<32; i++) { 
       #if defined(FCSR)
       __asm__("csrw fcsr, %0;"::"r"(i));
       __asm__("csrr %0, fcsr;":"=r"(o));
       #elif defined(UITB)
       __asm__("csrw 0x800, %0;"::"r"(i));
       __asm__("csrr %0, 0x800;":"=r"(o));
       #endif
       }
       --loop_n;
   } while (loop_n > 0);
   gettimeofday(&end,NULL);
   unsigned long diff = 1000000 * 
(end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec;
   printf("%f\n", (double)(diff)/1000000);
   return 0;
}

$ riscv64-linux-gnu-gcc -static -DUITB ./test_csr.c -o ./u
$ riscv64-linux-gnu-gcc -static -DFCSR ./test_csr.c -o ./f
$ qemu-riscv64 ./{u,f}

Cordially yours,
Ruinland Chuan-Tzu Tsai

Ruinland Chuan-Tzu Tsai (3):
  riscv: Adding Andes A25 and AX25 cpu models
  riscv: Introduce custom CSR hooks to riscv_csrrw()
  riscv: Enable custom CSR support for Andes AX25 and A25 CPUs

 target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
 target/riscv/cpu.c             |  39 +++++++
 target/riscv/cpu.h             |  15 ++-
 target/riscv/csr.c             |  38 +++++--
 target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
 target/riscv/custom_csr_defs.h |   8 ++
 target/riscv/meson.build       |   1 +
 7 files changed, 404 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.c
 create mode 100644 target/riscv/custom_csr_defs.h

-- 
2.25.1



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

* [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
  To: alistair23, wangjunqiang, bmeng.cn
  Cc: qemu-devel, qemu-riscv, ycliang, alankao, dylan, Ruinland Chuan-Tzu Tsai

Hi Alistair, Bin and all :

Sorry for bumping this stale topic.
As our last discussion, I have removed Kconfigs and meson options.
The custom CSR logic is in-built by default and whether a custom CSR
is presented on the accessing hart will be checked at runtime.

Changes from V4 :
Remove Kconfigs and meson options.
Make custom CSR handling logic self-contained.
Use g_hash_table_new instead of g_hash_table_new_full.

The performance slowdown could be easily tested with a simple program
running on linux-user mode :

/* test_csr.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

int main (int ac, char *av[]) {
   struct  timeval start;
   struct  timeval end;
   gettimeofday(&start,NULL);
   unsigned int loop_n = 999999 ;
   unsigned char i;
   unsigned char o;
   do {
       for(i=0; i<32; i++) { 
       #if defined(FCSR)
       __asm__("csrw fcsr, %0;"::"r"(i));
       __asm__("csrr %0, fcsr;":"=r"(o));
       #elif defined(UITB)
       __asm__("csrw 0x800, %0;"::"r"(i));
       __asm__("csrr %0, 0x800;":"=r"(o));
       #endif
       }
       --loop_n;
   } while (loop_n > 0);
   gettimeofday(&end,NULL);
   unsigned long diff = 1000000 * 
(end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec;
   printf("%f\n", (double)(diff)/1000000);
   return 0;
}

$ riscv64-linux-gnu-gcc -static -DUITB ./test_csr.c -o ./u
$ riscv64-linux-gnu-gcc -static -DFCSR ./test_csr.c -o ./f
$ qemu-riscv64 ./{u,f}

Cordially yours,
Ruinland Chuan-Tzu Tsai

Ruinland Chuan-Tzu Tsai (3):
  riscv: Adding Andes A25 and AX25 cpu models
  riscv: Introduce custom CSR hooks to riscv_csrrw()
  riscv: Enable custom CSR support for Andes AX25 and A25 CPUs

 target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
 target/riscv/cpu.c             |  39 +++++++
 target/riscv/cpu.h             |  15 ++-
 target/riscv/csr.c             |  38 +++++--
 target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
 target/riscv/custom_csr_defs.h |   8 ++
 target/riscv/meson.build       |   1 +
 7 files changed, 404 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.c
 create mode 100644 target/riscv/custom_csr_defs.h

-- 
2.25.1



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

* [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models
  2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
  To: alistair23, wangjunqiang, bmeng.cn
  Cc: ycliang, alankao, dylan, qemu-devel, Ruinland Chuan-Tzu Tsai, qemu-riscv

Introduce A25 and AX25 CPU model designed by Andes Technology.

Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
 target/riscv/cpu.c | 16 ++++++++++++++++
 target/riscv/cpu.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7c626d89cd..0c93b7edd7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -168,6 +168,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;
@@ -222,6 +229,13 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
     set_resetvec(env, DEFAULT_RSTVEC);
     qdev_prop_set_bit(DEVICE(obj), "mmu", false);
 }
+
+static void a25_cpu_init(Object *obj)
+{
+    CPURISCVState *env = &RISCV_CPU(obj)->env;
+    set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+    set_priv_version(env, PRIV_VERSION_1_10_0);
+}
 #endif
 
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
@@ -789,8 +803,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,       rv32_sifive_e_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34,       rv32_imafcu_nommu_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
+    DEFINE_CPU(TYPE_RISCV_CPU_A25,              a25_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),
     DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C,         rv64_sifive_u_cpu_init),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5896aca346..3bef0d1265 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -37,6 +37,8 @@
 #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_A25             RISCV_CPU_TYPE_NAME("andes-a25")
+#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_SHAKTI_C         RISCV_CPU_TYPE_NAME("shakti-c")
 #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
-- 
2.25.1



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

* [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models
@ 2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
  To: alistair23, wangjunqiang, bmeng.cn
  Cc: qemu-devel, qemu-riscv, ycliang, alankao, dylan, Ruinland Chuan-Tzu Tsai

Introduce A25 and AX25 CPU model designed by Andes Technology.

Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
 target/riscv/cpu.c | 16 ++++++++++++++++
 target/riscv/cpu.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7c626d89cd..0c93b7edd7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -168,6 +168,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;
@@ -222,6 +229,13 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
     set_resetvec(env, DEFAULT_RSTVEC);
     qdev_prop_set_bit(DEVICE(obj), "mmu", false);
 }
+
+static void a25_cpu_init(Object *obj)
+{
+    CPURISCVState *env = &RISCV_CPU(obj)->env;
+    set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+    set_priv_version(env, PRIV_VERSION_1_10_0);
+}
 #endif
 
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
@@ -789,8 +803,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,       rv32_sifive_e_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34,       rv32_imafcu_nommu_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
+    DEFINE_CPU(TYPE_RISCV_CPU_A25,              a25_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),
     DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C,         rv64_sifive_u_cpu_init),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5896aca346..3bef0d1265 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -37,6 +37,8 @@
 #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_A25             RISCV_CPU_TYPE_NAME("andes-a25")
+#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_SHAKTI_C         RISCV_CPU_TYPE_NAME("shakti-c")
 #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
-- 
2.25.1



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

* [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
  2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
  To: alistair23, wangjunqiang, bmeng.cn
  Cc: ycliang, alankao, dylan, qemu-devel, Ruinland Chuan-Tzu Tsai, qemu-riscv

riscv_csrrw() will be called by CSR handling helpers, which is the
most suitable place for checking wheter a custom CSR is being accessed.

If we're touching a custom CSR, invoke the registered handlers.

Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
 target/riscv/cpu.c             | 19 +++++++++++++++++
 target/riscv/cpu.h             | 13 +++++++++++-
 target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
 target/riscv/custom_csr_defs.h |  7 +++++++
 4 files changed, 68 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/custom_csr_defs.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0c93b7edd7..a72fd32f01 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -34,6 +34,9 @@
 
 static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
 
+GHashTable *custom_csr_map = NULL;
+#include "custom_csr_defs.h"
+
 const char * const riscv_int_regnames[] = {
   "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
   "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
@@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
 #endif
 }
 
+static void setup_custom_csr(CPURISCVState *env,
+                             riscv_custom_csr_operations csr_map_struct[])
+{
+    int i;
+    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
+    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;
+        }
+    }
+}
+
 static void riscv_any_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3bef0d1265..012be10d0a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -245,6 +245,11 @@ struct CPURISCVState {
 
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *timer; /* Internal timer */
+
+    /* Custom CSR opset table per hart */
+    GHashTable *custom_csr_map;                                         
+    /* Custom CSR value holder per hart */                                         
+    void *custom_csr_val;        
 };
 
 OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
@@ -496,9 +501,15 @@ 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 */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 23fbbd3216..1048ee3b44 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
 
 #endif
 
+/* Custom CSR related routines */
+static gpointer find_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
  *
@@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
     RISCVException ret;
     target_ulong old_value;
     RISCVCPU *cpu = env_archcpu(env);
+    riscv_csr_operations *csr_op;
     int read_only = get_field(csrno, 0xC00) == 3;
 
     /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
@@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
         return RISCV_EXCP_ILLEGAL_INST;
     }
 
+    /* try to handle_custom_csr */
+    if (unlikely(env->custom_csr_map != NULL)) {
+        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
+            find_custom_csr(env, csrno);
+        if (custom_csr_opset != NULL) {
+            csr_op = custom_csr_opset;
+            } else {
+            csr_op = &csr_ops[csrno];
+            }
+        } else {
+        csr_op = &csr_ops[csrno];
+        }
+
     /* check predicate */
-    if (!csr_ops[csrno].predicate) {
+    if (!csr_op->predicate) {
         return RISCV_EXCP_ILLEGAL_INST;
     }
-    ret = csr_ops[csrno].predicate(env, csrno);
+    ret = csr_op->predicate(env, csrno);
     if (ret != RISCV_EXCP_NONE) {
         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 (csr_op->op) {
+        return csr_op->op(env, csrno, ret_value, new_value, write_mask);
     }
 
     /* if no accessor exists then return failure */
-    if (!csr_ops[csrno].read) {
+    if (!csr_op->read) {
         return RISCV_EXCP_ILLEGAL_INST;
     }
     /* read old value */
-    ret = csr_ops[csrno].read(env, csrno, &old_value);
+    ret = csr_op->read(env, csrno, &old_value);
     if (ret != RISCV_EXCP_NONE) {
         return ret;
     }
@@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
     /* 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 (csr_op->write) {
+            ret = csr_op->write(env, csrno, new_value);
             if (ret != RISCV_EXCP_NONE) {
                 return ret;
             }
diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
new file mode 100644
index 0000000000..4dbf8cf1fd
--- /dev/null
+++ b/target/riscv/custom_csr_defs.h
@@ -0,0 +1,7 @@
+/* 
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ * Custom CSR variables provided by <cpu_model_name>_csr.c
+ */
+
+/* Left blank purposely in this commit. */
-- 
2.25.1



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

* [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
  To: alistair23, wangjunqiang, bmeng.cn
  Cc: qemu-devel, qemu-riscv, ycliang, alankao, dylan, Ruinland Chuan-Tzu Tsai

riscv_csrrw() will be called by CSR handling helpers, which is the
most suitable place for checking wheter a custom CSR is being accessed.

If we're touching a custom CSR, invoke the registered handlers.

Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
 target/riscv/cpu.c             | 19 +++++++++++++++++
 target/riscv/cpu.h             | 13 +++++++++++-
 target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
 target/riscv/custom_csr_defs.h |  7 +++++++
 4 files changed, 68 insertions(+), 9 deletions(-)
 create mode 100644 target/riscv/custom_csr_defs.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0c93b7edd7..a72fd32f01 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -34,6 +34,9 @@
 
 static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
 
+GHashTable *custom_csr_map = NULL;
+#include "custom_csr_defs.h"
+
 const char * const riscv_int_regnames[] = {
   "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
   "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
@@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
 #endif
 }
 
+static void setup_custom_csr(CPURISCVState *env,
+                             riscv_custom_csr_operations csr_map_struct[])
+{
+    int i;
+    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
+    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;
+        }
+    }
+}
+
 static void riscv_any_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3bef0d1265..012be10d0a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -245,6 +245,11 @@ struct CPURISCVState {
 
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *timer; /* Internal timer */
+
+    /* Custom CSR opset table per hart */
+    GHashTable *custom_csr_map;                                         
+    /* Custom CSR value holder per hart */                                         
+    void *custom_csr_val;        
 };
 
 OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
@@ -496,9 +501,15 @@ 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 */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 23fbbd3216..1048ee3b44 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
 
 #endif
 
+/* Custom CSR related routines */
+static gpointer find_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
  *
@@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
     RISCVException ret;
     target_ulong old_value;
     RISCVCPU *cpu = env_archcpu(env);
+    riscv_csr_operations *csr_op;
     int read_only = get_field(csrno, 0xC00) == 3;
 
     /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
@@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
         return RISCV_EXCP_ILLEGAL_INST;
     }
 
+    /* try to handle_custom_csr */
+    if (unlikely(env->custom_csr_map != NULL)) {
+        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
+            find_custom_csr(env, csrno);
+        if (custom_csr_opset != NULL) {
+            csr_op = custom_csr_opset;
+            } else {
+            csr_op = &csr_ops[csrno];
+            }
+        } else {
+        csr_op = &csr_ops[csrno];
+        }
+
     /* check predicate */
-    if (!csr_ops[csrno].predicate) {
+    if (!csr_op->predicate) {
         return RISCV_EXCP_ILLEGAL_INST;
     }
-    ret = csr_ops[csrno].predicate(env, csrno);
+    ret = csr_op->predicate(env, csrno);
     if (ret != RISCV_EXCP_NONE) {
         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 (csr_op->op) {
+        return csr_op->op(env, csrno, ret_value, new_value, write_mask);
     }
 
     /* if no accessor exists then return failure */
-    if (!csr_ops[csrno].read) {
+    if (!csr_op->read) {
         return RISCV_EXCP_ILLEGAL_INST;
     }
     /* read old value */
-    ret = csr_ops[csrno].read(env, csrno, &old_value);
+    ret = csr_op->read(env, csrno, &old_value);
     if (ret != RISCV_EXCP_NONE) {
         return ret;
     }
@@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
     /* 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 (csr_op->write) {
+            ret = csr_op->write(env, csrno, new_value);
             if (ret != RISCV_EXCP_NONE) {
                 return ret;
             }
diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
new file mode 100644
index 0000000000..4dbf8cf1fd
--- /dev/null
+++ b/target/riscv/custom_csr_defs.h
@@ -0,0 +1,7 @@
+/* 
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ * Custom CSR variables provided by <cpu_model_name>_csr.c
+ */
+
+/* Left blank purposely in this commit. */
-- 
2.25.1



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

* [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
  2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
  To: alistair23, wangjunqiang, bmeng.cn
  Cc: ycliang, alankao, dylan, qemu-devel, Ruinland Chuan-Tzu Tsai, qemu-riscv

Add CSR bits definitions, CSR table and handler functions for Andes
AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().

Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
 target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
 target/riscv/cpu.c             |   4 +
 target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
 target/riscv/custom_csr_defs.h |   3 +-
 target/riscv/meson.build       |   1 +
 5 files changed, 319 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.c

diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
new file mode 100644
index 0000000000..84b0900423
--- /dev/null
+++ b/target/riscv/andes_cpu_bits.h
@@ -0,0 +1,129 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Andes custom CSRs bit definitions
+ *
+ */
+
+/*
+ * ========= Missing drafted/standard CSR definitions =========
+ * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
+ */
+#define CSR_TINFO           0x7a4
+
+#if !defined(CONFIG_USER_ONLY)
+/* ========= 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
+
+#endif /* !defined(CONFIG_USER_ONLY) */
+
+/* ========= 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 a72fd32f01..fe63e68b8e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -192,6 +192,8 @@ 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(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
 }
 
 static void rv64_sifive_u_cpu_init(Object *obj)
@@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
     set_priv_version(env, PRIV_VERSION_1_10_0);
+    setup_custom_csr(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
 }
 #endif
 
diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
new file mode 100644
index 0000000000..8617f40483
--- /dev/null
+++ b/target/riscv/csr_andes.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ * Andes custom CSR table and handling functions
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "qemu/main-loop.h"
+#include "exec/exec-all.h"
+#include "andes_cpu_bits.h"
+
+struct andes_csr_val {
+    target_long uitb;
+};
+
+#if !defined(CONFIG_USER_ONLY)
+static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    /* enable pma probe */
+    *val = 0x40000000;
+    return RISCV_EXCP_NONE;
+}
+#endif
+
+static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
+{
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    andes_csr->uitb = val;
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    *val = andes_csr->uitb;
+    return RISCV_EXCP_NONE;
+}
+
+
+static RISCVException any(CPURISCVState *env, int csrno)
+{
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    *val = 0;
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
+{
+    return RISCV_EXCP_NONE;
+}
+
+int andes_custom_csr_size = sizeof(struct andes_csr_val);
+riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
+    /* ========= AndeStar V5 machine mode CSRs ========= */
+    #if !defined(CONFIG_USER_ONLY)
+    /* 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} },
+    #endif
+
+    /* ========= 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 } },
+    };
diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
index 4dbf8cf1fd..b09083585b 100644
--- a/target/riscv/custom_csr_defs.h
+++ b/target/riscv/custom_csr_defs.h
@@ -4,4 +4,5 @@
  * Custom CSR variables provided by <cpu_model_name>_csr.c
  */
 
-/* Left blank purposely in this commit. */
+extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
+extern int andes_custom_csr_size;
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index d5e0bc93ea..5c87672ff9 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -9,6 +9,7 @@ gen = [
 riscv_ss = ss.source_set()
 riscv_ss.add(gen)
 riscv_ss.add(files(
+  'csr_andes.c',
   'cpu.c',
   'cpu_helper.c',
   'csr.c',
-- 
2.25.1



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

* [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
@ 2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
  To: alistair23, wangjunqiang, bmeng.cn
  Cc: qemu-devel, qemu-riscv, ycliang, alankao, dylan, Ruinland Chuan-Tzu Tsai

Add CSR bits definitions, CSR table and handler functions for Andes
AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().

Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
 target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
 target/riscv/cpu.c             |   4 +
 target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
 target/riscv/custom_csr_defs.h |   3 +-
 target/riscv/meson.build       |   1 +
 5 files changed, 319 insertions(+), 1 deletion(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.c

diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
new file mode 100644
index 0000000000..84b0900423
--- /dev/null
+++ b/target/riscv/andes_cpu_bits.h
@@ -0,0 +1,129 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Andes custom CSRs bit definitions
+ *
+ */
+
+/*
+ * ========= Missing drafted/standard CSR definitions =========
+ * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
+ */
+#define CSR_TINFO           0x7a4
+
+#if !defined(CONFIG_USER_ONLY)
+/* ========= 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
+
+#endif /* !defined(CONFIG_USER_ONLY) */
+
+/* ========= 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 a72fd32f01..fe63e68b8e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -192,6 +192,8 @@ 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(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
 }
 
 static void rv64_sifive_u_cpu_init(Object *obj)
@@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
     CPURISCVState *env = &RISCV_CPU(obj)->env;
     set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
     set_priv_version(env, PRIV_VERSION_1_10_0);
+    setup_custom_csr(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
 }
 #endif
 
diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
new file mode 100644
index 0000000000..8617f40483
--- /dev/null
+++ b/target/riscv/csr_andes.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ * Andes custom CSR table and handling functions
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "qemu/main-loop.h"
+#include "exec/exec-all.h"
+#include "andes_cpu_bits.h"
+
+struct andes_csr_val {
+    target_long uitb;
+};
+
+#if !defined(CONFIG_USER_ONLY)
+static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    /* enable pma probe */
+    *val = 0x40000000;
+    return RISCV_EXCP_NONE;
+}
+#endif
+
+static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
+{
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    andes_csr->uitb = val;
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    *val = andes_csr->uitb;
+    return RISCV_EXCP_NONE;
+}
+
+
+static RISCVException any(CPURISCVState *env, int csrno)
+{
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    *val = 0;
+    return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
+{
+    return RISCV_EXCP_NONE;
+}
+
+int andes_custom_csr_size = sizeof(struct andes_csr_val);
+riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
+    /* ========= AndeStar V5 machine mode CSRs ========= */
+    #if !defined(CONFIG_USER_ONLY)
+    /* 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} },
+    #endif
+
+    /* ========= 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 } },
+    };
diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
index 4dbf8cf1fd..b09083585b 100644
--- a/target/riscv/custom_csr_defs.h
+++ b/target/riscv/custom_csr_defs.h
@@ -4,4 +4,5 @@
  * Custom CSR variables provided by <cpu_model_name>_csr.c
  */
 
-/* Left blank purposely in this commit. */
+extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
+extern int andes_custom_csr_size;
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index d5e0bc93ea..5c87672ff9 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -9,6 +9,7 @@ gen = [
 riscv_ss = ss.source_set()
 riscv_ss.add(gen)
 riscv_ss.add(files(
+  'csr_andes.c',
   'cpu.c',
   'cpu_helper.c',
   'csr.c',
-- 
2.25.1



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

* Re: [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models
  2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 22:33     ` Alistair Francis
  -1 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:33 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: ycliang, Alan Quey-Liang Kao((((((((((),
	wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
	open list:RISC-V, Bin Meng

On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Introduce A25 and AX25 CPU model designed by Andes Technology.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c | 16 ++++++++++++++++
>  target/riscv/cpu.h |  2 ++
>  2 files changed, 18 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7c626d89cd..0c93b7edd7 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -168,6 +168,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;
> @@ -222,6 +229,13 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>      set_resetvec(env, DEFAULT_RSTVEC);
>      qdev_prop_set_bit(DEVICE(obj), "mmu", false);
>  }
> +
> +static void a25_cpu_init(Object *obj)
> +{
> +    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> +    set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
>  #endif
>
>  static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
> @@ -789,8 +803,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,       rv32_sifive_e_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34,       rv32_imafcu_nommu_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
> +    DEFINE_CPU(TYPE_RISCV_CPU_A25,              a25_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),
>      DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C,         rv64_sifive_u_cpu_init),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5896aca346..3bef0d1265 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -37,6 +37,8 @@
>  #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_A25             RISCV_CPU_TYPE_NAME("andes-a25")
> +#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_SHAKTI_C         RISCV_CPU_TYPE_NAME("shakti-c")
>  #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
> --
> 2.25.1
>


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

* Re: [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models
@ 2021-10-21 22:33     ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:33 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
	open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
	Dylan Jhong

On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Introduce A25 and AX25 CPU model designed by Andes Technology.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c | 16 ++++++++++++++++
>  target/riscv/cpu.h |  2 ++
>  2 files changed, 18 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7c626d89cd..0c93b7edd7 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -168,6 +168,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;
> @@ -222,6 +229,13 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
>      set_resetvec(env, DEFAULT_RSTVEC);
>      qdev_prop_set_bit(DEVICE(obj), "mmu", false);
>  }
> +
> +static void a25_cpu_init(Object *obj)
> +{
> +    CPURISCVState *env = &RISCV_CPU(obj)->env;
> +    set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> +    set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
>  #endif
>
>  static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
> @@ -789,8 +803,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,       rv32_sifive_e_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34,       rv32_imafcu_nommu_cpu_init),
>      DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,       rv32_sifive_u_cpu_init),
> +    DEFINE_CPU(TYPE_RISCV_CPU_A25,              a25_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),
>      DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C,         rv64_sifive_u_cpu_init),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5896aca346..3bef0d1265 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -37,6 +37,8 @@
>  #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_A25             RISCV_CPU_TYPE_NAME("andes-a25")
> +#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_SHAKTI_C         RISCV_CPU_TYPE_NAME("shakti-c")
>  #define TYPE_RISCV_CPU_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
> --
> 2.25.1
>


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
  2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 22:43     ` Alistair Francis
  -1 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:43 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: ycliang, Alan Quey-Liang Kao((((((((((),
	wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
	open list:RISC-V, Bin Meng

On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> riscv_csrrw() will be called by CSR handling helpers, which is the
> most suitable place for checking wheter a custom CSR is being accessed.
>
> If we're touching a custom CSR, invoke the registered handlers.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>

Awesome! This looks really good :)

> ---
>  target/riscv/cpu.c             | 19 +++++++++++++++++
>  target/riscv/cpu.h             | 13 +++++++++++-
>  target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
>  target/riscv/custom_csr_defs.h |  7 +++++++
>  4 files changed, 68 insertions(+), 9 deletions(-)
>  create mode 100644 target/riscv/custom_csr_defs.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0c93b7edd7..a72fd32f01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -34,6 +34,9 @@
>
>  static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>
> +GHashTable *custom_csr_map = NULL;
> +#include "custom_csr_defs.h"
> +
>  const char * const riscv_int_regnames[] = {
>    "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
>    "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
>  #endif
>  }
>
> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[])
> +{
> +    int i;
> +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> +    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;
> +        }
> +    }
> +}
> +
>  static void riscv_any_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 3bef0d1265..012be10d0a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -245,6 +245,11 @@ struct CPURISCVState {
>
>      /* Fields from here on are preserved across CPU reset. */
>      QEMUTimer *timer; /* Internal timer */
> +
> +    /* Custom CSR opset table per hart */
> +    GHashTable *custom_csr_map;
> +    /* Custom CSR value holder per hart */
> +    void *custom_csr_val;
>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -496,9 +501,15 @@ 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 */
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 23fbbd3216..1048ee3b44 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
>
>  #endif
>
> +/* Custom CSR related routines */
> +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> +{
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;

You can just return directly here, so:

return g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));

Also, I think you need to run checkpatch.pl on this patch (you should
run it on all patches).

Alistair

> +}
> +
>  /*
>   * riscv_csrrw - read and/or update control and status register
>   *
> @@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>      RISCVException ret;
>      target_ulong old_value;
>      RISCVCPU *cpu = env_archcpu(env);
> +    riscv_csr_operations *csr_op;
>      int read_only = get_field(csrno, 0xC00) == 3;
>
>      /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>          return RISCV_EXCP_ILLEGAL_INST;
>      }
>
> +    /* try to handle_custom_csr */
> +    if (unlikely(env->custom_csr_map != NULL)) {
> +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +            find_custom_csr(env, csrno);
> +        if (custom_csr_opset != NULL) {
> +            csr_op = custom_csr_opset;
> +            } else {
> +            csr_op = &csr_ops[csrno];
> +            }
> +        } else {
> +        csr_op = &csr_ops[csrno];
> +        }
> +
>      /* check predicate */
> -    if (!csr_ops[csrno].predicate) {
> +    if (!csr_op->predicate) {
>          return RISCV_EXCP_ILLEGAL_INST;
>      }
> -    ret = csr_ops[csrno].predicate(env, csrno);
> +    ret = csr_op->predicate(env, csrno);
>      if (ret != RISCV_EXCP_NONE) {
>          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 (csr_op->op) {
> +        return csr_op->op(env, csrno, ret_value, new_value, write_mask);
>      }
>
>      /* if no accessor exists then return failure */
> -    if (!csr_ops[csrno].read) {
> +    if (!csr_op->read) {
>          return RISCV_EXCP_ILLEGAL_INST;
>      }
>      /* read old value */
> -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> +    ret = csr_op->read(env, csrno, &old_value);
>      if (ret != RISCV_EXCP_NONE) {
>          return ret;
>      }
> @@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>      /* 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 (csr_op->write) {
> +            ret = csr_op->write(env, csrno, new_value);
>              if (ret != RISCV_EXCP_NONE) {
>                  return ret;
>              }
> diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> new file mode 100644
> index 0000000000..4dbf8cf1fd
> --- /dev/null
> +++ b/target/riscv/custom_csr_defs.h
> @@ -0,0 +1,7 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Custom CSR variables provided by <cpu_model_name>_csr.c
> + */
> +
> +/* Left blank purposely in this commit. */
> --
> 2.25.1
>


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-21 22:43     ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:43 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
	open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
	Dylan Jhong

On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> riscv_csrrw() will be called by CSR handling helpers, which is the
> most suitable place for checking wheter a custom CSR is being accessed.
>
> If we're touching a custom CSR, invoke the registered handlers.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>

Awesome! This looks really good :)

> ---
>  target/riscv/cpu.c             | 19 +++++++++++++++++
>  target/riscv/cpu.h             | 13 +++++++++++-
>  target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
>  target/riscv/custom_csr_defs.h |  7 +++++++
>  4 files changed, 68 insertions(+), 9 deletions(-)
>  create mode 100644 target/riscv/custom_csr_defs.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0c93b7edd7..a72fd32f01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -34,6 +34,9 @@
>
>  static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>
> +GHashTable *custom_csr_map = NULL;
> +#include "custom_csr_defs.h"
> +
>  const char * const riscv_int_regnames[] = {
>    "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
>    "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
>  #endif
>  }
>
> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[])
> +{
> +    int i;
> +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> +    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;
> +        }
> +    }
> +}
> +
>  static void riscv_any_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 3bef0d1265..012be10d0a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -245,6 +245,11 @@ struct CPURISCVState {
>
>      /* Fields from here on are preserved across CPU reset. */
>      QEMUTimer *timer; /* Internal timer */
> +
> +    /* Custom CSR opset table per hart */
> +    GHashTable *custom_csr_map;
> +    /* Custom CSR value holder per hart */
> +    void *custom_csr_val;
>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -496,9 +501,15 @@ 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 */
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 23fbbd3216..1048ee3b44 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
>
>  #endif
>
> +/* Custom CSR related routines */
> +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> +{
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;

You can just return directly here, so:

return g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));

Also, I think you need to run checkpatch.pl on this patch (you should
run it on all patches).

Alistair

> +}
> +
>  /*
>   * riscv_csrrw - read and/or update control and status register
>   *
> @@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>      RISCVException ret;
>      target_ulong old_value;
>      RISCVCPU *cpu = env_archcpu(env);
> +    riscv_csr_operations *csr_op;
>      int read_only = get_field(csrno, 0xC00) == 3;
>
>      /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>          return RISCV_EXCP_ILLEGAL_INST;
>      }
>
> +    /* try to handle_custom_csr */
> +    if (unlikely(env->custom_csr_map != NULL)) {
> +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +            find_custom_csr(env, csrno);
> +        if (custom_csr_opset != NULL) {
> +            csr_op = custom_csr_opset;
> +            } else {
> +            csr_op = &csr_ops[csrno];
> +            }
> +        } else {
> +        csr_op = &csr_ops[csrno];
> +        }
> +
>      /* check predicate */
> -    if (!csr_ops[csrno].predicate) {
> +    if (!csr_op->predicate) {
>          return RISCV_EXCP_ILLEGAL_INST;
>      }
> -    ret = csr_ops[csrno].predicate(env, csrno);
> +    ret = csr_op->predicate(env, csrno);
>      if (ret != RISCV_EXCP_NONE) {
>          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 (csr_op->op) {
> +        return csr_op->op(env, csrno, ret_value, new_value, write_mask);
>      }
>
>      /* if no accessor exists then return failure */
> -    if (!csr_ops[csrno].read) {
> +    if (!csr_op->read) {
>          return RISCV_EXCP_ILLEGAL_INST;
>      }
>      /* read old value */
> -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> +    ret = csr_op->read(env, csrno, &old_value);
>      if (ret != RISCV_EXCP_NONE) {
>          return ret;
>      }
> @@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>      /* 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 (csr_op->write) {
> +            ret = csr_op->write(env, csrno, new_value);
>              if (ret != RISCV_EXCP_NONE) {
>                  return ret;
>              }
> diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> new file mode 100644
> index 0000000000..4dbf8cf1fd
> --- /dev/null
> +++ b/target/riscv/custom_csr_defs.h
> @@ -0,0 +1,7 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Custom CSR variables provided by <cpu_model_name>_csr.c
> + */
> +
> +/* Left blank purposely in this commit. */
> --
> 2.25.1
>


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

* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
  2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 22:44     ` Alistair Francis
  -1 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:44 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: ycliang, Alan Quey-Liang Kao((((((((((),
	wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
	open list:RISC-V, Bin Meng

On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Add CSR bits definitions, CSR table and handler functions for Andes
> AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> ---
>  target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
>  target/riscv/cpu.c             |   4 +
>  target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_csr_defs.h |   3 +-
>  target/riscv/meson.build       |   1 +
>  5 files changed, 319 insertions(+), 1 deletion(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.c
>
> diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> new file mode 100644
> index 0000000000..84b0900423
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,129 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0+
> + *
> + * Andes custom CSRs bit definitions
> + *
> + */
> +
> +/*
> + * ========= Missing drafted/standard CSR definitions =========
> + * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
> + */
> +#define CSR_TINFO           0x7a4
> +
> +#if !defined(CONFIG_USER_ONLY)
> +/* ========= 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
> +
> +#endif /* !defined(CONFIG_USER_ONLY) */
> +
> +/* ========= 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 a72fd32f01..fe63e68b8e 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -192,6 +192,8 @@ 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(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
>  }
>
>  static void rv64_sifive_u_cpu_init(Object *obj)
> @@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
>      set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>      set_priv_version(env, PRIV_VERSION_1_10_0);
> +    setup_custom_csr(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
>  }
>  #endif
>
> diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> new file mode 100644
> index 0000000000..8617f40483
> --- /dev/null
> +++ b/target/riscv/csr_andes.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Andes custom CSR table and handling functions
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "cpu.h"
> +#include "qemu/main-loop.h"
> +#include "exec/exec-all.h"
> +#include "andes_cpu_bits.h"
> +
> +struct andes_csr_val {
> +    target_long uitb;
> +};
> +
> +#if !defined(CONFIG_USER_ONLY)
> +static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    /* enable pma probe */
> +    *val = 0x40000000;
> +    return RISCV_EXCP_NONE;
> +}
> +#endif
> +
> +static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    andes_csr->uitb = val;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    *val = andes_csr->uitb;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +
> +static RISCVException any(CPURISCVState *env, int csrno)
> +{
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    *val = 0;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    return RISCV_EXCP_NONE;
> +}
> +
> +int andes_custom_csr_size = sizeof(struct andes_csr_val);

I think just drop this value and use sizeof(struct andes_csr_val) in
the other places.

I haven't checked this against the Andes spec, but overall the series
looks good.

Alistair

> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> +    /* ========= AndeStar V5 machine mode CSRs ========= */
> +    #if !defined(CONFIG_USER_ONLY)
> +    /* 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} },
> +    #endif
> +
> +    /* ========= 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 } },
> +    };
> diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> index 4dbf8cf1fd..b09083585b 100644
> --- a/target/riscv/custom_csr_defs.h
> +++ b/target/riscv/custom_csr_defs.h
> @@ -4,4 +4,5 @@
>   * Custom CSR variables provided by <cpu_model_name>_csr.c
>   */
>
> -/* Left blank purposely in this commit. */
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
> +extern int andes_custom_csr_size;
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index d5e0bc93ea..5c87672ff9 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -9,6 +9,7 @@ gen = [
>  riscv_ss = ss.source_set()
>  riscv_ss.add(gen)
>  riscv_ss.add(files(
> +  'csr_andes.c',
>    'cpu.c',
>    'cpu_helper.c',
>    'csr.c',
> --
> 2.25.1
>


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

* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
@ 2021-10-21 22:44     ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:44 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
	open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
	Dylan Jhong

On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Add CSR bits definitions, CSR table and handler functions for Andes
> AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> ---
>  target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
>  target/riscv/cpu.c             |   4 +
>  target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_csr_defs.h |   3 +-
>  target/riscv/meson.build       |   1 +
>  5 files changed, 319 insertions(+), 1 deletion(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.c
>
> diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> new file mode 100644
> index 0000000000..84b0900423
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,129 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0+
> + *
> + * Andes custom CSRs bit definitions
> + *
> + */
> +
> +/*
> + * ========= Missing drafted/standard CSR definitions =========
> + * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
> + */
> +#define CSR_TINFO           0x7a4
> +
> +#if !defined(CONFIG_USER_ONLY)
> +/* ========= 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
> +
> +#endif /* !defined(CONFIG_USER_ONLY) */
> +
> +/* ========= 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 a72fd32f01..fe63e68b8e 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -192,6 +192,8 @@ 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(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
>  }
>
>  static void rv64_sifive_u_cpu_init(Object *obj)
> @@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
>      set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
>      set_priv_version(env, PRIV_VERSION_1_10_0);
> +    setup_custom_csr(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
>  }
>  #endif
>
> diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> new file mode 100644
> index 0000000000..8617f40483
> --- /dev/null
> +++ b/target/riscv/csr_andes.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Andes custom CSR table and handling functions
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "cpu.h"
> +#include "qemu/main-loop.h"
> +#include "exec/exec-all.h"
> +#include "andes_cpu_bits.h"
> +
> +struct andes_csr_val {
> +    target_long uitb;
> +};
> +
> +#if !defined(CONFIG_USER_ONLY)
> +static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    /* enable pma probe */
> +    *val = 0x40000000;
> +    return RISCV_EXCP_NONE;
> +}
> +#endif
> +
> +static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    andes_csr->uitb = val;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    *val = andes_csr->uitb;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +
> +static RISCVException any(CPURISCVState *env, int csrno)
> +{
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    *val = 0;
> +    return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    return RISCV_EXCP_NONE;
> +}
> +
> +int andes_custom_csr_size = sizeof(struct andes_csr_val);

I think just drop this value and use sizeof(struct andes_csr_val) in
the other places.

I haven't checked this against the Andes spec, but overall the series
looks good.

Alistair

> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> +    /* ========= AndeStar V5 machine mode CSRs ========= */
> +    #if !defined(CONFIG_USER_ONLY)
> +    /* 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} },
> +    #endif
> +
> +    /* ========= 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 } },
> +    };
> diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> index 4dbf8cf1fd..b09083585b 100644
> --- a/target/riscv/custom_csr_defs.h
> +++ b/target/riscv/custom_csr_defs.h
> @@ -4,4 +4,5 @@
>   * Custom CSR variables provided by <cpu_model_name>_csr.c
>   */
>
> -/* Left blank purposely in this commit. */
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
> +extern int andes_custom_csr_size;
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index d5e0bc93ea..5c87672ff9 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -9,6 +9,7 @@ gen = [
>  riscv_ss = ss.source_set()
>  riscv_ss.add(gen)
>  riscv_ss.add(files(
> +  'csr_andes.c',
>    'cpu.c',
>    'cpu_helper.c',
>    'csr.c',
> --
> 2.25.1
>


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

* Re: [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support
  2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 22:47   ` Alistair Francis
  -1 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:47 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: ycliang, Alan Quey-Liang Kao((((((((((),
	wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
	open list:RISC-V, Bin Meng

On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Hi Alistair, Bin and all :
>
> Sorry for bumping this stale topic.
> As our last discussion, I have removed Kconfigs and meson options.
> The custom CSR logic is in-built by default and whether a custom CSR
> is presented on the accessing hart will be checked at runtime.

No worries!

This looks great! I had a look through this and I think we are almost
there. I left a few comments, but otherwise I think we are close.

Let's see if anyone else has any comments. Otherwise can you run
checkpatch on each patch and then send a PATCH series (not an RFC) in
a week or so and we can go from there.

>
> Changes from V4 :
> Remove Kconfigs and meson options.
> Make custom CSR handling logic self-contained.
> Use g_hash_table_new instead of g_hash_table_new_full.
>
> The performance slowdown could be easily tested with a simple program
> running on linux-user mode :
>
> /* test_csr.c */
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/time.h>
>
> int main (int ac, char *av[]) {
>    struct  timeval start;
>    struct  timeval end;
>    gettimeofday(&start,NULL);
>    unsigned int loop_n = 999999 ;
>    unsigned char i;
>    unsigned char o;
>    do {
>        for(i=0; i<32; i++) {
>        #if defined(FCSR)
>        __asm__("csrw fcsr, %0;"::"r"(i));
>        __asm__("csrr %0, fcsr;":"=r"(o));
>        #elif defined(UITB)
>        __asm__("csrw 0x800, %0;"::"r"(i));
>        __asm__("csrr %0, 0x800;":"=r"(o));
>        #endif
>        }
>        --loop_n;
>    } while (loop_n > 0);
>    gettimeofday(&end,NULL);
>    unsigned long diff = 1000000 *
> (end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec;
>    printf("%f\n", (double)(diff)/1000000);
>    return 0;
> }
>
> $ riscv64-linux-gnu-gcc -static -DUITB ./test_csr.c -o ./u
> $ riscv64-linux-gnu-gcc -static -DFCSR ./test_csr.c -o ./f
> $ qemu-riscv64 ./{u,f}

Do you have the results?

Alistair

>
> Cordially yours,
> Ruinland Chuan-Tzu Tsai
>
> Ruinland Chuan-Tzu Tsai (3):
>   riscv: Adding Andes A25 and AX25 cpu models
>   riscv: Introduce custom CSR hooks to riscv_csrrw()
>   riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
>
>  target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
>  target/riscv/cpu.c             |  39 +++++++
>  target/riscv/cpu.h             |  15 ++-
>  target/riscv/csr.c             |  38 +++++--
>  target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_csr_defs.h |   8 ++
>  target/riscv/meson.build       |   1 +
>  7 files changed, 404 insertions(+), 9 deletions(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.c
>  create mode 100644 target/riscv/custom_csr_defs.h
>
> --
> 2.25.1
>


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

* Re: [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support
@ 2021-10-21 22:47   ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:47 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
	open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
	Dylan Jhong

On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Hi Alistair, Bin and all :
>
> Sorry for bumping this stale topic.
> As our last discussion, I have removed Kconfigs and meson options.
> The custom CSR logic is in-built by default and whether a custom CSR
> is presented on the accessing hart will be checked at runtime.

No worries!

This looks great! I had a look through this and I think we are almost
there. I left a few comments, but otherwise I think we are close.

Let's see if anyone else has any comments. Otherwise can you run
checkpatch on each patch and then send a PATCH series (not an RFC) in
a week or so and we can go from there.

>
> Changes from V4 :
> Remove Kconfigs and meson options.
> Make custom CSR handling logic self-contained.
> Use g_hash_table_new instead of g_hash_table_new_full.
>
> The performance slowdown could be easily tested with a simple program
> running on linux-user mode :
>
> /* test_csr.c */
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/time.h>
>
> int main (int ac, char *av[]) {
>    struct  timeval start;
>    struct  timeval end;
>    gettimeofday(&start,NULL);
>    unsigned int loop_n = 999999 ;
>    unsigned char i;
>    unsigned char o;
>    do {
>        for(i=0; i<32; i++) {
>        #if defined(FCSR)
>        __asm__("csrw fcsr, %0;"::"r"(i));
>        __asm__("csrr %0, fcsr;":"=r"(o));
>        #elif defined(UITB)
>        __asm__("csrw 0x800, %0;"::"r"(i));
>        __asm__("csrr %0, 0x800;":"=r"(o));
>        #endif
>        }
>        --loop_n;
>    } while (loop_n > 0);
>    gettimeofday(&end,NULL);
>    unsigned long diff = 1000000 *
> (end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec;
>    printf("%f\n", (double)(diff)/1000000);
>    return 0;
> }
>
> $ riscv64-linux-gnu-gcc -static -DUITB ./test_csr.c -o ./u
> $ riscv64-linux-gnu-gcc -static -DFCSR ./test_csr.c -o ./f
> $ qemu-riscv64 ./{u,f}

Do you have the results?

Alistair

>
> Cordially yours,
> Ruinland Chuan-Tzu Tsai
>
> Ruinland Chuan-Tzu Tsai (3):
>   riscv: Adding Andes A25 and AX25 cpu models
>   riscv: Introduce custom CSR hooks to riscv_csrrw()
>   riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
>
>  target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
>  target/riscv/cpu.c             |  39 +++++++
>  target/riscv/cpu.h             |  15 ++-
>  target/riscv/csr.c             |  38 +++++--
>  target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_csr_defs.h |   8 ++
>  target/riscv/meson.build       |   1 +
>  7 files changed, 404 insertions(+), 9 deletions(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.c
>  create mode 100644 target/riscv/custom_csr_defs.h
>
> --
> 2.25.1
>


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
  2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
@ 2021-10-22  0:08     ` Richard Henderson
  -1 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22  0:08 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, alistair23, wangjunqiang, bmeng.cn
  Cc: qemu-riscv, dylan, ycliang, qemu-devel, alankao

On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> riscv_csrrw() will be called by CSR handling helpers, which is the
> most suitable place for checking wheter a custom CSR is being accessed.
> 
> If we're touching a custom CSR, invoke the registered handlers.
> 
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> ---
>   target/riscv/cpu.c             | 19 +++++++++++++++++
>   target/riscv/cpu.h             | 13 +++++++++++-
>   target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
>   target/riscv/custom_csr_defs.h |  7 +++++++
>   4 files changed, 68 insertions(+), 9 deletions(-)
>   create mode 100644 target/riscv/custom_csr_defs.h
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0c93b7edd7..a72fd32f01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -34,6 +34,9 @@
>   
>   static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>   
> +GHashTable *custom_csr_map = NULL;

Leftover from a previous revision?

> +#include "custom_csr_defs.h"

I think that the few declarations that are required can just go in internals.h.

> +
>   const char * const riscv_int_regnames[] = {
>     "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
>     "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
>   #endif
>   }
>   
> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[])

Why is this static?  Surely it needs to be called from csr_andes.c, etc?
Oh, I see that in the next patch you call this directly from ax25_cpu_init.

I think the split of declarations is less than ideal.  See below.

> +{
> +    int i;
> +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {

Having a hard maximum seems a mistake.  You should pass in the array size...

> +        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;
> +        }

... which would also allow you to remove the terminator in the data, and the check here.

> @@ -245,6 +245,11 @@ struct CPURISCVState {
>   
>       /* Fields from here on are preserved across CPU reset. */
>       QEMUTimer *timer; /* Internal timer */
> +
> +    /* Custom CSR opset table per hart */
> +    GHashTable *custom_csr_map;

I think placing this in the CPURISCVState is incorrect.  A much better place would be on 
the RISCVCPUClass, so that there is exactly one copy of this per cpu type, i.e. all 
A25/AX25 cpus would share the same table.

You would of course need to hook class_init, which the current definition of DEFINE_CPU 
does not allow.  But that's easy to fix.

> +    /* Custom CSR value holder per hart */
> +    void *custom_csr_val;
>   };

Value singular?  Anyhow, I think that it's a mistake trying to hide the value structure in 
another file.  It complicates allocation of the CPURISCVState, and you have no mechanism 
by which to migrate the csr values.

I think you should simply place your structure here in CPURISCVState.

> +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> +{
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;
> +}

Fix the return type; the csr is not gpointer.
It would be better to put the map not null test here.

I think it would be even better to name this find_csr,
and include the normal index of csr_ops[] if the map
test fails.

> @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>           return RISCV_EXCP_ILLEGAL_INST;
>       }
>   
> +    /* try to handle_custom_csr */
> +    if (unlikely(env->custom_csr_map != NULL)) {
> +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +            find_custom_csr(env, csrno);
> +        if (custom_csr_opset != NULL) {
> +            csr_op = custom_csr_opset;
> +            } else {
> +            csr_op = &csr_ops[csrno];
> +            }
> +        } else {
> +        csr_op = &csr_ops[csrno];
> +        }

As Alistair noted, run checkpatch.pl to find all of these indentation errors.

That said, a better structure here would be

     csr_op = find_csr(env, csrno);
     if (csr_op == NULL) {
         return RISCV_EXCP_ILLEGAL_INST;
     }


r~


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-22  0:08     ` Richard Henderson
  0 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22  0:08 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, alistair23, wangjunqiang, bmeng.cn
  Cc: ycliang, alankao, dylan, qemu-devel, qemu-riscv

On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> riscv_csrrw() will be called by CSR handling helpers, which is the
> most suitable place for checking wheter a custom CSR is being accessed.
> 
> If we're touching a custom CSR, invoke the registered handlers.
> 
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> ---
>   target/riscv/cpu.c             | 19 +++++++++++++++++
>   target/riscv/cpu.h             | 13 +++++++++++-
>   target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
>   target/riscv/custom_csr_defs.h |  7 +++++++
>   4 files changed, 68 insertions(+), 9 deletions(-)
>   create mode 100644 target/riscv/custom_csr_defs.h
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0c93b7edd7..a72fd32f01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -34,6 +34,9 @@
>   
>   static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>   
> +GHashTable *custom_csr_map = NULL;

Leftover from a previous revision?

> +#include "custom_csr_defs.h"

I think that the few declarations that are required can just go in internals.h.

> +
>   const char * const riscv_int_regnames[] = {
>     "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
>     "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
>   #endif
>   }
>   
> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[])

Why is this static?  Surely it needs to be called from csr_andes.c, etc?
Oh, I see that in the next patch you call this directly from ax25_cpu_init.

I think the split of declarations is less than ideal.  See below.

> +{
> +    int i;
> +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {

Having a hard maximum seems a mistake.  You should pass in the array size...

> +        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;
> +        }

... which would also allow you to remove the terminator in the data, and the check here.

> @@ -245,6 +245,11 @@ struct CPURISCVState {
>   
>       /* Fields from here on are preserved across CPU reset. */
>       QEMUTimer *timer; /* Internal timer */
> +
> +    /* Custom CSR opset table per hart */
> +    GHashTable *custom_csr_map;

I think placing this in the CPURISCVState is incorrect.  A much better place would be on 
the RISCVCPUClass, so that there is exactly one copy of this per cpu type, i.e. all 
A25/AX25 cpus would share the same table.

You would of course need to hook class_init, which the current definition of DEFINE_CPU 
does not allow.  But that's easy to fix.

> +    /* Custom CSR value holder per hart */
> +    void *custom_csr_val;
>   };

Value singular?  Anyhow, I think that it's a mistake trying to hide the value structure in 
another file.  It complicates allocation of the CPURISCVState, and you have no mechanism 
by which to migrate the csr values.

I think you should simply place your structure here in CPURISCVState.

> +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> +{
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;
> +}

Fix the return type; the csr is not gpointer.
It would be better to put the map not null test here.

I think it would be even better to name this find_csr,
and include the normal index of csr_ops[] if the map
test fails.

> @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
>           return RISCV_EXCP_ILLEGAL_INST;
>       }
>   
> +    /* try to handle_custom_csr */
> +    if (unlikely(env->custom_csr_map != NULL)) {
> +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +            find_custom_csr(env, csrno);
> +        if (custom_csr_opset != NULL) {
> +            csr_op = custom_csr_opset;
> +            } else {
> +            csr_op = &csr_ops[csrno];
> +            }
> +        } else {
> +        csr_op = &csr_ops[csrno];
> +        }

As Alistair noted, run checkpatch.pl to find all of these indentation errors.

That said, a better structure here would be

     csr_op = find_csr(env, csrno);
     if (csr_op == NULL) {
         return RISCV_EXCP_ILLEGAL_INST;
     }


r~


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

* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
  2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
@ 2021-10-22  1:12     ` Richard Henderson
  -1 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22  1:12 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, alistair23, wangjunqiang, bmeng.cn
  Cc: qemu-riscv, dylan, ycliang, qemu-devel, alankao

On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> new file mode 100644
> index 0000000000..8617f40483
> --- /dev/null
> +++ b/target/riscv/csr_andes.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Andes custom CSR table and handling functions
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "cpu.h"
> +#include "qemu/main-loop.h"
> +#include "exec/exec-all.h"
> +#include "andes_cpu_bits.h"
> +
> +struct andes_csr_val {
> +    target_long uitb;
> +};

docs/devel/style.rst: Use a typedef and CamelCase.
And of course per review of patch 2, this needs to go elsewhere.

You need to add a subsection to machine.c to migrate this new state.  With respect to the 
custom instructions, I suggested adding an ext_andes field.  I would expect these CSRs, 
which go with those instructions, to use the same predicate.

> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
...
> +    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
> +    {0, { "", NULL, NULL, NULL } },
> +    };

Indentation here.

I think you should not export the array itself, but instead

void andes_setup_custom_csrs(RISCVCPUClass *cc)
{
     setup_custom_csrs(cc, andes_custom_csr_table,
                       ARRAY_SIZE(andes_custom_csr_table));
}


r~


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

* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
@ 2021-10-22  1:12     ` Richard Henderson
  0 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22  1:12 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, alistair23, wangjunqiang, bmeng.cn
  Cc: ycliang, alankao, dylan, qemu-devel, qemu-riscv

On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> new file mode 100644
> index 0000000000..8617f40483
> --- /dev/null
> +++ b/target/riscv/csr_andes.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Andes custom CSR table and handling functions
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "cpu.h"
> +#include "qemu/main-loop.h"
> +#include "exec/exec-all.h"
> +#include "andes_cpu_bits.h"
> +
> +struct andes_csr_val {
> +    target_long uitb;
> +};

docs/devel/style.rst: Use a typedef and CamelCase.
And of course per review of patch 2, this needs to go elsewhere.

You need to add a subsection to machine.c to migrate this new state.  With respect to the 
custom instructions, I suggested adding an ext_andes field.  I would expect these CSRs, 
which go with those instructions, to use the same predicate.

> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
...
> +    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
> +    {0, { "", NULL, NULL, NULL } },
> +    };

Indentation here.

I think you should not export the array itself, but instead

void andes_setup_custom_csrs(RISCVCPUClass *cc)
{
     setup_custom_csrs(cc, andes_custom_csr_table,
                       ARRAY_SIZE(andes_custom_csr_table));
}


r~


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
  2021-10-22  0:08     ` Richard Henderson
@ 2021-10-22  8:34       ` Ruinland ChuanTzu Tsai
  -1 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22  8:34 UTC (permalink / raw)
  To: Richard Henderson
  Cc: ycliang, qemu-riscv, alankao, wangjunqiang, dylan, qemu-devel,
	alistair23, bmeng.cn

On Thu, Oct 21, 2021 at 05:08:09PM -0700, Richard Henderson wrote:
> On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> > 
> > If we're touching a custom CSR, invoke the registered handlers.
> > 
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> >   target/riscv/cpu.c             | 19 +++++++++++++++++
> >   target/riscv/cpu.h             | 13 +++++++++++-
> >   target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
> >   target/riscv/custom_csr_defs.h |  7 +++++++
> >   4 files changed, 68 insertions(+), 9 deletions(-)
> >   create mode 100644 target/riscv/custom_csr_defs.h
> > 
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> >   static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> > +GHashTable *custom_csr_map = NULL;
> 
> Leftover from a previous revision?

By default there's no custom_csr_map (pointing to NULL) and thus only the
custom CSR equipped CPU models will need to initialize that. Standard CPU will
pass the check of custom_csr_map in riscv_csrrw() by default.

> 
> > +#include "custom_csr_defs.h"
> 
> I think that the few declarations that are required can just go in internals.h.

Wilco.

> 
> > +
> >   const char * const riscv_int_regnames[] = {
> >     "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
> >     "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> >   #endif
> >   }
> > +static void setup_custom_csr(CPURISCVState *env,
> > +                             riscv_custom_csr_operations csr_map_struct[])
> 
> Why is this static?  Surely it needs to be called from csr_andes.c, etc?
> Oh, I see that in the next patch you call this directly from ax25_cpu_init.
> 
> I think the split of declarations is less than ideal.  See below.
> 
> > +{
> > +    int i;
> > +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> 
> Having a hard maximum seems a mistake.  You should pass in the array size...
> 
> > +        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;
> > +        }
> 
> ... which would also allow you to remove the terminator in the data, and the check here.

Wilco.

> 
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> >       /* Fields from here on are preserved across CPU reset. */
> >       QEMUTimer *timer; /* Internal timer */
> > +
> > +    /* Custom CSR opset table per hart */
> > +    GHashTable *custom_csr_map;
> 
> I think placing this in the CPURISCVState is incorrect.  A much better place
> would be on the RISCVCPUClass, so that there is exactly one copy of this per
> cpu type, i.e. all A25/AX25 cpus would share the same table.
> 
> You would of course need to hook class_init, which the current definition of
> DEFINE_CPU does not allow.  But that's easy to fix.
> 
> > +    /* Custom CSR value holder per hart */
> > +    void *custom_csr_val;
> >   };
> 
> Value singular?  Anyhow, I think that it's a mistake trying to hide the
> value structure in another file.  It complicates allocation of the
> CPURISCVState, and you have no mechanism by which to migrate the csr values.

What I'm trying to do here is to provide a hook for CSR value storage and let
it being set during CPU initilization. We have heterogeneous harts which
have different sets of CSRs.

> 
> I think you should simply place your structure here in CPURISCVState.
> 
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > +    gpointer ret;
> > +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > +    return ret;
> > +}
> 
> Fix the return type; the csr is not gpointer.
> It would be better to put the map not null test here.
> 
> I think it would be even better to name this find_csr,
> and include the normal index of csr_ops[] if the map
> test fails.

Wilco.

> 
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >           return RISCV_EXCP_ILLEGAL_INST;
> >       }
> > +    /* try to handle_custom_csr */
> > +    if (unlikely(env->custom_csr_map != NULL)) {
> > +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > +            find_custom_csr(env, csrno);
> > +        if (custom_csr_opset != NULL) {
> > +            csr_op = custom_csr_opset;
> > +            } else {
> > +            csr_op = &csr_ops[csrno];
> > +            }
> > +        } else {
> > +        csr_op = &csr_ops[csrno];
> > +        }
> 
> As Alistair noted, run checkpatch.pl to find all of these indentation errors.
> 
> That said, a better structure here would be
> 
>     csr_op = find_csr(env, csrno);
>     if (csr_op == NULL) {
>         return RISCV_EXCP_ILLEGAL_INST;
>     }

Thanks for the tips. Wilco.
> 
> 
> r~

Cordially yours,
Ruinland


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-22  8:34       ` Ruinland ChuanTzu Tsai
  0 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22  8:34 UTC (permalink / raw)
  To: Richard Henderson
  Cc: alistair23, wangjunqiang, bmeng.cn, ycliang, alankao, dylan,
	qemu-devel, qemu-riscv

On Thu, Oct 21, 2021 at 05:08:09PM -0700, Richard Henderson wrote:
> On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> > 
> > If we're touching a custom CSR, invoke the registered handlers.
> > 
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> >   target/riscv/cpu.c             | 19 +++++++++++++++++
> >   target/riscv/cpu.h             | 13 +++++++++++-
> >   target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
> >   target/riscv/custom_csr_defs.h |  7 +++++++
> >   4 files changed, 68 insertions(+), 9 deletions(-)
> >   create mode 100644 target/riscv/custom_csr_defs.h
> > 
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> >   static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> > +GHashTable *custom_csr_map = NULL;
> 
> Leftover from a previous revision?

By default there's no custom_csr_map (pointing to NULL) and thus only the
custom CSR equipped CPU models will need to initialize that. Standard CPU will
pass the check of custom_csr_map in riscv_csrrw() by default.

> 
> > +#include "custom_csr_defs.h"
> 
> I think that the few declarations that are required can just go in internals.h.

Wilco.

> 
> > +
> >   const char * const riscv_int_regnames[] = {
> >     "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
> >     "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> >   #endif
> >   }
> > +static void setup_custom_csr(CPURISCVState *env,
> > +                             riscv_custom_csr_operations csr_map_struct[])
> 
> Why is this static?  Surely it needs to be called from csr_andes.c, etc?
> Oh, I see that in the next patch you call this directly from ax25_cpu_init.
> 
> I think the split of declarations is less than ideal.  See below.
> 
> > +{
> > +    int i;
> > +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> 
> Having a hard maximum seems a mistake.  You should pass in the array size...
> 
> > +        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;
> > +        }
> 
> ... which would also allow you to remove the terminator in the data, and the check here.

Wilco.

> 
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> >       /* Fields from here on are preserved across CPU reset. */
> >       QEMUTimer *timer; /* Internal timer */
> > +
> > +    /* Custom CSR opset table per hart */
> > +    GHashTable *custom_csr_map;
> 
> I think placing this in the CPURISCVState is incorrect.  A much better place
> would be on the RISCVCPUClass, so that there is exactly one copy of this per
> cpu type, i.e. all A25/AX25 cpus would share the same table.
> 
> You would of course need to hook class_init, which the current definition of
> DEFINE_CPU does not allow.  But that's easy to fix.
> 
> > +    /* Custom CSR value holder per hart */
> > +    void *custom_csr_val;
> >   };
> 
> Value singular?  Anyhow, I think that it's a mistake trying to hide the
> value structure in another file.  It complicates allocation of the
> CPURISCVState, and you have no mechanism by which to migrate the csr values.

What I'm trying to do here is to provide a hook for CSR value storage and let
it being set during CPU initilization. We have heterogeneous harts which
have different sets of CSRs.

> 
> I think you should simply place your structure here in CPURISCVState.
> 
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > +    gpointer ret;
> > +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > +    return ret;
> > +}
> 
> Fix the return type; the csr is not gpointer.
> It would be better to put the map not null test here.
> 
> I think it would be even better to name this find_csr,
> and include the normal index of csr_ops[] if the map
> test fails.

Wilco.

> 
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >           return RISCV_EXCP_ILLEGAL_INST;
> >       }
> > +    /* try to handle_custom_csr */
> > +    if (unlikely(env->custom_csr_map != NULL)) {
> > +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > +            find_custom_csr(env, csrno);
> > +        if (custom_csr_opset != NULL) {
> > +            csr_op = custom_csr_opset;
> > +            } else {
> > +            csr_op = &csr_ops[csrno];
> > +            }
> > +        } else {
> > +        csr_op = &csr_ops[csrno];
> > +        }
> 
> As Alistair noted, run checkpatch.pl to find all of these indentation errors.
> 
> That said, a better structure here would be
> 
>     csr_op = find_csr(env, csrno);
>     if (csr_op == NULL) {
>         return RISCV_EXCP_ILLEGAL_INST;
>     }

Thanks for the tips. Wilco.
> 
> 
> r~

Cordially yours,
Ruinland


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
  2021-10-21 22:43     ` Alistair Francis
@ 2021-10-22  8:36       ` Ruinland ChuanTzu Tsai
  -1 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22  8:36 UTC (permalink / raw)
  To: Alistair Francis
  Cc: ycliang, Alan Quey-Liang Kao((((((((((),
	wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
	open list:RISC-V, Bin Meng

On Fri, Oct 22, 2021 at 08:43:08AM +1000, Alistair Francis wrote:
> On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> >
> > If we're touching a custom CSR, invoke the registered handlers.
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> 
> Awesome! This looks really good :)
> 
> > ---
> >  target/riscv/cpu.c             | 19 +++++++++++++++++
> >  target/riscv/cpu.h             | 13 +++++++++++-
> >  target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
> >  target/riscv/custom_csr_defs.h |  7 +++++++
> >  4 files changed, 68 insertions(+), 9 deletions(-)
> >  create mode 100644 target/riscv/custom_csr_defs.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> >
> >  static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> >
> > +GHashTable *custom_csr_map = NULL;
> > +#include "custom_csr_defs.h"
> > +
> >  const char * const riscv_int_regnames[] = {
> >    "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
> >    "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> >  #endif
> >  }
> >
> > +static void setup_custom_csr(CPURISCVState *env,
> > +                             riscv_custom_csr_operations csr_map_struct[])
> > +{
> > +    int i;
> > +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > +    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;
> > +        }
> > +    }
> > +}
> > +
> >  static void riscv_any_cpu_init(Object *obj)
> >  {
> >      CPURISCVState *env = &RISCV_CPU(obj)->env;
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 3bef0d1265..012be10d0a 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> >
> >      /* Fields from here on are preserved across CPU reset. */
> >      QEMUTimer *timer; /* Internal timer */
> > +
> > +    /* Custom CSR opset table per hart */
> > +    GHashTable *custom_csr_map;
> > +    /* Custom CSR value holder per hart */
> > +    void *custom_csr_val;
> >  };
> >
> >  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> > @@ -496,9 +501,15 @@ 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 */
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 23fbbd3216..1048ee3b44 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
> >
> >  #endif
> >
> > +/* Custom CSR related routines */
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > +    gpointer ret;
> > +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > +    return ret;
> 
> You can just return directly here, so:
> 
> return g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> 
> Also, I think you need to run checkpatch.pl on this patch (you should
> run it on all patches).

Wilco.
Thanks for the tips.
And sorry for my negligence.

Cordially yours,
Ruinland

> 
> Alistair
> 
> > +}
> > +
> >  /*
> >   * riscv_csrrw - read and/or update control and status register
> >   *
> > @@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >      RISCVException ret;
> >      target_ulong old_value;
> >      RISCVCPU *cpu = env_archcpu(env);
> > +    riscv_csr_operations *csr_op;
> >      int read_only = get_field(csrno, 0xC00) == 3;
> >
> >      /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >          return RISCV_EXCP_ILLEGAL_INST;
> >      }
> >
> > +    /* try to handle_custom_csr */
> > +    if (unlikely(env->custom_csr_map != NULL)) {
> > +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > +            find_custom_csr(env, csrno);
> > +        if (custom_csr_opset != NULL) {
> > +            csr_op = custom_csr_opset;
> > +            } else {
> > +            csr_op = &csr_ops[csrno];
> > +            }
> > +        } else {
> > +        csr_op = &csr_ops[csrno];
> > +        }
> > +
> >      /* check predicate */
> > -    if (!csr_ops[csrno].predicate) {
> > +    if (!csr_op->predicate) {
> >          return RISCV_EXCP_ILLEGAL_INST;
> >      }
> > -    ret = csr_ops[csrno].predicate(env, csrno);
> > +    ret = csr_op->predicate(env, csrno);
> >      if (ret != RISCV_EXCP_NONE) {
> >          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 (csr_op->op) {
> > +        return csr_op->op(env, csrno, ret_value, new_value, write_mask);
> >      }
> >
> >      /* if no accessor exists then return failure */
> > -    if (!csr_ops[csrno].read) {
> > +    if (!csr_op->read) {
> >          return RISCV_EXCP_ILLEGAL_INST;
> >      }
> >      /* read old value */
> > -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> > +    ret = csr_op->read(env, csrno, &old_value);
> >      if (ret != RISCV_EXCP_NONE) {
> >          return ret;
> >      }
> > @@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >      /* 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 (csr_op->write) {
> > +            ret = csr_op->write(env, csrno, new_value);
> >              if (ret != RISCV_EXCP_NONE) {
> >                  return ret;
> >              }
> > diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> > new file mode 100644
> > index 0000000000..4dbf8cf1fd
> > --- /dev/null
> > +++ b/target/riscv/custom_csr_defs.h
> > @@ -0,0 +1,7 @@
> > +/*
> > + * Copyright (c) 2021 Andes Technology Corp.
> > + * SPDX-License-Identifier: GPL-2.0+
> > + * Custom CSR variables provided by <cpu_model_name>_csr.c
> > + */
> > +
> > +/* Left blank purposely in this commit. */
> > --
> > 2.25.1
> >


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-22  8:36       ` Ruinland ChuanTzu Tsai
  0 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22  8:36 UTC (permalink / raw)
  To: Alistair Francis
  Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
	open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
	Dylan Jhong

On Fri, Oct 22, 2021 at 08:43:08AM +1000, Alistair Francis wrote:
> On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> >
> > If we're touching a custom CSR, invoke the registered handlers.
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> 
> Awesome! This looks really good :)
> 
> > ---
> >  target/riscv/cpu.c             | 19 +++++++++++++++++
> >  target/riscv/cpu.h             | 13 +++++++++++-
> >  target/riscv/csr.c             | 38 +++++++++++++++++++++++++++-------
> >  target/riscv/custom_csr_defs.h |  7 +++++++
> >  4 files changed, 68 insertions(+), 9 deletions(-)
> >  create mode 100644 target/riscv/custom_csr_defs.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> >
> >  static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> >
> > +GHashTable *custom_csr_map = NULL;
> > +#include "custom_csr_defs.h"
> > +
> >  const char * const riscv_int_regnames[] = {
> >    "x0/zero", "x1/ra",  "x2/sp",  "x3/gp",  "x4/tp",  "x5/t0",   "x6/t1",
> >    "x7/t2",   "x8/s0",  "x9/s1",  "x10/a0", "x11/a1", "x12/a2",  "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> >  #endif
> >  }
> >
> > +static void setup_custom_csr(CPURISCVState *env,
> > +                             riscv_custom_csr_operations csr_map_struct[])
> > +{
> > +    int i;
> > +    env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > +    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;
> > +        }
> > +    }
> > +}
> > +
> >  static void riscv_any_cpu_init(Object *obj)
> >  {
> >      CPURISCVState *env = &RISCV_CPU(obj)->env;
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 3bef0d1265..012be10d0a 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> >
> >      /* Fields from here on are preserved across CPU reset. */
> >      QEMUTimer *timer; /* Internal timer */
> > +
> > +    /* Custom CSR opset table per hart */
> > +    GHashTable *custom_csr_map;
> > +    /* Custom CSR value holder per hart */
> > +    void *custom_csr_val;
> >  };
> >
> >  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> > @@ -496,9 +501,15 @@ 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 */
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 23fbbd3216..1048ee3b44 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
> >
> >  #endif
> >
> > +/* Custom CSR related routines */
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > +    gpointer ret;
> > +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > +    return ret;
> 
> You can just return directly here, so:
> 
> return g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> 
> Also, I think you need to run checkpatch.pl on this patch (you should
> run it on all patches).

Wilco.
Thanks for the tips.
And sorry for my negligence.

Cordially yours,
Ruinland

> 
> Alistair
> 
> > +}
> > +
> >  /*
> >   * riscv_csrrw - read and/or update control and status register
> >   *
> > @@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >      RISCVException ret;
> >      target_ulong old_value;
> >      RISCVCPU *cpu = env_archcpu(env);
> > +    riscv_csr_operations *csr_op;
> >      int read_only = get_field(csrno, 0xC00) == 3;
> >
> >      /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >          return RISCV_EXCP_ILLEGAL_INST;
> >      }
> >
> > +    /* try to handle_custom_csr */
> > +    if (unlikely(env->custom_csr_map != NULL)) {
> > +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > +            find_custom_csr(env, csrno);
> > +        if (custom_csr_opset != NULL) {
> > +            csr_op = custom_csr_opset;
> > +            } else {
> > +            csr_op = &csr_ops[csrno];
> > +            }
> > +        } else {
> > +        csr_op = &csr_ops[csrno];
> > +        }
> > +
> >      /* check predicate */
> > -    if (!csr_ops[csrno].predicate) {
> > +    if (!csr_op->predicate) {
> >          return RISCV_EXCP_ILLEGAL_INST;
> >      }
> > -    ret = csr_ops[csrno].predicate(env, csrno);
> > +    ret = csr_op->predicate(env, csrno);
> >      if (ret != RISCV_EXCP_NONE) {
> >          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 (csr_op->op) {
> > +        return csr_op->op(env, csrno, ret_value, new_value, write_mask);
> >      }
> >
> >      /* if no accessor exists then return failure */
> > -    if (!csr_ops[csrno].read) {
> > +    if (!csr_op->read) {
> >          return RISCV_EXCP_ILLEGAL_INST;
> >      }
> >      /* read old value */
> > -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> > +    ret = csr_op->read(env, csrno, &old_value);
> >      if (ret != RISCV_EXCP_NONE) {
> >          return ret;
> >      }
> > @@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> >      /* 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 (csr_op->write) {
> > +            ret = csr_op->write(env, csrno, new_value);
> >              if (ret != RISCV_EXCP_NONE) {
> >                  return ret;
> >              }
> > diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> > new file mode 100644
> > index 0000000000..4dbf8cf1fd
> > --- /dev/null
> > +++ b/target/riscv/custom_csr_defs.h
> > @@ -0,0 +1,7 @@
> > +/*
> > + * Copyright (c) 2021 Andes Technology Corp.
> > + * SPDX-License-Identifier: GPL-2.0+
> > + * Custom CSR variables provided by <cpu_model_name>_csr.c
> > + */
> > +
> > +/* Left blank purposely in this commit. */
> > --
> > 2.25.1
> >


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

* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
  2021-10-21 22:44     ` Alistair Francis
@ 2021-10-22  8:37       ` Ruinland ChuanTzu Tsai
  -1 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22  8:37 UTC (permalink / raw)
  To: Alistair Francis
  Cc: ycliang, Alan Quey-Liang Kao((((((((((),
	wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
	open list:RISC-V, Bin Meng

On Fri, Oct 22, 2021 at 08:44:56AM +1000, Alistair Francis wrote:
> On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > Add CSR bits definitions, CSR table and handler functions for Andes
> > AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> >  target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
> >  target/riscv/cpu.c             |   4 +
> >  target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
> >  target/riscv/custom_csr_defs.h |   3 +-
> >  target/riscv/meson.build       |   1 +
> >  5 files changed, 319 insertions(+), 1 deletion(-)
> >  create mode 100644 target/riscv/andes_cpu_bits.h
> >  create mode 100644 target/riscv/csr_andes.c
> >
> > diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> > new file mode 100644
> > index 0000000000..84b0900423
> > --- /dev/null
> > +++ b/target/riscv/andes_cpu_bits.h
> > @@ -0,0 +1,129 @@
> > +/*
> > + * SPDX-License-Identifier: GPL-2.0+
> > + *
> > + * Andes custom CSRs bit definitions
> > + *
> > + */
> > +
> > +/*
> > + * ========= Missing drafted/standard CSR definitions =========
> > + * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
> > + */
> > +#define CSR_TINFO           0x7a4
> > +
> > +#if !defined(CONFIG_USER_ONLY)
> > +/* ========= 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
> > +
> > +#endif /* !defined(CONFIG_USER_ONLY) */
> > +
> > +/* ========= 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 a72fd32f01..fe63e68b8e 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -192,6 +192,8 @@ 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(env, andes_custom_csr_table);
> > +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> >  }
> >
> >  static void rv64_sifive_u_cpu_init(Object *obj)
> > @@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
> >      CPURISCVState *env = &RISCV_CPU(obj)->env;
> >      set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> >      set_priv_version(env, PRIV_VERSION_1_10_0);
> > +    setup_custom_csr(env, andes_custom_csr_table);
> > +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> >  }
> >  #endif
> >
> > diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> > new file mode 100644
> > index 0000000000..8617f40483
> > --- /dev/null
> > +++ b/target/riscv/csr_andes.c
> > @@ -0,0 +1,183 @@
> > +/*
> > + * Copyright (c) 2021 Andes Technology Corp.
> > + * SPDX-License-Identifier: GPL-2.0+
> > + * Andes custom CSR table and handling functions
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/log.h"
> > +#include "cpu.h"
> > +#include "qemu/main-loop.h"
> > +#include "exec/exec-all.h"
> > +#include "andes_cpu_bits.h"
> > +
> > +struct andes_csr_val {
> > +    target_long uitb;
> > +};
> > +
> > +#if !defined(CONFIG_USER_ONLY)
> > +static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > +    /* enable pma probe */
> > +    *val = 0x40000000;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +#endif
> > +
> > +static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> > +    andes_csr->uitb = val;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> > +    *val = andes_csr->uitb;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +
> > +static RISCVException any(CPURISCVState *env, int csrno)
> > +{
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > +    *val = 0;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +int andes_custom_csr_size = sizeof(struct andes_csr_val);
> 
> I think just drop this value and use sizeof(struct andes_csr_val) in
> the other places.

Wilco.
Thanks for the tips.


Cordially yours,
Ruinland
> 
> I haven't checked this against the Andes spec, but overall the series
> looks good.
> 
> Alistair
> 
> > +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> > +    /* ========= AndeStar V5 machine mode CSRs ========= */
> > +    #if !defined(CONFIG_USER_ONLY)
> > +    /* 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} },
> > +    #endif
> > +
> > +    /* ========= 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 } },
> > +    };
> > diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> > index 4dbf8cf1fd..b09083585b 100644
> > --- a/target/riscv/custom_csr_defs.h
> > +++ b/target/riscv/custom_csr_defs.h
> > @@ -4,4 +4,5 @@
> >   * Custom CSR variables provided by <cpu_model_name>_csr.c
> >   */
> >
> > -/* Left blank purposely in this commit. */
> > +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
> > +extern int andes_custom_csr_size;
> > diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> > index d5e0bc93ea..5c87672ff9 100644
> > --- a/target/riscv/meson.build
> > +++ b/target/riscv/meson.build
> > @@ -9,6 +9,7 @@ gen = [
> >  riscv_ss = ss.source_set()
> >  riscv_ss.add(gen)
> >  riscv_ss.add(files(
> > +  'csr_andes.c',
> >    'cpu.c',
> >    'cpu_helper.c',
> >    'csr.c',
> > --
> > 2.25.1
> >


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

* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
@ 2021-10-22  8:37       ` Ruinland ChuanTzu Tsai
  0 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22  8:37 UTC (permalink / raw)
  To: Alistair Francis
  Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
	open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
	Dylan Jhong

On Fri, Oct 22, 2021 at 08:44:56AM +1000, Alistair Francis wrote:
> On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > Add CSR bits definitions, CSR table and handler functions for Andes
> > AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> >  target/riscv/andes_cpu_bits.h  | 129 +++++++++++++++++++++++
> >  target/riscv/cpu.c             |   4 +
> >  target/riscv/csr_andes.c       | 183 +++++++++++++++++++++++++++++++++
> >  target/riscv/custom_csr_defs.h |   3 +-
> >  target/riscv/meson.build       |   1 +
> >  5 files changed, 319 insertions(+), 1 deletion(-)
> >  create mode 100644 target/riscv/andes_cpu_bits.h
> >  create mode 100644 target/riscv/csr_andes.c
> >
> > diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> > new file mode 100644
> > index 0000000000..84b0900423
> > --- /dev/null
> > +++ b/target/riscv/andes_cpu_bits.h
> > @@ -0,0 +1,129 @@
> > +/*
> > + * SPDX-License-Identifier: GPL-2.0+
> > + *
> > + * Andes custom CSRs bit definitions
> > + *
> > + */
> > +
> > +/*
> > + * ========= Missing drafted/standard CSR definitions =========
> > + * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
> > + */
> > +#define CSR_TINFO           0x7a4
> > +
> > +#if !defined(CONFIG_USER_ONLY)
> > +/* ========= 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
> > +
> > +#endif /* !defined(CONFIG_USER_ONLY) */
> > +
> > +/* ========= 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 a72fd32f01..fe63e68b8e 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -192,6 +192,8 @@ 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(env, andes_custom_csr_table);
> > +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> >  }
> >
> >  static void rv64_sifive_u_cpu_init(Object *obj)
> > @@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
> >      CPURISCVState *env = &RISCV_CPU(obj)->env;
> >      set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> >      set_priv_version(env, PRIV_VERSION_1_10_0);
> > +    setup_custom_csr(env, andes_custom_csr_table);
> > +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> >  }
> >  #endif
> >
> > diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> > new file mode 100644
> > index 0000000000..8617f40483
> > --- /dev/null
> > +++ b/target/riscv/csr_andes.c
> > @@ -0,0 +1,183 @@
> > +/*
> > + * Copyright (c) 2021 Andes Technology Corp.
> > + * SPDX-License-Identifier: GPL-2.0+
> > + * Andes custom CSR table and handling functions
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/log.h"
> > +#include "cpu.h"
> > +#include "qemu/main-loop.h"
> > +#include "exec/exec-all.h"
> > +#include "andes_cpu_bits.h"
> > +
> > +struct andes_csr_val {
> > +    target_long uitb;
> > +};
> > +
> > +#if !defined(CONFIG_USER_ONLY)
> > +static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > +    /* enable pma probe */
> > +    *val = 0x40000000;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +#endif
> > +
> > +static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> > +    andes_csr->uitb = val;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> > +    *val = andes_csr->uitb;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +
> > +static RISCVException any(CPURISCVState *env, int csrno)
> > +{
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > +    *val = 0;
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > +    return RISCV_EXCP_NONE;
> > +}
> > +
> > +int andes_custom_csr_size = sizeof(struct andes_csr_val);
> 
> I think just drop this value and use sizeof(struct andes_csr_val) in
> the other places.

Wilco.
Thanks for the tips.


Cordially yours,
Ruinland
> 
> I haven't checked this against the Andes spec, but overall the series
> looks good.
> 
> Alistair
> 
> > +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> > +    /* ========= AndeStar V5 machine mode CSRs ========= */
> > +    #if !defined(CONFIG_USER_ONLY)
> > +    /* 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} },
> > +    #endif
> > +
> > +    /* ========= 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 } },
> > +    };
> > diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> > index 4dbf8cf1fd..b09083585b 100644
> > --- a/target/riscv/custom_csr_defs.h
> > +++ b/target/riscv/custom_csr_defs.h
> > @@ -4,4 +4,5 @@
> >   * Custom CSR variables provided by <cpu_model_name>_csr.c
> >   */
> >
> > -/* Left blank purposely in this commit. */
> > +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
> > +extern int andes_custom_csr_size;
> > diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> > index d5e0bc93ea..5c87672ff9 100644
> > --- a/target/riscv/meson.build
> > +++ b/target/riscv/meson.build
> > @@ -9,6 +9,7 @@ gen = [
> >  riscv_ss = ss.source_set()
> >  riscv_ss.add(gen)
> >  riscv_ss.add(files(
> > +  'csr_andes.c',
> >    'cpu.c',
> >    'cpu_helper.c',
> >    'csr.c',
> > --
> > 2.25.1
> >


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
  2021-10-22  8:34       ` Ruinland ChuanTzu Tsai
@ 2021-10-22 15:59         ` Richard Henderson
  -1 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22 15:59 UTC (permalink / raw)
  To: Ruinland ChuanTzu Tsai
  Cc: ycliang, qemu-riscv, alankao, wangjunqiang, dylan, qemu-devel,
	alistair23, bmeng.cn

On 10/22/21 1:34 AM, Ruinland ChuanTzu Tsai wrote:
>>> +    /* Custom CSR value holder per hart */
>>> +    void *custom_csr_val;
>>>    };
>>
>> Value singular?  Anyhow, I think that it's a mistake trying to hide the
>> value structure in another file.  It complicates allocation of the
>> CPURISCVState, and you have no mechanism by which to migrate the csr values.
> 
> What I'm trying to do here is to provide a hook for CSR value storage and let
> it being set during CPU initilization. We have heterogeneous harts which
> have different sets of CSRs.

I understand that, but the common CPURISCVState should contain the storage for all of the 
CSRs for every possible hart.

I might have made a different call if we had a more object-y language, but we have C.  The 
difference in size (here exactly one word) is not worth the complication of splitting 
structures apart.


r~


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

* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-22 15:59         ` Richard Henderson
  0 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22 15:59 UTC (permalink / raw)
  To: Ruinland ChuanTzu Tsai
  Cc: alistair23, wangjunqiang, bmeng.cn, ycliang, alankao, dylan,
	qemu-devel, qemu-riscv

On 10/22/21 1:34 AM, Ruinland ChuanTzu Tsai wrote:
>>> +    /* Custom CSR value holder per hart */
>>> +    void *custom_csr_val;
>>>    };
>>
>> Value singular?  Anyhow, I think that it's a mistake trying to hide the
>> value structure in another file.  It complicates allocation of the
>> CPURISCVState, and you have no mechanism by which to migrate the csr values.
> 
> What I'm trying to do here is to provide a hook for CSR value storage and let
> it being set during CPU initilization. We have heterogeneous harts which
> have different sets of CSRs.

I understand that, but the common CPURISCVState should contain the storage for all of the 
CSRs for every possible hart.

I might have made a different call if we had a more object-y language, but we have C.  The 
difference in size (here exactly one word) is not worth the complication of splitting 
structures apart.


r~


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

end of thread, other threads:[~2021-10-22 16:03 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-21 15:09 [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support Ruinland Chuan-Tzu Tsai
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
2021-10-21 15:09 ` [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models Ruinland Chuan-Tzu Tsai
2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
2021-10-21 22:33   ` Alistair Francis
2021-10-21 22:33     ` Alistair Francis
2021-10-21 15:09 ` [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw() Ruinland Chuan-Tzu Tsai
2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
2021-10-21 22:43   ` Alistair Francis
2021-10-21 22:43     ` Alistair Francis
2021-10-22  8:36     ` Ruinland ChuanTzu Tsai
2021-10-22  8:36       ` Ruinland ChuanTzu Tsai
2021-10-22  0:08   ` Richard Henderson
2021-10-22  0:08     ` Richard Henderson
2021-10-22  8:34     ` Ruinland ChuanTzu Tsai
2021-10-22  8:34       ` Ruinland ChuanTzu Tsai
2021-10-22 15:59       ` Richard Henderson
2021-10-22 15:59         ` Richard Henderson
2021-10-21 15:09 ` [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs Ruinland Chuan-Tzu Tsai
2021-10-21 15:09   ` Ruinland Chuan-Tzu Tsai
2021-10-21 22:44   ` Alistair Francis
2021-10-21 22:44     ` Alistair Francis
2021-10-22  8:37     ` Ruinland ChuanTzu Tsai
2021-10-22  8:37       ` Ruinland ChuanTzu Tsai
2021-10-22  1:12   ` Richard Henderson
2021-10-22  1:12     ` Richard Henderson
2021-10-21 22:47 ` [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support Alistair Francis
2021-10-21 22:47   ` 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.