All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v4 0/4] Add basic support for custom CSR
@ 2021-08-05 17:56 ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng

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

Dear all,

In this patch, the implementation of custom CSR handling logic is introduced.

If --enable-riscv-custom is set during configuration, custom CSR logic will be
turned on. During CPU model initialization, setup_custom_csr() is invoked to
register vendor-provided custom CSR opsets into a hash table.
When accessing a CSR, in riscv_csrrw(), is_custom_csr() will be called to check
whether the encountering csrno is a custom CSR. If that's a custom one, a
struct riscv_csr_operations will be returned and such CSR will be served
accordingly.

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

For a custom CSR, uitb, being accessed on andes-ax25 :
$ ./build/qemu-riscv64 -cpu andes-ax25 ./u
4.283091

For a stock CSR, fcsr, being accessed on andes-ax25:
$ ./build/qemu-riscv64 ./f
3.875519

For a custom CSR being accessed on stock rv64:
$ ./build/qemu-riscv64 -cpu rv64 ./u
Illegal instruction (core dumped)
# This is expected to fail.

Currently, the statics on my hands shows that :
When the custom CSR handling mechanism is activated, we will suffer a 17% slow-
down on stock CSRs and the penalty of accessing to a custom CSR will be another
7% more.

Cordially yours,
Ruinland ChuanTzu Tsai

Changes from v3 :
* Adding options in configure and meson files to turn on/off custom CSR logic.
* Adding unlikely() to check if custom_csr_map is set.
* Moving any32 and any out of !(CONFIG_USER_ONLY) for enabling linux-user mode.
* Fix comment style, add missing license boilerplate.


Ruinalnd ChuanTzu Tsai (4):
  Adding basic custom/vendor CSR handling mechanism
  Adding Andes AX25 and A25 CPU model
  Enable custom CSR logic for Andes AX25 and A25
  Add options to config/meson files for custom CSR

 configure                      |   6 ++
 meson.build                    |   2 +
 meson_options.txt              |   2 +
 target/riscv/andes_cpu_bits.h  | 124 +++++++++++++++++++++++++
 target/riscv/cpu.c             |  51 +++++++++++
 target/riscv/cpu.h             |  33 ++++++-
 target/riscv/cpu_bits.h        |   4 +
 target/riscv/csr.c             |  83 ++++++++++++++---
 target/riscv/csr_andes.inc.c   | 160 +++++++++++++++++++++++++++++++++
 target/riscv/custom_cpu_bits.h |  12 +++
 10 files changed, 462 insertions(+), 15 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.inc.c
 create mode 100644 target/riscv/custom_cpu_bits.h

-- 
2.32.0



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

* [RFC PATCH v4 0/4] Add basic support for custom CSR
@ 2021-08-05 17:56 ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng

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

Dear all,

In this patch, the implementation of custom CSR handling logic is introduced.

If --enable-riscv-custom is set during configuration, custom CSR logic will be
turned on. During CPU model initialization, setup_custom_csr() is invoked to
register vendor-provided custom CSR opsets into a hash table.
When accessing a CSR, in riscv_csrrw(), is_custom_csr() will be called to check
whether the encountering csrno is a custom CSR. If that's a custom one, a
struct riscv_csr_operations will be returned and such CSR will be served
accordingly.

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

For a custom CSR, uitb, being accessed on andes-ax25 :
$ ./build/qemu-riscv64 -cpu andes-ax25 ./u
4.283091

For a stock CSR, fcsr, being accessed on andes-ax25:
$ ./build/qemu-riscv64 ./f
3.875519

For a custom CSR being accessed on stock rv64:
$ ./build/qemu-riscv64 -cpu rv64 ./u
Illegal instruction (core dumped)
# This is expected to fail.

Currently, the statics on my hands shows that :
When the custom CSR handling mechanism is activated, we will suffer a 17% slow-
down on stock CSRs and the penalty of accessing to a custom CSR will be another
7% more.

Cordially yours,
Ruinland ChuanTzu Tsai

Changes from v3 :
* Adding options in configure and meson files to turn on/off custom CSR logic.
* Adding unlikely() to check if custom_csr_map is set.
* Moving any32 and any out of !(CONFIG_USER_ONLY) for enabling linux-user mode.
* Fix comment style, add missing license boilerplate.


Ruinalnd ChuanTzu Tsai (4):
  Adding basic custom/vendor CSR handling mechanism
  Adding Andes AX25 and A25 CPU model
  Enable custom CSR logic for Andes AX25 and A25
  Add options to config/meson files for custom CSR

 configure                      |   6 ++
 meson.build                    |   2 +
 meson_options.txt              |   2 +
 target/riscv/andes_cpu_bits.h  | 124 +++++++++++++++++++++++++
 target/riscv/cpu.c             |  51 +++++++++++
 target/riscv/cpu.h             |  33 ++++++-
 target/riscv/cpu_bits.h        |   4 +
 target/riscv/csr.c             |  83 ++++++++++++++---
 target/riscv/csr_andes.inc.c   | 160 +++++++++++++++++++++++++++++++++
 target/riscv/custom_cpu_bits.h |  12 +++
 10 files changed, 462 insertions(+), 15 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.inc.c
 create mode 100644 target/riscv/custom_cpu_bits.h

-- 
2.32.0



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

* [RFC PATCH v4 1/4] Add options to config/meson files for custom CSR
  2021-08-05 17:56 ` Ruinland Chuan-Tzu Tsai
@ 2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng, Dylan Jhong

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

Adding option `riscv_custom` to configure script, meson.build and
meson_options.txt so as to toggle custom CSR and will-be-upstreamed custom
instructions handling logic.

Signed-off-by: Dylan Jhong <dylan@andestech.com>
---
 configure         | 6 ++++++
 meson.build       | 2 ++
 meson_options.txt | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/configure b/configure
index 34fccaa..88f6584 100755
--- a/configure
+++ b/configure
@@ -324,6 +324,7 @@ virtiofsd="auto"
 virtfs="auto"
 libudev="auto"
 mpath="auto"
+riscv_custom="auto"
 vnc="enabled"
 sparse="auto"
 vde="$default_feature"
@@ -1016,6 +1017,10 @@ for opt do
   ;;
   --enable-vnc) vnc="enabled"
   ;;
+  --enable-riscv-custom) riscv_custom="enabled"
+  ;;
+  --disable-riscv-custom) riscv_custom="disabled"
+  ;;
   --disable-gettext) gettext="disabled"
   ;;
   --enable-gettext) gettext="enabled"
@@ -6416,6 +6421,7 @@ NINJA=$ninja $meson setup \
         -Dcocoa=$cocoa -Dgtk=$gtk -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \
         -Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \
         -Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f -Dvirtiofsd=$virtiofsd \
+        -Driscv_custom=$riscv_custom \
         -Dcapstone=$capstone -Dslirp=$slirp -Dfdt=$fdt -Dbrlapi=$brlapi \
         -Dcurl=$curl -Dglusterfs=$glusterfs -Dbzip2=$bzip2 -Dlibiscsi=$libiscsi \
         -Dlibnfs=$libnfs -Diconv=$iconv -Dcurses=$curses -Dlibudev=$libudev\
diff --git a/meson.build b/meson.build
index adeec15..736810e 100644
--- a/meson.build
+++ b/meson.build
@@ -1151,6 +1151,7 @@ config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
 
 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
+config_host_data.set('CONFIG_RISCV_CUSTOM', get_option('riscv_custom').enabled())
 
 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
@@ -2694,6 +2695,7 @@ summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
 summary_info += {'libudev':           libudev.found()}
 summary_info += {'FUSE lseek':        fuse_lseek.found()}
+summary_info += {'RISC-V custom CSRs/instructions': get_option('riscv_custom').enabled()}
 summary(summary_info, bool_yn: true, section: 'Dependencies')
 
 if not supported_cpus.contains(cpu)
diff --git a/meson_options.txt b/meson_options.txt
index 9734019..470ef23 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -125,3 +125,5 @@ option('slirp', type: 'combo', value: 'auto',
 option('fdt', type: 'combo', value: 'auto',
        choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],
        description: 'Whether and how to find the libfdt library')
+option('riscv_custom', type: 'feature', value: 'auto',
+       description: 'RISC-V custom')
-- 
2.32.0



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

* [RFC PATCH v4 1/4] Add options to config/meson files for custom CSR
@ 2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng, Dylan Jhong

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

Adding option `riscv_custom` to configure script, meson.build and
meson_options.txt so as to toggle custom CSR and will-be-upstreamed custom
instructions handling logic.

Signed-off-by: Dylan Jhong <dylan@andestech.com>
---
 configure         | 6 ++++++
 meson.build       | 2 ++
 meson_options.txt | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/configure b/configure
index 34fccaa..88f6584 100755
--- a/configure
+++ b/configure
@@ -324,6 +324,7 @@ virtiofsd="auto"
 virtfs="auto"
 libudev="auto"
 mpath="auto"
+riscv_custom="auto"
 vnc="enabled"
 sparse="auto"
 vde="$default_feature"
@@ -1016,6 +1017,10 @@ for opt do
   ;;
   --enable-vnc) vnc="enabled"
   ;;
+  --enable-riscv-custom) riscv_custom="enabled"
+  ;;
+  --disable-riscv-custom) riscv_custom="disabled"
+  ;;
   --disable-gettext) gettext="disabled"
   ;;
   --enable-gettext) gettext="enabled"
@@ -6416,6 +6421,7 @@ NINJA=$ninja $meson setup \
         -Dcocoa=$cocoa -Dgtk=$gtk -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \
         -Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \
         -Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f -Dvirtiofsd=$virtiofsd \
+        -Driscv_custom=$riscv_custom \
         -Dcapstone=$capstone -Dslirp=$slirp -Dfdt=$fdt -Dbrlapi=$brlapi \
         -Dcurl=$curl -Dglusterfs=$glusterfs -Dbzip2=$bzip2 -Dlibiscsi=$libiscsi \
         -Dlibnfs=$libnfs -Diconv=$iconv -Dcurses=$curses -Dlibudev=$libudev\
diff --git a/meson.build b/meson.build
index adeec15..736810e 100644
--- a/meson.build
+++ b/meson.build
@@ -1151,6 +1151,7 @@ config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
 
 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
+config_host_data.set('CONFIG_RISCV_CUSTOM', get_option('riscv_custom').enabled())
 
 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
@@ -2694,6 +2695,7 @@ summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
 summary_info += {'libudev':           libudev.found()}
 summary_info += {'FUSE lseek':        fuse_lseek.found()}
+summary_info += {'RISC-V custom CSRs/instructions': get_option('riscv_custom').enabled()}
 summary(summary_info, bool_yn: true, section: 'Dependencies')
 
 if not supported_cpus.contains(cpu)
diff --git a/meson_options.txt b/meson_options.txt
index 9734019..470ef23 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -125,3 +125,5 @@ option('slirp', type: 'combo', value: 'auto',
 option('fdt', type: 'combo', value: 'auto',
        choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],
        description: 'Whether and how to find the libfdt library')
+option('riscv_custom', type: 'feature', value: 'auto',
+       description: 'RISC-V custom')
-- 
2.32.0



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

* [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
  2021-08-05 17:56 ` Ruinland Chuan-Tzu Tsai
@ 2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng, Dylan Jhong

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

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

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

Signed-off-by: Dylan Jhong <dylan@andestech.com>
---
 target/riscv/cpu.c             | 23 ++++++++++
 target/riscv/cpu.h             | 31 ++++++++++++-
 target/riscv/cpu_bits.h        |  4 ++
 target/riscv/csr.c             | 83 ++++++++++++++++++++++++++++------
 target/riscv/custom_cpu_bits.h |  8 ++++
 5 files changed, 134 insertions(+), 15 deletions(-)
 create mode 100644 target/riscv/custom_cpu_bits.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7401325..3a638b5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -144,6 +144,29 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
 #endif
 }
 
+#if defined(CONFIG_RISCV_CUSTOM)
+static void setup_custom_csr(CPURISCVState *env,
+                             riscv_custom_csr_operations csr_map_struct[]
+                             ) {
+
+    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
+                                                g_direct_equal, \
+                                                NULL, NULL);
+
+
+    int i;
+    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
+        if (csr_map_struct[i].csrno != 0) {
+            g_hash_table_insert(env->custom_csr_map,
+                GINT_TO_POINTER(csr_map_struct[i].csrno),
+                &csr_map_struct[i].csr_opset);
+        } else {
+            break;
+        }
+    }
+}
+#endif
+
 static void riscv_any_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0edb282..52df9bb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -239,6 +239,16 @@ struct CPURISCVState {
 
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *timer; /* Internal timer */
+
+    /*
+     * The reason why we have an opset map for custom CSRs and a seperated
+     * storage map is that we might have heterogeneous architecture, in which
+     * different harts have different custom CSRs.
+     * Custom CSR opset map
+     */
+    GHashTable *custom_csr_map;
+    /* Custom CSR val holder */
+    void *custom_csr_val;
 };
 
 OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
@@ -485,17 +495,36 @@ typedef struct {
     riscv_csr_op_fn op;
 } riscv_csr_operations;
 
+typedef struct {
+    int csrno;
+    riscv_csr_operations csr_opset;
+    } riscv_custom_csr_operations;
+
+/*
+ * The reason why we have an abstraction here is that : We could have CSR
+ * number M on hart A is an alias of CSR number N on hart B. So we make a
+ * CSR number to value address map.
+ */
+typedef struct  {
+    int csrno;
+    target_ulong val;
+    } riscv_custom_csr_vals;
+
 /* CSR function table constants */
 enum {
-    CSR_TABLE_SIZE = 0x1000
+    CSR_TABLE_SIZE = 0x1000,
+    MAX_CUSTOM_CSR_NUM = 100
 };
 
 /* CSR function table */
+extern int andes_custom_csr_size;
+extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 
 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
 
+
 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index caf4599..de77242 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -593,3 +593,7 @@
 #define MIE_SSIE                           (1 << IRQ_S_SOFT)
 #define MIE_USIE                           (1 << IRQ_U_SOFT)
 #endif
+
+#if defined(CONFIG_RISCV_CUSTOM)
+#include "custom_cpu_bits.h"
+#endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fd2e636..1c4dc94 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -137,7 +137,8 @@ static int ctr32(CPURISCVState *env, int csrno)
     return ctr(env, csrno);
 }
 
-#if !defined(CONFIG_USER_ONLY)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
 static int any(CPURISCVState *env, int csrno)
 {
     return 0;
@@ -152,6 +153,25 @@ static int any32(CPURISCVState *env, int csrno)
     return any(env, csrno);
 
 }
+#pragma GCC diagnostic pop
+
+/* Machine Information Registers */
+static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    return *val = 0;
+}
+
+/*
+ * XXX: This is just a write stub for developing custom CSR handler,
+ * if the behavior of writting such CSR is not presentable in QEMU and doesn't
+ * affect the functionality, just stub it.
+ */
+static int write_stub(CPURISCVState *env, int csrno, target_ulong val)
+{
+    return 0;
+}
+
+#if !defined(CONFIG_USER_ONLY)
 
 static int smode(CPURISCVState *env, int csrno)
 {
@@ -435,11 +455,6 @@ static const char valid_vm_1_10_64[16] = {
     [VM_1_10_SV57] = 1
 };
 
-/* Machine Information Registers */
-static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
-{
-    return *val = 0;
-}
 
 static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
 {
@@ -1264,6 +1279,18 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
 
 #endif
 
+
+#if defined(CONFIG_RISCV_CUSTOM)
+/* Custom CSR related routines and data structures */
+
+static gpointer is_custom_csr(CPURISCVState *env, int csrno)
+{
+    gpointer ret;
+    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
+    return ret;
+}
+#endif
+
 /*
  * riscv_csrrw - read and/or update control and status register
  *
@@ -1273,12 +1300,19 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
  * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
  */
 
+
+
 int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
                 target_ulong new_value, target_ulong write_mask)
 {
     int ret;
     target_ulong old_value;
     RISCVCPU *cpu = env_archcpu(env);
+    #if !defined(CONFIG_RISCV_CUSTOM)
+    riscv_csr_operations *csrop = &csr_ops[csrno];
+    #else
+    riscv_csr_operations *csrop;
+    #endif
 
     /* check privileges and return -1 if check fails */
 #if !defined(CONFIG_USER_ONLY)
@@ -1300,6 +1334,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
         (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
+
 #endif
 
     /* ensure the CSR extension is enabled. */
@@ -1307,27 +1342,43 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
         return -RISCV_EXCP_ILLEGAL_INST;
     }
 
+    /* try handle_custom_csr */
+
+    #if defined(CONFIG_RISCV_CUSTOM)
+    if (unlikely(env->custom_csr_map != NULL)) {
+        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
+            is_custom_csr(env, csrno);
+        if (NULL != custom_csr_opset) {
+            csrop = custom_csr_opset;
+            } else {
+            csrop = &csr_ops[csrno];
+            }
+        } else {
+        csrop = &csr_ops[csrno];
+        }
+    #endif
+
     /* check predicate */
-    if (!csr_ops[csrno].predicate) {
+    if (!csrop->predicate) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
-    ret = csr_ops[csrno].predicate(env, csrno);
+    ret = csrop->predicate(env, csrno);
     if (ret < 0) {
         return ret;
     }
 
     /* execute combined read/write operation if it exists */
-    if (csr_ops[csrno].op) {
-        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
+    if (csrop->op) {
+        return csrop->op(env, csrno, ret_value, new_value, write_mask);
     }
 
     /* if no accessor exists then return failure */
-    if (!csr_ops[csrno].read) {
+    if (!csrop->read) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
 
     /* read old value */
-    ret = csr_ops[csrno].read(env, csrno, &old_value);
+    ret = csrop->read(env, csrno, &old_value);
     if (ret < 0) {
         return ret;
     }
@@ -1335,8 +1386,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
     /* write value if writable and write mask set, otherwise drop writes */
     if (write_mask) {
         new_value = (old_value & ~write_mask) | (new_value & write_mask);
-        if (csr_ops[csrno].write) {
-            ret = csr_ops[csrno].write(env, csrno, new_value);
+        if (csrop->write) {
+            ret = csrop->write(env, csrno, new_value);
             if (ret < 0) {
                 return ret;
             }
@@ -1369,6 +1420,10 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
     return ret;
 }
 
+#if defined(CONFIG_RISCV_CUSTOM)
+/* Include the custom CSR table here. */
+#endif
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     /* User Floating-Point CSRs */
diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
new file mode 100644
index 0000000..5df31f8
--- /dev/null
+++ b/target/riscv/custom_cpu_bits.h
@@ -0,0 +1,8 @@
+/*
+ * RISC-V cpu bits for custom CSR logic.
+ *
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* This file is intentionally left blank at this commit. */
-- 
2.32.0



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

* [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
@ 2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng, Dylan Jhong

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

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

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

Signed-off-by: Dylan Jhong <dylan@andestech.com>
---
 target/riscv/cpu.c             | 23 ++++++++++
 target/riscv/cpu.h             | 31 ++++++++++++-
 target/riscv/cpu_bits.h        |  4 ++
 target/riscv/csr.c             | 83 ++++++++++++++++++++++++++++------
 target/riscv/custom_cpu_bits.h |  8 ++++
 5 files changed, 134 insertions(+), 15 deletions(-)
 create mode 100644 target/riscv/custom_cpu_bits.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7401325..3a638b5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -144,6 +144,29 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
 #endif
 }
 
+#if defined(CONFIG_RISCV_CUSTOM)
+static void setup_custom_csr(CPURISCVState *env,
+                             riscv_custom_csr_operations csr_map_struct[]
+                             ) {
+
+    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
+                                                g_direct_equal, \
+                                                NULL, NULL);
+
+
+    int i;
+    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
+        if (csr_map_struct[i].csrno != 0) {
+            g_hash_table_insert(env->custom_csr_map,
+                GINT_TO_POINTER(csr_map_struct[i].csrno),
+                &csr_map_struct[i].csr_opset);
+        } else {
+            break;
+        }
+    }
+}
+#endif
+
 static void riscv_any_cpu_init(Object *obj)
 {
     CPURISCVState *env = &RISCV_CPU(obj)->env;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0edb282..52df9bb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -239,6 +239,16 @@ struct CPURISCVState {
 
     /* Fields from here on are preserved across CPU reset. */
     QEMUTimer *timer; /* Internal timer */
+
+    /*
+     * The reason why we have an opset map for custom CSRs and a seperated
+     * storage map is that we might have heterogeneous architecture, in which
+     * different harts have different custom CSRs.
+     * Custom CSR opset map
+     */
+    GHashTable *custom_csr_map;
+    /* Custom CSR val holder */
+    void *custom_csr_val;
 };
 
 OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
@@ -485,17 +495,36 @@ typedef struct {
     riscv_csr_op_fn op;
 } riscv_csr_operations;
 
+typedef struct {
+    int csrno;
+    riscv_csr_operations csr_opset;
+    } riscv_custom_csr_operations;
+
+/*
+ * The reason why we have an abstraction here is that : We could have CSR
+ * number M on hart A is an alias of CSR number N on hart B. So we make a
+ * CSR number to value address map.
+ */
+typedef struct  {
+    int csrno;
+    target_ulong val;
+    } riscv_custom_csr_vals;
+
 /* CSR function table constants */
 enum {
-    CSR_TABLE_SIZE = 0x1000
+    CSR_TABLE_SIZE = 0x1000,
+    MAX_CUSTOM_CSR_NUM = 100
 };
 
 /* CSR function table */
+extern int andes_custom_csr_size;
+extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 
 void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
 void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
 
+
 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index caf4599..de77242 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -593,3 +593,7 @@
 #define MIE_SSIE                           (1 << IRQ_S_SOFT)
 #define MIE_USIE                           (1 << IRQ_U_SOFT)
 #endif
+
+#if defined(CONFIG_RISCV_CUSTOM)
+#include "custom_cpu_bits.h"
+#endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fd2e636..1c4dc94 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -137,7 +137,8 @@ static int ctr32(CPURISCVState *env, int csrno)
     return ctr(env, csrno);
 }
 
-#if !defined(CONFIG_USER_ONLY)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
 static int any(CPURISCVState *env, int csrno)
 {
     return 0;
@@ -152,6 +153,25 @@ static int any32(CPURISCVState *env, int csrno)
     return any(env, csrno);
 
 }
+#pragma GCC diagnostic pop
+
+/* Machine Information Registers */
+static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    return *val = 0;
+}
+
+/*
+ * XXX: This is just a write stub for developing custom CSR handler,
+ * if the behavior of writting such CSR is not presentable in QEMU and doesn't
+ * affect the functionality, just stub it.
+ */
+static int write_stub(CPURISCVState *env, int csrno, target_ulong val)
+{
+    return 0;
+}
+
+#if !defined(CONFIG_USER_ONLY)
 
 static int smode(CPURISCVState *env, int csrno)
 {
@@ -435,11 +455,6 @@ static const char valid_vm_1_10_64[16] = {
     [VM_1_10_SV57] = 1
 };
 
-/* Machine Information Registers */
-static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
-{
-    return *val = 0;
-}
 
 static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
 {
@@ -1264,6 +1279,18 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
 
 #endif
 
+
+#if defined(CONFIG_RISCV_CUSTOM)
+/* Custom CSR related routines and data structures */
+
+static gpointer is_custom_csr(CPURISCVState *env, int csrno)
+{
+    gpointer ret;
+    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
+    return ret;
+}
+#endif
+
 /*
  * riscv_csrrw - read and/or update control and status register
  *
@@ -1273,12 +1300,19 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
  * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
  */
 
+
+
 int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
                 target_ulong new_value, target_ulong write_mask)
 {
     int ret;
     target_ulong old_value;
     RISCVCPU *cpu = env_archcpu(env);
+    #if !defined(CONFIG_RISCV_CUSTOM)
+    riscv_csr_operations *csrop = &csr_ops[csrno];
+    #else
+    riscv_csr_operations *csrop;
+    #endif
 
     /* check privileges and return -1 if check fails */
 #if !defined(CONFIG_USER_ONLY)
@@ -1300,6 +1334,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
         (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
+
 #endif
 
     /* ensure the CSR extension is enabled. */
@@ -1307,27 +1342,43 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
         return -RISCV_EXCP_ILLEGAL_INST;
     }
 
+    /* try handle_custom_csr */
+
+    #if defined(CONFIG_RISCV_CUSTOM)
+    if (unlikely(env->custom_csr_map != NULL)) {
+        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
+            is_custom_csr(env, csrno);
+        if (NULL != custom_csr_opset) {
+            csrop = custom_csr_opset;
+            } else {
+            csrop = &csr_ops[csrno];
+            }
+        } else {
+        csrop = &csr_ops[csrno];
+        }
+    #endif
+
     /* check predicate */
-    if (!csr_ops[csrno].predicate) {
+    if (!csrop->predicate) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
-    ret = csr_ops[csrno].predicate(env, csrno);
+    ret = csrop->predicate(env, csrno);
     if (ret < 0) {
         return ret;
     }
 
     /* execute combined read/write operation if it exists */
-    if (csr_ops[csrno].op) {
-        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
+    if (csrop->op) {
+        return csrop->op(env, csrno, ret_value, new_value, write_mask);
     }
 
     /* if no accessor exists then return failure */
-    if (!csr_ops[csrno].read) {
+    if (!csrop->read) {
         return -RISCV_EXCP_ILLEGAL_INST;
     }
 
     /* read old value */
-    ret = csr_ops[csrno].read(env, csrno, &old_value);
+    ret = csrop->read(env, csrno, &old_value);
     if (ret < 0) {
         return ret;
     }
@@ -1335,8 +1386,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
     /* write value if writable and write mask set, otherwise drop writes */
     if (write_mask) {
         new_value = (old_value & ~write_mask) | (new_value & write_mask);
-        if (csr_ops[csrno].write) {
-            ret = csr_ops[csrno].write(env, csrno, new_value);
+        if (csrop->write) {
+            ret = csrop->write(env, csrno, new_value);
             if (ret < 0) {
                 return ret;
             }
@@ -1369,6 +1420,10 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
     return ret;
 }
 
+#if defined(CONFIG_RISCV_CUSTOM)
+/* Include the custom CSR table here. */
+#endif
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
     /* User Floating-Point CSRs */
diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
new file mode 100644
index 0000000..5df31f8
--- /dev/null
+++ b/target/riscv/custom_cpu_bits.h
@@ -0,0 +1,8 @@
+/*
+ * RISC-V cpu bits for custom CSR logic.
+ *
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* This file is intentionally left blank at this commit. */
-- 
2.32.0



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

* [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
  2021-08-05 17:56 ` Ruinland Chuan-Tzu Tsai
@ 2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng, Dylan Jhong

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

Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without
enhanced features (yet).

Signed-off-by: Dylan Jhong <dylan@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 3a638b5..9eb1e3a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -182,6 +182,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;
@@ -235,6 +242,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)
@@ -726,8 +740,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),
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 52df9bb..bd79d63 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_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
 #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
-- 
2.32.0



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

* [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
@ 2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng, Dylan Jhong

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

Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without
enhanced features (yet).

Signed-off-by: Dylan Jhong <dylan@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 3a638b5..9eb1e3a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -182,6 +182,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;
@@ -235,6 +242,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)
@@ -726,8 +740,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),
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 52df9bb..bd79d63 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_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
 #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")
-- 
2.32.0



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

* [RFC PATCH v4 4/4] Enable custom CSR logic for Andes AX25 and A25
  2021-08-05 17:56 ` Ruinland Chuan-Tzu Tsai
@ 2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
  -1 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng, Dylan Jhong

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

In this patch we enabled custom CSR logic for Andes AX25 and A25 logic.
Hence csr_andes.inc.c and andes_cpu_bits.h is added.

Signed-off-by: Dylan Jhong <dylan@andestech.com>
---
 target/riscv/andes_cpu_bits.h  | 124 +++++++++++++++++++++++++
 target/riscv/cpu.c             |  12 +++
 target/riscv/csr.c             |   2 +-
 target/riscv/csr_andes.inc.c   | 160 +++++++++++++++++++++++++++++++++
 target/riscv/custom_cpu_bits.h |   6 +-
 5 files changed, 302 insertions(+), 2 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.inc.c

diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
new file mode 100644
index 0000000..bd2b7d1
--- /dev/null
+++ b/target/riscv/andes_cpu_bits.h
@@ -0,0 +1,124 @@
+/*
+ * Andes custom CSRs bit definitions
+ *
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* ========= Missing drafted/standard CSR definitions */
+/* Although TINFO is in official debug sepc, it's not in cpu_bits.h yet. */
+#define CSR_TINFO           0x7a4
+
+/* ========= AndeStar V5 machine mode CSRs ========= */
+/* Configuration Registers */
+#define CSR_MICM_CFG            0xfc0
+#define CSR_MDCM_CFG            0xfc1
+#define CSR_MMSC_CFG            0xfc2
+#define CSR_MMSC_CFG2           0xfc3
+#define CSR_MVEC_CFG            0xfc7
+
+/* Crash Debug CSRs */
+#define CSR_MCRASH_STATESAVE    0xfc8
+#define CSR_MSTATUS_CRASHSAVE   0xfc9
+
+/* Memory CSRs */
+#define CSR_MILMB               0x7c0
+#define CSR_MDLMB               0x7c1
+#define CSR_MECC_CODE           0x7C2
+#define CSR_MNVEC               0x7c3
+#define CSR_MCACHE_CTL          0x7ca
+#define CSR_MCCTLBEGINADDR      0x7cb
+#define CSR_MCCTLCOMMAND        0x7cc
+#define CSR_MCCTLDATA           0x7cd
+#define CSR_MPPIB               0x7f0
+#define CSR_MFIOB               0x7f1
+
+/* Hardware Stack Protection & Recording */
+#define CSR_MHSP_CTL            0x7c6
+#define CSR_MSP_BOUND           0x7c7
+#define CSR_MSP_BASE            0x7c8
+#define CSR_MXSTATUS            0x7c4
+#define CSR_MDCAUSE             0x7c9
+#define CSR_MSLIDELEG           0x7d5
+#define CSR_MSAVESTATUS         0x7d6
+#define CSR_MSAVEEPC1           0x7d7
+#define CSR_MSAVECAUSE1         0x7d8
+#define CSR_MSAVEEPC2           0x7d9
+#define CSR_MSAVECAUSE2         0x7da
+#define CSR_MSAVEDCAUSE1        0x7db
+#define CSR_MSAVEDCAUSE2        0x7dc
+
+/* Control CSRs */
+#define CSR_MPFT_CTL            0x7c5
+#define CSR_MMISC_CTL           0x7d0
+#define CSR_MCLK_CTL            0x7df
+
+/* Counter related CSRs */
+#define CSR_MCOUNTERWEN         0x7ce
+#define CSR_MCOUNTERINTEN       0x7cf
+#define CSR_MCOUNTERMASK_M      0x7d1
+#define CSR_MCOUNTERMASK_S      0x7d2
+#define CSR_MCOUNTERMASK_U      0x7d3
+#define CSR_MCOUNTEROVF         0x7d4
+
+/* Enhanced CLIC CSRs */
+#define CSR_MIRQ_ENTRY          0x7ec
+#define CSR_MINTSEL_JAL         0x7ed
+#define CSR_PUSHMCAUSE          0x7ee
+#define CSR_PUSHMEPC            0x7ef
+#define CSR_PUSHMXSTATUS        0x7eb
+
+/* Andes Physical Memory Attribute(PMA) CSRs */
+#define CSR_PMACFG0             0xbc0
+#define CSR_PMACFG1             0xbc1
+#define CSR_PMACFG2             0xbc2
+#define CSR_PMACFG3             0xbc3
+#define CSR_PMAADDR0            0xbd0
+#define CSR_PMAADDR1            0xbd1
+#define CSR_PMAADDR2            0xbd2
+#define CSR_PMAADDR3            0xbd2
+#define CSR_PMAADDR4            0xbd4
+#define CSR_PMAADDR5            0xbd5
+#define CSR_PMAADDR6            0xbd6
+#define CSR_PMAADDR7            0xbd7
+#define CSR_PMAADDR8            0xbd8
+#define CSR_PMAADDR9            0xbd9
+#define CSR_PMAADDR10           0xbda
+#define CSR_PMAADDR11           0xbdb
+#define CSR_PMAADDR12           0xbdc
+#define CSR_PMAADDR13           0xbdd
+#define CSR_PMAADDR14           0xbde
+#define CSR_PMAADDR15           0xbdf
+
+/* ========= AndeStar V5 supervisor mode CSRs ========= */
+/* Supervisor trap registers */
+#define CSR_SLIE                0x9c4
+#define CSR_SLIP                0x9c5
+#define CSR_SDCAUSE             0x9c9
+
+/* Supervisor counter registers */
+#define CSR_SCOUNTERINTEN       0x9cf
+#define CSR_SCOUNTERMASK_M      0x9d1
+#define CSR_SCOUNTERMASK_S      0x9d2
+#define CSR_SCOUNTERMASK_U      0x9d3
+#define CSR_SCOUNTEROVF         0x9d4
+#define CSR_SCOUNTINHIBIT       0x9e0
+#define CSR_SHPMEVENT3          0x9e3
+#define CSR_SHPMEVENT4          0x9e4
+#define CSR_SHPMEVENT5          0x9e5
+#define CSR_SHPMEVENT6          0x9e6
+
+/* Supervisor control registers */
+#define CSR_SCCTLDATA           0x9cd
+#define CSR_SMISC_CTL           0x9d0
+
+/* ========= AndeStar V5 user mode CSRs ========= */
+/* User mode control registers */
+#define CSR_UITB                0x800
+#define CSR_UCODE               0x801
+#define CSR_UDCAUSE             0x809
+#define CSR_UCCTLBEGINADDR      0x80b
+#define CSR_UCCTLCOMMAND        0x80c
+#define CSR_WFE                 0x810
+#define CSR_SLEEPVALUE          0x811
+#define CSR_TXEVT               0x812
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9eb1e3a..d1d4773 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -187,6 +187,12 @@ 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);
+
+    #if defined(CONFIG_RISCV_CUSTOM)
+    /* setup custom csr handler hash table */
+    setup_custom_csr(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
+    #endif
 }
 
 static void rv64_sifive_u_cpu_init(Object *obj)
@@ -248,6 +254,12 @@ 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);
+
+    #if defined(CONFIG_RISCV_CUSTOM)
+    /* setup custom csr handler hash table */
+    setup_custom_csr(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
+    #endif
 }
 #endif
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 1c4dc94..9c16b88 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1421,7 +1421,7 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
 }
 
 #if defined(CONFIG_RISCV_CUSTOM)
-/* Include the custom CSR table here. */
+#include "csr_andes.inc.c"
 #endif
 
 /* Control and Status Register function table */
diff --git a/target/riscv/csr_andes.inc.c b/target/riscv/csr_andes.inc.c
new file mode 100644
index 0000000..da226b0
--- /dev/null
+++ b/target/riscv/csr_andes.inc.c
@@ -0,0 +1,160 @@
+/*
+ * Andes custom CSR table and handling functions
+ *
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+static int write_uitb(CPURISCVState *env, int csrno, target_ulong val);
+static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val);
+
+struct andes_csr_val {
+    target_long uitb;
+};
+
+static int read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    /* enable pma probe */
+    *val = 0x40000000;
+    return 0;
+}
+
+static int write_uitb(CPURISCVState *env, int csrno, target_ulong val)
+{
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    andes_csr->uitb = val;
+    return 0;
+}
+
+static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    *val = andes_csr->uitb;
+    return 0;
+}
+
+
+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 ==================== */
+    /* Configuration Registers */
+    {CSR_MICM_CFG,         { "micm_cfg",          any, read_zero, write_stub} },
+    {CSR_MDCM_CFG,         { "mdcm_cfg",          any, read_zero, write_stub} },
+    {CSR_MMSC_CFG,         { "mmsc_cfg",          any, read_mmsc_cfg, write_stub} },
+    {CSR_MMSC_CFG2,        { "mmsc_cfg2",         any, read_zero, write_stub} },
+    {CSR_MVEC_CFG,         { "mvec_cfg",          any, read_zero, write_stub} },
+
+    /* Crash Debug CSRs */
+    {CSR_MCRASH_STATESAVE,  { "mcrash_statesave",  any, read_zero, write_stub} },
+    {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
+
+    /* Memory CSRs */
+    {CSR_MILMB,            { "milmb",             any, read_zero, write_stub} },
+    {CSR_MDLMB,            { "mdlmb",             any, read_zero, write_stub} },
+    {CSR_MECC_CODE,        { "mecc_code",         any, read_zero, write_stub} },
+    {CSR_MNVEC,            { "mnvec",             any, read_zero, write_stub} },
+    {CSR_MCACHE_CTL,       { "mcache_ctl",        any, read_zero, write_stub} },
+    {CSR_MCCTLBEGINADDR,   { "mcctlbeginaddr",    any, read_zero, write_stub} },
+    {CSR_MCCTLCOMMAND,     { "mcctlcommand",      any, read_zero, write_stub} },
+    {CSR_MCCTLDATA,        { "mcctldata",         any, read_zero, write_stub} },
+    {CSR_MPPIB,            { "mppib",             any, read_zero, write_stub} },
+    {CSR_MFIOB,            { "mfiob",             any, read_zero, write_stub} },
+
+    /* Hardware Stack Protection & Recording */
+    {CSR_MHSP_CTL,         { "mhsp_ctl",          any, read_zero, write_stub} },
+    {CSR_MSP_BOUND,        { "msp_bound",         any, read_zero, write_stub} },
+    {CSR_MSP_BASE,         { "msp_base",          any, read_zero, write_stub} },
+    {CSR_MXSTATUS,         { "mxstatus",          any, read_zero, write_stub} },
+    {CSR_MDCAUSE,          { "mdcause",           any, read_zero, write_stub} },
+    {CSR_MSLIDELEG,        { "mslideleg",         any, read_zero, write_stub} },
+    {CSR_MSAVESTATUS,      { "msavestatus",       any, read_zero, write_stub} },
+    {CSR_MSAVEEPC1,        { "msaveepc1",         any, read_zero, write_stub} },
+    {CSR_MSAVECAUSE1,      { "msavecause1",       any, read_zero, write_stub} },
+    {CSR_MSAVEEPC2,        { "msaveepc2",         any, read_zero, write_stub} },
+    {CSR_MSAVECAUSE2,      { "msavecause2",       any, read_zero, write_stub} },
+    {CSR_MSAVEDCAUSE1,     { "msavedcause1",      any, read_zero, write_stub} },
+    {CSR_MSAVEDCAUSE2,     { "msavedcause2",      any, read_zero, write_stub} },
+
+    /* Control CSRs */
+    {CSR_MPFT_CTL,         { "mpft_ctl",          any, read_zero, write_stub} },
+    {CSR_MMISC_CTL,        { "mmisc_ctl",         any, read_zero, write_stub} },
+    {CSR_MCLK_CTL,         { "mclk_ctl",          any, read_zero, write_stub} },
+
+    /* Counter related CSRs */
+    {CSR_MCOUNTERWEN,      { "mcounterwen",       any, read_zero, write_stub} },
+    {CSR_MCOUNTERINTEN,    { "mcounterinten",     any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_M,   { "mcountermask_m",    any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_S,   { "mcountermask_s",    any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_U,   { "mcountermask_u",    any, read_zero, write_stub} },
+    {CSR_MCOUNTEROVF,      { "mcounterovf",       any, read_zero, write_stub} },
+
+    /* Enhanced CLIC CSRs */
+    {CSR_MIRQ_ENTRY,       { "mirq_entry",        any, read_zero, write_stub} },
+    {CSR_MINTSEL_JAL,      { "mintsel_jal",       any, read_zero, write_stub} },
+    {CSR_PUSHMCAUSE,       { "pushmcause",        any, read_zero, write_stub} },
+    {CSR_PUSHMEPC,         { "pushmepc",          any, read_zero, write_stub} },
+    {CSR_PUSHMXSTATUS,     { "pushmxstatus",      any, read_zero, write_stub} },
+
+    /* Andes Physical Memory Attribute(PMA) CSRs */
+    {CSR_PMACFG0,          { "pmacfg0",           any, read_zero, write_stub} },
+    {CSR_PMACFG1,          { "pmacfg1",           any, read_zero, write_stub} },
+    {CSR_PMACFG2,          { "pmacfg2",           any, read_zero, write_stub} },
+    {CSR_PMACFG3,          { "pmacfg3",           any, read_zero, write_stub} },
+    {CSR_PMAADDR0,         { "pmaaddr0",          any, read_zero, write_stub} },
+    {CSR_PMAADDR1,         { "pmaaddr1",          any, read_zero, write_stub} },
+    {CSR_PMAADDR2,         { "pmaaddr2",          any, read_zero, write_stub} },
+    {CSR_PMAADDR3,         { "pmaaddr3",          any, read_zero, write_stub} },
+    {CSR_PMAADDR4,         { "pmaaddr4",          any, read_zero, write_stub} },
+    {CSR_PMAADDR5,         { "pmaaddr5",          any, read_zero, write_stub} },
+    {CSR_PMAADDR6,         { "pmaaddr6",          any, read_zero, write_stub} },
+    {CSR_PMAADDR7,         { "pmaaddr7",          any, read_zero, write_stub} },
+    {CSR_PMAADDR8,         { "pmaaddr8",          any, read_zero, write_stub} },
+    {CSR_PMAADDR9,         { "pmaaddr9",          any, read_zero, write_stub} },
+    {CSR_PMAADDR10,        { "pmaaddr10",         any, read_zero, write_stub} },
+    {CSR_PMAADDR11,        { "pmaaddr11",         any, read_zero, write_stub} },
+    {CSR_PMAADDR12,        { "pmaaddr12",         any, read_zero, write_stub} },
+    {CSR_PMAADDR13,        { "pmaaddr13",         any, read_zero, write_stub} },
+    {CSR_PMAADDR14,        { "pmaaddr14",         any, read_zero, write_stub} },
+    {CSR_PMAADDR15,        { "pmaaddr15",         any, read_zero, write_stub} },
+
+    /* Debug/Trace Registers (shared with Debug Mode) */
+    {CSR_TSELECT,          { "tselect",           any, read_zero, write_stub} },
+    {CSR_TDATA1,           { "tdata1",            any, read_zero, write_stub} },
+    {CSR_TDATA2,           { "tdata2",            any, read_zero, write_stub} },
+    {CSR_TDATA3,           { "tdata3",            any, read_zero, write_stub} },
+    {CSR_TINFO,            { "tinfo",             any, read_zero, write_stub} },
+
+    /* ================== AndeStar V5 supervisor mode CSRs ================== */
+    /* Supervisor trap registers */
+    {CSR_SLIE,             { "slie",              any, read_zero, write_stub} },
+    {CSR_SLIP,             { "slip",              any, read_zero, write_stub} },
+    {CSR_SDCAUSE,          { "sdcause",           any, read_zero, write_stub} },
+
+    /* Supervisor counter registers */
+    {CSR_SCOUNTERINTEN,    { "scounterinten",     any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_M,   { "scountermask_m",    any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_S,   { "scountermask_s",    any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_U,   { "scountermask_u",    any, read_zero, write_stub} },
+    {CSR_SCOUNTEROVF,      { "scounterovf",       any, read_zero, write_stub} },
+    {CSR_SCOUNTINHIBIT,    { "scountinhibit",     any, read_zero, write_stub} },
+    {CSR_SHPMEVENT3,       { "shpmevent3",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT4,       { "shpmevent4",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT5,       { "shpmevent5",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT6,       { "shpmevent6",        any, read_zero, write_stub} },
+
+    /* Supervisor control registers */
+    {CSR_SCCTLDATA,        { "scctldata",         any, read_zero, write_stub} },
+    {CSR_SMISC_CTL,        { "smisc_ctl",         any, read_zero, write_stub} },
+
+    /* ===================== AndeStar V5 user mode CSRs ===================== */
+    /* User mode control registers */
+    {CSR_UITB,             { "uitb",              any, read_uitb, write_uitb} },
+    {CSR_UCODE,            { "ucode",             any, read_zero, write_stub} },
+    {CSR_UDCAUSE,          { "udcause",           any, read_zero, write_stub} },
+    {CSR_UCCTLBEGINADDR,   { "ucctlbeginaddr",    any, read_zero, write_stub} },
+    {CSR_UCCTLCOMMAND,     { "ucctlcommand",      any, read_zero, write_stub} },
+    {CSR_WFE,              { "wfe",               any, read_zero, write_stub} },
+    {CSR_SLEEPVALUE,       { "sleepvalue",        any, read_zero, write_stub} },
+    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
+    {0, { "", NULL, NULL, NULL } },
+    };
diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
index 5df31f8..ba67e95 100644
--- a/target/riscv/custom_cpu_bits.h
+++ b/target/riscv/custom_cpu_bits.h
@@ -5,4 +5,8 @@
  * SPDX-License-Identifier: GPL-2.0+
  */
 
-/* This file is intentionally left blank at this commit. */
+/*
+ * XXX: Maybe we should add a "target-list"-like option to toggle enabled
+ * custom CSR variations ?
+ */
+#include "andes_cpu_bits.h"
-- 
2.32.0



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

* [RFC PATCH v4 4/4] Enable custom CSR logic for Andes AX25 and A25
@ 2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
  0 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-08-05 17:56 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: ruinland, wangjunqiang, bin.meng, Dylan Jhong

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

In this patch we enabled custom CSR logic for Andes AX25 and A25 logic.
Hence csr_andes.inc.c and andes_cpu_bits.h is added.

Signed-off-by: Dylan Jhong <dylan@andestech.com>
---
 target/riscv/andes_cpu_bits.h  | 124 +++++++++++++++++++++++++
 target/riscv/cpu.c             |  12 +++
 target/riscv/csr.c             |   2 +-
 target/riscv/csr_andes.inc.c   | 160 +++++++++++++++++++++++++++++++++
 target/riscv/custom_cpu_bits.h |   6 +-
 5 files changed, 302 insertions(+), 2 deletions(-)
 create mode 100644 target/riscv/andes_cpu_bits.h
 create mode 100644 target/riscv/csr_andes.inc.c

diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
new file mode 100644
index 0000000..bd2b7d1
--- /dev/null
+++ b/target/riscv/andes_cpu_bits.h
@@ -0,0 +1,124 @@
+/*
+ * Andes custom CSRs bit definitions
+ *
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* ========= Missing drafted/standard CSR definitions */
+/* Although TINFO is in official debug sepc, it's not in cpu_bits.h yet. */
+#define CSR_TINFO           0x7a4
+
+/* ========= AndeStar V5 machine mode CSRs ========= */
+/* Configuration Registers */
+#define CSR_MICM_CFG            0xfc0
+#define CSR_MDCM_CFG            0xfc1
+#define CSR_MMSC_CFG            0xfc2
+#define CSR_MMSC_CFG2           0xfc3
+#define CSR_MVEC_CFG            0xfc7
+
+/* Crash Debug CSRs */
+#define CSR_MCRASH_STATESAVE    0xfc8
+#define CSR_MSTATUS_CRASHSAVE   0xfc9
+
+/* Memory CSRs */
+#define CSR_MILMB               0x7c0
+#define CSR_MDLMB               0x7c1
+#define CSR_MECC_CODE           0x7C2
+#define CSR_MNVEC               0x7c3
+#define CSR_MCACHE_CTL          0x7ca
+#define CSR_MCCTLBEGINADDR      0x7cb
+#define CSR_MCCTLCOMMAND        0x7cc
+#define CSR_MCCTLDATA           0x7cd
+#define CSR_MPPIB               0x7f0
+#define CSR_MFIOB               0x7f1
+
+/* Hardware Stack Protection & Recording */
+#define CSR_MHSP_CTL            0x7c6
+#define CSR_MSP_BOUND           0x7c7
+#define CSR_MSP_BASE            0x7c8
+#define CSR_MXSTATUS            0x7c4
+#define CSR_MDCAUSE             0x7c9
+#define CSR_MSLIDELEG           0x7d5
+#define CSR_MSAVESTATUS         0x7d6
+#define CSR_MSAVEEPC1           0x7d7
+#define CSR_MSAVECAUSE1         0x7d8
+#define CSR_MSAVEEPC2           0x7d9
+#define CSR_MSAVECAUSE2         0x7da
+#define CSR_MSAVEDCAUSE1        0x7db
+#define CSR_MSAVEDCAUSE2        0x7dc
+
+/* Control CSRs */
+#define CSR_MPFT_CTL            0x7c5
+#define CSR_MMISC_CTL           0x7d0
+#define CSR_MCLK_CTL            0x7df
+
+/* Counter related CSRs */
+#define CSR_MCOUNTERWEN         0x7ce
+#define CSR_MCOUNTERINTEN       0x7cf
+#define CSR_MCOUNTERMASK_M      0x7d1
+#define CSR_MCOUNTERMASK_S      0x7d2
+#define CSR_MCOUNTERMASK_U      0x7d3
+#define CSR_MCOUNTEROVF         0x7d4
+
+/* Enhanced CLIC CSRs */
+#define CSR_MIRQ_ENTRY          0x7ec
+#define CSR_MINTSEL_JAL         0x7ed
+#define CSR_PUSHMCAUSE          0x7ee
+#define CSR_PUSHMEPC            0x7ef
+#define CSR_PUSHMXSTATUS        0x7eb
+
+/* Andes Physical Memory Attribute(PMA) CSRs */
+#define CSR_PMACFG0             0xbc0
+#define CSR_PMACFG1             0xbc1
+#define CSR_PMACFG2             0xbc2
+#define CSR_PMACFG3             0xbc3
+#define CSR_PMAADDR0            0xbd0
+#define CSR_PMAADDR1            0xbd1
+#define CSR_PMAADDR2            0xbd2
+#define CSR_PMAADDR3            0xbd2
+#define CSR_PMAADDR4            0xbd4
+#define CSR_PMAADDR5            0xbd5
+#define CSR_PMAADDR6            0xbd6
+#define CSR_PMAADDR7            0xbd7
+#define CSR_PMAADDR8            0xbd8
+#define CSR_PMAADDR9            0xbd9
+#define CSR_PMAADDR10           0xbda
+#define CSR_PMAADDR11           0xbdb
+#define CSR_PMAADDR12           0xbdc
+#define CSR_PMAADDR13           0xbdd
+#define CSR_PMAADDR14           0xbde
+#define CSR_PMAADDR15           0xbdf
+
+/* ========= AndeStar V5 supervisor mode CSRs ========= */
+/* Supervisor trap registers */
+#define CSR_SLIE                0x9c4
+#define CSR_SLIP                0x9c5
+#define CSR_SDCAUSE             0x9c9
+
+/* Supervisor counter registers */
+#define CSR_SCOUNTERINTEN       0x9cf
+#define CSR_SCOUNTERMASK_M      0x9d1
+#define CSR_SCOUNTERMASK_S      0x9d2
+#define CSR_SCOUNTERMASK_U      0x9d3
+#define CSR_SCOUNTEROVF         0x9d4
+#define CSR_SCOUNTINHIBIT       0x9e0
+#define CSR_SHPMEVENT3          0x9e3
+#define CSR_SHPMEVENT4          0x9e4
+#define CSR_SHPMEVENT5          0x9e5
+#define CSR_SHPMEVENT6          0x9e6
+
+/* Supervisor control registers */
+#define CSR_SCCTLDATA           0x9cd
+#define CSR_SMISC_CTL           0x9d0
+
+/* ========= AndeStar V5 user mode CSRs ========= */
+/* User mode control registers */
+#define CSR_UITB                0x800
+#define CSR_UCODE               0x801
+#define CSR_UDCAUSE             0x809
+#define CSR_UCCTLBEGINADDR      0x80b
+#define CSR_UCCTLCOMMAND        0x80c
+#define CSR_WFE                 0x810
+#define CSR_SLEEPVALUE          0x811
+#define CSR_TXEVT               0x812
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9eb1e3a..d1d4773 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -187,6 +187,12 @@ 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);
+
+    #if defined(CONFIG_RISCV_CUSTOM)
+    /* setup custom csr handler hash table */
+    setup_custom_csr(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
+    #endif
 }
 
 static void rv64_sifive_u_cpu_init(Object *obj)
@@ -248,6 +254,12 @@ 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);
+
+    #if defined(CONFIG_RISCV_CUSTOM)
+    /* setup custom csr handler hash table */
+    setup_custom_csr(env, andes_custom_csr_table);
+    env->custom_csr_val = g_malloc(andes_custom_csr_size);
+    #endif
 }
 #endif
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 1c4dc94..9c16b88 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1421,7 +1421,7 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
 }
 
 #if defined(CONFIG_RISCV_CUSTOM)
-/* Include the custom CSR table here. */
+#include "csr_andes.inc.c"
 #endif
 
 /* Control and Status Register function table */
diff --git a/target/riscv/csr_andes.inc.c b/target/riscv/csr_andes.inc.c
new file mode 100644
index 0000000..da226b0
--- /dev/null
+++ b/target/riscv/csr_andes.inc.c
@@ -0,0 +1,160 @@
+/*
+ * Andes custom CSR table and handling functions
+ *
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+static int write_uitb(CPURISCVState *env, int csrno, target_ulong val);
+static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val);
+
+struct andes_csr_val {
+    target_long uitb;
+};
+
+static int read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    /* enable pma probe */
+    *val = 0x40000000;
+    return 0;
+}
+
+static int write_uitb(CPURISCVState *env, int csrno, target_ulong val)
+{
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    andes_csr->uitb = val;
+    return 0;
+}
+
+static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
+{
+    struct andes_csr_val *andes_csr = env->custom_csr_val;
+    *val = andes_csr->uitb;
+    return 0;
+}
+
+
+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 ==================== */
+    /* Configuration Registers */
+    {CSR_MICM_CFG,         { "micm_cfg",          any, read_zero, write_stub} },
+    {CSR_MDCM_CFG,         { "mdcm_cfg",          any, read_zero, write_stub} },
+    {CSR_MMSC_CFG,         { "mmsc_cfg",          any, read_mmsc_cfg, write_stub} },
+    {CSR_MMSC_CFG2,        { "mmsc_cfg2",         any, read_zero, write_stub} },
+    {CSR_MVEC_CFG,         { "mvec_cfg",          any, read_zero, write_stub} },
+
+    /* Crash Debug CSRs */
+    {CSR_MCRASH_STATESAVE,  { "mcrash_statesave",  any, read_zero, write_stub} },
+    {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
+
+    /* Memory CSRs */
+    {CSR_MILMB,            { "milmb",             any, read_zero, write_stub} },
+    {CSR_MDLMB,            { "mdlmb",             any, read_zero, write_stub} },
+    {CSR_MECC_CODE,        { "mecc_code",         any, read_zero, write_stub} },
+    {CSR_MNVEC,            { "mnvec",             any, read_zero, write_stub} },
+    {CSR_MCACHE_CTL,       { "mcache_ctl",        any, read_zero, write_stub} },
+    {CSR_MCCTLBEGINADDR,   { "mcctlbeginaddr",    any, read_zero, write_stub} },
+    {CSR_MCCTLCOMMAND,     { "mcctlcommand",      any, read_zero, write_stub} },
+    {CSR_MCCTLDATA,        { "mcctldata",         any, read_zero, write_stub} },
+    {CSR_MPPIB,            { "mppib",             any, read_zero, write_stub} },
+    {CSR_MFIOB,            { "mfiob",             any, read_zero, write_stub} },
+
+    /* Hardware Stack Protection & Recording */
+    {CSR_MHSP_CTL,         { "mhsp_ctl",          any, read_zero, write_stub} },
+    {CSR_MSP_BOUND,        { "msp_bound",         any, read_zero, write_stub} },
+    {CSR_MSP_BASE,         { "msp_base",          any, read_zero, write_stub} },
+    {CSR_MXSTATUS,         { "mxstatus",          any, read_zero, write_stub} },
+    {CSR_MDCAUSE,          { "mdcause",           any, read_zero, write_stub} },
+    {CSR_MSLIDELEG,        { "mslideleg",         any, read_zero, write_stub} },
+    {CSR_MSAVESTATUS,      { "msavestatus",       any, read_zero, write_stub} },
+    {CSR_MSAVEEPC1,        { "msaveepc1",         any, read_zero, write_stub} },
+    {CSR_MSAVECAUSE1,      { "msavecause1",       any, read_zero, write_stub} },
+    {CSR_MSAVEEPC2,        { "msaveepc2",         any, read_zero, write_stub} },
+    {CSR_MSAVECAUSE2,      { "msavecause2",       any, read_zero, write_stub} },
+    {CSR_MSAVEDCAUSE1,     { "msavedcause1",      any, read_zero, write_stub} },
+    {CSR_MSAVEDCAUSE2,     { "msavedcause2",      any, read_zero, write_stub} },
+
+    /* Control CSRs */
+    {CSR_MPFT_CTL,         { "mpft_ctl",          any, read_zero, write_stub} },
+    {CSR_MMISC_CTL,        { "mmisc_ctl",         any, read_zero, write_stub} },
+    {CSR_MCLK_CTL,         { "mclk_ctl",          any, read_zero, write_stub} },
+
+    /* Counter related CSRs */
+    {CSR_MCOUNTERWEN,      { "mcounterwen",       any, read_zero, write_stub} },
+    {CSR_MCOUNTERINTEN,    { "mcounterinten",     any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_M,   { "mcountermask_m",    any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_S,   { "mcountermask_s",    any, read_zero, write_stub} },
+    {CSR_MCOUNTERMASK_U,   { "mcountermask_u",    any, read_zero, write_stub} },
+    {CSR_MCOUNTEROVF,      { "mcounterovf",       any, read_zero, write_stub} },
+
+    /* Enhanced CLIC CSRs */
+    {CSR_MIRQ_ENTRY,       { "mirq_entry",        any, read_zero, write_stub} },
+    {CSR_MINTSEL_JAL,      { "mintsel_jal",       any, read_zero, write_stub} },
+    {CSR_PUSHMCAUSE,       { "pushmcause",        any, read_zero, write_stub} },
+    {CSR_PUSHMEPC,         { "pushmepc",          any, read_zero, write_stub} },
+    {CSR_PUSHMXSTATUS,     { "pushmxstatus",      any, read_zero, write_stub} },
+
+    /* Andes Physical Memory Attribute(PMA) CSRs */
+    {CSR_PMACFG0,          { "pmacfg0",           any, read_zero, write_stub} },
+    {CSR_PMACFG1,          { "pmacfg1",           any, read_zero, write_stub} },
+    {CSR_PMACFG2,          { "pmacfg2",           any, read_zero, write_stub} },
+    {CSR_PMACFG3,          { "pmacfg3",           any, read_zero, write_stub} },
+    {CSR_PMAADDR0,         { "pmaaddr0",          any, read_zero, write_stub} },
+    {CSR_PMAADDR1,         { "pmaaddr1",          any, read_zero, write_stub} },
+    {CSR_PMAADDR2,         { "pmaaddr2",          any, read_zero, write_stub} },
+    {CSR_PMAADDR3,         { "pmaaddr3",          any, read_zero, write_stub} },
+    {CSR_PMAADDR4,         { "pmaaddr4",          any, read_zero, write_stub} },
+    {CSR_PMAADDR5,         { "pmaaddr5",          any, read_zero, write_stub} },
+    {CSR_PMAADDR6,         { "pmaaddr6",          any, read_zero, write_stub} },
+    {CSR_PMAADDR7,         { "pmaaddr7",          any, read_zero, write_stub} },
+    {CSR_PMAADDR8,         { "pmaaddr8",          any, read_zero, write_stub} },
+    {CSR_PMAADDR9,         { "pmaaddr9",          any, read_zero, write_stub} },
+    {CSR_PMAADDR10,        { "pmaaddr10",         any, read_zero, write_stub} },
+    {CSR_PMAADDR11,        { "pmaaddr11",         any, read_zero, write_stub} },
+    {CSR_PMAADDR12,        { "pmaaddr12",         any, read_zero, write_stub} },
+    {CSR_PMAADDR13,        { "pmaaddr13",         any, read_zero, write_stub} },
+    {CSR_PMAADDR14,        { "pmaaddr14",         any, read_zero, write_stub} },
+    {CSR_PMAADDR15,        { "pmaaddr15",         any, read_zero, write_stub} },
+
+    /* Debug/Trace Registers (shared with Debug Mode) */
+    {CSR_TSELECT,          { "tselect",           any, read_zero, write_stub} },
+    {CSR_TDATA1,           { "tdata1",            any, read_zero, write_stub} },
+    {CSR_TDATA2,           { "tdata2",            any, read_zero, write_stub} },
+    {CSR_TDATA3,           { "tdata3",            any, read_zero, write_stub} },
+    {CSR_TINFO,            { "tinfo",             any, read_zero, write_stub} },
+
+    /* ================== AndeStar V5 supervisor mode CSRs ================== */
+    /* Supervisor trap registers */
+    {CSR_SLIE,             { "slie",              any, read_zero, write_stub} },
+    {CSR_SLIP,             { "slip",              any, read_zero, write_stub} },
+    {CSR_SDCAUSE,          { "sdcause",           any, read_zero, write_stub} },
+
+    /* Supervisor counter registers */
+    {CSR_SCOUNTERINTEN,    { "scounterinten",     any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_M,   { "scountermask_m",    any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_S,   { "scountermask_s",    any, read_zero, write_stub} },
+    {CSR_SCOUNTERMASK_U,   { "scountermask_u",    any, read_zero, write_stub} },
+    {CSR_SCOUNTEROVF,      { "scounterovf",       any, read_zero, write_stub} },
+    {CSR_SCOUNTINHIBIT,    { "scountinhibit",     any, read_zero, write_stub} },
+    {CSR_SHPMEVENT3,       { "shpmevent3",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT4,       { "shpmevent4",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT5,       { "shpmevent5",        any, read_zero, write_stub} },
+    {CSR_SHPMEVENT6,       { "shpmevent6",        any, read_zero, write_stub} },
+
+    /* Supervisor control registers */
+    {CSR_SCCTLDATA,        { "scctldata",         any, read_zero, write_stub} },
+    {CSR_SMISC_CTL,        { "smisc_ctl",         any, read_zero, write_stub} },
+
+    /* ===================== AndeStar V5 user mode CSRs ===================== */
+    /* User mode control registers */
+    {CSR_UITB,             { "uitb",              any, read_uitb, write_uitb} },
+    {CSR_UCODE,            { "ucode",             any, read_zero, write_stub} },
+    {CSR_UDCAUSE,          { "udcause",           any, read_zero, write_stub} },
+    {CSR_UCCTLBEGINADDR,   { "ucctlbeginaddr",    any, read_zero, write_stub} },
+    {CSR_UCCTLCOMMAND,     { "ucctlcommand",      any, read_zero, write_stub} },
+    {CSR_WFE,              { "wfe",               any, read_zero, write_stub} },
+    {CSR_SLEEPVALUE,       { "sleepvalue",        any, read_zero, write_stub} },
+    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
+    {0, { "", NULL, NULL, NULL } },
+    };
diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
index 5df31f8..ba67e95 100644
--- a/target/riscv/custom_cpu_bits.h
+++ b/target/riscv/custom_cpu_bits.h
@@ -5,4 +5,8 @@
  * SPDX-License-Identifier: GPL-2.0+
  */
 
-/* This file is intentionally left blank at this commit. */
+/*
+ * XXX: Maybe we should add a "target-list"-like option to toggle enabled
+ * custom CSR variations ?
+ */
+#include "andes_cpu_bits.h"
-- 
2.32.0



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

* Re: [RFC PATCH v4 1/4] Add options to config/meson files for custom CSR
  2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
@ 2021-08-06  2:39     ` Bin Meng
  -1 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  2:39 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Dylan Jhong

On Fri, Aug 6, 2021 at 1:57 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinland ChuanTzu Tsai <ruinland@andestech.com>
>
> Adding option `riscv_custom` to configure script, meson.build and
> meson_options.txt so as to toggle custom CSR and will-be-upstreamed custom
> instructions handling logic.
>
> Signed-off-by: Dylan Jhong <dylan@andestech.com>
> ---
>  configure         | 6 ++++++
>  meson.build       | 2 ++
>  meson_options.txt | 2 ++
>  3 files changed, 10 insertions(+)
>

This sounds like unnecessary to bring such a config option to the meson level.

I believe a Kconfig option should just be fine.

Regards,
Bin


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

* Re: [RFC PATCH v4 1/4] Add options to config/meson files for custom CSR
@ 2021-08-06  2:39     ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  2:39 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Dylan Jhong

On Fri, Aug 6, 2021 at 1:57 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinland ChuanTzu Tsai <ruinland@andestech.com>
>
> Adding option `riscv_custom` to configure script, meson.build and
> meson_options.txt so as to toggle custom CSR and will-be-upstreamed custom
> instructions handling logic.
>
> Signed-off-by: Dylan Jhong <dylan@andestech.com>
> ---
>  configure         | 6 ++++++
>  meson.build       | 2 ++
>  meson_options.txt | 2 ++
>  3 files changed, 10 insertions(+)
>

This sounds like unnecessary to bring such a config option to the meson level.

I believe a Kconfig option should just be fine.

Regards,
Bin


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

* Re: [RFC PATCH v4 1/4] Add options to config/meson files for custom CSR
  2021-08-06  2:39     ` Bin Meng
@ 2021-08-06  2:41       ` Bin Meng
  -1 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  2:41 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, Alistair Francis
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Dylan Jhong

On Fri, Aug 6, 2021 at 10:39 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Fri, Aug 6, 2021 at 1:57 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > From: Ruinland ChuanTzu Tsai <ruinland@andestech.com>
> >
> > Adding option `riscv_custom` to configure script, meson.build and
> > meson_options.txt so as to toggle custom CSR and will-be-upstreamed custom
> > instructions handling logic.
> >
> > Signed-off-by: Dylan Jhong <dylan@andestech.com>
> > ---
> >  configure         | 6 ++++++
> >  meson.build       | 2 ++
> >  meson_options.txt | 2 ++
> >  3 files changed, 10 insertions(+)
> >
>
> This sounds like unnecessary to bring such a config option to the meson level.
>
> I believe a Kconfig option should just be fine.

+Alistair


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

* Re: [RFC PATCH v4 1/4] Add options to config/meson files for custom CSR
@ 2021-08-06  2:41       ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  2:41 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Dylan Jhong

On Fri, Aug 6, 2021 at 10:39 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Fri, Aug 6, 2021 at 1:57 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > From: Ruinland ChuanTzu Tsai <ruinland@andestech.com>
> >
> > Adding option `riscv_custom` to configure script, meson.build and
> > meson_options.txt so as to toggle custom CSR and will-be-upstreamed custom
> > instructions handling logic.
> >
> > Signed-off-by: Dylan Jhong <dylan@andestech.com>
> > ---
> >  configure         | 6 ++++++
> >  meson.build       | 2 ++
> >  meson_options.txt | 2 ++
> >  3 files changed, 10 insertions(+)
> >
>
> This sounds like unnecessary to bring such a config option to the meson level.
>
> I believe a Kconfig option should just be fine.

+Alistair


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

* Re: [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
  2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
@ 2021-08-06  3:35     ` Bin Meng
  -1 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  3:35 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, Alistair Francis
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Dylan Jhong

+Alistair

On Fri, Aug 6, 2021 at 1:58 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinalnd ChuanTzu Tsai <ruinland@andestech.com>
>
> For now we add a custom CSR handling mechanism to handle non-standard CSR read
> or write.
>
> The write_stub() and read_zero() are provided for quick placeholder usage if
> such CSRs' behavior are expected to fail-over in its user code.
>
> Signed-off-by: Dylan Jhong <dylan@andestech.com>
> ---
>  target/riscv/cpu.c             | 23 ++++++++++
>  target/riscv/cpu.h             | 31 ++++++++++++-
>  target/riscv/cpu_bits.h        |  4 ++
>  target/riscv/csr.c             | 83 ++++++++++++++++++++++++++++------
>  target/riscv/custom_cpu_bits.h |  8 ++++
>  5 files changed, 134 insertions(+), 15 deletions(-)
>  create mode 100644 target/riscv/custom_cpu_bits.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7401325..3a638b5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -144,6 +144,29 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
>  #endif
>  }
>
> +#if defined(CONFIG_RISCV_CUSTOM)
> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[]
> +                             ) {

{ should be put to the next line, per QEMU coding convention. Please
fix this globally in this series.

> +
> +    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
> +                                                g_direct_equal, \
> +                                                NULL, NULL);

Is it possible to juse use g_hash_table_new() directly, with both 2
parameters being NULL, given you don't provide the destroy hooks?
like:

    env->custom_csr_map = g_hash_table_new(NULL, NULL);

> +
> +
> +    int i;

nits: please move this to the beginning of this function.

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

break? I think we should continue the loop.

> +        }
> +    }
> +}
> +#endif
> +
>  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 0edb282..52df9bb 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -239,6 +239,16 @@ struct CPURISCVState {
>
>      /* Fields from here on are preserved across CPU reset. */
>      QEMUTimer *timer; /* Internal timer */
> +
> +    /*
> +     * The reason why we have an opset map for custom CSRs and a seperated
> +     * storage map is that we might have heterogeneous architecture, in which
> +     * different harts have different custom CSRs.
> +     * Custom CSR opset map
> +     */
> +    GHashTable *custom_csr_map;
> +    /* Custom CSR val holder */
> +    void *custom_csr_val;
>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -485,17 +495,36 @@ typedef struct {
>      riscv_csr_op_fn op;
>  } riscv_csr_operations;
>
> +typedef struct {
> +    int csrno;
> +    riscv_csr_operations csr_opset;
> +    } riscv_custom_csr_operations;

} should be put in the beginning without space. Please fix this
globally in this series.

> +
> +/*
> + * The reason why we have an abstraction here is that : We could have CSR
> + * number M on hart A is an alias of CSR number N on hart B. So we make a
> + * CSR number to value address map.
> + */
> +typedef struct  {
> +    int csrno;
> +    target_ulong val;
> +    } riscv_custom_csr_vals;
> +

It looks this struct is not used by any patch in this series?

>  /* CSR function table constants */
>  enum {
> -    CSR_TABLE_SIZE = 0x1000
> +    CSR_TABLE_SIZE = 0x1000,
> +    MAX_CUSTOM_CSR_NUM = 100

To be consistent, name this to be: CUSTOM_CSR_TABLE_SIZE

>  };
>
>  /* CSR function table */
> +extern int andes_custom_csr_size;
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];

The above 2 should not be in this patch.

>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>
>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> +

This is unnecessary.

>  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>
>  #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf4599..de77242 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -593,3 +593,7 @@
>  #define MIE_SSIE                           (1 << IRQ_S_SOFT)
>  #define MIE_USIE                           (1 << IRQ_U_SOFT)
>  #endif
> +
> +#if defined(CONFIG_RISCV_CUSTOM)
> +#include "custom_cpu_bits.h"
> +#endif
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fd2e636..1c4dc94 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -137,7 +137,8 @@ static int ctr32(CPURISCVState *env, int csrno)
>      return ctr(env, csrno);
>  }
>
> -#if !defined(CONFIG_USER_ONLY)
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wunused-function"

Use __attribute__((__unused__)), so we don't need to use GCC push/pop

>  static int any(CPURISCVState *env, int csrno)
>  {
>      return 0;
> @@ -152,6 +153,25 @@ static int any32(CPURISCVState *env, int csrno)
>      return any(env, csrno);
>
>  }
> +#pragma GCC diagnostic pop
> +
> +/* Machine Information Registers */
> +static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    return *val = 0;
> +}
> +
> +/*
> + * XXX: This is just a write stub for developing custom CSR handler,

Remove XXX

> + * if the behavior of writting such CSR is not presentable in QEMU and doesn't

typo: writing.

Is that present, or presentable?

> + * affect the functionality, just stub it.
> + */
> +static int write_stub(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    return 0;
> +}
> +
> +#if !defined(CONFIG_USER_ONLY)
>
>  static int smode(CPURISCVState *env, int csrno)
>  {
> @@ -435,11 +455,6 @@ static const char valid_vm_1_10_64[16] = {
>      [VM_1_10_SV57] = 1
>  };
>
> -/* Machine Information Registers */
> -static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> -{
> -    return *val = 0;
> -}
>
>  static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> @@ -1264,6 +1279,18 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>
>  #endif
>
> +
> +#if defined(CONFIG_RISCV_CUSTOM)
> +/* Custom CSR related routines and data structures */
> +
> +static gpointer is_custom_csr(CPURISCVState *env, int csrno)

The function name suggests that the return value should be of bool
type. Suggest we do:

static bool is_custom_csr(CPURISCVState *env, int csrno,
riscv_custom_csr_operations *custom_csr_ops)

> +{
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;
> +}
> +#endif
> +
>  /*
>   * riscv_csrrw - read and/or update control and status register
>   *
> @@ -1273,12 +1300,19 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>   * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
>   */
>
> +
> +

Unnecessary changes

>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>                  target_ulong new_value, target_ulong write_mask)
>  {
>      int ret;
>      target_ulong old_value;
>      RISCVCPU *cpu = env_archcpu(env);
> +    #if !defined(CONFIG_RISCV_CUSTOM)

Please make sure #if starts from the beginning of this line, without space ahead

> +    riscv_csr_operations *csrop = &csr_ops[csrno];

nits: name this variable to csr_ops

> +    #else
> +    riscv_csr_operations *csrop;
> +    #endif
>
>      /* check privileges and return -1 if check fails */
>  #if !defined(CONFIG_USER_ONLY)
> @@ -1300,6 +1334,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> +
>  #endif
>
>      /* ensure the CSR extension is enabled. */
> @@ -1307,27 +1342,43 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
> +    /* try handle_custom_csr */
> +
> +    #if defined(CONFIG_RISCV_CUSTOM)
> +    if (unlikely(env->custom_csr_map != NULL)) {
> +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +            is_custom_csr(env, csrno);
> +        if (NULL != custom_csr_opset) {
> +            csrop = custom_csr_opset;
> +            } else {
> +            csrop = &csr_ops[csrno];
> +            }
> +        } else {
> +        csrop = &csr_ops[csrno];
> +        }
> +    #endif
> +
>      /* check predicate */
> -    if (!csr_ops[csrno].predicate) {
> +    if (!csrop->predicate) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> -    ret = csr_ops[csrno].predicate(env, csrno);
> +    ret = csrop->predicate(env, csrno);
>      if (ret < 0) {
>          return ret;
>      }
>
>      /* execute combined read/write operation if it exists */
> -    if (csr_ops[csrno].op) {
> -        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> +    if (csrop->op) {
> +        return csrop->op(env, csrno, ret_value, new_value, write_mask);
>      }
>
>      /* if no accessor exists then return failure */
> -    if (!csr_ops[csrno].read) {
> +    if (!csrop->read) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
>      /* read old value */
> -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> +    ret = csrop->read(env, csrno, &old_value);
>      if (ret < 0) {
>          return ret;
>      }
> @@ -1335,8 +1386,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      /* write value if writable and write mask set, otherwise drop writes */
>      if (write_mask) {
>          new_value = (old_value & ~write_mask) | (new_value & write_mask);
> -        if (csr_ops[csrno].write) {
> -            ret = csr_ops[csrno].write(env, csrno, new_value);
> +        if (csrop->write) {
> +            ret = csrop->write(env, csrno, new_value);
>              if (ret < 0) {
>                  return ret;
>              }
> @@ -1369,6 +1420,10 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      return ret;
>  }
>
> +#if defined(CONFIG_RISCV_CUSTOM)
> +/* Include the custom CSR table here. */

nits: remove the ending .

> +#endif
> +
>  /* Control and Status Register function table */
>  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      /* User Floating-Point CSRs */
> diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
> new file mode 100644
> index 0000000..5df31f8
> --- /dev/null
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -0,0 +1,8 @@
> +/*
> + * RISC-V cpu bits for custom CSR logic.
> + *
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +/* This file is intentionally left blank at this commit. */

nits: remove the ending .

%s/at/in

Regards,
Bin


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

* Re: [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
@ 2021-08-06  3:35     ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  3:35 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Dylan Jhong

+Alistair

On Fri, Aug 6, 2021 at 1:58 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinalnd ChuanTzu Tsai <ruinland@andestech.com>
>
> For now we add a custom CSR handling mechanism to handle non-standard CSR read
> or write.
>
> The write_stub() and read_zero() are provided for quick placeholder usage if
> such CSRs' behavior are expected to fail-over in its user code.
>
> Signed-off-by: Dylan Jhong <dylan@andestech.com>
> ---
>  target/riscv/cpu.c             | 23 ++++++++++
>  target/riscv/cpu.h             | 31 ++++++++++++-
>  target/riscv/cpu_bits.h        |  4 ++
>  target/riscv/csr.c             | 83 ++++++++++++++++++++++++++++------
>  target/riscv/custom_cpu_bits.h |  8 ++++
>  5 files changed, 134 insertions(+), 15 deletions(-)
>  create mode 100644 target/riscv/custom_cpu_bits.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7401325..3a638b5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -144,6 +144,29 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
>  #endif
>  }
>
> +#if defined(CONFIG_RISCV_CUSTOM)
> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[]
> +                             ) {

{ should be put to the next line, per QEMU coding convention. Please
fix this globally in this series.

> +
> +    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
> +                                                g_direct_equal, \
> +                                                NULL, NULL);

Is it possible to juse use g_hash_table_new() directly, with both 2
parameters being NULL, given you don't provide the destroy hooks?
like:

    env->custom_csr_map = g_hash_table_new(NULL, NULL);

> +
> +
> +    int i;

nits: please move this to the beginning of this function.

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

break? I think we should continue the loop.

> +        }
> +    }
> +}
> +#endif
> +
>  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 0edb282..52df9bb 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -239,6 +239,16 @@ struct CPURISCVState {
>
>      /* Fields from here on are preserved across CPU reset. */
>      QEMUTimer *timer; /* Internal timer */
> +
> +    /*
> +     * The reason why we have an opset map for custom CSRs and a seperated
> +     * storage map is that we might have heterogeneous architecture, in which
> +     * different harts have different custom CSRs.
> +     * Custom CSR opset map
> +     */
> +    GHashTable *custom_csr_map;
> +    /* Custom CSR val holder */
> +    void *custom_csr_val;
>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -485,17 +495,36 @@ typedef struct {
>      riscv_csr_op_fn op;
>  } riscv_csr_operations;
>
> +typedef struct {
> +    int csrno;
> +    riscv_csr_operations csr_opset;
> +    } riscv_custom_csr_operations;

} should be put in the beginning without space. Please fix this
globally in this series.

> +
> +/*
> + * The reason why we have an abstraction here is that : We could have CSR
> + * number M on hart A is an alias of CSR number N on hart B. So we make a
> + * CSR number to value address map.
> + */
> +typedef struct  {
> +    int csrno;
> +    target_ulong val;
> +    } riscv_custom_csr_vals;
> +

It looks this struct is not used by any patch in this series?

>  /* CSR function table constants */
>  enum {
> -    CSR_TABLE_SIZE = 0x1000
> +    CSR_TABLE_SIZE = 0x1000,
> +    MAX_CUSTOM_CSR_NUM = 100

To be consistent, name this to be: CUSTOM_CSR_TABLE_SIZE

>  };
>
>  /* CSR function table */
> +extern int andes_custom_csr_size;
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];

The above 2 should not be in this patch.

>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>
>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> +

This is unnecessary.

>  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>
>  #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf4599..de77242 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -593,3 +593,7 @@
>  #define MIE_SSIE                           (1 << IRQ_S_SOFT)
>  #define MIE_USIE                           (1 << IRQ_U_SOFT)
>  #endif
> +
> +#if defined(CONFIG_RISCV_CUSTOM)
> +#include "custom_cpu_bits.h"
> +#endif
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fd2e636..1c4dc94 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -137,7 +137,8 @@ static int ctr32(CPURISCVState *env, int csrno)
>      return ctr(env, csrno);
>  }
>
> -#if !defined(CONFIG_USER_ONLY)
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wunused-function"

Use __attribute__((__unused__)), so we don't need to use GCC push/pop

>  static int any(CPURISCVState *env, int csrno)
>  {
>      return 0;
> @@ -152,6 +153,25 @@ static int any32(CPURISCVState *env, int csrno)
>      return any(env, csrno);
>
>  }
> +#pragma GCC diagnostic pop
> +
> +/* Machine Information Registers */
> +static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    return *val = 0;
> +}
> +
> +/*
> + * XXX: This is just a write stub for developing custom CSR handler,

Remove XXX

> + * if the behavior of writting such CSR is not presentable in QEMU and doesn't

typo: writing.

Is that present, or presentable?

> + * affect the functionality, just stub it.
> + */
> +static int write_stub(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    return 0;
> +}
> +
> +#if !defined(CONFIG_USER_ONLY)
>
>  static int smode(CPURISCVState *env, int csrno)
>  {
> @@ -435,11 +455,6 @@ static const char valid_vm_1_10_64[16] = {
>      [VM_1_10_SV57] = 1
>  };
>
> -/* Machine Information Registers */
> -static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> -{
> -    return *val = 0;
> -}
>
>  static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> @@ -1264,6 +1279,18 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>
>  #endif
>
> +
> +#if defined(CONFIG_RISCV_CUSTOM)
> +/* Custom CSR related routines and data structures */
> +
> +static gpointer is_custom_csr(CPURISCVState *env, int csrno)

The function name suggests that the return value should be of bool
type. Suggest we do:

static bool is_custom_csr(CPURISCVState *env, int csrno,
riscv_custom_csr_operations *custom_csr_ops)

> +{
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;
> +}
> +#endif
> +
>  /*
>   * riscv_csrrw - read and/or update control and status register
>   *
> @@ -1273,12 +1300,19 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>   * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
>   */
>
> +
> +

Unnecessary changes

>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>                  target_ulong new_value, target_ulong write_mask)
>  {
>      int ret;
>      target_ulong old_value;
>      RISCVCPU *cpu = env_archcpu(env);
> +    #if !defined(CONFIG_RISCV_CUSTOM)

Please make sure #if starts from the beginning of this line, without space ahead

> +    riscv_csr_operations *csrop = &csr_ops[csrno];

nits: name this variable to csr_ops

> +    #else
> +    riscv_csr_operations *csrop;
> +    #endif
>
>      /* check privileges and return -1 if check fails */
>  #if !defined(CONFIG_USER_ONLY)
> @@ -1300,6 +1334,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> +
>  #endif
>
>      /* ensure the CSR extension is enabled. */
> @@ -1307,27 +1342,43 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
> +    /* try handle_custom_csr */
> +
> +    #if defined(CONFIG_RISCV_CUSTOM)
> +    if (unlikely(env->custom_csr_map != NULL)) {
> +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +            is_custom_csr(env, csrno);
> +        if (NULL != custom_csr_opset) {
> +            csrop = custom_csr_opset;
> +            } else {
> +            csrop = &csr_ops[csrno];
> +            }
> +        } else {
> +        csrop = &csr_ops[csrno];
> +        }
> +    #endif
> +
>      /* check predicate */
> -    if (!csr_ops[csrno].predicate) {
> +    if (!csrop->predicate) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> -    ret = csr_ops[csrno].predicate(env, csrno);
> +    ret = csrop->predicate(env, csrno);
>      if (ret < 0) {
>          return ret;
>      }
>
>      /* execute combined read/write operation if it exists */
> -    if (csr_ops[csrno].op) {
> -        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> +    if (csrop->op) {
> +        return csrop->op(env, csrno, ret_value, new_value, write_mask);
>      }
>
>      /* if no accessor exists then return failure */
> -    if (!csr_ops[csrno].read) {
> +    if (!csrop->read) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
>      /* read old value */
> -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> +    ret = csrop->read(env, csrno, &old_value);
>      if (ret < 0) {
>          return ret;
>      }
> @@ -1335,8 +1386,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      /* write value if writable and write mask set, otherwise drop writes */
>      if (write_mask) {
>          new_value = (old_value & ~write_mask) | (new_value & write_mask);
> -        if (csr_ops[csrno].write) {
> -            ret = csr_ops[csrno].write(env, csrno, new_value);
> +        if (csrop->write) {
> +            ret = csrop->write(env, csrno, new_value);
>              if (ret < 0) {
>                  return ret;
>              }
> @@ -1369,6 +1420,10 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      return ret;
>  }
>
> +#if defined(CONFIG_RISCV_CUSTOM)
> +/* Include the custom CSR table here. */

nits: remove the ending .

> +#endif
> +
>  /* Control and Status Register function table */
>  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      /* User Floating-Point CSRs */
> diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
> new file mode 100644
> index 0000000..5df31f8
> --- /dev/null
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -0,0 +1,8 @@
> +/*
> + * RISC-V cpu bits for custom CSR logic.
> + *
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +/* This file is intentionally left blank at this commit. */

nits: remove the ending .

%s/at/in

Regards,
Bin


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

* Re: [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
  2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
@ 2021-08-06  3:40     ` Bin Meng
  -1 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  3:40 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, Alistair Francis
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Dylan Jhong

On Fri, Aug 6, 2021 at 2:00 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinalnd ChuanTzu Tsai <ruinland@andestech.com>
>
> Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without

The latest RISC-V core from Andes is AX45 and A45. Should we just
support the latest one?

> enhanced features (yet).
>
> Signed-off-by: Dylan Jhong <dylan@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 3a638b5..9eb1e3a 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -182,6 +182,13 @@ static void rv64_base_cpu_init(Object *obj)
>      set_misa(env, RV64);
>  }
>
> +static void ax25_cpu_init(Object *obj)

nits: for name consistency, should be rv64_andes_ax25_cpu_init()

> +{
> +    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;
> @@ -235,6 +242,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)

nits: rv32_andes_a25_cpu_init()

> +{
> +    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)
> @@ -726,8 +740,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),
>  #endif
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 52df9bb..bd79d63 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_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
>  #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")

Regards,
Bin


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

* Re: [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
@ 2021-08-06  3:40     ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  3:40 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai, Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Dylan Jhong

On Fri, Aug 6, 2021 at 2:00 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinalnd ChuanTzu Tsai <ruinland@andestech.com>
>
> Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without

The latest RISC-V core from Andes is AX45 and A45. Should we just
support the latest one?

> enhanced features (yet).
>
> Signed-off-by: Dylan Jhong <dylan@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 3a638b5..9eb1e3a 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -182,6 +182,13 @@ static void rv64_base_cpu_init(Object *obj)
>      set_misa(env, RV64);
>  }
>
> +static void ax25_cpu_init(Object *obj)

nits: for name consistency, should be rv64_andes_ax25_cpu_init()

> +{
> +    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;
> @@ -235,6 +242,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)

nits: rv32_andes_a25_cpu_init()

> +{
> +    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)
> @@ -726,8 +740,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),
>  #endif
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 52df9bb..bd79d63 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_SIFIVE_E31       RISCV_CPU_TYPE_NAME("sifive-e31")
>  #define TYPE_RISCV_CPU_SIFIVE_E34       RISCV_CPU_TYPE_NAME("sifive-e34")

Regards,
Bin


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

* Re: [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
  2021-08-06  3:35     ` Bin Meng
@ 2021-08-06  6:07       ` Ruinland Chuan-Tzu Tsa(蔡傳資)
  -1 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsa(蔡傳資) @ 2021-08-06  6:07 UTC (permalink / raw)
  To: Bin Meng, Alistair Francis
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers,
	Dylan Dai-Rong Jhong(鍾岱融)

[-- Attachment #1: Type: text/plain, Size: 5456 bytes --]


Hi Bin and Alistair,


>> +#if defined(CONFIG_RISCV_CUSTOM)
>> +static void setup_custom_csr(CPURISCVState *env,
>> +                             riscv_custom_csr_operations csr_map_struct[]
>> +                             ) {

>{ should be put to the next line, per QEMU coding convention. Please
>fix this globally in this series.

Will do

>> +
>> +    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
>> +                                                g_direct_equal, \
>> +                                                NULL, NULL);

> Is it possible to juse use g_hash_table_new() directly, with both 2
> parameters being NULL, given you don't provide the destroy hooks?
> like:
>
>    env->custom_csr_map = g_hash_table_new(NULL, NULL);

I can try.

>> +
>> +
>> +    int i;

>nits: please move this to the beginning of this function.

Will do.

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

>break? I think we should continue the loop.

Please refer to Patch 4.
The table is null-ended.
Thus it's a break here.


>> +typedef struct {
>> +    int csrno;
>> +    riscv_csr_operations csr_opset;
>> +    } riscv_custom_csr_operations;

> } should be put in the beginning without space. Please fix this
> globally in this series.

Will do.

> +
> +/*
> + * The reason why we have an abstraction here is that : We could have CSR
> + * number M on hart A is an alias of CSR number N on hart B. So we make a
> + * CSR number to value address map.
> + */
> +typedef struct  {
> +    int csrno;
> +    target_ulong val;
> +    } riscv_custom_csr_vals;
> +

It looks this struct is not used by any patch in this series?

>>  /* CSR function table constants */
>>  enum {
>> -    CSR_TABLE_SIZE = 0x1000
>> +    CSR_TABLE_SIZE = 0x1000,
>> +    MAX_CUSTOM_CSR_NUM = 100

>To be consistent, name this to be: CUSTOM_CSR_TABLE_SIZE

Sounds reasonable.

>>  /* CSR function table */
>> +extern int andes_custom_csr_size;
>> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];

>The above 2 should not be in this patch.
Could you elaborate a little bit more ?

>>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>>
>>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>>
>> +

>This is unnecessary.
Sorry for the newline.

>> -#if !defined(CONFIG_USER_ONLY)
>> +#pragma GCC diagnostic push
>> +#pragma GCC diagnostic ignored "-Wunused-function"

>Use __attribute__((__unused__)), so we don't need to use GCC push/pop
Thanks for the tips.
Will do.

>> +/*
>> + * XXX: This is just a write stub for developing custom CSR handler,

>Remove XXX
Will do.

>> + * if the behavior of writting such CSR is not presentable in QEMU and doesn't

>typo: writing.

>Is that present, or presentable?

It's not a writing typo. I mean "presentable" with its literal meaning.
If we cannot demonstrate a hardware feature inside QEMU, we can just stub it.


>> +#if defined(CONFIG_RISCV_CUSTOM)
>> +/* Custom CSR related routines and data structures */
>> +
>> +static gpointer is_custom_csr(CPURISCVState *env, int csrno)

>The function name suggests that the return value should be of bool
>type. Suggest we do:

>static bool is_custom_csr(CPURISCVState *env, int csrno,
>riscv_custom_csr_operations *custom_csr_ops)

Thanks for the advice, will modify it for V5.


>> +
>> +

>Unnecessary changes
Sorry for the newline.

>>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>>                  target_ulong new_value, target_ulong write_mask)
>>  {
>>      int ret;
>>      target_ulong old_value;
>>      RISCVCPU *cpu = env_archcpu(env);
>> +    #if !defined(CONFIG_RISCV_CUSTOM)

>Please make sure #if starts from the beginning of this line, without space ahead
Will do.

>> +    riscv_csr_operations *csrop = &csr_ops[csrno];

>nits: name this variable to csr_ops

It will collide with original csr_ops.
I'll change to another name.


>>
>> +#if defined(CONFIG_RISCV_CUSTOM)
>> +/* Include the custom CSR table here. */

>nits: remove the ending .
Will do.
Sorry for all these style format issues.
I must I cherry-picked a wrong before I ran checkpatch.pl.

>> +/* This file is intentionally left blank at this commit. */

>nits: remove the ending .

>%s/at/in

Will do.

>Regards,
>Bin

Thanks for the quick reply and advice.
I'll cook the v5 ASAP.

Best regards,
Ruinland
CONFIDENTIALITY NOTICE:

This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.

Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.

[-- Attachment #2: Type: text/html, Size: 10040 bytes --]

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

* Re: [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
@ 2021-08-06  6:07       ` Ruinland Chuan-Tzu Tsa(蔡傳資)
  0 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsa(蔡傳資) @ 2021-08-06  6:07 UTC (permalink / raw)
  To: Bin Meng, Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Dylan Dai-Rong Jhong(鍾岱融)

[-- Attachment #1: Type: text/plain, Size: 5456 bytes --]


Hi Bin and Alistair,


>> +#if defined(CONFIG_RISCV_CUSTOM)
>> +static void setup_custom_csr(CPURISCVState *env,
>> +                             riscv_custom_csr_operations csr_map_struct[]
>> +                             ) {

>{ should be put to the next line, per QEMU coding convention. Please
>fix this globally in this series.

Will do

>> +
>> +    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
>> +                                                g_direct_equal, \
>> +                                                NULL, NULL);

> Is it possible to juse use g_hash_table_new() directly, with both 2
> parameters being NULL, given you don't provide the destroy hooks?
> like:
>
>    env->custom_csr_map = g_hash_table_new(NULL, NULL);

I can try.

>> +
>> +
>> +    int i;

>nits: please move this to the beginning of this function.

Will do.

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

>break? I think we should continue the loop.

Please refer to Patch 4.
The table is null-ended.
Thus it's a break here.


>> +typedef struct {
>> +    int csrno;
>> +    riscv_csr_operations csr_opset;
>> +    } riscv_custom_csr_operations;

> } should be put in the beginning without space. Please fix this
> globally in this series.

Will do.

> +
> +/*
> + * The reason why we have an abstraction here is that : We could have CSR
> + * number M on hart A is an alias of CSR number N on hart B. So we make a
> + * CSR number to value address map.
> + */
> +typedef struct  {
> +    int csrno;
> +    target_ulong val;
> +    } riscv_custom_csr_vals;
> +

It looks this struct is not used by any patch in this series?

>>  /* CSR function table constants */
>>  enum {
>> -    CSR_TABLE_SIZE = 0x1000
>> +    CSR_TABLE_SIZE = 0x1000,
>> +    MAX_CUSTOM_CSR_NUM = 100

>To be consistent, name this to be: CUSTOM_CSR_TABLE_SIZE

Sounds reasonable.

>>  /* CSR function table */
>> +extern int andes_custom_csr_size;
>> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];

>The above 2 should not be in this patch.
Could you elaborate a little bit more ?

>>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>>
>>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>>
>> +

>This is unnecessary.
Sorry for the newline.

>> -#if !defined(CONFIG_USER_ONLY)
>> +#pragma GCC diagnostic push
>> +#pragma GCC diagnostic ignored "-Wunused-function"

>Use __attribute__((__unused__)), so we don't need to use GCC push/pop
Thanks for the tips.
Will do.

>> +/*
>> + * XXX: This is just a write stub for developing custom CSR handler,

>Remove XXX
Will do.

>> + * if the behavior of writting such CSR is not presentable in QEMU and doesn't

>typo: writing.

>Is that present, or presentable?

It's not a writing typo. I mean "presentable" with its literal meaning.
If we cannot demonstrate a hardware feature inside QEMU, we can just stub it.


>> +#if defined(CONFIG_RISCV_CUSTOM)
>> +/* Custom CSR related routines and data structures */
>> +
>> +static gpointer is_custom_csr(CPURISCVState *env, int csrno)

>The function name suggests that the return value should be of bool
>type. Suggest we do:

>static bool is_custom_csr(CPURISCVState *env, int csrno,
>riscv_custom_csr_operations *custom_csr_ops)

Thanks for the advice, will modify it for V5.


>> +
>> +

>Unnecessary changes
Sorry for the newline.

>>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>>                  target_ulong new_value, target_ulong write_mask)
>>  {
>>      int ret;
>>      target_ulong old_value;
>>      RISCVCPU *cpu = env_archcpu(env);
>> +    #if !defined(CONFIG_RISCV_CUSTOM)

>Please make sure #if starts from the beginning of this line, without space ahead
Will do.

>> +    riscv_csr_operations *csrop = &csr_ops[csrno];

>nits: name this variable to csr_ops

It will collide with original csr_ops.
I'll change to another name.


>>
>> +#if defined(CONFIG_RISCV_CUSTOM)
>> +/* Include the custom CSR table here. */

>nits: remove the ending .
Will do.
Sorry for all these style format issues.
I must I cherry-picked a wrong before I ran checkpatch.pl.

>> +/* This file is intentionally left blank at this commit. */

>nits: remove the ending .

>%s/at/in

Will do.

>Regards,
>Bin

Thanks for the quick reply and advice.
I'll cook the v5 ASAP.

Best regards,
Ruinland
CONFIDENTIALITY NOTICE:

This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.

Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.

[-- Attachment #2: Type: text/html, Size: 10040 bytes --]

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

* Re: [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
  2021-08-06  3:40     ` Bin Meng
@ 2021-08-06  6:11       ` Ruinland Chuan-Tzu Tsa(蔡傳資)
  -1 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsa(蔡傳資) @ 2021-08-06  6:11 UTC (permalink / raw)
  To: Bin Meng, Alistair Francis
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers,
	Dylan Dai-Rong Jhong(鍾岱融)

[-- Attachment #1: Type: text/plain, Size: 1388 bytes --]

Hi Bin and Alistair,

>> Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without

> The latest RISC-V core from Andes is AX45 and A45. Should we just
> support the latest one?

Maybe we can have them all ?
AX25 and A25 is still in production, and we still have new clients using these CPU models.

>> +static void ax25_cpu_init(Object *obj)
>nits: for name consistency, should be rv64_andes_ax25_cpu_init()

Will do.


>> +static void a25_cpu_init(Object *obj)
>nits: rv32_andes_a25_cpu_init()

Will do.

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

> Regards,
> Bin

My sincere regards,
Ruinland
CONFIDENTIALITY NOTICE:

This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.

Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.

[-- Attachment #2: Type: text/html, Size: 2877 bytes --]

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

* Re: [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
@ 2021-08-06  6:11       ` Ruinland Chuan-Tzu Tsa(蔡傳資)
  0 siblings, 0 replies; 34+ messages in thread
From: Ruinland Chuan-Tzu Tsa(蔡傳資) @ 2021-08-06  6:11 UTC (permalink / raw)
  To: Bin Meng, Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Dylan Dai-Rong Jhong(鍾岱融)

[-- Attachment #1: Type: text/plain, Size: 1388 bytes --]

Hi Bin and Alistair,

>> Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without

> The latest RISC-V core from Andes is AX45 and A45. Should we just
> support the latest one?

Maybe we can have them all ?
AX25 and A25 is still in production, and we still have new clients using these CPU models.

>> +static void ax25_cpu_init(Object *obj)
>nits: for name consistency, should be rv64_andes_ax25_cpu_init()

Will do.


>> +static void a25_cpu_init(Object *obj)
>nits: rv32_andes_a25_cpu_init()

Will do.

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

> Regards,
> Bin

My sincere regards,
Ruinland
CONFIDENTIALITY NOTICE:

This e-mail (and its attachments) may contain confidential and legally privileged information or information protected from disclosure. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein is strictly prohibited. In this case, please immediately notify the sender by return e-mail, delete the message (and any accompanying documents) and destroy all printed hard copies. Thank you for your cooperation.

Copyright ANDES TECHNOLOGY CORPORATION - All Rights Reserved.

[-- Attachment #2: Type: text/html, Size: 2877 bytes --]

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

* Re: [RFC PATCH v4 4/4] Enable custom CSR logic for Andes AX25 and A25
  2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
@ 2021-08-06  6:14     ` Bin Meng
  -1 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  6:14 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Dylan Jhong

On Fri, Aug 6, 2021 at 1:57 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinalnd ChuanTzu Tsai <ruinland@andestech.com>
>
> In this patch we enabled custom CSR logic for Andes AX25 and A25 logic.
> Hence csr_andes.inc.c and andes_cpu_bits.h is added.
>
> Signed-off-by: Dylan Jhong <dylan@andestech.com>
> ---
>  target/riscv/andes_cpu_bits.h  | 124 +++++++++++++++++++++++++
>  target/riscv/cpu.c             |  12 +++
>  target/riscv/csr.c             |   2 +-
>  target/riscv/csr_andes.inc.c   | 160 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_cpu_bits.h |   6 +-
>  5 files changed, 302 insertions(+), 2 deletions(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.inc.c
>
> diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> new file mode 100644
> index 0000000..bd2b7d1
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,124 @@
> +/*
> + * Andes custom CSRs bit definitions
> + *
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+

nits: please put the license at the beginning of this comment block

> + */
> +
> +/* ========= Missing drafted/standard CSR definitions */
> +/* Although TINFO is in official debug sepc, it's not in cpu_bits.h yet. */
> +#define CSR_TINFO           0x7a4
> +
> +/* ========= 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

nits: please make 0x7C2 lower cases

> +#define CSR_MNVEC               0x7c3
> +#define CSR_MCACHE_CTL          0x7ca
> +#define CSR_MCCTLBEGINADDR      0x7cb
> +#define CSR_MCCTLCOMMAND        0x7cc
> +#define CSR_MCCTLDATA           0x7cd
> +#define CSR_MPPIB               0x7f0
> +#define CSR_MFIOB               0x7f1
> +
> +/* Hardware Stack Protection & Recording */
> +#define CSR_MHSP_CTL            0x7c6
> +#define CSR_MSP_BOUND           0x7c7
> +#define CSR_MSP_BASE            0x7c8
> +#define CSR_MXSTATUS            0x7c4
> +#define CSR_MDCAUSE             0x7c9
> +#define CSR_MSLIDELEG           0x7d5
> +#define CSR_MSAVESTATUS         0x7d6
> +#define CSR_MSAVEEPC1           0x7d7
> +#define CSR_MSAVECAUSE1         0x7d8
> +#define CSR_MSAVEEPC2           0x7d9
> +#define CSR_MSAVECAUSE2         0x7da
> +#define CSR_MSAVEDCAUSE1        0x7db
> +#define CSR_MSAVEDCAUSE2        0x7dc
> +
> +/* Control CSRs */
> +#define CSR_MPFT_CTL            0x7c5
> +#define CSR_MMISC_CTL           0x7d0
> +#define CSR_MCLK_CTL            0x7df
> +
> +/* Counter related CSRs */
> +#define CSR_MCOUNTERWEN         0x7ce
> +#define CSR_MCOUNTERINTEN       0x7cf
> +#define CSR_MCOUNTERMASK_M      0x7d1
> +#define CSR_MCOUNTERMASK_S      0x7d2
> +#define CSR_MCOUNTERMASK_U      0x7d3
> +#define CSR_MCOUNTEROVF         0x7d4
> +
> +/* Enhanced CLIC CSRs */
> +#define CSR_MIRQ_ENTRY          0x7ec
> +#define CSR_MINTSEL_JAL         0x7ed
> +#define CSR_PUSHMCAUSE          0x7ee
> +#define CSR_PUSHMEPC            0x7ef
> +#define CSR_PUSHMXSTATUS        0x7eb
> +
> +/* Andes Physical Memory Attribute(PMA) CSRs */
> +#define CSR_PMACFG0             0xbc0
> +#define CSR_PMACFG1             0xbc1
> +#define CSR_PMACFG2             0xbc2
> +#define CSR_PMACFG3             0xbc3
> +#define CSR_PMAADDR0            0xbd0
> +#define CSR_PMAADDR1            0xbd1
> +#define CSR_PMAADDR2            0xbd2
> +#define CSR_PMAADDR3            0xbd2
> +#define CSR_PMAADDR4            0xbd4
> +#define CSR_PMAADDR5            0xbd5
> +#define CSR_PMAADDR6            0xbd6
> +#define CSR_PMAADDR7            0xbd7
> +#define CSR_PMAADDR8            0xbd8
> +#define CSR_PMAADDR9            0xbd9
> +#define CSR_PMAADDR10           0xbda
> +#define CSR_PMAADDR11           0xbdb
> +#define CSR_PMAADDR12           0xbdc
> +#define CSR_PMAADDR13           0xbdd
> +#define CSR_PMAADDR14           0xbde
> +#define CSR_PMAADDR15           0xbdf
> +
> +/* ========= AndeStar V5 supervisor mode CSRs ========= */
> +/* Supervisor trap registers */
> +#define CSR_SLIE                0x9c4
> +#define CSR_SLIP                0x9c5
> +#define CSR_SDCAUSE             0x9c9
> +
> +/* Supervisor counter registers */
> +#define CSR_SCOUNTERINTEN       0x9cf
> +#define CSR_SCOUNTERMASK_M      0x9d1
> +#define CSR_SCOUNTERMASK_S      0x9d2
> +#define CSR_SCOUNTERMASK_U      0x9d3
> +#define CSR_SCOUNTEROVF         0x9d4
> +#define CSR_SCOUNTINHIBIT       0x9e0
> +#define CSR_SHPMEVENT3          0x9e3
> +#define CSR_SHPMEVENT4          0x9e4
> +#define CSR_SHPMEVENT5          0x9e5
> +#define CSR_SHPMEVENT6          0x9e6
> +
> +/* Supervisor control registers */
> +#define CSR_SCCTLDATA           0x9cd
> +#define CSR_SMISC_CTL           0x9d0
> +
> +/* ========= AndeStar V5 user mode CSRs ========= */
> +/* User mode control registers */
> +#define CSR_UITB                0x800
> +#define CSR_UCODE               0x801
> +#define CSR_UDCAUSE             0x809
> +#define CSR_UCCTLBEGINADDR      0x80b
> +#define CSR_UCCTLCOMMAND        0x80c
> +#define CSR_WFE                 0x810
> +#define CSR_SLEEPVALUE          0x811
> +#define CSR_TXEVT               0x812
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9eb1e3a..d1d4773 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -187,6 +187,12 @@ 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);
> +
> +    #if defined(CONFIG_RISCV_CUSTOM)

nits: no space before #if

> +    /* setup custom csr handler hash table */
> +    setup_custom_csr(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> +    #endif
>  }
>
>  static void rv64_sifive_u_cpu_init(Object *obj)
> @@ -248,6 +254,12 @@ 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);
> +
> +    #if defined(CONFIG_RISCV_CUSTOM)
> +    /* setup custom csr handler hash table */
> +    setup_custom_csr(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> +    #endif
>  }
>  #endif
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 1c4dc94..9c16b88 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1421,7 +1421,7 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
>  }
>
>  #if defined(CONFIG_RISCV_CUSTOM)
> -/* Include the custom CSR table here. */
> +#include "csr_andes.inc.c"
>  #endif
>
>  /* Control and Status Register function table */
> diff --git a/target/riscv/csr_andes.inc.c b/target/riscv/csr_andes.inc.c
> new file mode 100644
> index 0000000..da226b0
> --- /dev/null
> +++ b/target/riscv/csr_andes.inc.c
> @@ -0,0 +1,160 @@
> +/*
> + * Andes custom CSR table and handling functions
> + *
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +static int write_uitb(CPURISCVState *env, int csrno, target_ulong val);
> +static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val);
> +
> +struct andes_csr_val {
> +    target_long uitb;
> +};
> +
> +static int read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    /* enable pma probe */
> +    *val = 0x40000000;
> +    return 0;
> +}
> +
> +static int write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    andes_csr->uitb = val;
> +    return 0;
> +}
> +
> +static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    *val = andes_csr->uitb;
> +    return 0;
> +}
> +
> +
> +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 ==================== */
> +    /* Configuration Registers */
> +    {CSR_MICM_CFG,         { "micm_cfg",          any, read_zero, write_stub} },
> +    {CSR_MDCM_CFG,         { "mdcm_cfg",          any, read_zero, write_stub} },
> +    {CSR_MMSC_CFG,         { "mmsc_cfg",          any, read_mmsc_cfg, write_stub} },
> +    {CSR_MMSC_CFG2,        { "mmsc_cfg2",         any, read_zero, write_stub} },
> +    {CSR_MVEC_CFG,         { "mvec_cfg",          any, read_zero, write_stub} },
> +
> +    /* Crash Debug CSRs */
> +    {CSR_MCRASH_STATESAVE,  { "mcrash_statesave",  any, read_zero, write_stub} },
> +    {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
> +
> +    /* Memory CSRs */
> +    {CSR_MILMB,            { "milmb",             any, read_zero, write_stub} },
> +    {CSR_MDLMB,            { "mdlmb",             any, read_zero, write_stub} },
> +    {CSR_MECC_CODE,        { "mecc_code",         any, read_zero, write_stub} },
> +    {CSR_MNVEC,            { "mnvec",             any, read_zero, write_stub} },
> +    {CSR_MCACHE_CTL,       { "mcache_ctl",        any, read_zero, write_stub} },
> +    {CSR_MCCTLBEGINADDR,   { "mcctlbeginaddr",    any, read_zero, write_stub} },
> +    {CSR_MCCTLCOMMAND,     { "mcctlcommand",      any, read_zero, write_stub} },
> +    {CSR_MCCTLDATA,        { "mcctldata",         any, read_zero, write_stub} },
> +    {CSR_MPPIB,            { "mppib",             any, read_zero, write_stub} },
> +    {CSR_MFIOB,            { "mfiob",             any, read_zero, write_stub} },
> +
> +    /* Hardware Stack Protection & Recording */
> +    {CSR_MHSP_CTL,         { "mhsp_ctl",          any, read_zero, write_stub} },
> +    {CSR_MSP_BOUND,        { "msp_bound",         any, read_zero, write_stub} },
> +    {CSR_MSP_BASE,         { "msp_base",          any, read_zero, write_stub} },
> +    {CSR_MXSTATUS,         { "mxstatus",          any, read_zero, write_stub} },
> +    {CSR_MDCAUSE,          { "mdcause",           any, read_zero, write_stub} },
> +    {CSR_MSLIDELEG,        { "mslideleg",         any, read_zero, write_stub} },
> +    {CSR_MSAVESTATUS,      { "msavestatus",       any, read_zero, write_stub} },
> +    {CSR_MSAVEEPC1,        { "msaveepc1",         any, read_zero, write_stub} },
> +    {CSR_MSAVECAUSE1,      { "msavecause1",       any, read_zero, write_stub} },
> +    {CSR_MSAVEEPC2,        { "msaveepc2",         any, read_zero, write_stub} },
> +    {CSR_MSAVECAUSE2,      { "msavecause2",       any, read_zero, write_stub} },
> +    {CSR_MSAVEDCAUSE1,     { "msavedcause1",      any, read_zero, write_stub} },
> +    {CSR_MSAVEDCAUSE2,     { "msavedcause2",      any, read_zero, write_stub} },
> +
> +    /* Control CSRs */
> +    {CSR_MPFT_CTL,         { "mpft_ctl",          any, read_zero, write_stub} },
> +    {CSR_MMISC_CTL,        { "mmisc_ctl",         any, read_zero, write_stub} },
> +    {CSR_MCLK_CTL,         { "mclk_ctl",          any, read_zero, write_stub} },
> +
> +    /* Counter related CSRs */
> +    {CSR_MCOUNTERWEN,      { "mcounterwen",       any, read_zero, write_stub} },
> +    {CSR_MCOUNTERINTEN,    { "mcounterinten",     any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_M,   { "mcountermask_m",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_S,   { "mcountermask_s",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_U,   { "mcountermask_u",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTEROVF,      { "mcounterovf",       any, read_zero, write_stub} },
> +
> +    /* Enhanced CLIC CSRs */
> +    {CSR_MIRQ_ENTRY,       { "mirq_entry",        any, read_zero, write_stub} },
> +    {CSR_MINTSEL_JAL,      { "mintsel_jal",       any, read_zero, write_stub} },
> +    {CSR_PUSHMCAUSE,       { "pushmcause",        any, read_zero, write_stub} },
> +    {CSR_PUSHMEPC,         { "pushmepc",          any, read_zero, write_stub} },
> +    {CSR_PUSHMXSTATUS,     { "pushmxstatus",      any, read_zero, write_stub} },
> +
> +    /* Andes Physical Memory Attribute(PMA) CSRs */
> +    {CSR_PMACFG0,          { "pmacfg0",           any, read_zero, write_stub} },
> +    {CSR_PMACFG1,          { "pmacfg1",           any, read_zero, write_stub} },
> +    {CSR_PMACFG2,          { "pmacfg2",           any, read_zero, write_stub} },
> +    {CSR_PMACFG3,          { "pmacfg3",           any, read_zero, write_stub} },
> +    {CSR_PMAADDR0,         { "pmaaddr0",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR1,         { "pmaaddr1",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR2,         { "pmaaddr2",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR3,         { "pmaaddr3",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR4,         { "pmaaddr4",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR5,         { "pmaaddr5",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR6,         { "pmaaddr6",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR7,         { "pmaaddr7",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR8,         { "pmaaddr8",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR9,         { "pmaaddr9",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR10,        { "pmaaddr10",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR11,        { "pmaaddr11",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR12,        { "pmaaddr12",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR13,        { "pmaaddr13",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR14,        { "pmaaddr14",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR15,        { "pmaaddr15",         any, read_zero, write_stub} },
> +
> +    /* Debug/Trace Registers (shared with Debug Mode) */
> +    {CSR_TSELECT,          { "tselect",           any, read_zero, write_stub} },
> +    {CSR_TDATA1,           { "tdata1",            any, read_zero, write_stub} },
> +    {CSR_TDATA2,           { "tdata2",            any, read_zero, write_stub} },
> +    {CSR_TDATA3,           { "tdata3",            any, read_zero, write_stub} },
> +    {CSR_TINFO,            { "tinfo",             any, read_zero, write_stub} },
> +
> +    /* ================== AndeStar V5 supervisor mode CSRs ================== */
> +    /* Supervisor trap registers */
> +    {CSR_SLIE,             { "slie",              any, read_zero, write_stub} },
> +    {CSR_SLIP,             { "slip",              any, read_zero, write_stub} },
> +    {CSR_SDCAUSE,          { "sdcause",           any, read_zero, write_stub} },
> +
> +    /* Supervisor counter registers */
> +    {CSR_SCOUNTERINTEN,    { "scounterinten",     any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_M,   { "scountermask_m",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_S,   { "scountermask_s",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_U,   { "scountermask_u",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTEROVF,      { "scounterovf",       any, read_zero, write_stub} },
> +    {CSR_SCOUNTINHIBIT,    { "scountinhibit",     any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT3,       { "shpmevent3",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT4,       { "shpmevent4",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT5,       { "shpmevent5",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT6,       { "shpmevent6",        any, read_zero, write_stub} },
> +
> +    /* Supervisor control registers */
> +    {CSR_SCCTLDATA,        { "scctldata",         any, read_zero, write_stub} },
> +    {CSR_SMISC_CTL,        { "smisc_ctl",         any, read_zero, write_stub} },
> +
> +    /* ===================== AndeStar V5 user mode CSRs ===================== */
> +    /* User mode control registers */
> +    {CSR_UITB,             { "uitb",              any, read_uitb, write_uitb} },
> +    {CSR_UCODE,            { "ucode",             any, read_zero, write_stub} },
> +    {CSR_UDCAUSE,          { "udcause",           any, read_zero, write_stub} },
> +    {CSR_UCCTLBEGINADDR,   { "ucctlbeginaddr",    any, read_zero, write_stub} },
> +    {CSR_UCCTLCOMMAND,     { "ucctlcommand",      any, read_zero, write_stub} },
> +    {CSR_WFE,              { "wfe",               any, read_zero, write_stub} },
> +    {CSR_SLEEPVALUE,       { "sleepvalue",        any, read_zero, write_stub} },
> +    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
> +    {0, { "", NULL, NULL, NULL } },
> +    };
> diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
> index 5df31f8..ba67e95 100644
> --- a/target/riscv/custom_cpu_bits.h
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -5,4 +5,8 @@
>   * SPDX-License-Identifier: GPL-2.0+
>   */
>
> -/* This file is intentionally left blank at this commit. */
> +/*
> + * XXX: Maybe we should add a "target-list"-like option to toggle enabled
> + * custom CSR variations ?

As I mentioned in patch 1, we'd better use a Kconfig option. This
Koption option should be selected by the Andes machine.

> + */
> +#include "andes_cpu_bits.h"
> --

Regards,
Bin


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

* Re: [RFC PATCH v4 4/4] Enable custom CSR logic for Andes AX25 and A25
@ 2021-08-06  6:14     ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  6:14 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Dylan Jhong

On Fri, Aug 6, 2021 at 1:57 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinalnd ChuanTzu Tsai <ruinland@andestech.com>
>
> In this patch we enabled custom CSR logic for Andes AX25 and A25 logic.
> Hence csr_andes.inc.c and andes_cpu_bits.h is added.
>
> Signed-off-by: Dylan Jhong <dylan@andestech.com>
> ---
>  target/riscv/andes_cpu_bits.h  | 124 +++++++++++++++++++++++++
>  target/riscv/cpu.c             |  12 +++
>  target/riscv/csr.c             |   2 +-
>  target/riscv/csr_andes.inc.c   | 160 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_cpu_bits.h |   6 +-
>  5 files changed, 302 insertions(+), 2 deletions(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.inc.c
>
> diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> new file mode 100644
> index 0000000..bd2b7d1
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,124 @@
> +/*
> + * Andes custom CSRs bit definitions
> + *
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+

nits: please put the license at the beginning of this comment block

> + */
> +
> +/* ========= Missing drafted/standard CSR definitions */
> +/* Although TINFO is in official debug sepc, it's not in cpu_bits.h yet. */
> +#define CSR_TINFO           0x7a4
> +
> +/* ========= 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

nits: please make 0x7C2 lower cases

> +#define CSR_MNVEC               0x7c3
> +#define CSR_MCACHE_CTL          0x7ca
> +#define CSR_MCCTLBEGINADDR      0x7cb
> +#define CSR_MCCTLCOMMAND        0x7cc
> +#define CSR_MCCTLDATA           0x7cd
> +#define CSR_MPPIB               0x7f0
> +#define CSR_MFIOB               0x7f1
> +
> +/* Hardware Stack Protection & Recording */
> +#define CSR_MHSP_CTL            0x7c6
> +#define CSR_MSP_BOUND           0x7c7
> +#define CSR_MSP_BASE            0x7c8
> +#define CSR_MXSTATUS            0x7c4
> +#define CSR_MDCAUSE             0x7c9
> +#define CSR_MSLIDELEG           0x7d5
> +#define CSR_MSAVESTATUS         0x7d6
> +#define CSR_MSAVEEPC1           0x7d7
> +#define CSR_MSAVECAUSE1         0x7d8
> +#define CSR_MSAVEEPC2           0x7d9
> +#define CSR_MSAVECAUSE2         0x7da
> +#define CSR_MSAVEDCAUSE1        0x7db
> +#define CSR_MSAVEDCAUSE2        0x7dc
> +
> +/* Control CSRs */
> +#define CSR_MPFT_CTL            0x7c5
> +#define CSR_MMISC_CTL           0x7d0
> +#define CSR_MCLK_CTL            0x7df
> +
> +/* Counter related CSRs */
> +#define CSR_MCOUNTERWEN         0x7ce
> +#define CSR_MCOUNTERINTEN       0x7cf
> +#define CSR_MCOUNTERMASK_M      0x7d1
> +#define CSR_MCOUNTERMASK_S      0x7d2
> +#define CSR_MCOUNTERMASK_U      0x7d3
> +#define CSR_MCOUNTEROVF         0x7d4
> +
> +/* Enhanced CLIC CSRs */
> +#define CSR_MIRQ_ENTRY          0x7ec
> +#define CSR_MINTSEL_JAL         0x7ed
> +#define CSR_PUSHMCAUSE          0x7ee
> +#define CSR_PUSHMEPC            0x7ef
> +#define CSR_PUSHMXSTATUS        0x7eb
> +
> +/* Andes Physical Memory Attribute(PMA) CSRs */
> +#define CSR_PMACFG0             0xbc0
> +#define CSR_PMACFG1             0xbc1
> +#define CSR_PMACFG2             0xbc2
> +#define CSR_PMACFG3             0xbc3
> +#define CSR_PMAADDR0            0xbd0
> +#define CSR_PMAADDR1            0xbd1
> +#define CSR_PMAADDR2            0xbd2
> +#define CSR_PMAADDR3            0xbd2
> +#define CSR_PMAADDR4            0xbd4
> +#define CSR_PMAADDR5            0xbd5
> +#define CSR_PMAADDR6            0xbd6
> +#define CSR_PMAADDR7            0xbd7
> +#define CSR_PMAADDR8            0xbd8
> +#define CSR_PMAADDR9            0xbd9
> +#define CSR_PMAADDR10           0xbda
> +#define CSR_PMAADDR11           0xbdb
> +#define CSR_PMAADDR12           0xbdc
> +#define CSR_PMAADDR13           0xbdd
> +#define CSR_PMAADDR14           0xbde
> +#define CSR_PMAADDR15           0xbdf
> +
> +/* ========= AndeStar V5 supervisor mode CSRs ========= */
> +/* Supervisor trap registers */
> +#define CSR_SLIE                0x9c4
> +#define CSR_SLIP                0x9c5
> +#define CSR_SDCAUSE             0x9c9
> +
> +/* Supervisor counter registers */
> +#define CSR_SCOUNTERINTEN       0x9cf
> +#define CSR_SCOUNTERMASK_M      0x9d1
> +#define CSR_SCOUNTERMASK_S      0x9d2
> +#define CSR_SCOUNTERMASK_U      0x9d3
> +#define CSR_SCOUNTEROVF         0x9d4
> +#define CSR_SCOUNTINHIBIT       0x9e0
> +#define CSR_SHPMEVENT3          0x9e3
> +#define CSR_SHPMEVENT4          0x9e4
> +#define CSR_SHPMEVENT5          0x9e5
> +#define CSR_SHPMEVENT6          0x9e6
> +
> +/* Supervisor control registers */
> +#define CSR_SCCTLDATA           0x9cd
> +#define CSR_SMISC_CTL           0x9d0
> +
> +/* ========= AndeStar V5 user mode CSRs ========= */
> +/* User mode control registers */
> +#define CSR_UITB                0x800
> +#define CSR_UCODE               0x801
> +#define CSR_UDCAUSE             0x809
> +#define CSR_UCCTLBEGINADDR      0x80b
> +#define CSR_UCCTLCOMMAND        0x80c
> +#define CSR_WFE                 0x810
> +#define CSR_SLEEPVALUE          0x811
> +#define CSR_TXEVT               0x812
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9eb1e3a..d1d4773 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -187,6 +187,12 @@ 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);
> +
> +    #if defined(CONFIG_RISCV_CUSTOM)

nits: no space before #if

> +    /* setup custom csr handler hash table */
> +    setup_custom_csr(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> +    #endif
>  }
>
>  static void rv64_sifive_u_cpu_init(Object *obj)
> @@ -248,6 +254,12 @@ 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);
> +
> +    #if defined(CONFIG_RISCV_CUSTOM)
> +    /* setup custom csr handler hash table */
> +    setup_custom_csr(env, andes_custom_csr_table);
> +    env->custom_csr_val = g_malloc(andes_custom_csr_size);
> +    #endif
>  }
>  #endif
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 1c4dc94..9c16b88 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1421,7 +1421,7 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
>  }
>
>  #if defined(CONFIG_RISCV_CUSTOM)
> -/* Include the custom CSR table here. */
> +#include "csr_andes.inc.c"
>  #endif
>
>  /* Control and Status Register function table */
> diff --git a/target/riscv/csr_andes.inc.c b/target/riscv/csr_andes.inc.c
> new file mode 100644
> index 0000000..da226b0
> --- /dev/null
> +++ b/target/riscv/csr_andes.inc.c
> @@ -0,0 +1,160 @@
> +/*
> + * Andes custom CSR table and handling functions
> + *
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +static int write_uitb(CPURISCVState *env, int csrno, target_ulong val);
> +static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val);
> +
> +struct andes_csr_val {
> +    target_long uitb;
> +};
> +
> +static int read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    /* enable pma probe */
> +    *val = 0x40000000;
> +    return 0;
> +}
> +
> +static int write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    andes_csr->uitb = val;
> +    return 0;
> +}
> +
> +static int read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    struct andes_csr_val *andes_csr = env->custom_csr_val;
> +    *val = andes_csr->uitb;
> +    return 0;
> +}
> +
> +
> +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 ==================== */
> +    /* Configuration Registers */
> +    {CSR_MICM_CFG,         { "micm_cfg",          any, read_zero, write_stub} },
> +    {CSR_MDCM_CFG,         { "mdcm_cfg",          any, read_zero, write_stub} },
> +    {CSR_MMSC_CFG,         { "mmsc_cfg",          any, read_mmsc_cfg, write_stub} },
> +    {CSR_MMSC_CFG2,        { "mmsc_cfg2",         any, read_zero, write_stub} },
> +    {CSR_MVEC_CFG,         { "mvec_cfg",          any, read_zero, write_stub} },
> +
> +    /* Crash Debug CSRs */
> +    {CSR_MCRASH_STATESAVE,  { "mcrash_statesave",  any, read_zero, write_stub} },
> +    {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
> +
> +    /* Memory CSRs */
> +    {CSR_MILMB,            { "milmb",             any, read_zero, write_stub} },
> +    {CSR_MDLMB,            { "mdlmb",             any, read_zero, write_stub} },
> +    {CSR_MECC_CODE,        { "mecc_code",         any, read_zero, write_stub} },
> +    {CSR_MNVEC,            { "mnvec",             any, read_zero, write_stub} },
> +    {CSR_MCACHE_CTL,       { "mcache_ctl",        any, read_zero, write_stub} },
> +    {CSR_MCCTLBEGINADDR,   { "mcctlbeginaddr",    any, read_zero, write_stub} },
> +    {CSR_MCCTLCOMMAND,     { "mcctlcommand",      any, read_zero, write_stub} },
> +    {CSR_MCCTLDATA,        { "mcctldata",         any, read_zero, write_stub} },
> +    {CSR_MPPIB,            { "mppib",             any, read_zero, write_stub} },
> +    {CSR_MFIOB,            { "mfiob",             any, read_zero, write_stub} },
> +
> +    /* Hardware Stack Protection & Recording */
> +    {CSR_MHSP_CTL,         { "mhsp_ctl",          any, read_zero, write_stub} },
> +    {CSR_MSP_BOUND,        { "msp_bound",         any, read_zero, write_stub} },
> +    {CSR_MSP_BASE,         { "msp_base",          any, read_zero, write_stub} },
> +    {CSR_MXSTATUS,         { "mxstatus",          any, read_zero, write_stub} },
> +    {CSR_MDCAUSE,          { "mdcause",           any, read_zero, write_stub} },
> +    {CSR_MSLIDELEG,        { "mslideleg",         any, read_zero, write_stub} },
> +    {CSR_MSAVESTATUS,      { "msavestatus",       any, read_zero, write_stub} },
> +    {CSR_MSAVEEPC1,        { "msaveepc1",         any, read_zero, write_stub} },
> +    {CSR_MSAVECAUSE1,      { "msavecause1",       any, read_zero, write_stub} },
> +    {CSR_MSAVEEPC2,        { "msaveepc2",         any, read_zero, write_stub} },
> +    {CSR_MSAVECAUSE2,      { "msavecause2",       any, read_zero, write_stub} },
> +    {CSR_MSAVEDCAUSE1,     { "msavedcause1",      any, read_zero, write_stub} },
> +    {CSR_MSAVEDCAUSE2,     { "msavedcause2",      any, read_zero, write_stub} },
> +
> +    /* Control CSRs */
> +    {CSR_MPFT_CTL,         { "mpft_ctl",          any, read_zero, write_stub} },
> +    {CSR_MMISC_CTL,        { "mmisc_ctl",         any, read_zero, write_stub} },
> +    {CSR_MCLK_CTL,         { "mclk_ctl",          any, read_zero, write_stub} },
> +
> +    /* Counter related CSRs */
> +    {CSR_MCOUNTERWEN,      { "mcounterwen",       any, read_zero, write_stub} },
> +    {CSR_MCOUNTERINTEN,    { "mcounterinten",     any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_M,   { "mcountermask_m",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_S,   { "mcountermask_s",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTERMASK_U,   { "mcountermask_u",    any, read_zero, write_stub} },
> +    {CSR_MCOUNTEROVF,      { "mcounterovf",       any, read_zero, write_stub} },
> +
> +    /* Enhanced CLIC CSRs */
> +    {CSR_MIRQ_ENTRY,       { "mirq_entry",        any, read_zero, write_stub} },
> +    {CSR_MINTSEL_JAL,      { "mintsel_jal",       any, read_zero, write_stub} },
> +    {CSR_PUSHMCAUSE,       { "pushmcause",        any, read_zero, write_stub} },
> +    {CSR_PUSHMEPC,         { "pushmepc",          any, read_zero, write_stub} },
> +    {CSR_PUSHMXSTATUS,     { "pushmxstatus",      any, read_zero, write_stub} },
> +
> +    /* Andes Physical Memory Attribute(PMA) CSRs */
> +    {CSR_PMACFG0,          { "pmacfg0",           any, read_zero, write_stub} },
> +    {CSR_PMACFG1,          { "pmacfg1",           any, read_zero, write_stub} },
> +    {CSR_PMACFG2,          { "pmacfg2",           any, read_zero, write_stub} },
> +    {CSR_PMACFG3,          { "pmacfg3",           any, read_zero, write_stub} },
> +    {CSR_PMAADDR0,         { "pmaaddr0",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR1,         { "pmaaddr1",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR2,         { "pmaaddr2",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR3,         { "pmaaddr3",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR4,         { "pmaaddr4",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR5,         { "pmaaddr5",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR6,         { "pmaaddr6",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR7,         { "pmaaddr7",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR8,         { "pmaaddr8",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR9,         { "pmaaddr9",          any, read_zero, write_stub} },
> +    {CSR_PMAADDR10,        { "pmaaddr10",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR11,        { "pmaaddr11",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR12,        { "pmaaddr12",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR13,        { "pmaaddr13",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR14,        { "pmaaddr14",         any, read_zero, write_stub} },
> +    {CSR_PMAADDR15,        { "pmaaddr15",         any, read_zero, write_stub} },
> +
> +    /* Debug/Trace Registers (shared with Debug Mode) */
> +    {CSR_TSELECT,          { "tselect",           any, read_zero, write_stub} },
> +    {CSR_TDATA1,           { "tdata1",            any, read_zero, write_stub} },
> +    {CSR_TDATA2,           { "tdata2",            any, read_zero, write_stub} },
> +    {CSR_TDATA3,           { "tdata3",            any, read_zero, write_stub} },
> +    {CSR_TINFO,            { "tinfo",             any, read_zero, write_stub} },
> +
> +    /* ================== AndeStar V5 supervisor mode CSRs ================== */
> +    /* Supervisor trap registers */
> +    {CSR_SLIE,             { "slie",              any, read_zero, write_stub} },
> +    {CSR_SLIP,             { "slip",              any, read_zero, write_stub} },
> +    {CSR_SDCAUSE,          { "sdcause",           any, read_zero, write_stub} },
> +
> +    /* Supervisor counter registers */
> +    {CSR_SCOUNTERINTEN,    { "scounterinten",     any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_M,   { "scountermask_m",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_S,   { "scountermask_s",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTERMASK_U,   { "scountermask_u",    any, read_zero, write_stub} },
> +    {CSR_SCOUNTEROVF,      { "scounterovf",       any, read_zero, write_stub} },
> +    {CSR_SCOUNTINHIBIT,    { "scountinhibit",     any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT3,       { "shpmevent3",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT4,       { "shpmevent4",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT5,       { "shpmevent5",        any, read_zero, write_stub} },
> +    {CSR_SHPMEVENT6,       { "shpmevent6",        any, read_zero, write_stub} },
> +
> +    /* Supervisor control registers */
> +    {CSR_SCCTLDATA,        { "scctldata",         any, read_zero, write_stub} },
> +    {CSR_SMISC_CTL,        { "smisc_ctl",         any, read_zero, write_stub} },
> +
> +    /* ===================== AndeStar V5 user mode CSRs ===================== */
> +    /* User mode control registers */
> +    {CSR_UITB,             { "uitb",              any, read_uitb, write_uitb} },
> +    {CSR_UCODE,            { "ucode",             any, read_zero, write_stub} },
> +    {CSR_UDCAUSE,          { "udcause",           any, read_zero, write_stub} },
> +    {CSR_UCCTLBEGINADDR,   { "ucctlbeginaddr",    any, read_zero, write_stub} },
> +    {CSR_UCCTLCOMMAND,     { "ucctlcommand",      any, read_zero, write_stub} },
> +    {CSR_WFE,              { "wfe",               any, read_zero, write_stub} },
> +    {CSR_SLEEPVALUE,       { "sleepvalue",        any, read_zero, write_stub} },
> +    {CSR_TXEVT,            { "csr_txevt",         any, read_zero, write_stub} },
> +    {0, { "", NULL, NULL, NULL } },
> +    };
> diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
> index 5df31f8..ba67e95 100644
> --- a/target/riscv/custom_cpu_bits.h
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -5,4 +5,8 @@
>   * SPDX-License-Identifier: GPL-2.0+
>   */
>
> -/* This file is intentionally left blank at this commit. */
> +/*
> + * XXX: Maybe we should add a "target-list"-like option to toggle enabled
> + * custom CSR variations ?

As I mentioned in patch 1, we'd better use a Kconfig option. This
Koption option should be selected by the Andes machine.

> + */
> +#include "andes_cpu_bits.h"
> --

Regards,
Bin


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

* Re: [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
  2021-08-06  6:07       ` Ruinland Chuan-Tzu Tsa(蔡傳資)
@ 2021-08-06  6:19         ` Bin Meng
  -1 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  6:19 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsa(蔡傳資)
  Cc: Dylan Dai-Rong Jhong(鍾岱融),
	open list:RISC-V, wangjunqiang, Bin Meng,
	qemu-devel@nongnu.org Developers, Alistair Francis

On Fri, Aug 6, 2021 at 2:08 PM Ruinland Chuan-Tzu Tsa(蔡傳資)
<ruinland@andestech.com> wrote:
>
>
> Hi Bin and Alistair,
>
>
> >> +#if defined(CONFIG_RISCV_CUSTOM)
> >> +static void setup_custom_csr(CPURISCVState *env,
> >> +                             riscv_custom_csr_operations csr_map_struct[]
> >> +                             ) {
>
> >{ should be put to the next line, per QEMU coding convention. Please
> >fix this globally in this series.
>
> Will do
>
> >> +
> >> +    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
> >> +                                                g_direct_equal, \
> >> +                                                NULL, NULL);
>
> > Is it possible to juse use g_hash_table_new() directly, with both 2
> > parameters being NULL, given you don't provide the destroy hooks?
> > like:
> >
> >    env->custom_csr_map = g_hash_table_new(NULL, NULL);
>
> I can try.
>
> >> +
> >> +
> >> +    int i;
>
> >nits: please move this to the beginning of this function.
>
> Will do.
>
> >> +    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;
>
> >break? I think we should continue the loop.
>
> Please refer to Patch 4.
> The table is null-ended.
> Thus it's a break here.
>
>
> >> +typedef struct {
> >> +    int csrno;
> >> +    riscv_csr_operations csr_opset;
> >> +    } riscv_custom_csr_operations;
>
> > } should be put in the beginning without space. Please fix this
> > globally in this series.
>
> Will do.
>
> > +
> > +/*
> > + * The reason why we have an abstraction here is that : We could have CSR
> > + * number M on hart A is an alias of CSR number N on hart B. So we make a
> > + * CSR number to value address map.
> > + */
> > +typedef struct  {
> > +    int csrno;
> > +    target_ulong val;
> > +    } riscv_custom_csr_vals;
> > +
>
> It looks this struct is not used by any patch in this series?
>
> >>  /* CSR function table constants */
> >>  enum {
> >> -    CSR_TABLE_SIZE = 0x1000
> >> +    CSR_TABLE_SIZE = 0x1000,
> >> +    MAX_CUSTOM_CSR_NUM = 100
>
> >To be consistent, name this to be: CUSTOM_CSR_TABLE_SIZE
>
> Sounds reasonable.
>
> >>  /* CSR function table */
> >> +extern int andes_custom_csr_size;
> >> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
>
> >The above 2 should not be in this patch.
> Could you elaborate a little bit more ?

These 2 should belong to patch 4 where Andes custom CSR is added.

>
> >>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
> >>
> >>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
> >>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
> >>
> >> +
>
> >This is unnecessary.
> Sorry for the newline.
>
> >> -#if !defined(CONFIG_USER_ONLY)
> >> +#pragma GCC diagnostic push
> >> +#pragma GCC diagnostic ignored "-Wunused-function"
>
> >Use __attribute__((__unused__)), so we don't need to use GCC push/pop
> Thanks for the tips.
> Will do.
>
> >> +/*
> >> + * XXX: This is just a write stub for developing custom CSR handler,
>
> >Remove XXX
> Will do.
>
> >> + * if the behavior of writting such CSR is not presentable in QEMU and doesn't
>
> >typo: writing.
>
> >Is that present, or presentable?
>
> It's not a writing typo. I mean "presentable" with its literal meaning.
> If we cannot demonstrate a hardware feature inside QEMU, we can just stub it.
>
>
> >> +#if defined(CONFIG_RISCV_CUSTOM)
> >> +/* Custom CSR related routines and data structures */
> >> +
> >> +static gpointer is_custom_csr(CPURISCVState *env, int csrno)
>
> >The function name suggests that the return value should be of bool
> >type. Suggest we do:
>
> >static bool is_custom_csr(CPURISCVState *env, int csrno,
> >riscv_custom_csr_operations *custom_csr_ops)
>
> Thanks for the advice, will modify it for V5.
>
>
> >> +
> >> +
>
> >Unnecessary changes
> Sorry for the newline.
>
> >>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
> >>                  target_ulong new_value, target_ulong write_mask)
> >>  {
> >>      int ret;
> >>      target_ulong old_value;
> >>      RISCVCPU *cpu = env_archcpu(env);
> >> +    #if !defined(CONFIG_RISCV_CUSTOM)
>
> >Please make sure #if starts from the beginning of this line, without space ahead
> Will do.
>
> >> +    riscv_csr_operations *csrop = &csr_ops[csrno];
>
> >nits: name this variable to csr_ops
>
> It will collide with original csr_ops.

Maybe csr_op ?

> I'll change to another name.
>
>
> >>
> >> +#if defined(CONFIG_RISCV_CUSTOM)
> >> +/* Include the custom CSR table here. */
>
> >nits: remove the ending .
> Will do.
> Sorry for all these style format issues.
> I must I cherry-picked a wrong before I ran checkpatch.pl.
>
> >> +/* This file is intentionally left blank at this commit. */
>
> >nits: remove the ending .
>
> >%s/at/in
>
> Will do.
>
> >Regards,
> >Bin
>
> Thanks for the quick reply and advice.
> I'll cook the v5 ASAP.

Note: one more place you need to modify in this patch, is the
riscv_gen_dynamic_csr_xml() in target/riscv/gdbstub.c

Regards,
Bin


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

* Re: [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
@ 2021-08-06  6:19         ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  6:19 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsa(蔡傳資)
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers,
	open list:RISC-V, wangjunqiang, Bin Meng,
	Dylan Dai-Rong Jhong(鍾岱融)

On Fri, Aug 6, 2021 at 2:08 PM Ruinland Chuan-Tzu Tsa(蔡傳資)
<ruinland@andestech.com> wrote:
>
>
> Hi Bin and Alistair,
>
>
> >> +#if defined(CONFIG_RISCV_CUSTOM)
> >> +static void setup_custom_csr(CPURISCVState *env,
> >> +                             riscv_custom_csr_operations csr_map_struct[]
> >> +                             ) {
>
> >{ should be put to the next line, per QEMU coding convention. Please
> >fix this globally in this series.
>
> Will do
>
> >> +
> >> +    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
> >> +                                                g_direct_equal, \
> >> +                                                NULL, NULL);
>
> > Is it possible to juse use g_hash_table_new() directly, with both 2
> > parameters being NULL, given you don't provide the destroy hooks?
> > like:
> >
> >    env->custom_csr_map = g_hash_table_new(NULL, NULL);
>
> I can try.
>
> >> +
> >> +
> >> +    int i;
>
> >nits: please move this to the beginning of this function.
>
> Will do.
>
> >> +    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;
>
> >break? I think we should continue the loop.
>
> Please refer to Patch 4.
> The table is null-ended.
> Thus it's a break here.
>
>
> >> +typedef struct {
> >> +    int csrno;
> >> +    riscv_csr_operations csr_opset;
> >> +    } riscv_custom_csr_operations;
>
> > } should be put in the beginning without space. Please fix this
> > globally in this series.
>
> Will do.
>
> > +
> > +/*
> > + * The reason why we have an abstraction here is that : We could have CSR
> > + * number M on hart A is an alias of CSR number N on hart B. So we make a
> > + * CSR number to value address map.
> > + */
> > +typedef struct  {
> > +    int csrno;
> > +    target_ulong val;
> > +    } riscv_custom_csr_vals;
> > +
>
> It looks this struct is not used by any patch in this series?
>
> >>  /* CSR function table constants */
> >>  enum {
> >> -    CSR_TABLE_SIZE = 0x1000
> >> +    CSR_TABLE_SIZE = 0x1000,
> >> +    MAX_CUSTOM_CSR_NUM = 100
>
> >To be consistent, name this to be: CUSTOM_CSR_TABLE_SIZE
>
> Sounds reasonable.
>
> >>  /* CSR function table */
> >> +extern int andes_custom_csr_size;
> >> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
>
> >The above 2 should not be in this patch.
> Could you elaborate a little bit more ?

These 2 should belong to patch 4 where Andes custom CSR is added.

>
> >>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
> >>
> >>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
> >>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
> >>
> >> +
>
> >This is unnecessary.
> Sorry for the newline.
>
> >> -#if !defined(CONFIG_USER_ONLY)
> >> +#pragma GCC diagnostic push
> >> +#pragma GCC diagnostic ignored "-Wunused-function"
>
> >Use __attribute__((__unused__)), so we don't need to use GCC push/pop
> Thanks for the tips.
> Will do.
>
> >> +/*
> >> + * XXX: This is just a write stub for developing custom CSR handler,
>
> >Remove XXX
> Will do.
>
> >> + * if the behavior of writting such CSR is not presentable in QEMU and doesn't
>
> >typo: writing.
>
> >Is that present, or presentable?
>
> It's not a writing typo. I mean "presentable" with its literal meaning.
> If we cannot demonstrate a hardware feature inside QEMU, we can just stub it.
>
>
> >> +#if defined(CONFIG_RISCV_CUSTOM)
> >> +/* Custom CSR related routines and data structures */
> >> +
> >> +static gpointer is_custom_csr(CPURISCVState *env, int csrno)
>
> >The function name suggests that the return value should be of bool
> >type. Suggest we do:
>
> >static bool is_custom_csr(CPURISCVState *env, int csrno,
> >riscv_custom_csr_operations *custom_csr_ops)
>
> Thanks for the advice, will modify it for V5.
>
>
> >> +
> >> +
>
> >Unnecessary changes
> Sorry for the newline.
>
> >>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
> >>                  target_ulong new_value, target_ulong write_mask)
> >>  {
> >>      int ret;
> >>      target_ulong old_value;
> >>      RISCVCPU *cpu = env_archcpu(env);
> >> +    #if !defined(CONFIG_RISCV_CUSTOM)
>
> >Please make sure #if starts from the beginning of this line, without space ahead
> Will do.
>
> >> +    riscv_csr_operations *csrop = &csr_ops[csrno];
>
> >nits: name this variable to csr_ops
>
> It will collide with original csr_ops.

Maybe csr_op ?

> I'll change to another name.
>
>
> >>
> >> +#if defined(CONFIG_RISCV_CUSTOM)
> >> +/* Include the custom CSR table here. */
>
> >nits: remove the ending .
> Will do.
> Sorry for all these style format issues.
> I must I cherry-picked a wrong before I ran checkpatch.pl.
>
> >> +/* This file is intentionally left blank at this commit. */
>
> >nits: remove the ending .
>
> >%s/at/in
>
> Will do.
>
> >Regards,
> >Bin
>
> Thanks for the quick reply and advice.
> I'll cook the v5 ASAP.

Note: one more place you need to modify in this patch, is the
riscv_gen_dynamic_csr_xml() in target/riscv/gdbstub.c

Regards,
Bin


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

* Re: [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
  2021-08-06  6:11       ` Ruinland Chuan-Tzu Tsa(蔡傳資)
@ 2021-08-06  9:50         ` Bin Meng
  -1 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  9:50 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsa(蔡傳資)
  Cc: Dylan Dai-Rong Jhong(鍾岱融),
	open list:RISC-V, wangjunqiang, Bin Meng,
	qemu-devel@nongnu.org Developers, Alistair Francis

On Fri, Aug 6, 2021 at 2:12 PM Ruinland Chuan-Tzu Tsa(蔡傳資)
<ruinland@andestech.com> wrote:
>
> Hi Bin and Alistair,
>
> >> Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without
>
> > The latest RISC-V core from Andes is AX45 and A45. Should we just
> > support the latest one?
>
> Maybe we can have them all ?
> AX25 and A25 is still in production, and we still have new clients using these CPU models.
>

Does AX25 and AX45 have any significant difference?

Regards,
Bin


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

* Re: [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
@ 2021-08-06  9:50         ` Bin Meng
  0 siblings, 0 replies; 34+ messages in thread
From: Bin Meng @ 2021-08-06  9:50 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsa(蔡傳資)
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers,
	open list:RISC-V, wangjunqiang, Bin Meng,
	Dylan Dai-Rong Jhong(鍾岱融)

On Fri, Aug 6, 2021 at 2:12 PM Ruinland Chuan-Tzu Tsa(蔡傳資)
<ruinland@andestech.com> wrote:
>
> Hi Bin and Alistair,
>
> >> Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without
>
> > The latest RISC-V core from Andes is AX45 and A45. Should we just
> > support the latest one?
>
> Maybe we can have them all ?
> AX25 and A25 is still in production, and we still have new clients using these CPU models.
>

Does AX25 and AX45 have any significant difference?

Regards,
Bin


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

* Re: [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
  2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
@ 2021-08-13  5:20     ` Alistair Francis
  -1 siblings, 0 replies; 34+ messages in thread
From: Alistair Francis @ 2021-08-13  5:20 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Dylan Jhong

On Fri, Aug 6, 2021 at 3:58 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinalnd ChuanTzu Tsai <ruinland@andestech.com>
>
> For now we add a custom CSR handling mechanism to handle non-standard CSR read
> or write.
>
> The write_stub() and read_zero() are provided for quick placeholder usage if
> such CSRs' behavior are expected to fail-over in its user code.
>
> Signed-off-by: Dylan Jhong <dylan@andestech.com>
> ---
>  target/riscv/cpu.c             | 23 ++++++++++
>  target/riscv/cpu.h             | 31 ++++++++++++-
>  target/riscv/cpu_bits.h        |  4 ++
>  target/riscv/csr.c             | 83 ++++++++++++++++++++++++++++------
>  target/riscv/custom_cpu_bits.h |  8 ++++
>  5 files changed, 134 insertions(+), 15 deletions(-)
>  create mode 100644 target/riscv/custom_cpu_bits.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7401325..3a638b5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -144,6 +144,29 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
>  #endif
>  }
>
> +#if defined(CONFIG_RISCV_CUSTOM)
> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[]
> +                             ) {

Can you run `checkpatch.pl` on each patch? That will catch issues like this.


> +
> +    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
> +                                                g_direct_equal, \
> +                                                NULL, NULL);
> +
> +
> +    int i;
> +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> +        if (csr_map_struct[i].csrno != 0) {
> +            g_hash_table_insert(env->custom_csr_map,
> +                GINT_TO_POINTER(csr_map_struct[i].csrno),
> +                &csr_map_struct[i].csr_opset);
> +        } else {
> +            break;
> +        }
> +    }
> +}
> +#endif
> +
>  static void riscv_any_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 0edb282..52df9bb 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -239,6 +239,16 @@ struct CPURISCVState {
>
>      /* Fields from here on are preserved across CPU reset. */
>      QEMUTimer *timer; /* Internal timer */
> +
> +    /*
> +     * The reason why we have an opset map for custom CSRs and a seperated
> +     * storage map is that we might have heterogeneous architecture, in which
> +     * different harts have different custom CSRs.
> +     * Custom CSR opset map
> +     */
> +    GHashTable *custom_csr_map;
> +    /* Custom CSR val holder */
> +    void *custom_csr_val;
>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -485,17 +495,36 @@ typedef struct {
>      riscv_csr_op_fn op;
>  } riscv_csr_operations;
>
> +typedef struct {
> +    int csrno;
> +    riscv_csr_operations csr_opset;
> +    } riscv_custom_csr_operations;
> +
> +/*
> + * The reason why we have an abstraction here is that : We could have CSR
> + * number M on hart A is an alias of CSR number N on hart B. So we make a
> + * CSR number to value address map.
> + */
> +typedef struct  {
> +    int csrno;
> +    target_ulong val;
> +    } riscv_custom_csr_vals;

This should be a seperate patch.

> +
>  /* CSR function table constants */
>  enum {
> -    CSR_TABLE_SIZE = 0x1000
> +    CSR_TABLE_SIZE = 0x1000,
> +    MAX_CUSTOM_CSR_NUM = 100
>  };
>
>  /* CSR function table */
> +extern int andes_custom_csr_size;
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];

This should be a seperate patch

>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>
>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> +
>  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>
>  #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf4599..de77242 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -593,3 +593,7 @@
>  #define MIE_SSIE                           (1 << IRQ_S_SOFT)
>  #define MIE_USIE                           (1 << IRQ_U_SOFT)
>  #endif
> +
> +#if defined(CONFIG_RISCV_CUSTOM)
> +#include "custom_cpu_bits.h"
> +#endif
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fd2e636..1c4dc94 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -137,7 +137,8 @@ static int ctr32(CPURISCVState *env, int csrno)
>      return ctr(env, csrno);
>  }
>
> -#if !defined(CONFIG_USER_ONLY)
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wunused-function"

Don't do this. It it is unused then just remove it.

>  static int any(CPURISCVState *env, int csrno)
>  {
>      return 0;
> @@ -152,6 +153,25 @@ static int any32(CPURISCVState *env, int csrno)
>      return any(env, csrno);
>
>  }
> +#pragma GCC diagnostic pop
> +
> +/* Machine Information Registers */
> +static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    return *val = 0;
> +}
> +
> +/*
> + * XXX: This is just a write stub for developing custom CSR handler,
> + * if the behavior of writting such CSR is not presentable in QEMU and doesn't
> + * affect the functionality, just stub it.
> + */
> +static int write_stub(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    return 0;
> +}
> +
> +#if !defined(CONFIG_USER_ONLY)
>
>  static int smode(CPURISCVState *env, int csrno)
>  {
> @@ -435,11 +455,6 @@ static const char valid_vm_1_10_64[16] = {
>      [VM_1_10_SV57] = 1
>  };
>
> -/* Machine Information Registers */
> -static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> -{
> -    return *val = 0;
> -}
>
>  static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> @@ -1264,6 +1279,18 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>
>  #endif
>
> +
> +#if defined(CONFIG_RISCV_CUSTOM)
> +/* Custom CSR related routines and data structures */
> +
> +static gpointer is_custom_csr(CPURISCVState *env, int csrno)
> +{
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;
> +}
> +#endif
> +
>  /*
>   * riscv_csrrw - read and/or update control and status register
>   *
> @@ -1273,12 +1300,19 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>   * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
>   */
>
> +
> +
>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>                  target_ulong new_value, target_ulong write_mask)
>  {
>      int ret;
>      target_ulong old_value;
>      RISCVCPU *cpu = env_archcpu(env);
> +    #if !defined(CONFIG_RISCV_CUSTOM)
> +    riscv_csr_operations *csrop = &csr_ops[csrno];
> +    #else
> +    riscv_csr_operations *csrop;

Why declare this at all?


> +    #endif
>
>      /* check privileges and return -1 if check fails */
>  #if !defined(CONFIG_USER_ONLY)
> @@ -1300,6 +1334,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> +
>  #endif
>
>      /* ensure the CSR extension is enabled. */
> @@ -1307,27 +1342,43 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
> +    /* try handle_custom_csr */
> +
> +    #if defined(CONFIG_RISCV_CUSTOM)
> +    if (unlikely(env->custom_csr_map != NULL)) {
> +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +            is_custom_csr(env, csrno);
> +        if (NULL != custom_csr_opset) {
> +            csrop = custom_csr_opset;
> +            } else {
> +            csrop = &csr_ops[csrno];
> +            }
> +        } else {
> +        csrop = &csr_ops[csrno];
> +        }

Cool! This looks like it's going in the right direction.

Alistair

> +    #endif
> +
>      /* check predicate */
> -    if (!csr_ops[csrno].predicate) {
> +    if (!csrop->predicate) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> -    ret = csr_ops[csrno].predicate(env, csrno);
> +    ret = csrop->predicate(env, csrno);
>      if (ret < 0) {
>          return ret;
>      }
>
>      /* execute combined read/write operation if it exists */
> -    if (csr_ops[csrno].op) {
> -        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> +    if (csrop->op) {
> +        return csrop->op(env, csrno, ret_value, new_value, write_mask);
>      }
>
>      /* if no accessor exists then return failure */
> -    if (!csr_ops[csrno].read) {
> +    if (!csrop->read) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
>      /* read old value */
> -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> +    ret = csrop->read(env, csrno, &old_value);
>      if (ret < 0) {
>          return ret;
>      }
> @@ -1335,8 +1386,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      /* write value if writable and write mask set, otherwise drop writes */
>      if (write_mask) {
>          new_value = (old_value & ~write_mask) | (new_value & write_mask);
> -        if (csr_ops[csrno].write) {
> -            ret = csr_ops[csrno].write(env, csrno, new_value);
> +        if (csrop->write) {
> +            ret = csrop->write(env, csrno, new_value);
>              if (ret < 0) {
>                  return ret;
>              }
> @@ -1369,6 +1420,10 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      return ret;
>  }
>
> +#if defined(CONFIG_RISCV_CUSTOM)
> +/* Include the custom CSR table here. */
> +#endif
> +
>  /* Control and Status Register function table */
>  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      /* User Floating-Point CSRs */
> diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
> new file mode 100644
> index 0000000..5df31f8
> --- /dev/null
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -0,0 +1,8 @@
> +/*
> + * RISC-V cpu bits for custom CSR logic.
> + *
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +/* This file is intentionally left blank at this commit. */
> --
> 2.32.0
>
>


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

* Re: [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism
@ 2021-08-13  5:20     ` Alistair Francis
  0 siblings, 0 replies; 34+ messages in thread
From: Alistair Francis @ 2021-08-13  5:20 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng, Dylan Jhong

On Fri, Aug 6, 2021 at 3:58 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinalnd ChuanTzu Tsai <ruinland@andestech.com>
>
> For now we add a custom CSR handling mechanism to handle non-standard CSR read
> or write.
>
> The write_stub() and read_zero() are provided for quick placeholder usage if
> such CSRs' behavior are expected to fail-over in its user code.
>
> Signed-off-by: Dylan Jhong <dylan@andestech.com>
> ---
>  target/riscv/cpu.c             | 23 ++++++++++
>  target/riscv/cpu.h             | 31 ++++++++++++-
>  target/riscv/cpu_bits.h        |  4 ++
>  target/riscv/csr.c             | 83 ++++++++++++++++++++++++++++------
>  target/riscv/custom_cpu_bits.h |  8 ++++
>  5 files changed, 134 insertions(+), 15 deletions(-)
>  create mode 100644 target/riscv/custom_cpu_bits.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7401325..3a638b5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -144,6 +144,29 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
>  #endif
>  }
>
> +#if defined(CONFIG_RISCV_CUSTOM)
> +static void setup_custom_csr(CPURISCVState *env,
> +                             riscv_custom_csr_operations csr_map_struct[]
> +                             ) {

Can you run `checkpatch.pl` on each patch? That will catch issues like this.


> +
> +    env->custom_csr_map = g_hash_table_new_full(g_direct_hash, \
> +                                                g_direct_equal, \
> +                                                NULL, NULL);
> +
> +
> +    int i;
> +    for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> +        if (csr_map_struct[i].csrno != 0) {
> +            g_hash_table_insert(env->custom_csr_map,
> +                GINT_TO_POINTER(csr_map_struct[i].csrno),
> +                &csr_map_struct[i].csr_opset);
> +        } else {
> +            break;
> +        }
> +    }
> +}
> +#endif
> +
>  static void riscv_any_cpu_init(Object *obj)
>  {
>      CPURISCVState *env = &RISCV_CPU(obj)->env;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 0edb282..52df9bb 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -239,6 +239,16 @@ struct CPURISCVState {
>
>      /* Fields from here on are preserved across CPU reset. */
>      QEMUTimer *timer; /* Internal timer */
> +
> +    /*
> +     * The reason why we have an opset map for custom CSRs and a seperated
> +     * storage map is that we might have heterogeneous architecture, in which
> +     * different harts have different custom CSRs.
> +     * Custom CSR opset map
> +     */
> +    GHashTable *custom_csr_map;
> +    /* Custom CSR val holder */
> +    void *custom_csr_val;
>  };
>
>  OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -485,17 +495,36 @@ typedef struct {
>      riscv_csr_op_fn op;
>  } riscv_csr_operations;
>
> +typedef struct {
> +    int csrno;
> +    riscv_csr_operations csr_opset;
> +    } riscv_custom_csr_operations;
> +
> +/*
> + * The reason why we have an abstraction here is that : We could have CSR
> + * number M on hart A is an alias of CSR number N on hart B. So we make a
> + * CSR number to value address map.
> + */
> +typedef struct  {
> +    int csrno;
> +    target_ulong val;
> +    } riscv_custom_csr_vals;

This should be a seperate patch.

> +
>  /* CSR function table constants */
>  enum {
> -    CSR_TABLE_SIZE = 0x1000
> +    CSR_TABLE_SIZE = 0x1000,
> +    MAX_CUSTOM_CSR_NUM = 100
>  };
>
>  /* CSR function table */
> +extern int andes_custom_csr_size;
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];

This should be a seperate patch

>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>
>  void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
>  void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> +
>  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>
>  #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf4599..de77242 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -593,3 +593,7 @@
>  #define MIE_SSIE                           (1 << IRQ_S_SOFT)
>  #define MIE_USIE                           (1 << IRQ_U_SOFT)
>  #endif
> +
> +#if defined(CONFIG_RISCV_CUSTOM)
> +#include "custom_cpu_bits.h"
> +#endif
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fd2e636..1c4dc94 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -137,7 +137,8 @@ static int ctr32(CPURISCVState *env, int csrno)
>      return ctr(env, csrno);
>  }
>
> -#if !defined(CONFIG_USER_ONLY)
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wunused-function"

Don't do this. It it is unused then just remove it.

>  static int any(CPURISCVState *env, int csrno)
>  {
>      return 0;
> @@ -152,6 +153,25 @@ static int any32(CPURISCVState *env, int csrno)
>      return any(env, csrno);
>
>  }
> +#pragma GCC diagnostic pop
> +
> +/* Machine Information Registers */
> +static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> +    return *val = 0;
> +}
> +
> +/*
> + * XXX: This is just a write stub for developing custom CSR handler,
> + * if the behavior of writting such CSR is not presentable in QEMU and doesn't
> + * affect the functionality, just stub it.
> + */
> +static int write_stub(CPURISCVState *env, int csrno, target_ulong val)
> +{
> +    return 0;
> +}
> +
> +#if !defined(CONFIG_USER_ONLY)
>
>  static int smode(CPURISCVState *env, int csrno)
>  {
> @@ -435,11 +455,6 @@ static const char valid_vm_1_10_64[16] = {
>      [VM_1_10_SV57] = 1
>  };
>
> -/* Machine Information Registers */
> -static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> -{
> -    return *val = 0;
> -}
>
>  static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val)
>  {
> @@ -1264,6 +1279,18 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>
>  #endif
>
> +
> +#if defined(CONFIG_RISCV_CUSTOM)
> +/* Custom CSR related routines and data structures */
> +
> +static gpointer is_custom_csr(CPURISCVState *env, int csrno)
> +{
> +    gpointer ret;
> +    ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> +    return ret;
> +}
> +#endif
> +
>  /*
>   * riscv_csrrw - read and/or update control and status register
>   *
> @@ -1273,12 +1300,19 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val)
>   * csrrc  <->  riscv_csrrw(env, csrno, ret_value, 0, value);
>   */
>
> +
> +
>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>                  target_ulong new_value, target_ulong write_mask)
>  {
>      int ret;
>      target_ulong old_value;
>      RISCVCPU *cpu = env_archcpu(env);
> +    #if !defined(CONFIG_RISCV_CUSTOM)
> +    riscv_csr_operations *csrop = &csr_ops[csrno];
> +    #else
> +    riscv_csr_operations *csrop;

Why declare this at all?


> +    #endif
>
>      /* check privileges and return -1 if check fails */
>  #if !defined(CONFIG_USER_ONLY)
> @@ -1300,6 +1334,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> +
>  #endif
>
>      /* ensure the CSR extension is enabled. */
> @@ -1307,27 +1342,43 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
> +    /* try handle_custom_csr */
> +
> +    #if defined(CONFIG_RISCV_CUSTOM)
> +    if (unlikely(env->custom_csr_map != NULL)) {
> +        riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> +            is_custom_csr(env, csrno);
> +        if (NULL != custom_csr_opset) {
> +            csrop = custom_csr_opset;
> +            } else {
> +            csrop = &csr_ops[csrno];
> +            }
> +        } else {
> +        csrop = &csr_ops[csrno];
> +        }

Cool! This looks like it's going in the right direction.

Alistair

> +    #endif
> +
>      /* check predicate */
> -    if (!csr_ops[csrno].predicate) {
> +    if (!csrop->predicate) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
> -    ret = csr_ops[csrno].predicate(env, csrno);
> +    ret = csrop->predicate(env, csrno);
>      if (ret < 0) {
>          return ret;
>      }
>
>      /* execute combined read/write operation if it exists */
> -    if (csr_ops[csrno].op) {
> -        return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> +    if (csrop->op) {
> +        return csrop->op(env, csrno, ret_value, new_value, write_mask);
>      }
>
>      /* if no accessor exists then return failure */
> -    if (!csr_ops[csrno].read) {
> +    if (!csrop->read) {
>          return -RISCV_EXCP_ILLEGAL_INST;
>      }
>
>      /* read old value */
> -    ret = csr_ops[csrno].read(env, csrno, &old_value);
> +    ret = csrop->read(env, csrno, &old_value);
>      if (ret < 0) {
>          return ret;
>      }
> @@ -1335,8 +1386,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      /* write value if writable and write mask set, otherwise drop writes */
>      if (write_mask) {
>          new_value = (old_value & ~write_mask) | (new_value & write_mask);
> -        if (csr_ops[csrno].write) {
> -            ret = csr_ops[csrno].write(env, csrno, new_value);
> +        if (csrop->write) {
> +            ret = csrop->write(env, csrno, new_value);
>              if (ret < 0) {
>                  return ret;
>              }
> @@ -1369,6 +1420,10 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value,
>      return ret;
>  }
>
> +#if defined(CONFIG_RISCV_CUSTOM)
> +/* Include the custom CSR table here. */
> +#endif
> +
>  /* Control and Status Register function table */
>  riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>      /* User Floating-Point CSRs */
> diff --git a/target/riscv/custom_cpu_bits.h b/target/riscv/custom_cpu_bits.h
> new file mode 100644
> index 0000000..5df31f8
> --- /dev/null
> +++ b/target/riscv/custom_cpu_bits.h
> @@ -0,0 +1,8 @@
> +/*
> + * RISC-V cpu bits for custom CSR logic.
> + *
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +/* This file is intentionally left blank at this commit. */
> --
> 2.32.0
>
>


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

* Re: [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
  2021-08-06  9:50         ` Bin Meng
@ 2021-08-13  5:23           ` Alistair Francis
  -1 siblings, 0 replies; 34+ messages in thread
From: Alistair Francis @ 2021-08-13  5:23 UTC (permalink / raw)
  To: Bin Meng
  Cc: Dylan Dai-Rong Jhong(鍾岱融),
	open list:RISC-V, wangjunqiang, Bin Meng,
	qemu-devel@nongnu.org Developers, Alistair Francis,
	Ruinland Chuan-Tzu Tsa(蔡傳資)

On Fri, Aug 6, 2021 at 7:51 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Fri, Aug 6, 2021 at 2:12 PM Ruinland Chuan-Tzu Tsa(蔡傳資)
> <ruinland@andestech.com> wrote:
> >
> > Hi Bin and Alistair,
> >
> > >> Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without
> >
> > > The latest RISC-V core from Andes is AX45 and A45. Should we just
> > > support the latest one?
> >
> > Maybe we can have them all ?
> > AX25 and A25 is still in production, and we still have new clients using these CPU models.
> >
>
> Does AX25 and AX45 have any significant difference?

My hope is that the way the custom CSRs are implemented means that the
Andes CPUs can be self contained. That way QEMU can support whatever
Andes upstreams and it shouldn't add a maintenance burden on anyone
else.

Starting with a AX25 is fine with me. Whatever Andes is willing to
upstream, maintain and test works for me.

Alistair

>
> Regards,
> Bin
>


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

* Re: [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model
@ 2021-08-13  5:23           ` Alistair Francis
  0 siblings, 0 replies; 34+ messages in thread
From: Alistair Francis @ 2021-08-13  5:23 UTC (permalink / raw)
  To: Bin Meng
  Cc: Ruinland Chuan-Tzu Tsa(蔡傳資),
	Dylan Dai-Rong Jhong(鍾岱融),
	open list:RISC-V, wangjunqiang, Bin Meng,
	qemu-devel@nongnu.org Developers, Alistair Francis

On Fri, Aug 6, 2021 at 7:51 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Fri, Aug 6, 2021 at 2:12 PM Ruinland Chuan-Tzu Tsa(蔡傳資)
> <ruinland@andestech.com> wrote:
> >
> > Hi Bin and Alistair,
> >
> > >> Adding Andes AX25 and A25 CPU model into cpu.h and cpu.c without
> >
> > > The latest RISC-V core from Andes is AX45 and A45. Should we just
> > > support the latest one?
> >
> > Maybe we can have them all ?
> > AX25 and A25 is still in production, and we still have new clients using these CPU models.
> >
>
> Does AX25 and AX45 have any significant difference?

My hope is that the way the custom CSRs are implemented means that the
Andes CPUs can be self contained. That way QEMU can support whatever
Andes upstreams and it shouldn't add a maintenance burden on anyone
else.

Starting with a AX25 is fine with me. Whatever Andes is willing to
upstream, maintain and test works for me.

Alistair

>
> Regards,
> Bin
>


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

* Re: [RFC PATCH v4 0/4] Add basic support for custom CSR
  2021-08-05 17:56 ` Ruinland Chuan-Tzu Tsai
@ 2021-08-13  5:33   ` Alistair Francis
  -1 siblings, 0 replies; 34+ messages in thread
From: Alistair Francis @ 2021-08-13  5:33 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: wangjunqiang, Bin Meng, open list:RISC-V,
	qemu-devel@nongnu.org Developers

On Fri, Aug 6, 2021 at 3:59 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinland ChuanTzu Tsai <ruinland@andestech.com>
>
> Dear all,
>
> In this patch, the implementation of custom CSR handling logic is introduced.
>
> If --enable-riscv-custom is set during configuration, custom CSR logic will be
> turned on. During CPU model initialization, setup_custom_csr() is invoked to
> register vendor-provided custom CSR opsets into a hash table.
> When accessing a CSR, in riscv_csrrw(), is_custom_csr() will be called to check
> whether the encountering csrno is a custom CSR. If that's a custom one, a
> struct riscv_csr_operations will be returned and such CSR will be served
> accordingly.

Thanks for adding this. I don't think we need to expose it via the
config logic. A Kconfig option would be enough, it can be enabled by
default and users can choose to disable it if they really want.

>
> 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
>
> For a custom CSR, uitb, being accessed on andes-ax25 :
> $ ./build/qemu-riscv64 -cpu andes-ax25 ./u
> 4.283091
>
> For a stock CSR, fcsr, being accessed on andes-ax25:
> $ ./build/qemu-riscv64 ./f
> 3.875519
>
> For a custom CSR being accessed on stock rv64:
> $ ./build/qemu-riscv64 -cpu rv64 ./u
> Illegal instruction (core dumped)
> # This is expected to fail.
>
> Currently, the statics on my hands shows that :
> When the custom CSR handling mechanism is activated, we will suffer a 17% slow-
> down on stock CSRs and the penalty of accessing to a custom CSR will be another
> 7% more.

Thanks for testing this.

The critical number here is what is the impact for a CPU that doesn't
have the custom CSRs. So for example what impact does this have on the
rv64 accessing a standard CSR? We don't want to affect performance of
other CPUs. CPUs with custom CSRs can take the performance hit as it
adds a useful feature for them.

Alistair

>
> Cordially yours,
> Ruinland ChuanTzu Tsai
>
> Changes from v3 :
> * Adding options in configure and meson files to turn on/off custom CSR logic.
> * Adding unlikely() to check if custom_csr_map is set.
> * Moving any32 and any out of !(CONFIG_USER_ONLY) for enabling linux-user mode.
> * Fix comment style, add missing license boilerplate.
>
>
> Ruinalnd ChuanTzu Tsai (4):
>   Adding basic custom/vendor CSR handling mechanism
>   Adding Andes AX25 and A25 CPU model
>   Enable custom CSR logic for Andes AX25 and A25
>   Add options to config/meson files for custom CSR
>
>  configure                      |   6 ++
>  meson.build                    |   2 +
>  meson_options.txt              |   2 +
>  target/riscv/andes_cpu_bits.h  | 124 +++++++++++++++++++++++++
>  target/riscv/cpu.c             |  51 +++++++++++
>  target/riscv/cpu.h             |  33 ++++++-
>  target/riscv/cpu_bits.h        |   4 +
>  target/riscv/csr.c             |  83 ++++++++++++++---
>  target/riscv/csr_andes.inc.c   | 160 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_cpu_bits.h |  12 +++
>  10 files changed, 462 insertions(+), 15 deletions(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.inc.c
>  create mode 100644 target/riscv/custom_cpu_bits.h
>
> --
> 2.32.0
>
>


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

* Re: [RFC PATCH v4 0/4] Add basic support for custom CSR
@ 2021-08-13  5:33   ` Alistair Francis
  0 siblings, 0 replies; 34+ messages in thread
From: Alistair Francis @ 2021-08-13  5:33 UTC (permalink / raw)
  To: Ruinland Chuan-Tzu Tsai
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, wangjunqiang,
	Bin Meng

On Fri, Aug 6, 2021 at 3:59 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> From: Ruinland ChuanTzu Tsai <ruinland@andestech.com>
>
> Dear all,
>
> In this patch, the implementation of custom CSR handling logic is introduced.
>
> If --enable-riscv-custom is set during configuration, custom CSR logic will be
> turned on. During CPU model initialization, setup_custom_csr() is invoked to
> register vendor-provided custom CSR opsets into a hash table.
> When accessing a CSR, in riscv_csrrw(), is_custom_csr() will be called to check
> whether the encountering csrno is a custom CSR. If that's a custom one, a
> struct riscv_csr_operations will be returned and such CSR will be served
> accordingly.

Thanks for adding this. I don't think we need to expose it via the
config logic. A Kconfig option would be enough, it can be enabled by
default and users can choose to disable it if they really want.

>
> 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
>
> For a custom CSR, uitb, being accessed on andes-ax25 :
> $ ./build/qemu-riscv64 -cpu andes-ax25 ./u
> 4.283091
>
> For a stock CSR, fcsr, being accessed on andes-ax25:
> $ ./build/qemu-riscv64 ./f
> 3.875519
>
> For a custom CSR being accessed on stock rv64:
> $ ./build/qemu-riscv64 -cpu rv64 ./u
> Illegal instruction (core dumped)
> # This is expected to fail.
>
> Currently, the statics on my hands shows that :
> When the custom CSR handling mechanism is activated, we will suffer a 17% slow-
> down on stock CSRs and the penalty of accessing to a custom CSR will be another
> 7% more.

Thanks for testing this.

The critical number here is what is the impact for a CPU that doesn't
have the custom CSRs. So for example what impact does this have on the
rv64 accessing a standard CSR? We don't want to affect performance of
other CPUs. CPUs with custom CSRs can take the performance hit as it
adds a useful feature for them.

Alistair

>
> Cordially yours,
> Ruinland ChuanTzu Tsai
>
> Changes from v3 :
> * Adding options in configure and meson files to turn on/off custom CSR logic.
> * Adding unlikely() to check if custom_csr_map is set.
> * Moving any32 and any out of !(CONFIG_USER_ONLY) for enabling linux-user mode.
> * Fix comment style, add missing license boilerplate.
>
>
> Ruinalnd ChuanTzu Tsai (4):
>   Adding basic custom/vendor CSR handling mechanism
>   Adding Andes AX25 and A25 CPU model
>   Enable custom CSR logic for Andes AX25 and A25
>   Add options to config/meson files for custom CSR
>
>  configure                      |   6 ++
>  meson.build                    |   2 +
>  meson_options.txt              |   2 +
>  target/riscv/andes_cpu_bits.h  | 124 +++++++++++++++++++++++++
>  target/riscv/cpu.c             |  51 +++++++++++
>  target/riscv/cpu.h             |  33 ++++++-
>  target/riscv/cpu_bits.h        |   4 +
>  target/riscv/csr.c             |  83 ++++++++++++++---
>  target/riscv/csr_andes.inc.c   | 160 +++++++++++++++++++++++++++++++++
>  target/riscv/custom_cpu_bits.h |  12 +++
>  10 files changed, 462 insertions(+), 15 deletions(-)
>  create mode 100644 target/riscv/andes_cpu_bits.h
>  create mode 100644 target/riscv/csr_andes.inc.c
>  create mode 100644 target/riscv/custom_cpu_bits.h
>
> --
> 2.32.0
>
>


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

end of thread, other threads:[~2021-08-13  5:35 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-05 17:56 [RFC PATCH v4 0/4] Add basic support for custom CSR Ruinland Chuan-Tzu Tsai
2021-08-05 17:56 ` Ruinland Chuan-Tzu Tsai
2021-08-05 17:56 ` [RFC PATCH v4 1/4] Add options to config/meson files " Ruinland Chuan-Tzu Tsai
2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
2021-08-06  2:39   ` Bin Meng
2021-08-06  2:39     ` Bin Meng
2021-08-06  2:41     ` Bin Meng
2021-08-06  2:41       ` Bin Meng
2021-08-05 17:56 ` [RFC PATCH v4 2/4] Adding basic custom/vendor CSR handling mechanism Ruinland Chuan-Tzu Tsai
2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
2021-08-06  3:35   ` Bin Meng
2021-08-06  3:35     ` Bin Meng
2021-08-06  6:07     ` Ruinland Chuan-Tzu Tsa(蔡傳資)
2021-08-06  6:07       ` Ruinland Chuan-Tzu Tsa(蔡傳資)
2021-08-06  6:19       ` Bin Meng
2021-08-06  6:19         ` Bin Meng
2021-08-13  5:20   ` Alistair Francis
2021-08-13  5:20     ` Alistair Francis
2021-08-05 17:56 ` [RFC PATCH v4 3/4] Adding Andes AX25 and A25 CPU model Ruinland Chuan-Tzu Tsai
2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
2021-08-06  3:40   ` Bin Meng
2021-08-06  3:40     ` Bin Meng
2021-08-06  6:11     ` Ruinland Chuan-Tzu Tsa(蔡傳資)
2021-08-06  6:11       ` Ruinland Chuan-Tzu Tsa(蔡傳資)
2021-08-06  9:50       ` Bin Meng
2021-08-06  9:50         ` Bin Meng
2021-08-13  5:23         ` Alistair Francis
2021-08-13  5:23           ` Alistair Francis
2021-08-05 17:56 ` [RFC PATCH v4 4/4] Enable custom CSR logic for Andes AX25 and A25 Ruinland Chuan-Tzu Tsai
2021-08-05 17:56   ` Ruinland Chuan-Tzu Tsai
2021-08-06  6:14   ` Bin Meng
2021-08-06  6:14     ` Bin Meng
2021-08-13  5:33 ` [RFC PATCH v4 0/4] Add basic support for custom CSR Alistair Francis
2021-08-13  5:33   ` 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.