* [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
To: alistair23, wangjunqiang, bmeng.cn
Cc: ycliang, alankao, dylan, qemu-devel, Ruinland Chuan-Tzu Tsai, qemu-riscv
Hi Alistair, Bin and all :
Sorry for bumping this stale topic.
As our last discussion, I have removed Kconfigs and meson options.
The custom CSR logic is in-built by default and whether a custom CSR
is presented on the accessing hart will be checked at runtime.
Changes from V4 :
Remove Kconfigs and meson options.
Make custom CSR handling logic self-contained.
Use g_hash_table_new instead of g_hash_table_new_full.
The performance slowdown could be easily tested with a simple program
running on linux-user mode :
/* test_csr.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
int main (int ac, char *av[]) {
struct timeval start;
struct timeval end;
gettimeofday(&start,NULL);
unsigned int loop_n = 999999 ;
unsigned char i;
unsigned char o;
do {
for(i=0; i<32; i++) {
#if defined(FCSR)
__asm__("csrw fcsr, %0;"::"r"(i));
__asm__("csrr %0, fcsr;":"=r"(o));
#elif defined(UITB)
__asm__("csrw 0x800, %0;"::"r"(i));
__asm__("csrr %0, 0x800;":"=r"(o));
#endif
}
--loop_n;
} while (loop_n > 0);
gettimeofday(&end,NULL);
unsigned long diff = 1000000 *
(end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec;
printf("%f\n", (double)(diff)/1000000);
return 0;
}
$ riscv64-linux-gnu-gcc -static -DUITB ./test_csr.c -o ./u
$ riscv64-linux-gnu-gcc -static -DFCSR ./test_csr.c -o ./f
$ qemu-riscv64 ./{u,f}
Cordially yours,
Ruinland Chuan-Tzu Tsai
Ruinland Chuan-Tzu Tsai (3):
riscv: Adding Andes A25 and AX25 cpu models
riscv: Introduce custom CSR hooks to riscv_csrrw()
riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
target/riscv/cpu.c | 39 +++++++
target/riscv/cpu.h | 15 ++-
target/riscv/csr.c | 38 +++++--
target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
target/riscv/custom_csr_defs.h | 8 ++
target/riscv/meson.build | 1 +
7 files changed, 404 insertions(+), 9 deletions(-)
create mode 100644 target/riscv/andes_cpu_bits.h
create mode 100644 target/riscv/csr_andes.c
create mode 100644 target/riscv/custom_csr_defs.h
--
2.25.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
To: alistair23, wangjunqiang, bmeng.cn
Cc: qemu-devel, qemu-riscv, ycliang, alankao, dylan, Ruinland Chuan-Tzu Tsai
Hi Alistair, Bin and all :
Sorry for bumping this stale topic.
As our last discussion, I have removed Kconfigs and meson options.
The custom CSR logic is in-built by default and whether a custom CSR
is presented on the accessing hart will be checked at runtime.
Changes from V4 :
Remove Kconfigs and meson options.
Make custom CSR handling logic self-contained.
Use g_hash_table_new instead of g_hash_table_new_full.
The performance slowdown could be easily tested with a simple program
running on linux-user mode :
/* test_csr.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
int main (int ac, char *av[]) {
struct timeval start;
struct timeval end;
gettimeofday(&start,NULL);
unsigned int loop_n = 999999 ;
unsigned char i;
unsigned char o;
do {
for(i=0; i<32; i++) {
#if defined(FCSR)
__asm__("csrw fcsr, %0;"::"r"(i));
__asm__("csrr %0, fcsr;":"=r"(o));
#elif defined(UITB)
__asm__("csrw 0x800, %0;"::"r"(i));
__asm__("csrr %0, 0x800;":"=r"(o));
#endif
}
--loop_n;
} while (loop_n > 0);
gettimeofday(&end,NULL);
unsigned long diff = 1000000 *
(end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec;
printf("%f\n", (double)(diff)/1000000);
return 0;
}
$ riscv64-linux-gnu-gcc -static -DUITB ./test_csr.c -o ./u
$ riscv64-linux-gnu-gcc -static -DFCSR ./test_csr.c -o ./f
$ qemu-riscv64 ./{u,f}
Cordially yours,
Ruinland Chuan-Tzu Tsai
Ruinland Chuan-Tzu Tsai (3):
riscv: Adding Andes A25 and AX25 cpu models
riscv: Introduce custom CSR hooks to riscv_csrrw()
riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
target/riscv/cpu.c | 39 +++++++
target/riscv/cpu.h | 15 ++-
target/riscv/csr.c | 38 +++++--
target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
target/riscv/custom_csr_defs.h | 8 ++
target/riscv/meson.build | 1 +
7 files changed, 404 insertions(+), 9 deletions(-)
create mode 100644 target/riscv/andes_cpu_bits.h
create mode 100644 target/riscv/csr_andes.c
create mode 100644 target/riscv/custom_csr_defs.h
--
2.25.1
^ permalink raw reply [flat|nested] 28+ messages in thread
* [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
-1 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
To: alistair23, wangjunqiang, bmeng.cn
Cc: ycliang, alankao, dylan, qemu-devel, Ruinland Chuan-Tzu Tsai, qemu-riscv
Introduce A25 and AX25 CPU model designed by Andes Technology.
Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
target/riscv/cpu.c | 16 ++++++++++++++++
target/riscv/cpu.h | 2 ++
2 files changed, 18 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7c626d89cd..0c93b7edd7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -168,6 +168,13 @@ static void rv64_base_cpu_init(Object *obj)
set_misa(env, RV64);
}
+static void ax25_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
+}
+
static void rv64_sifive_u_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -222,6 +229,13 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
set_resetvec(env, DEFAULT_RSTVEC);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
}
+
+static void a25_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
+}
#endif
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
@@ -789,8 +803,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_A25, a25_cpu_init),
#elif defined(TARGET_RISCV64)
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_AX25, ax25_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5896aca346..3bef0d1265 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -37,6 +37,8 @@
#define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any")
#define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
+#define TYPE_RISCV_CPU_A25 RISCV_CPU_TYPE_NAME("andes-a25")
+#define TYPE_RISCV_CPU_AX25 RISCV_CPU_TYPE_NAME("andes-ax25")
#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
#define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
#define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
--
2.25.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
To: alistair23, wangjunqiang, bmeng.cn
Cc: qemu-devel, qemu-riscv, ycliang, alankao, dylan, Ruinland Chuan-Tzu Tsai
Introduce A25 and AX25 CPU model designed by Andes Technology.
Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
target/riscv/cpu.c | 16 ++++++++++++++++
target/riscv/cpu.h | 2 ++
2 files changed, 18 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7c626d89cd..0c93b7edd7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -168,6 +168,13 @@ static void rv64_base_cpu_init(Object *obj)
set_misa(env, RV64);
}
+static void ax25_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
+}
+
static void rv64_sifive_u_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -222,6 +229,13 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
set_resetvec(env, DEFAULT_RSTVEC);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
}
+
+static void a25_cpu_init(Object *obj)
+{
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
+ set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
+}
#endif
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
@@ -789,8 +803,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_A25, a25_cpu_init),
#elif defined(TARGET_RISCV64)
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_AX25, ax25_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5896aca346..3bef0d1265 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -37,6 +37,8 @@
#define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any")
#define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
+#define TYPE_RISCV_CPU_A25 RISCV_CPU_TYPE_NAME("andes-a25")
+#define TYPE_RISCV_CPU_AX25 RISCV_CPU_TYPE_NAME("andes-ax25")
#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
#define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
#define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
--
2.25.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
-1 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
To: alistair23, wangjunqiang, bmeng.cn
Cc: ycliang, alankao, dylan, qemu-devel, Ruinland Chuan-Tzu Tsai, qemu-riscv
riscv_csrrw() will be called by CSR handling helpers, which is the
most suitable place for checking wheter a custom CSR is being accessed.
If we're touching a custom CSR, invoke the registered handlers.
Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
target/riscv/cpu.c | 19 +++++++++++++++++
target/riscv/cpu.h | 13 +++++++++++-
target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
target/riscv/custom_csr_defs.h | 7 +++++++
4 files changed, 68 insertions(+), 9 deletions(-)
create mode 100644 target/riscv/custom_csr_defs.h
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0c93b7edd7..a72fd32f01 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -34,6 +34,9 @@
static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
+GHashTable *custom_csr_map = NULL;
+#include "custom_csr_defs.h"
+
const char * const riscv_int_regnames[] = {
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
@@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
#endif
}
+static void setup_custom_csr(CPURISCVState *env,
+ riscv_custom_csr_operations csr_map_struct[])
+{
+ int i;
+ env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
+ for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
+ if (csr_map_struct[i].csrno != 0) {
+ g_hash_table_insert(env->custom_csr_map,
+ GINT_TO_POINTER(csr_map_struct[i].csrno),
+ &csr_map_struct[i].csr_opset);
+ } else {
+ break;
+ }
+ }
+}
+
static void riscv_any_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3bef0d1265..012be10d0a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -245,6 +245,11 @@ struct CPURISCVState {
/* Fields from here on are preserved across CPU reset. */
QEMUTimer *timer; /* Internal timer */
+
+ /* Custom CSR opset table per hart */
+ GHashTable *custom_csr_map;
+ /* Custom CSR value holder per hart */
+ void *custom_csr_val;
};
OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
@@ -496,9 +501,15 @@ typedef struct {
riscv_csr_op_fn op;
} riscv_csr_operations;
+typedef struct {
+ int csrno;
+ riscv_csr_operations csr_opset;
+} riscv_custom_csr_operations;
+
/* CSR function table constants */
enum {
- CSR_TABLE_SIZE = 0x1000
+ CSR_TABLE_SIZE = 0x1000,
+ MAX_CUSTOM_CSR_NUM = 100
};
/* CSR function table */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 23fbbd3216..1048ee3b44 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
#endif
+/* Custom CSR related routines */
+static gpointer find_custom_csr(CPURISCVState *env, int csrno)
+{
+ gpointer ret;
+ ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
+ return ret;
+}
+
/*
* riscv_csrrw - read and/or update control and status register
*
@@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
RISCVException ret;
target_ulong old_value;
RISCVCPU *cpu = env_archcpu(env);
+ riscv_csr_operations *csr_op;
int read_only = get_field(csrno, 0xC00) == 3;
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
@@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
return RISCV_EXCP_ILLEGAL_INST;
}
+ /* try to handle_custom_csr */
+ if (unlikely(env->custom_csr_map != NULL)) {
+ riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
+ find_custom_csr(env, csrno);
+ if (custom_csr_opset != NULL) {
+ csr_op = custom_csr_opset;
+ } else {
+ csr_op = &csr_ops[csrno];
+ }
+ } else {
+ csr_op = &csr_ops[csrno];
+ }
+
/* check predicate */
- if (!csr_ops[csrno].predicate) {
+ if (!csr_op->predicate) {
return RISCV_EXCP_ILLEGAL_INST;
}
- ret = csr_ops[csrno].predicate(env, csrno);
+ ret = csr_op->predicate(env, csrno);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
/* execute combined read/write operation if it exists */
- if (csr_ops[csrno].op) {
- return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
+ if (csr_op->op) {
+ return csr_op->op(env, csrno, ret_value, new_value, write_mask);
}
/* if no accessor exists then return failure */
- if (!csr_ops[csrno].read) {
+ if (!csr_op->read) {
return RISCV_EXCP_ILLEGAL_INST;
}
/* read old value */
- ret = csr_ops[csrno].read(env, csrno, &old_value);
+ ret = csr_op->read(env, csrno, &old_value);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
@@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
/* write value if writable and write mask set, otherwise drop writes */
if (write_mask) {
new_value = (old_value & ~write_mask) | (new_value & write_mask);
- if (csr_ops[csrno].write) {
- ret = csr_ops[csrno].write(env, csrno, new_value);
+ if (csr_op->write) {
+ ret = csr_op->write(env, csrno, new_value);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
new file mode 100644
index 0000000000..4dbf8cf1fd
--- /dev/null
+++ b/target/riscv/custom_csr_defs.h
@@ -0,0 +1,7 @@
+/*
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ * Custom CSR variables provided by <cpu_model_name>_csr.c
+ */
+
+/* Left blank purposely in this commit. */
--
2.25.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
To: alistair23, wangjunqiang, bmeng.cn
Cc: qemu-devel, qemu-riscv, ycliang, alankao, dylan, Ruinland Chuan-Tzu Tsai
riscv_csrrw() will be called by CSR handling helpers, which is the
most suitable place for checking wheter a custom CSR is being accessed.
If we're touching a custom CSR, invoke the registered handlers.
Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
target/riscv/cpu.c | 19 +++++++++++++++++
target/riscv/cpu.h | 13 +++++++++++-
target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
target/riscv/custom_csr_defs.h | 7 +++++++
4 files changed, 68 insertions(+), 9 deletions(-)
create mode 100644 target/riscv/custom_csr_defs.h
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0c93b7edd7..a72fd32f01 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -34,6 +34,9 @@
static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
+GHashTable *custom_csr_map = NULL;
+#include "custom_csr_defs.h"
+
const char * const riscv_int_regnames[] = {
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
@@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
#endif
}
+static void setup_custom_csr(CPURISCVState *env,
+ riscv_custom_csr_operations csr_map_struct[])
+{
+ int i;
+ env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
+ for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
+ if (csr_map_struct[i].csrno != 0) {
+ g_hash_table_insert(env->custom_csr_map,
+ GINT_TO_POINTER(csr_map_struct[i].csrno),
+ &csr_map_struct[i].csr_opset);
+ } else {
+ break;
+ }
+ }
+}
+
static void riscv_any_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3bef0d1265..012be10d0a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -245,6 +245,11 @@ struct CPURISCVState {
/* Fields from here on are preserved across CPU reset. */
QEMUTimer *timer; /* Internal timer */
+
+ /* Custom CSR opset table per hart */
+ GHashTable *custom_csr_map;
+ /* Custom CSR value holder per hart */
+ void *custom_csr_val;
};
OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
@@ -496,9 +501,15 @@ typedef struct {
riscv_csr_op_fn op;
} riscv_csr_operations;
+typedef struct {
+ int csrno;
+ riscv_csr_operations csr_opset;
+} riscv_custom_csr_operations;
+
/* CSR function table constants */
enum {
- CSR_TABLE_SIZE = 0x1000
+ CSR_TABLE_SIZE = 0x1000,
+ MAX_CUSTOM_CSR_NUM = 100
};
/* CSR function table */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 23fbbd3216..1048ee3b44 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
#endif
+/* Custom CSR related routines */
+static gpointer find_custom_csr(CPURISCVState *env, int csrno)
+{
+ gpointer ret;
+ ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
+ return ret;
+}
+
/*
* riscv_csrrw - read and/or update control and status register
*
@@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
RISCVException ret;
target_ulong old_value;
RISCVCPU *cpu = env_archcpu(env);
+ riscv_csr_operations *csr_op;
int read_only = get_field(csrno, 0xC00) == 3;
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
@@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
return RISCV_EXCP_ILLEGAL_INST;
}
+ /* try to handle_custom_csr */
+ if (unlikely(env->custom_csr_map != NULL)) {
+ riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
+ find_custom_csr(env, csrno);
+ if (custom_csr_opset != NULL) {
+ csr_op = custom_csr_opset;
+ } else {
+ csr_op = &csr_ops[csrno];
+ }
+ } else {
+ csr_op = &csr_ops[csrno];
+ }
+
/* check predicate */
- if (!csr_ops[csrno].predicate) {
+ if (!csr_op->predicate) {
return RISCV_EXCP_ILLEGAL_INST;
}
- ret = csr_ops[csrno].predicate(env, csrno);
+ ret = csr_op->predicate(env, csrno);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
/* execute combined read/write operation if it exists */
- if (csr_ops[csrno].op) {
- return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
+ if (csr_op->op) {
+ return csr_op->op(env, csrno, ret_value, new_value, write_mask);
}
/* if no accessor exists then return failure */
- if (!csr_ops[csrno].read) {
+ if (!csr_op->read) {
return RISCV_EXCP_ILLEGAL_INST;
}
/* read old value */
- ret = csr_ops[csrno].read(env, csrno, &old_value);
+ ret = csr_op->read(env, csrno, &old_value);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
@@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
/* write value if writable and write mask set, otherwise drop writes */
if (write_mask) {
new_value = (old_value & ~write_mask) | (new_value & write_mask);
- if (csr_ops[csrno].write) {
- ret = csr_ops[csrno].write(env, csrno, new_value);
+ if (csr_op->write) {
+ ret = csr_op->write(env, csrno, new_value);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
new file mode 100644
index 0000000000..4dbf8cf1fd
--- /dev/null
+++ b/target/riscv/custom_csr_defs.h
@@ -0,0 +1,7 @@
+/*
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ * Custom CSR variables provided by <cpu_model_name>_csr.c
+ */
+
+/* Left blank purposely in this commit. */
--
2.25.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
-1 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
To: alistair23, wangjunqiang, bmeng.cn
Cc: ycliang, alankao, dylan, qemu-devel, Ruinland Chuan-Tzu Tsai, qemu-riscv
Add CSR bits definitions, CSR table and handler functions for Andes
AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
target/riscv/cpu.c | 4 +
target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
target/riscv/custom_csr_defs.h | 3 +-
target/riscv/meson.build | 1 +
5 files changed, 319 insertions(+), 1 deletion(-)
create mode 100644 target/riscv/andes_cpu_bits.h
create mode 100644 target/riscv/csr_andes.c
diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
new file mode 100644
index 0000000000..84b0900423
--- /dev/null
+++ b/target/riscv/andes_cpu_bits.h
@@ -0,0 +1,129 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Andes custom CSRs bit definitions
+ *
+ */
+
+/*
+ * ========= Missing drafted/standard CSR definitions =========
+ * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
+ */
+#define CSR_TINFO 0x7a4
+
+#if !defined(CONFIG_USER_ONLY)
+/* ========= AndeStar V5 machine mode CSRs ========= */
+/* Configuration Registers */
+#define CSR_MICM_CFG 0xfc0
+#define CSR_MDCM_CFG 0xfc1
+#define CSR_MMSC_CFG 0xfc2
+#define CSR_MMSC_CFG2 0xfc3
+#define CSR_MVEC_CFG 0xfc7
+
+/* Crash Debug CSRs */
+#define CSR_MCRASH_STATESAVE 0xfc8
+#define CSR_MSTATUS_CRASHSAVE 0xfc9
+
+/* Memory CSRs */
+#define CSR_MILMB 0x7c0
+#define CSR_MDLMB 0x7c1
+#define CSR_MECC_CODE 0x7C2
+#define CSR_MNVEC 0x7c3
+#define CSR_MCACHE_CTL 0x7ca
+#define CSR_MCCTLBEGINADDR 0x7cb
+#define CSR_MCCTLCOMMAND 0x7cc
+#define CSR_MCCTLDATA 0x7cd
+#define CSR_MPPIB 0x7f0
+#define CSR_MFIOB 0x7f1
+
+/* Hardware Stack Protection & Recording */
+#define CSR_MHSP_CTL 0x7c6
+#define CSR_MSP_BOUND 0x7c7
+#define CSR_MSP_BASE 0x7c8
+#define CSR_MXSTATUS 0x7c4
+#define CSR_MDCAUSE 0x7c9
+#define CSR_MSLIDELEG 0x7d5
+#define CSR_MSAVESTATUS 0x7d6
+#define CSR_MSAVEEPC1 0x7d7
+#define CSR_MSAVECAUSE1 0x7d8
+#define CSR_MSAVEEPC2 0x7d9
+#define CSR_MSAVECAUSE2 0x7da
+#define CSR_MSAVEDCAUSE1 0x7db
+#define CSR_MSAVEDCAUSE2 0x7dc
+
+/* Control CSRs */
+#define CSR_MPFT_CTL 0x7c5
+#define CSR_MMISC_CTL 0x7d0
+#define CSR_MCLK_CTL 0x7df
+
+/* Counter related CSRs */
+#define CSR_MCOUNTERWEN 0x7ce
+#define CSR_MCOUNTERINTEN 0x7cf
+#define CSR_MCOUNTERMASK_M 0x7d1
+#define CSR_MCOUNTERMASK_S 0x7d2
+#define CSR_MCOUNTERMASK_U 0x7d3
+#define CSR_MCOUNTEROVF 0x7d4
+
+/* Enhanced CLIC CSRs */
+#define CSR_MIRQ_ENTRY 0x7ec
+#define CSR_MINTSEL_JAL 0x7ed
+#define CSR_PUSHMCAUSE 0x7ee
+#define CSR_PUSHMEPC 0x7ef
+#define CSR_PUSHMXSTATUS 0x7eb
+
+/* Andes Physical Memory Attribute(PMA) CSRs */
+#define CSR_PMACFG0 0xbc0
+#define CSR_PMACFG1 0xbc1
+#define CSR_PMACFG2 0xbc2
+#define CSR_PMACFG3 0xbc3
+#define CSR_PMAADDR0 0xbd0
+#define CSR_PMAADDR1 0xbd1
+#define CSR_PMAADDR2 0xbd2
+#define CSR_PMAADDR3 0xbd2
+#define CSR_PMAADDR4 0xbd4
+#define CSR_PMAADDR5 0xbd5
+#define CSR_PMAADDR6 0xbd6
+#define CSR_PMAADDR7 0xbd7
+#define CSR_PMAADDR8 0xbd8
+#define CSR_PMAADDR9 0xbd9
+#define CSR_PMAADDR10 0xbda
+#define CSR_PMAADDR11 0xbdb
+#define CSR_PMAADDR12 0xbdc
+#define CSR_PMAADDR13 0xbdd
+#define CSR_PMAADDR14 0xbde
+#define CSR_PMAADDR15 0xbdf
+
+/* ========= AndeStar V5 supervisor mode CSRs ========= */
+/* Supervisor trap registers */
+#define CSR_SLIE 0x9c4
+#define CSR_SLIP 0x9c5
+#define CSR_SDCAUSE 0x9c9
+
+/* Supervisor counter registers */
+#define CSR_SCOUNTERINTEN 0x9cf
+#define CSR_SCOUNTERMASK_M 0x9d1
+#define CSR_SCOUNTERMASK_S 0x9d2
+#define CSR_SCOUNTERMASK_U 0x9d3
+#define CSR_SCOUNTEROVF 0x9d4
+#define CSR_SCOUNTINHIBIT 0x9e0
+#define CSR_SHPMEVENT3 0x9e3
+#define CSR_SHPMEVENT4 0x9e4
+#define CSR_SHPMEVENT5 0x9e5
+#define CSR_SHPMEVENT6 0x9e6
+
+/* Supervisor control registers */
+#define CSR_SCCTLDATA 0x9cd
+#define CSR_SMISC_CTL 0x9d0
+
+#endif /* !defined(CONFIG_USER_ONLY) */
+
+/* ========= AndeStar V5 user mode CSRs ========= */
+/* User mode control registers */
+#define CSR_UITB 0x800
+#define CSR_UCODE 0x801
+#define CSR_UDCAUSE 0x809
+#define CSR_UCCTLBEGINADDR 0x80b
+#define CSR_UCCTLCOMMAND 0x80c
+#define CSR_WFE 0x810
+#define CSR_SLEEPVALUE 0x811
+#define CSR_TXEVT 0x812
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a72fd32f01..fe63e68b8e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -192,6 +192,8 @@ static void ax25_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
+ setup_custom_csr(env, andes_custom_csr_table);
+ env->custom_csr_val = g_malloc(andes_custom_csr_size);
}
static void rv64_sifive_u_cpu_init(Object *obj)
@@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
+ setup_custom_csr(env, andes_custom_csr_table);
+ env->custom_csr_val = g_malloc(andes_custom_csr_size);
}
#endif
diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
new file mode 100644
index 0000000000..8617f40483
--- /dev/null
+++ b/target/riscv/csr_andes.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ * Andes custom CSR table and handling functions
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "qemu/main-loop.h"
+#include "exec/exec-all.h"
+#include "andes_cpu_bits.h"
+
+struct andes_csr_val {
+ target_long uitb;
+};
+
+#if !defined(CONFIG_USER_ONLY)
+static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ /* enable pma probe */
+ *val = 0x40000000;
+ return RISCV_EXCP_NONE;
+}
+#endif
+
+static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
+{
+ struct andes_csr_val *andes_csr = env->custom_csr_val;
+ andes_csr->uitb = val;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ struct andes_csr_val *andes_csr = env->custom_csr_val;
+ *val = andes_csr->uitb;
+ return RISCV_EXCP_NONE;
+}
+
+
+static RISCVException any(CPURISCVState *env, int csrno)
+{
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = 0;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
+{
+ return RISCV_EXCP_NONE;
+}
+
+int andes_custom_csr_size = sizeof(struct andes_csr_val);
+riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
+ /* ========= AndeStar V5 machine mode CSRs ========= */
+ #if !defined(CONFIG_USER_ONLY)
+ /* Configuration Registers */
+ {CSR_MICM_CFG, { "micm_cfg", any, read_zero, write_stub} },
+ {CSR_MDCM_CFG, { "mdcm_cfg", any, read_zero, write_stub} },
+ {CSR_MMSC_CFG, { "mmsc_cfg", any, read_mmsc_cfg, write_stub} },
+ {CSR_MMSC_CFG2, { "mmsc_cfg2", any, read_zero, write_stub} },
+ {CSR_MVEC_CFG, { "mvec_cfg", any, read_zero, write_stub} },
+
+ /* Crash Debug CSRs */
+ {CSR_MCRASH_STATESAVE, { "mcrash_statesave", any, read_zero, write_stub} },
+ {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
+
+ /* Memory CSRs */
+ {CSR_MILMB, { "milmb", any, read_zero, write_stub} },
+ {CSR_MDLMB, { "mdlmb", any, read_zero, write_stub} },
+ {CSR_MECC_CODE, { "mecc_code", any, read_zero, write_stub} },
+ {CSR_MNVEC, { "mnvec", any, read_zero, write_stub} },
+ {CSR_MCACHE_CTL, { "mcache_ctl", any, read_zero, write_stub} },
+ {CSR_MCCTLBEGINADDR, { "mcctlbeginaddr", any, read_zero, write_stub} },
+ {CSR_MCCTLCOMMAND, { "mcctlcommand", any, read_zero, write_stub} },
+ {CSR_MCCTLDATA, { "mcctldata", any, read_zero, write_stub} },
+ {CSR_MPPIB, { "mppib", any, read_zero, write_stub} },
+ {CSR_MFIOB, { "mfiob", any, read_zero, write_stub} },
+
+ /* Hardware Stack Protection & Recording */
+ {CSR_MHSP_CTL, { "mhsp_ctl", any, read_zero, write_stub} },
+ {CSR_MSP_BOUND, { "msp_bound", any, read_zero, write_stub} },
+ {CSR_MSP_BASE, { "msp_base", any, read_zero, write_stub} },
+ {CSR_MXSTATUS, { "mxstatus", any, read_zero, write_stub} },
+ {CSR_MDCAUSE, { "mdcause", any, read_zero, write_stub} },
+ {CSR_MSLIDELEG, { "mslideleg", any, read_zero, write_stub} },
+ {CSR_MSAVESTATUS, { "msavestatus", any, read_zero, write_stub} },
+ {CSR_MSAVEEPC1, { "msaveepc1", any, read_zero, write_stub} },
+ {CSR_MSAVECAUSE1, { "msavecause1", any, read_zero, write_stub} },
+ {CSR_MSAVEEPC2, { "msaveepc2", any, read_zero, write_stub} },
+ {CSR_MSAVECAUSE2, { "msavecause2", any, read_zero, write_stub} },
+ {CSR_MSAVEDCAUSE1, { "msavedcause1", any, read_zero, write_stub} },
+ {CSR_MSAVEDCAUSE2, { "msavedcause2", any, read_zero, write_stub} },
+
+ /* Control CSRs */
+ {CSR_MPFT_CTL, { "mpft_ctl", any, read_zero, write_stub} },
+ {CSR_MMISC_CTL, { "mmisc_ctl", any, read_zero, write_stub} },
+ {CSR_MCLK_CTL, { "mclk_ctl", any, read_zero, write_stub} },
+
+ /* Counter related CSRs */
+ {CSR_MCOUNTERWEN, { "mcounterwen", any, read_zero, write_stub} },
+ {CSR_MCOUNTERINTEN, { "mcounterinten", any, read_zero, write_stub} },
+ {CSR_MCOUNTERMASK_M, { "mcountermask_m", any, read_zero, write_stub} },
+ {CSR_MCOUNTERMASK_S, { "mcountermask_s", any, read_zero, write_stub} },
+ {CSR_MCOUNTERMASK_U, { "mcountermask_u", any, read_zero, write_stub} },
+ {CSR_MCOUNTEROVF, { "mcounterovf", any, read_zero, write_stub} },
+
+ /* Enhanced CLIC CSRs */
+ {CSR_MIRQ_ENTRY, { "mirq_entry", any, read_zero, write_stub} },
+ {CSR_MINTSEL_JAL, { "mintsel_jal", any, read_zero, write_stub} },
+ {CSR_PUSHMCAUSE, { "pushmcause", any, read_zero, write_stub} },
+ {CSR_PUSHMEPC, { "pushmepc", any, read_zero, write_stub} },
+ {CSR_PUSHMXSTATUS, { "pushmxstatus", any, read_zero, write_stub} },
+
+ /* Andes Physical Memory Attribute(PMA) CSRs */
+ {CSR_PMACFG0, { "pmacfg0", any, read_zero, write_stub} },
+ {CSR_PMACFG1, { "pmacfg1", any, read_zero, write_stub} },
+ {CSR_PMACFG2, { "pmacfg2", any, read_zero, write_stub} },
+ {CSR_PMACFG3, { "pmacfg3", any, read_zero, write_stub} },
+ {CSR_PMAADDR0, { "pmaaddr0", any, read_zero, write_stub} },
+ {CSR_PMAADDR1, { "pmaaddr1", any, read_zero, write_stub} },
+ {CSR_PMAADDR2, { "pmaaddr2", any, read_zero, write_stub} },
+ {CSR_PMAADDR3, { "pmaaddr3", any, read_zero, write_stub} },
+ {CSR_PMAADDR4, { "pmaaddr4", any, read_zero, write_stub} },
+ {CSR_PMAADDR5, { "pmaaddr5", any, read_zero, write_stub} },
+ {CSR_PMAADDR6, { "pmaaddr6", any, read_zero, write_stub} },
+ {CSR_PMAADDR7, { "pmaaddr7", any, read_zero, write_stub} },
+ {CSR_PMAADDR8, { "pmaaddr8", any, read_zero, write_stub} },
+ {CSR_PMAADDR9, { "pmaaddr9", any, read_zero, write_stub} },
+ {CSR_PMAADDR10, { "pmaaddr10", any, read_zero, write_stub} },
+ {CSR_PMAADDR11, { "pmaaddr11", any, read_zero, write_stub} },
+ {CSR_PMAADDR12, { "pmaaddr12", any, read_zero, write_stub} },
+ {CSR_PMAADDR13, { "pmaaddr13", any, read_zero, write_stub} },
+ {CSR_PMAADDR14, { "pmaaddr14", any, read_zero, write_stub} },
+ {CSR_PMAADDR15, { "pmaaddr15", any, read_zero, write_stub} },
+
+ /* Debug/Trace Registers (shared with Debug Mode) */
+ {CSR_TSELECT, { "tselect", any, read_zero, write_stub} },
+ {CSR_TDATA1, { "tdata1", any, read_zero, write_stub} },
+ {CSR_TDATA2, { "tdata2", any, read_zero, write_stub} },
+ {CSR_TDATA3, { "tdata3", any, read_zero, write_stub} },
+ {CSR_TINFO, { "tinfo", any, read_zero, write_stub} },
+
+ /* ========= AndeStar V5 supervisor mode CSRs ========= */
+ /* Supervisor trap registers */
+ {CSR_SLIE, { "slie", any, read_zero, write_stub} },
+ {CSR_SLIP, { "slip", any, read_zero, write_stub} },
+ {CSR_SDCAUSE, { "sdcause", any, read_zero, write_stub} },
+
+ /* Supervisor counter registers */
+ {CSR_SCOUNTERINTEN, { "scounterinten", any, read_zero, write_stub} },
+ {CSR_SCOUNTERMASK_M, { "scountermask_m", any, read_zero, write_stub} },
+ {CSR_SCOUNTERMASK_S, { "scountermask_s", any, read_zero, write_stub} },
+ {CSR_SCOUNTERMASK_U, { "scountermask_u", any, read_zero, write_stub} },
+ {CSR_SCOUNTEROVF, { "scounterovf", any, read_zero, write_stub} },
+ {CSR_SCOUNTINHIBIT, { "scountinhibit", any, read_zero, write_stub} },
+ {CSR_SHPMEVENT3, { "shpmevent3", any, read_zero, write_stub} },
+ {CSR_SHPMEVENT4, { "shpmevent4", any, read_zero, write_stub} },
+ {CSR_SHPMEVENT5, { "shpmevent5", any, read_zero, write_stub} },
+ {CSR_SHPMEVENT6, { "shpmevent6", any, read_zero, write_stub} },
+
+ /* Supervisor control registers */
+ {CSR_SCCTLDATA, { "scctldata", any, read_zero, write_stub} },
+ {CSR_SMISC_CTL, { "smisc_ctl", any, read_zero, write_stub} },
+ #endif
+
+ /* ========= AndeStar V5 user mode CSRs ========= */
+ /* User mode control registers */
+ {CSR_UITB, { "uitb", any, read_uitb, write_uitb} },
+ {CSR_UCODE, { "ucode", any, read_zero, write_stub} },
+ {CSR_UDCAUSE, { "udcause", any, read_zero, write_stub} },
+ {CSR_UCCTLBEGINADDR, { "ucctlbeginaddr", any, read_zero, write_stub} },
+ {CSR_UCCTLCOMMAND, { "ucctlcommand", any, read_zero, write_stub} },
+ {CSR_WFE, { "wfe", any, read_zero, write_stub} },
+ {CSR_SLEEPVALUE, { "sleepvalue", any, read_zero, write_stub} },
+ {CSR_TXEVT, { "csr_txevt", any, read_zero, write_stub} },
+ {0, { "", NULL, NULL, NULL } },
+ };
diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
index 4dbf8cf1fd..b09083585b 100644
--- a/target/riscv/custom_csr_defs.h
+++ b/target/riscv/custom_csr_defs.h
@@ -4,4 +4,5 @@
* Custom CSR variables provided by <cpu_model_name>_csr.c
*/
-/* Left blank purposely in this commit. */
+extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
+extern int andes_custom_csr_size;
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index d5e0bc93ea..5c87672ff9 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -9,6 +9,7 @@ gen = [
riscv_ss = ss.source_set()
riscv_ss.add(gen)
riscv_ss.add(files(
+ 'csr_andes.c',
'cpu.c',
'cpu_helper.c',
'csr.c',
--
2.25.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
@ 2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
0 siblings, 0 replies; 28+ messages in thread
From: Ruinland Chuan-Tzu Tsai @ 2021-10-21 15:09 UTC (permalink / raw)
To: alistair23, wangjunqiang, bmeng.cn
Cc: qemu-devel, qemu-riscv, ycliang, alankao, dylan, Ruinland Chuan-Tzu Tsai
Add CSR bits definitions, CSR table and handler functions for Andes
AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
---
target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
target/riscv/cpu.c | 4 +
target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
target/riscv/custom_csr_defs.h | 3 +-
target/riscv/meson.build | 1 +
5 files changed, 319 insertions(+), 1 deletion(-)
create mode 100644 target/riscv/andes_cpu_bits.h
create mode 100644 target/riscv/csr_andes.c
diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
new file mode 100644
index 0000000000..84b0900423
--- /dev/null
+++ b/target/riscv/andes_cpu_bits.h
@@ -0,0 +1,129 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Andes custom CSRs bit definitions
+ *
+ */
+
+/*
+ * ========= Missing drafted/standard CSR definitions =========
+ * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
+ */
+#define CSR_TINFO 0x7a4
+
+#if !defined(CONFIG_USER_ONLY)
+/* ========= AndeStar V5 machine mode CSRs ========= */
+/* Configuration Registers */
+#define CSR_MICM_CFG 0xfc0
+#define CSR_MDCM_CFG 0xfc1
+#define CSR_MMSC_CFG 0xfc2
+#define CSR_MMSC_CFG2 0xfc3
+#define CSR_MVEC_CFG 0xfc7
+
+/* Crash Debug CSRs */
+#define CSR_MCRASH_STATESAVE 0xfc8
+#define CSR_MSTATUS_CRASHSAVE 0xfc9
+
+/* Memory CSRs */
+#define CSR_MILMB 0x7c0
+#define CSR_MDLMB 0x7c1
+#define CSR_MECC_CODE 0x7C2
+#define CSR_MNVEC 0x7c3
+#define CSR_MCACHE_CTL 0x7ca
+#define CSR_MCCTLBEGINADDR 0x7cb
+#define CSR_MCCTLCOMMAND 0x7cc
+#define CSR_MCCTLDATA 0x7cd
+#define CSR_MPPIB 0x7f0
+#define CSR_MFIOB 0x7f1
+
+/* Hardware Stack Protection & Recording */
+#define CSR_MHSP_CTL 0x7c6
+#define CSR_MSP_BOUND 0x7c7
+#define CSR_MSP_BASE 0x7c8
+#define CSR_MXSTATUS 0x7c4
+#define CSR_MDCAUSE 0x7c9
+#define CSR_MSLIDELEG 0x7d5
+#define CSR_MSAVESTATUS 0x7d6
+#define CSR_MSAVEEPC1 0x7d7
+#define CSR_MSAVECAUSE1 0x7d8
+#define CSR_MSAVEEPC2 0x7d9
+#define CSR_MSAVECAUSE2 0x7da
+#define CSR_MSAVEDCAUSE1 0x7db
+#define CSR_MSAVEDCAUSE2 0x7dc
+
+/* Control CSRs */
+#define CSR_MPFT_CTL 0x7c5
+#define CSR_MMISC_CTL 0x7d0
+#define CSR_MCLK_CTL 0x7df
+
+/* Counter related CSRs */
+#define CSR_MCOUNTERWEN 0x7ce
+#define CSR_MCOUNTERINTEN 0x7cf
+#define CSR_MCOUNTERMASK_M 0x7d1
+#define CSR_MCOUNTERMASK_S 0x7d2
+#define CSR_MCOUNTERMASK_U 0x7d3
+#define CSR_MCOUNTEROVF 0x7d4
+
+/* Enhanced CLIC CSRs */
+#define CSR_MIRQ_ENTRY 0x7ec
+#define CSR_MINTSEL_JAL 0x7ed
+#define CSR_PUSHMCAUSE 0x7ee
+#define CSR_PUSHMEPC 0x7ef
+#define CSR_PUSHMXSTATUS 0x7eb
+
+/* Andes Physical Memory Attribute(PMA) CSRs */
+#define CSR_PMACFG0 0xbc0
+#define CSR_PMACFG1 0xbc1
+#define CSR_PMACFG2 0xbc2
+#define CSR_PMACFG3 0xbc3
+#define CSR_PMAADDR0 0xbd0
+#define CSR_PMAADDR1 0xbd1
+#define CSR_PMAADDR2 0xbd2
+#define CSR_PMAADDR3 0xbd2
+#define CSR_PMAADDR4 0xbd4
+#define CSR_PMAADDR5 0xbd5
+#define CSR_PMAADDR6 0xbd6
+#define CSR_PMAADDR7 0xbd7
+#define CSR_PMAADDR8 0xbd8
+#define CSR_PMAADDR9 0xbd9
+#define CSR_PMAADDR10 0xbda
+#define CSR_PMAADDR11 0xbdb
+#define CSR_PMAADDR12 0xbdc
+#define CSR_PMAADDR13 0xbdd
+#define CSR_PMAADDR14 0xbde
+#define CSR_PMAADDR15 0xbdf
+
+/* ========= AndeStar V5 supervisor mode CSRs ========= */
+/* Supervisor trap registers */
+#define CSR_SLIE 0x9c4
+#define CSR_SLIP 0x9c5
+#define CSR_SDCAUSE 0x9c9
+
+/* Supervisor counter registers */
+#define CSR_SCOUNTERINTEN 0x9cf
+#define CSR_SCOUNTERMASK_M 0x9d1
+#define CSR_SCOUNTERMASK_S 0x9d2
+#define CSR_SCOUNTERMASK_U 0x9d3
+#define CSR_SCOUNTEROVF 0x9d4
+#define CSR_SCOUNTINHIBIT 0x9e0
+#define CSR_SHPMEVENT3 0x9e3
+#define CSR_SHPMEVENT4 0x9e4
+#define CSR_SHPMEVENT5 0x9e5
+#define CSR_SHPMEVENT6 0x9e6
+
+/* Supervisor control registers */
+#define CSR_SCCTLDATA 0x9cd
+#define CSR_SMISC_CTL 0x9d0
+
+#endif /* !defined(CONFIG_USER_ONLY) */
+
+/* ========= AndeStar V5 user mode CSRs ========= */
+/* User mode control registers */
+#define CSR_UITB 0x800
+#define CSR_UCODE 0x801
+#define CSR_UDCAUSE 0x809
+#define CSR_UCCTLBEGINADDR 0x80b
+#define CSR_UCCTLCOMMAND 0x80c
+#define CSR_WFE 0x810
+#define CSR_SLEEPVALUE 0x811
+#define CSR_TXEVT 0x812
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a72fd32f01..fe63e68b8e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -192,6 +192,8 @@ static void ax25_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
+ setup_custom_csr(env, andes_custom_csr_table);
+ env->custom_csr_val = g_malloc(andes_custom_csr_size);
}
static void rv64_sifive_u_cpu_init(Object *obj)
@@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
+ setup_custom_csr(env, andes_custom_csr_table);
+ env->custom_csr_val = g_malloc(andes_custom_csr_size);
}
#endif
diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
new file mode 100644
index 0000000000..8617f40483
--- /dev/null
+++ b/target/riscv/csr_andes.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2021 Andes Technology Corp.
+ * SPDX-License-Identifier: GPL-2.0+
+ * Andes custom CSR table and handling functions
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "cpu.h"
+#include "qemu/main-loop.h"
+#include "exec/exec-all.h"
+#include "andes_cpu_bits.h"
+
+struct andes_csr_val {
+ target_long uitb;
+};
+
+#if !defined(CONFIG_USER_ONLY)
+static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ /* enable pma probe */
+ *val = 0x40000000;
+ return RISCV_EXCP_NONE;
+}
+#endif
+
+static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
+{
+ struct andes_csr_val *andes_csr = env->custom_csr_val;
+ andes_csr->uitb = val;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ struct andes_csr_val *andes_csr = env->custom_csr_val;
+ *val = andes_csr->uitb;
+ return RISCV_EXCP_NONE;
+}
+
+
+static RISCVException any(CPURISCVState *env, int csrno)
+{
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = 0;
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
+{
+ return RISCV_EXCP_NONE;
+}
+
+int andes_custom_csr_size = sizeof(struct andes_csr_val);
+riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
+ /* ========= AndeStar V5 machine mode CSRs ========= */
+ #if !defined(CONFIG_USER_ONLY)
+ /* Configuration Registers */
+ {CSR_MICM_CFG, { "micm_cfg", any, read_zero, write_stub} },
+ {CSR_MDCM_CFG, { "mdcm_cfg", any, read_zero, write_stub} },
+ {CSR_MMSC_CFG, { "mmsc_cfg", any, read_mmsc_cfg, write_stub} },
+ {CSR_MMSC_CFG2, { "mmsc_cfg2", any, read_zero, write_stub} },
+ {CSR_MVEC_CFG, { "mvec_cfg", any, read_zero, write_stub} },
+
+ /* Crash Debug CSRs */
+ {CSR_MCRASH_STATESAVE, { "mcrash_statesave", any, read_zero, write_stub} },
+ {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
+
+ /* Memory CSRs */
+ {CSR_MILMB, { "milmb", any, read_zero, write_stub} },
+ {CSR_MDLMB, { "mdlmb", any, read_zero, write_stub} },
+ {CSR_MECC_CODE, { "mecc_code", any, read_zero, write_stub} },
+ {CSR_MNVEC, { "mnvec", any, read_zero, write_stub} },
+ {CSR_MCACHE_CTL, { "mcache_ctl", any, read_zero, write_stub} },
+ {CSR_MCCTLBEGINADDR, { "mcctlbeginaddr", any, read_zero, write_stub} },
+ {CSR_MCCTLCOMMAND, { "mcctlcommand", any, read_zero, write_stub} },
+ {CSR_MCCTLDATA, { "mcctldata", any, read_zero, write_stub} },
+ {CSR_MPPIB, { "mppib", any, read_zero, write_stub} },
+ {CSR_MFIOB, { "mfiob", any, read_zero, write_stub} },
+
+ /* Hardware Stack Protection & Recording */
+ {CSR_MHSP_CTL, { "mhsp_ctl", any, read_zero, write_stub} },
+ {CSR_MSP_BOUND, { "msp_bound", any, read_zero, write_stub} },
+ {CSR_MSP_BASE, { "msp_base", any, read_zero, write_stub} },
+ {CSR_MXSTATUS, { "mxstatus", any, read_zero, write_stub} },
+ {CSR_MDCAUSE, { "mdcause", any, read_zero, write_stub} },
+ {CSR_MSLIDELEG, { "mslideleg", any, read_zero, write_stub} },
+ {CSR_MSAVESTATUS, { "msavestatus", any, read_zero, write_stub} },
+ {CSR_MSAVEEPC1, { "msaveepc1", any, read_zero, write_stub} },
+ {CSR_MSAVECAUSE1, { "msavecause1", any, read_zero, write_stub} },
+ {CSR_MSAVEEPC2, { "msaveepc2", any, read_zero, write_stub} },
+ {CSR_MSAVECAUSE2, { "msavecause2", any, read_zero, write_stub} },
+ {CSR_MSAVEDCAUSE1, { "msavedcause1", any, read_zero, write_stub} },
+ {CSR_MSAVEDCAUSE2, { "msavedcause2", any, read_zero, write_stub} },
+
+ /* Control CSRs */
+ {CSR_MPFT_CTL, { "mpft_ctl", any, read_zero, write_stub} },
+ {CSR_MMISC_CTL, { "mmisc_ctl", any, read_zero, write_stub} },
+ {CSR_MCLK_CTL, { "mclk_ctl", any, read_zero, write_stub} },
+
+ /* Counter related CSRs */
+ {CSR_MCOUNTERWEN, { "mcounterwen", any, read_zero, write_stub} },
+ {CSR_MCOUNTERINTEN, { "mcounterinten", any, read_zero, write_stub} },
+ {CSR_MCOUNTERMASK_M, { "mcountermask_m", any, read_zero, write_stub} },
+ {CSR_MCOUNTERMASK_S, { "mcountermask_s", any, read_zero, write_stub} },
+ {CSR_MCOUNTERMASK_U, { "mcountermask_u", any, read_zero, write_stub} },
+ {CSR_MCOUNTEROVF, { "mcounterovf", any, read_zero, write_stub} },
+
+ /* Enhanced CLIC CSRs */
+ {CSR_MIRQ_ENTRY, { "mirq_entry", any, read_zero, write_stub} },
+ {CSR_MINTSEL_JAL, { "mintsel_jal", any, read_zero, write_stub} },
+ {CSR_PUSHMCAUSE, { "pushmcause", any, read_zero, write_stub} },
+ {CSR_PUSHMEPC, { "pushmepc", any, read_zero, write_stub} },
+ {CSR_PUSHMXSTATUS, { "pushmxstatus", any, read_zero, write_stub} },
+
+ /* Andes Physical Memory Attribute(PMA) CSRs */
+ {CSR_PMACFG0, { "pmacfg0", any, read_zero, write_stub} },
+ {CSR_PMACFG1, { "pmacfg1", any, read_zero, write_stub} },
+ {CSR_PMACFG2, { "pmacfg2", any, read_zero, write_stub} },
+ {CSR_PMACFG3, { "pmacfg3", any, read_zero, write_stub} },
+ {CSR_PMAADDR0, { "pmaaddr0", any, read_zero, write_stub} },
+ {CSR_PMAADDR1, { "pmaaddr1", any, read_zero, write_stub} },
+ {CSR_PMAADDR2, { "pmaaddr2", any, read_zero, write_stub} },
+ {CSR_PMAADDR3, { "pmaaddr3", any, read_zero, write_stub} },
+ {CSR_PMAADDR4, { "pmaaddr4", any, read_zero, write_stub} },
+ {CSR_PMAADDR5, { "pmaaddr5", any, read_zero, write_stub} },
+ {CSR_PMAADDR6, { "pmaaddr6", any, read_zero, write_stub} },
+ {CSR_PMAADDR7, { "pmaaddr7", any, read_zero, write_stub} },
+ {CSR_PMAADDR8, { "pmaaddr8", any, read_zero, write_stub} },
+ {CSR_PMAADDR9, { "pmaaddr9", any, read_zero, write_stub} },
+ {CSR_PMAADDR10, { "pmaaddr10", any, read_zero, write_stub} },
+ {CSR_PMAADDR11, { "pmaaddr11", any, read_zero, write_stub} },
+ {CSR_PMAADDR12, { "pmaaddr12", any, read_zero, write_stub} },
+ {CSR_PMAADDR13, { "pmaaddr13", any, read_zero, write_stub} },
+ {CSR_PMAADDR14, { "pmaaddr14", any, read_zero, write_stub} },
+ {CSR_PMAADDR15, { "pmaaddr15", any, read_zero, write_stub} },
+
+ /* Debug/Trace Registers (shared with Debug Mode) */
+ {CSR_TSELECT, { "tselect", any, read_zero, write_stub} },
+ {CSR_TDATA1, { "tdata1", any, read_zero, write_stub} },
+ {CSR_TDATA2, { "tdata2", any, read_zero, write_stub} },
+ {CSR_TDATA3, { "tdata3", any, read_zero, write_stub} },
+ {CSR_TINFO, { "tinfo", any, read_zero, write_stub} },
+
+ /* ========= AndeStar V5 supervisor mode CSRs ========= */
+ /* Supervisor trap registers */
+ {CSR_SLIE, { "slie", any, read_zero, write_stub} },
+ {CSR_SLIP, { "slip", any, read_zero, write_stub} },
+ {CSR_SDCAUSE, { "sdcause", any, read_zero, write_stub} },
+
+ /* Supervisor counter registers */
+ {CSR_SCOUNTERINTEN, { "scounterinten", any, read_zero, write_stub} },
+ {CSR_SCOUNTERMASK_M, { "scountermask_m", any, read_zero, write_stub} },
+ {CSR_SCOUNTERMASK_S, { "scountermask_s", any, read_zero, write_stub} },
+ {CSR_SCOUNTERMASK_U, { "scountermask_u", any, read_zero, write_stub} },
+ {CSR_SCOUNTEROVF, { "scounterovf", any, read_zero, write_stub} },
+ {CSR_SCOUNTINHIBIT, { "scountinhibit", any, read_zero, write_stub} },
+ {CSR_SHPMEVENT3, { "shpmevent3", any, read_zero, write_stub} },
+ {CSR_SHPMEVENT4, { "shpmevent4", any, read_zero, write_stub} },
+ {CSR_SHPMEVENT5, { "shpmevent5", any, read_zero, write_stub} },
+ {CSR_SHPMEVENT6, { "shpmevent6", any, read_zero, write_stub} },
+
+ /* Supervisor control registers */
+ {CSR_SCCTLDATA, { "scctldata", any, read_zero, write_stub} },
+ {CSR_SMISC_CTL, { "smisc_ctl", any, read_zero, write_stub} },
+ #endif
+
+ /* ========= AndeStar V5 user mode CSRs ========= */
+ /* User mode control registers */
+ {CSR_UITB, { "uitb", any, read_uitb, write_uitb} },
+ {CSR_UCODE, { "ucode", any, read_zero, write_stub} },
+ {CSR_UDCAUSE, { "udcause", any, read_zero, write_stub} },
+ {CSR_UCCTLBEGINADDR, { "ucctlbeginaddr", any, read_zero, write_stub} },
+ {CSR_UCCTLCOMMAND, { "ucctlcommand", any, read_zero, write_stub} },
+ {CSR_WFE, { "wfe", any, read_zero, write_stub} },
+ {CSR_SLEEPVALUE, { "sleepvalue", any, read_zero, write_stub} },
+ {CSR_TXEVT, { "csr_txevt", any, read_zero, write_stub} },
+ {0, { "", NULL, NULL, NULL } },
+ };
diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
index 4dbf8cf1fd..b09083585b 100644
--- a/target/riscv/custom_csr_defs.h
+++ b/target/riscv/custom_csr_defs.h
@@ -4,4 +4,5 @@
* Custom CSR variables provided by <cpu_model_name>_csr.c
*/
-/* Left blank purposely in this commit. */
+extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
+extern int andes_custom_csr_size;
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index d5e0bc93ea..5c87672ff9 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -9,6 +9,7 @@ gen = [
riscv_ss = ss.source_set()
riscv_ss.add(gen)
riscv_ss.add(files(
+ 'csr_andes.c',
'cpu.c',
'cpu_helper.c',
'csr.c',
--
2.25.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 22:33 ` Alistair Francis
-1 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:33 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai
Cc: ycliang, Alan Quey-Liang Kao((((((((((),
wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
open list:RISC-V, Bin Meng
On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Introduce A25 and AX25 CPU model designed by Andes Technology.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/cpu.c | 16 ++++++++++++++++
> target/riscv/cpu.h | 2 ++
> 2 files changed, 18 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7c626d89cd..0c93b7edd7 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -168,6 +168,13 @@ static void rv64_base_cpu_init(Object *obj)
> set_misa(env, RV64);
> }
>
> +static void ax25_cpu_init(Object *obj)
> +{
> + CPURISCVState *env = &RISCV_CPU(obj)->env;
> + set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> + set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
> +
> static void rv64_sifive_u_cpu_init(Object *obj)
> {
> CPURISCVState *env = &RISCV_CPU(obj)->env;
> @@ -222,6 +229,13 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
> set_resetvec(env, DEFAULT_RSTVEC);
> qdev_prop_set_bit(DEVICE(obj), "mmu", false);
> }
> +
> +static void a25_cpu_init(Object *obj)
> +{
> + CPURISCVState *env = &RISCV_CPU(obj)->env;
> + set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> + set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
> #endif
>
> static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
> @@ -789,8 +803,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
> + DEFINE_CPU(TYPE_RISCV_CPU_A25, a25_cpu_init),
> #elif defined(TARGET_RISCV64)
> DEFINE_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
> + DEFINE_CPU(TYPE_RISCV_CPU_AX25, ax25_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5896aca346..3bef0d1265 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -37,6 +37,8 @@
> #define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any")
> #define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
> #define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
> +#define TYPE_RISCV_CPU_A25 RISCV_CPU_TYPE_NAME("andes-a25")
> +#define TYPE_RISCV_CPU_AX25 RISCV_CPU_TYPE_NAME("andes-ax25")
> #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
> #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
> #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models
@ 2021-10-21 22:33 ` Alistair Francis
0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:33 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai
Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
Dylan Jhong
On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Introduce A25 and AX25 CPU model designed by Andes Technology.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/cpu.c | 16 ++++++++++++++++
> target/riscv/cpu.h | 2 ++
> 2 files changed, 18 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7c626d89cd..0c93b7edd7 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -168,6 +168,13 @@ static void rv64_base_cpu_init(Object *obj)
> set_misa(env, RV64);
> }
>
> +static void ax25_cpu_init(Object *obj)
> +{
> + CPURISCVState *env = &RISCV_CPU(obj)->env;
> + set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> + set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
> +
> static void rv64_sifive_u_cpu_init(Object *obj)
> {
> CPURISCVState *env = &RISCV_CPU(obj)->env;
> @@ -222,6 +229,13 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
> set_resetvec(env, DEFAULT_RSTVEC);
> qdev_prop_set_bit(DEVICE(obj), "mmu", false);
> }
> +
> +static void a25_cpu_init(Object *obj)
> +{
> + CPURISCVState *env = &RISCV_CPU(obj)->env;
> + set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> + set_priv_version(env, PRIV_VERSION_1_10_0);
> +}
> #endif
>
> static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
> @@ -789,8 +803,10 @@ static const TypeInfo riscv_cpu_type_infos[] = {
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
> + DEFINE_CPU(TYPE_RISCV_CPU_A25, a25_cpu_init),
> #elif defined(TARGET_RISCV64)
> DEFINE_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
> + DEFINE_CPU(TYPE_RISCV_CPU_AX25, ax25_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
> DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5896aca346..3bef0d1265 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -37,6 +37,8 @@
> #define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any")
> #define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
> #define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
> +#define TYPE_RISCV_CPU_A25 RISCV_CPU_TYPE_NAME("andes-a25")
> +#define TYPE_RISCV_CPU_AX25 RISCV_CPU_TYPE_NAME("andes-ax25")
> #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
> #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
> #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 22:43 ` Alistair Francis
-1 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:43 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai
Cc: ycliang, Alan Quey-Liang Kao((((((((((),
wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
open list:RISC-V, Bin Meng
On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> riscv_csrrw() will be called by CSR handling helpers, which is the
> most suitable place for checking wheter a custom CSR is being accessed.
>
> If we're touching a custom CSR, invoke the registered handlers.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
Awesome! This looks really good :)
> ---
> target/riscv/cpu.c | 19 +++++++++++++++++
> target/riscv/cpu.h | 13 +++++++++++-
> target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
> target/riscv/custom_csr_defs.h | 7 +++++++
> 4 files changed, 68 insertions(+), 9 deletions(-)
> create mode 100644 target/riscv/custom_csr_defs.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0c93b7edd7..a72fd32f01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -34,6 +34,9 @@
>
> static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>
> +GHashTable *custom_csr_map = NULL;
> +#include "custom_csr_defs.h"
> +
> const char * const riscv_int_regnames[] = {
> "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
> "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
> @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> #endif
> }
>
> +static void setup_custom_csr(CPURISCVState *env,
> + riscv_custom_csr_operations csr_map_struct[])
> +{
> + int i;
> + env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> + for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> + if (csr_map_struct[i].csrno != 0) {
> + g_hash_table_insert(env->custom_csr_map,
> + GINT_TO_POINTER(csr_map_struct[i].csrno),
> + &csr_map_struct[i].csr_opset);
> + } else {
> + break;
> + }
> + }
> +}
> +
> static void riscv_any_cpu_init(Object *obj)
> {
> CPURISCVState *env = &RISCV_CPU(obj)->env;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 3bef0d1265..012be10d0a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -245,6 +245,11 @@ struct CPURISCVState {
>
> /* Fields from here on are preserved across CPU reset. */
> QEMUTimer *timer; /* Internal timer */
> +
> + /* Custom CSR opset table per hart */
> + GHashTable *custom_csr_map;
> + /* Custom CSR value holder per hart */
> + void *custom_csr_val;
> };
>
> OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -496,9 +501,15 @@ typedef struct {
> riscv_csr_op_fn op;
> } riscv_csr_operations;
>
> +typedef struct {
> + int csrno;
> + riscv_csr_operations csr_opset;
> +} riscv_custom_csr_operations;
> +
> /* CSR function table constants */
> enum {
> - CSR_TABLE_SIZE = 0x1000
> + CSR_TABLE_SIZE = 0x1000,
> + MAX_CUSTOM_CSR_NUM = 100
> };
>
> /* CSR function table */
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 23fbbd3216..1048ee3b44 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
>
> #endif
>
> +/* Custom CSR related routines */
> +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> +{
> + gpointer ret;
> + ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> + return ret;
You can just return directly here, so:
return g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
Also, I think you need to run checkpatch.pl on this patch (you should
run it on all patches).
Alistair
> +}
> +
> /*
> * riscv_csrrw - read and/or update control and status register
> *
> @@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> RISCVException ret;
> target_ulong old_value;
> RISCVCPU *cpu = env_archcpu(env);
> + riscv_csr_operations *csr_op;
> int read_only = get_field(csrno, 0xC00) == 3;
>
> /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> return RISCV_EXCP_ILLEGAL_INST;
> }
>
> + /* try to handle_custom_csr */
> + if (unlikely(env->custom_csr_map != NULL)) {
> + riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> + find_custom_csr(env, csrno);
> + if (custom_csr_opset != NULL) {
> + csr_op = custom_csr_opset;
> + } else {
> + csr_op = &csr_ops[csrno];
> + }
> + } else {
> + csr_op = &csr_ops[csrno];
> + }
> +
> /* check predicate */
> - if (!csr_ops[csrno].predicate) {
> + if (!csr_op->predicate) {
> return RISCV_EXCP_ILLEGAL_INST;
> }
> - ret = csr_ops[csrno].predicate(env, csrno);
> + ret = csr_op->predicate(env, csrno);
> if (ret != RISCV_EXCP_NONE) {
> return ret;
> }
>
> /* execute combined read/write operation if it exists */
> - if (csr_ops[csrno].op) {
> - return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> + if (csr_op->op) {
> + return csr_op->op(env, csrno, ret_value, new_value, write_mask);
> }
>
> /* if no accessor exists then return failure */
> - if (!csr_ops[csrno].read) {
> + if (!csr_op->read) {
> return RISCV_EXCP_ILLEGAL_INST;
> }
> /* read old value */
> - ret = csr_ops[csrno].read(env, csrno, &old_value);
> + ret = csr_op->read(env, csrno, &old_value);
> if (ret != RISCV_EXCP_NONE) {
> return ret;
> }
> @@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> /* write value if writable and write mask set, otherwise drop writes */
> if (write_mask) {
> new_value = (old_value & ~write_mask) | (new_value & write_mask);
> - if (csr_ops[csrno].write) {
> - ret = csr_ops[csrno].write(env, csrno, new_value);
> + if (csr_op->write) {
> + ret = csr_op->write(env, csrno, new_value);
> if (ret != RISCV_EXCP_NONE) {
> return ret;
> }
> diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> new file mode 100644
> index 0000000000..4dbf8cf1fd
> --- /dev/null
> +++ b/target/riscv/custom_csr_defs.h
> @@ -0,0 +1,7 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Custom CSR variables provided by <cpu_model_name>_csr.c
> + */
> +
> +/* Left blank purposely in this commit. */
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-21 22:43 ` Alistair Francis
0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:43 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai
Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
Dylan Jhong
On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> riscv_csrrw() will be called by CSR handling helpers, which is the
> most suitable place for checking wheter a custom CSR is being accessed.
>
> If we're touching a custom CSR, invoke the registered handlers.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
Awesome! This looks really good :)
> ---
> target/riscv/cpu.c | 19 +++++++++++++++++
> target/riscv/cpu.h | 13 +++++++++++-
> target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
> target/riscv/custom_csr_defs.h | 7 +++++++
> 4 files changed, 68 insertions(+), 9 deletions(-)
> create mode 100644 target/riscv/custom_csr_defs.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0c93b7edd7..a72fd32f01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -34,6 +34,9 @@
>
> static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>
> +GHashTable *custom_csr_map = NULL;
> +#include "custom_csr_defs.h"
> +
> const char * const riscv_int_regnames[] = {
> "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
> "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
> @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> #endif
> }
>
> +static void setup_custom_csr(CPURISCVState *env,
> + riscv_custom_csr_operations csr_map_struct[])
> +{
> + int i;
> + env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> + for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> + if (csr_map_struct[i].csrno != 0) {
> + g_hash_table_insert(env->custom_csr_map,
> + GINT_TO_POINTER(csr_map_struct[i].csrno),
> + &csr_map_struct[i].csr_opset);
> + } else {
> + break;
> + }
> + }
> +}
> +
> static void riscv_any_cpu_init(Object *obj)
> {
> CPURISCVState *env = &RISCV_CPU(obj)->env;
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 3bef0d1265..012be10d0a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -245,6 +245,11 @@ struct CPURISCVState {
>
> /* Fields from here on are preserved across CPU reset. */
> QEMUTimer *timer; /* Internal timer */
> +
> + /* Custom CSR opset table per hart */
> + GHashTable *custom_csr_map;
> + /* Custom CSR value holder per hart */
> + void *custom_csr_val;
> };
>
> OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> @@ -496,9 +501,15 @@ typedef struct {
> riscv_csr_op_fn op;
> } riscv_csr_operations;
>
> +typedef struct {
> + int csrno;
> + riscv_csr_operations csr_opset;
> +} riscv_custom_csr_operations;
> +
> /* CSR function table constants */
> enum {
> - CSR_TABLE_SIZE = 0x1000
> + CSR_TABLE_SIZE = 0x1000,
> + MAX_CUSTOM_CSR_NUM = 100
> };
>
> /* CSR function table */
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 23fbbd3216..1048ee3b44 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
>
> #endif
>
> +/* Custom CSR related routines */
> +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> +{
> + gpointer ret;
> + ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> + return ret;
You can just return directly here, so:
return g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
Also, I think you need to run checkpatch.pl on this patch (you should
run it on all patches).
Alistair
> +}
> +
> /*
> * riscv_csrrw - read and/or update control and status register
> *
> @@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> RISCVException ret;
> target_ulong old_value;
> RISCVCPU *cpu = env_archcpu(env);
> + riscv_csr_operations *csr_op;
> int read_only = get_field(csrno, 0xC00) == 3;
>
> /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> return RISCV_EXCP_ILLEGAL_INST;
> }
>
> + /* try to handle_custom_csr */
> + if (unlikely(env->custom_csr_map != NULL)) {
> + riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> + find_custom_csr(env, csrno);
> + if (custom_csr_opset != NULL) {
> + csr_op = custom_csr_opset;
> + } else {
> + csr_op = &csr_ops[csrno];
> + }
> + } else {
> + csr_op = &csr_ops[csrno];
> + }
> +
> /* check predicate */
> - if (!csr_ops[csrno].predicate) {
> + if (!csr_op->predicate) {
> return RISCV_EXCP_ILLEGAL_INST;
> }
> - ret = csr_ops[csrno].predicate(env, csrno);
> + ret = csr_op->predicate(env, csrno);
> if (ret != RISCV_EXCP_NONE) {
> return ret;
> }
>
> /* execute combined read/write operation if it exists */
> - if (csr_ops[csrno].op) {
> - return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> + if (csr_op->op) {
> + return csr_op->op(env, csrno, ret_value, new_value, write_mask);
> }
>
> /* if no accessor exists then return failure */
> - if (!csr_ops[csrno].read) {
> + if (!csr_op->read) {
> return RISCV_EXCP_ILLEGAL_INST;
> }
> /* read old value */
> - ret = csr_ops[csrno].read(env, csrno, &old_value);
> + ret = csr_op->read(env, csrno, &old_value);
> if (ret != RISCV_EXCP_NONE) {
> return ret;
> }
> @@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> /* write value if writable and write mask set, otherwise drop writes */
> if (write_mask) {
> new_value = (old_value & ~write_mask) | (new_value & write_mask);
> - if (csr_ops[csrno].write) {
> - ret = csr_ops[csrno].write(env, csrno, new_value);
> + if (csr_op->write) {
> + ret = csr_op->write(env, csrno, new_value);
> if (ret != RISCV_EXCP_NONE) {
> return ret;
> }
> diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> new file mode 100644
> index 0000000000..4dbf8cf1fd
> --- /dev/null
> +++ b/target/riscv/custom_csr_defs.h
> @@ -0,0 +1,7 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Custom CSR variables provided by <cpu_model_name>_csr.c
> + */
> +
> +/* Left blank purposely in this commit. */
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 22:44 ` Alistair Francis
-1 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:44 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai
Cc: ycliang, Alan Quey-Liang Kao((((((((((),
wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
open list:RISC-V, Bin Meng
On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Add CSR bits definitions, CSR table and handler functions for Andes
> AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> ---
> target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
> target/riscv/cpu.c | 4 +
> target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
> target/riscv/custom_csr_defs.h | 3 +-
> target/riscv/meson.build | 1 +
> 5 files changed, 319 insertions(+), 1 deletion(-)
> create mode 100644 target/riscv/andes_cpu_bits.h
> create mode 100644 target/riscv/csr_andes.c
>
> diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> new file mode 100644
> index 0000000000..84b0900423
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,129 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0+
> + *
> + * Andes custom CSRs bit definitions
> + *
> + */
> +
> +/*
> + * ========= Missing drafted/standard CSR definitions =========
> + * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
> + */
> +#define CSR_TINFO 0x7a4
> +
> +#if !defined(CONFIG_USER_ONLY)
> +/* ========= AndeStar V5 machine mode CSRs ========= */
> +/* Configuration Registers */
> +#define CSR_MICM_CFG 0xfc0
> +#define CSR_MDCM_CFG 0xfc1
> +#define CSR_MMSC_CFG 0xfc2
> +#define CSR_MMSC_CFG2 0xfc3
> +#define CSR_MVEC_CFG 0xfc7
> +
> +/* Crash Debug CSRs */
> +#define CSR_MCRASH_STATESAVE 0xfc8
> +#define CSR_MSTATUS_CRASHSAVE 0xfc9
> +
> +/* Memory CSRs */
> +#define CSR_MILMB 0x7c0
> +#define CSR_MDLMB 0x7c1
> +#define CSR_MECC_CODE 0x7C2
> +#define CSR_MNVEC 0x7c3
> +#define CSR_MCACHE_CTL 0x7ca
> +#define CSR_MCCTLBEGINADDR 0x7cb
> +#define CSR_MCCTLCOMMAND 0x7cc
> +#define CSR_MCCTLDATA 0x7cd
> +#define CSR_MPPIB 0x7f0
> +#define CSR_MFIOB 0x7f1
> +
> +/* Hardware Stack Protection & Recording */
> +#define CSR_MHSP_CTL 0x7c6
> +#define CSR_MSP_BOUND 0x7c7
> +#define CSR_MSP_BASE 0x7c8
> +#define CSR_MXSTATUS 0x7c4
> +#define CSR_MDCAUSE 0x7c9
> +#define CSR_MSLIDELEG 0x7d5
> +#define CSR_MSAVESTATUS 0x7d6
> +#define CSR_MSAVEEPC1 0x7d7
> +#define CSR_MSAVECAUSE1 0x7d8
> +#define CSR_MSAVEEPC2 0x7d9
> +#define CSR_MSAVECAUSE2 0x7da
> +#define CSR_MSAVEDCAUSE1 0x7db
> +#define CSR_MSAVEDCAUSE2 0x7dc
> +
> +/* Control CSRs */
> +#define CSR_MPFT_CTL 0x7c5
> +#define CSR_MMISC_CTL 0x7d0
> +#define CSR_MCLK_CTL 0x7df
> +
> +/* Counter related CSRs */
> +#define CSR_MCOUNTERWEN 0x7ce
> +#define CSR_MCOUNTERINTEN 0x7cf
> +#define CSR_MCOUNTERMASK_M 0x7d1
> +#define CSR_MCOUNTERMASK_S 0x7d2
> +#define CSR_MCOUNTERMASK_U 0x7d3
> +#define CSR_MCOUNTEROVF 0x7d4
> +
> +/* Enhanced CLIC CSRs */
> +#define CSR_MIRQ_ENTRY 0x7ec
> +#define CSR_MINTSEL_JAL 0x7ed
> +#define CSR_PUSHMCAUSE 0x7ee
> +#define CSR_PUSHMEPC 0x7ef
> +#define CSR_PUSHMXSTATUS 0x7eb
> +
> +/* Andes Physical Memory Attribute(PMA) CSRs */
> +#define CSR_PMACFG0 0xbc0
> +#define CSR_PMACFG1 0xbc1
> +#define CSR_PMACFG2 0xbc2
> +#define CSR_PMACFG3 0xbc3
> +#define CSR_PMAADDR0 0xbd0
> +#define CSR_PMAADDR1 0xbd1
> +#define CSR_PMAADDR2 0xbd2
> +#define CSR_PMAADDR3 0xbd2
> +#define CSR_PMAADDR4 0xbd4
> +#define CSR_PMAADDR5 0xbd5
> +#define CSR_PMAADDR6 0xbd6
> +#define CSR_PMAADDR7 0xbd7
> +#define CSR_PMAADDR8 0xbd8
> +#define CSR_PMAADDR9 0xbd9
> +#define CSR_PMAADDR10 0xbda
> +#define CSR_PMAADDR11 0xbdb
> +#define CSR_PMAADDR12 0xbdc
> +#define CSR_PMAADDR13 0xbdd
> +#define CSR_PMAADDR14 0xbde
> +#define CSR_PMAADDR15 0xbdf
> +
> +/* ========= AndeStar V5 supervisor mode CSRs ========= */
> +/* Supervisor trap registers */
> +#define CSR_SLIE 0x9c4
> +#define CSR_SLIP 0x9c5
> +#define CSR_SDCAUSE 0x9c9
> +
> +/* Supervisor counter registers */
> +#define CSR_SCOUNTERINTEN 0x9cf
> +#define CSR_SCOUNTERMASK_M 0x9d1
> +#define CSR_SCOUNTERMASK_S 0x9d2
> +#define CSR_SCOUNTERMASK_U 0x9d3
> +#define CSR_SCOUNTEROVF 0x9d4
> +#define CSR_SCOUNTINHIBIT 0x9e0
> +#define CSR_SHPMEVENT3 0x9e3
> +#define CSR_SHPMEVENT4 0x9e4
> +#define CSR_SHPMEVENT5 0x9e5
> +#define CSR_SHPMEVENT6 0x9e6
> +
> +/* Supervisor control registers */
> +#define CSR_SCCTLDATA 0x9cd
> +#define CSR_SMISC_CTL 0x9d0
> +
> +#endif /* !defined(CONFIG_USER_ONLY) */
> +
> +/* ========= AndeStar V5 user mode CSRs ========= */
> +/* User mode control registers */
> +#define CSR_UITB 0x800
> +#define CSR_UCODE 0x801
> +#define CSR_UDCAUSE 0x809
> +#define CSR_UCCTLBEGINADDR 0x80b
> +#define CSR_UCCTLCOMMAND 0x80c
> +#define CSR_WFE 0x810
> +#define CSR_SLEEPVALUE 0x811
> +#define CSR_TXEVT 0x812
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index a72fd32f01..fe63e68b8e 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -192,6 +192,8 @@ static void ax25_cpu_init(Object *obj)
> CPURISCVState *env = &RISCV_CPU(obj)->env;
> set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> set_priv_version(env, PRIV_VERSION_1_10_0);
> + setup_custom_csr(env, andes_custom_csr_table);
> + env->custom_csr_val = g_malloc(andes_custom_csr_size);
> }
>
> static void rv64_sifive_u_cpu_init(Object *obj)
> @@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
> CPURISCVState *env = &RISCV_CPU(obj)->env;
> set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> set_priv_version(env, PRIV_VERSION_1_10_0);
> + setup_custom_csr(env, andes_custom_csr_table);
> + env->custom_csr_val = g_malloc(andes_custom_csr_size);
> }
> #endif
>
> diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> new file mode 100644
> index 0000000000..8617f40483
> --- /dev/null
> +++ b/target/riscv/csr_andes.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Andes custom CSR table and handling functions
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "cpu.h"
> +#include "qemu/main-loop.h"
> +#include "exec/exec-all.h"
> +#include "andes_cpu_bits.h"
> +
> +struct andes_csr_val {
> + target_long uitb;
> +};
> +
> +#if !defined(CONFIG_USER_ONLY)
> +static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + /* enable pma probe */
> + *val = 0x40000000;
> + return RISCV_EXCP_NONE;
> +}
> +#endif
> +
> +static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + struct andes_csr_val *andes_csr = env->custom_csr_val;
> + andes_csr->uitb = val;
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + struct andes_csr_val *andes_csr = env->custom_csr_val;
> + *val = andes_csr->uitb;
> + return RISCV_EXCP_NONE;
> +}
> +
> +
> +static RISCVException any(CPURISCVState *env, int csrno)
> +{
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + *val = 0;
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + return RISCV_EXCP_NONE;
> +}
> +
> +int andes_custom_csr_size = sizeof(struct andes_csr_val);
I think just drop this value and use sizeof(struct andes_csr_val) in
the other places.
I haven't checked this against the Andes spec, but overall the series
looks good.
Alistair
> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> + /* ========= AndeStar V5 machine mode CSRs ========= */
> + #if !defined(CONFIG_USER_ONLY)
> + /* Configuration Registers */
> + {CSR_MICM_CFG, { "micm_cfg", any, read_zero, write_stub} },
> + {CSR_MDCM_CFG, { "mdcm_cfg", any, read_zero, write_stub} },
> + {CSR_MMSC_CFG, { "mmsc_cfg", any, read_mmsc_cfg, write_stub} },
> + {CSR_MMSC_CFG2, { "mmsc_cfg2", any, read_zero, write_stub} },
> + {CSR_MVEC_CFG, { "mvec_cfg", any, read_zero, write_stub} },
> +
> + /* Crash Debug CSRs */
> + {CSR_MCRASH_STATESAVE, { "mcrash_statesave", any, read_zero, write_stub} },
> + {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
> +
> + /* Memory CSRs */
> + {CSR_MILMB, { "milmb", any, read_zero, write_stub} },
> + {CSR_MDLMB, { "mdlmb", any, read_zero, write_stub} },
> + {CSR_MECC_CODE, { "mecc_code", any, read_zero, write_stub} },
> + {CSR_MNVEC, { "mnvec", any, read_zero, write_stub} },
> + {CSR_MCACHE_CTL, { "mcache_ctl", any, read_zero, write_stub} },
> + {CSR_MCCTLBEGINADDR, { "mcctlbeginaddr", any, read_zero, write_stub} },
> + {CSR_MCCTLCOMMAND, { "mcctlcommand", any, read_zero, write_stub} },
> + {CSR_MCCTLDATA, { "mcctldata", any, read_zero, write_stub} },
> + {CSR_MPPIB, { "mppib", any, read_zero, write_stub} },
> + {CSR_MFIOB, { "mfiob", any, read_zero, write_stub} },
> +
> + /* Hardware Stack Protection & Recording */
> + {CSR_MHSP_CTL, { "mhsp_ctl", any, read_zero, write_stub} },
> + {CSR_MSP_BOUND, { "msp_bound", any, read_zero, write_stub} },
> + {CSR_MSP_BASE, { "msp_base", any, read_zero, write_stub} },
> + {CSR_MXSTATUS, { "mxstatus", any, read_zero, write_stub} },
> + {CSR_MDCAUSE, { "mdcause", any, read_zero, write_stub} },
> + {CSR_MSLIDELEG, { "mslideleg", any, read_zero, write_stub} },
> + {CSR_MSAVESTATUS, { "msavestatus", any, read_zero, write_stub} },
> + {CSR_MSAVEEPC1, { "msaveepc1", any, read_zero, write_stub} },
> + {CSR_MSAVECAUSE1, { "msavecause1", any, read_zero, write_stub} },
> + {CSR_MSAVEEPC2, { "msaveepc2", any, read_zero, write_stub} },
> + {CSR_MSAVECAUSE2, { "msavecause2", any, read_zero, write_stub} },
> + {CSR_MSAVEDCAUSE1, { "msavedcause1", any, read_zero, write_stub} },
> + {CSR_MSAVEDCAUSE2, { "msavedcause2", any, read_zero, write_stub} },
> +
> + /* Control CSRs */
> + {CSR_MPFT_CTL, { "mpft_ctl", any, read_zero, write_stub} },
> + {CSR_MMISC_CTL, { "mmisc_ctl", any, read_zero, write_stub} },
> + {CSR_MCLK_CTL, { "mclk_ctl", any, read_zero, write_stub} },
> +
> + /* Counter related CSRs */
> + {CSR_MCOUNTERWEN, { "mcounterwen", any, read_zero, write_stub} },
> + {CSR_MCOUNTERINTEN, { "mcounterinten", any, read_zero, write_stub} },
> + {CSR_MCOUNTERMASK_M, { "mcountermask_m", any, read_zero, write_stub} },
> + {CSR_MCOUNTERMASK_S, { "mcountermask_s", any, read_zero, write_stub} },
> + {CSR_MCOUNTERMASK_U, { "mcountermask_u", any, read_zero, write_stub} },
> + {CSR_MCOUNTEROVF, { "mcounterovf", any, read_zero, write_stub} },
> +
> + /* Enhanced CLIC CSRs */
> + {CSR_MIRQ_ENTRY, { "mirq_entry", any, read_zero, write_stub} },
> + {CSR_MINTSEL_JAL, { "mintsel_jal", any, read_zero, write_stub} },
> + {CSR_PUSHMCAUSE, { "pushmcause", any, read_zero, write_stub} },
> + {CSR_PUSHMEPC, { "pushmepc", any, read_zero, write_stub} },
> + {CSR_PUSHMXSTATUS, { "pushmxstatus", any, read_zero, write_stub} },
> +
> + /* Andes Physical Memory Attribute(PMA) CSRs */
> + {CSR_PMACFG0, { "pmacfg0", any, read_zero, write_stub} },
> + {CSR_PMACFG1, { "pmacfg1", any, read_zero, write_stub} },
> + {CSR_PMACFG2, { "pmacfg2", any, read_zero, write_stub} },
> + {CSR_PMACFG3, { "pmacfg3", any, read_zero, write_stub} },
> + {CSR_PMAADDR0, { "pmaaddr0", any, read_zero, write_stub} },
> + {CSR_PMAADDR1, { "pmaaddr1", any, read_zero, write_stub} },
> + {CSR_PMAADDR2, { "pmaaddr2", any, read_zero, write_stub} },
> + {CSR_PMAADDR3, { "pmaaddr3", any, read_zero, write_stub} },
> + {CSR_PMAADDR4, { "pmaaddr4", any, read_zero, write_stub} },
> + {CSR_PMAADDR5, { "pmaaddr5", any, read_zero, write_stub} },
> + {CSR_PMAADDR6, { "pmaaddr6", any, read_zero, write_stub} },
> + {CSR_PMAADDR7, { "pmaaddr7", any, read_zero, write_stub} },
> + {CSR_PMAADDR8, { "pmaaddr8", any, read_zero, write_stub} },
> + {CSR_PMAADDR9, { "pmaaddr9", any, read_zero, write_stub} },
> + {CSR_PMAADDR10, { "pmaaddr10", any, read_zero, write_stub} },
> + {CSR_PMAADDR11, { "pmaaddr11", any, read_zero, write_stub} },
> + {CSR_PMAADDR12, { "pmaaddr12", any, read_zero, write_stub} },
> + {CSR_PMAADDR13, { "pmaaddr13", any, read_zero, write_stub} },
> + {CSR_PMAADDR14, { "pmaaddr14", any, read_zero, write_stub} },
> + {CSR_PMAADDR15, { "pmaaddr15", any, read_zero, write_stub} },
> +
> + /* Debug/Trace Registers (shared with Debug Mode) */
> + {CSR_TSELECT, { "tselect", any, read_zero, write_stub} },
> + {CSR_TDATA1, { "tdata1", any, read_zero, write_stub} },
> + {CSR_TDATA2, { "tdata2", any, read_zero, write_stub} },
> + {CSR_TDATA3, { "tdata3", any, read_zero, write_stub} },
> + {CSR_TINFO, { "tinfo", any, read_zero, write_stub} },
> +
> + /* ========= AndeStar V5 supervisor mode CSRs ========= */
> + /* Supervisor trap registers */
> + {CSR_SLIE, { "slie", any, read_zero, write_stub} },
> + {CSR_SLIP, { "slip", any, read_zero, write_stub} },
> + {CSR_SDCAUSE, { "sdcause", any, read_zero, write_stub} },
> +
> + /* Supervisor counter registers */
> + {CSR_SCOUNTERINTEN, { "scounterinten", any, read_zero, write_stub} },
> + {CSR_SCOUNTERMASK_M, { "scountermask_m", any, read_zero, write_stub} },
> + {CSR_SCOUNTERMASK_S, { "scountermask_s", any, read_zero, write_stub} },
> + {CSR_SCOUNTERMASK_U, { "scountermask_u", any, read_zero, write_stub} },
> + {CSR_SCOUNTEROVF, { "scounterovf", any, read_zero, write_stub} },
> + {CSR_SCOUNTINHIBIT, { "scountinhibit", any, read_zero, write_stub} },
> + {CSR_SHPMEVENT3, { "shpmevent3", any, read_zero, write_stub} },
> + {CSR_SHPMEVENT4, { "shpmevent4", any, read_zero, write_stub} },
> + {CSR_SHPMEVENT5, { "shpmevent5", any, read_zero, write_stub} },
> + {CSR_SHPMEVENT6, { "shpmevent6", any, read_zero, write_stub} },
> +
> + /* Supervisor control registers */
> + {CSR_SCCTLDATA, { "scctldata", any, read_zero, write_stub} },
> + {CSR_SMISC_CTL, { "smisc_ctl", any, read_zero, write_stub} },
> + #endif
> +
> + /* ========= AndeStar V5 user mode CSRs ========= */
> + /* User mode control registers */
> + {CSR_UITB, { "uitb", any, read_uitb, write_uitb} },
> + {CSR_UCODE, { "ucode", any, read_zero, write_stub} },
> + {CSR_UDCAUSE, { "udcause", any, read_zero, write_stub} },
> + {CSR_UCCTLBEGINADDR, { "ucctlbeginaddr", any, read_zero, write_stub} },
> + {CSR_UCCTLCOMMAND, { "ucctlcommand", any, read_zero, write_stub} },
> + {CSR_WFE, { "wfe", any, read_zero, write_stub} },
> + {CSR_SLEEPVALUE, { "sleepvalue", any, read_zero, write_stub} },
> + {CSR_TXEVT, { "csr_txevt", any, read_zero, write_stub} },
> + {0, { "", NULL, NULL, NULL } },
> + };
> diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> index 4dbf8cf1fd..b09083585b 100644
> --- a/target/riscv/custom_csr_defs.h
> +++ b/target/riscv/custom_csr_defs.h
> @@ -4,4 +4,5 @@
> * Custom CSR variables provided by <cpu_model_name>_csr.c
> */
>
> -/* Left blank purposely in this commit. */
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
> +extern int andes_custom_csr_size;
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index d5e0bc93ea..5c87672ff9 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -9,6 +9,7 @@ gen = [
> riscv_ss = ss.source_set()
> riscv_ss.add(gen)
> riscv_ss.add(files(
> + 'csr_andes.c',
> 'cpu.c',
> 'cpu_helper.c',
> 'csr.c',
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
@ 2021-10-21 22:44 ` Alistair Francis
0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:44 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai
Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
Dylan Jhong
On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Add CSR bits definitions, CSR table and handler functions for Andes
> AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> ---
> target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
> target/riscv/cpu.c | 4 +
> target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
> target/riscv/custom_csr_defs.h | 3 +-
> target/riscv/meson.build | 1 +
> 5 files changed, 319 insertions(+), 1 deletion(-)
> create mode 100644 target/riscv/andes_cpu_bits.h
> create mode 100644 target/riscv/csr_andes.c
>
> diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> new file mode 100644
> index 0000000000..84b0900423
> --- /dev/null
> +++ b/target/riscv/andes_cpu_bits.h
> @@ -0,0 +1,129 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0+
> + *
> + * Andes custom CSRs bit definitions
> + *
> + */
> +
> +/*
> + * ========= Missing drafted/standard CSR definitions =========
> + * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
> + */
> +#define CSR_TINFO 0x7a4
> +
> +#if !defined(CONFIG_USER_ONLY)
> +/* ========= AndeStar V5 machine mode CSRs ========= */
> +/* Configuration Registers */
> +#define CSR_MICM_CFG 0xfc0
> +#define CSR_MDCM_CFG 0xfc1
> +#define CSR_MMSC_CFG 0xfc2
> +#define CSR_MMSC_CFG2 0xfc3
> +#define CSR_MVEC_CFG 0xfc7
> +
> +/* Crash Debug CSRs */
> +#define CSR_MCRASH_STATESAVE 0xfc8
> +#define CSR_MSTATUS_CRASHSAVE 0xfc9
> +
> +/* Memory CSRs */
> +#define CSR_MILMB 0x7c0
> +#define CSR_MDLMB 0x7c1
> +#define CSR_MECC_CODE 0x7C2
> +#define CSR_MNVEC 0x7c3
> +#define CSR_MCACHE_CTL 0x7ca
> +#define CSR_MCCTLBEGINADDR 0x7cb
> +#define CSR_MCCTLCOMMAND 0x7cc
> +#define CSR_MCCTLDATA 0x7cd
> +#define CSR_MPPIB 0x7f0
> +#define CSR_MFIOB 0x7f1
> +
> +/* Hardware Stack Protection & Recording */
> +#define CSR_MHSP_CTL 0x7c6
> +#define CSR_MSP_BOUND 0x7c7
> +#define CSR_MSP_BASE 0x7c8
> +#define CSR_MXSTATUS 0x7c4
> +#define CSR_MDCAUSE 0x7c9
> +#define CSR_MSLIDELEG 0x7d5
> +#define CSR_MSAVESTATUS 0x7d6
> +#define CSR_MSAVEEPC1 0x7d7
> +#define CSR_MSAVECAUSE1 0x7d8
> +#define CSR_MSAVEEPC2 0x7d9
> +#define CSR_MSAVECAUSE2 0x7da
> +#define CSR_MSAVEDCAUSE1 0x7db
> +#define CSR_MSAVEDCAUSE2 0x7dc
> +
> +/* Control CSRs */
> +#define CSR_MPFT_CTL 0x7c5
> +#define CSR_MMISC_CTL 0x7d0
> +#define CSR_MCLK_CTL 0x7df
> +
> +/* Counter related CSRs */
> +#define CSR_MCOUNTERWEN 0x7ce
> +#define CSR_MCOUNTERINTEN 0x7cf
> +#define CSR_MCOUNTERMASK_M 0x7d1
> +#define CSR_MCOUNTERMASK_S 0x7d2
> +#define CSR_MCOUNTERMASK_U 0x7d3
> +#define CSR_MCOUNTEROVF 0x7d4
> +
> +/* Enhanced CLIC CSRs */
> +#define CSR_MIRQ_ENTRY 0x7ec
> +#define CSR_MINTSEL_JAL 0x7ed
> +#define CSR_PUSHMCAUSE 0x7ee
> +#define CSR_PUSHMEPC 0x7ef
> +#define CSR_PUSHMXSTATUS 0x7eb
> +
> +/* Andes Physical Memory Attribute(PMA) CSRs */
> +#define CSR_PMACFG0 0xbc0
> +#define CSR_PMACFG1 0xbc1
> +#define CSR_PMACFG2 0xbc2
> +#define CSR_PMACFG3 0xbc3
> +#define CSR_PMAADDR0 0xbd0
> +#define CSR_PMAADDR1 0xbd1
> +#define CSR_PMAADDR2 0xbd2
> +#define CSR_PMAADDR3 0xbd2
> +#define CSR_PMAADDR4 0xbd4
> +#define CSR_PMAADDR5 0xbd5
> +#define CSR_PMAADDR6 0xbd6
> +#define CSR_PMAADDR7 0xbd7
> +#define CSR_PMAADDR8 0xbd8
> +#define CSR_PMAADDR9 0xbd9
> +#define CSR_PMAADDR10 0xbda
> +#define CSR_PMAADDR11 0xbdb
> +#define CSR_PMAADDR12 0xbdc
> +#define CSR_PMAADDR13 0xbdd
> +#define CSR_PMAADDR14 0xbde
> +#define CSR_PMAADDR15 0xbdf
> +
> +/* ========= AndeStar V5 supervisor mode CSRs ========= */
> +/* Supervisor trap registers */
> +#define CSR_SLIE 0x9c4
> +#define CSR_SLIP 0x9c5
> +#define CSR_SDCAUSE 0x9c9
> +
> +/* Supervisor counter registers */
> +#define CSR_SCOUNTERINTEN 0x9cf
> +#define CSR_SCOUNTERMASK_M 0x9d1
> +#define CSR_SCOUNTERMASK_S 0x9d2
> +#define CSR_SCOUNTERMASK_U 0x9d3
> +#define CSR_SCOUNTEROVF 0x9d4
> +#define CSR_SCOUNTINHIBIT 0x9e0
> +#define CSR_SHPMEVENT3 0x9e3
> +#define CSR_SHPMEVENT4 0x9e4
> +#define CSR_SHPMEVENT5 0x9e5
> +#define CSR_SHPMEVENT6 0x9e6
> +
> +/* Supervisor control registers */
> +#define CSR_SCCTLDATA 0x9cd
> +#define CSR_SMISC_CTL 0x9d0
> +
> +#endif /* !defined(CONFIG_USER_ONLY) */
> +
> +/* ========= AndeStar V5 user mode CSRs ========= */
> +/* User mode control registers */
> +#define CSR_UITB 0x800
> +#define CSR_UCODE 0x801
> +#define CSR_UDCAUSE 0x809
> +#define CSR_UCCTLBEGINADDR 0x80b
> +#define CSR_UCCTLCOMMAND 0x80c
> +#define CSR_WFE 0x810
> +#define CSR_SLEEPVALUE 0x811
> +#define CSR_TXEVT 0x812
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index a72fd32f01..fe63e68b8e 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -192,6 +192,8 @@ static void ax25_cpu_init(Object *obj)
> CPURISCVState *env = &RISCV_CPU(obj)->env;
> set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> set_priv_version(env, PRIV_VERSION_1_10_0);
> + setup_custom_csr(env, andes_custom_csr_table);
> + env->custom_csr_val = g_malloc(andes_custom_csr_size);
> }
>
> static void rv64_sifive_u_cpu_init(Object *obj)
> @@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
> CPURISCVState *env = &RISCV_CPU(obj)->env;
> set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> set_priv_version(env, PRIV_VERSION_1_10_0);
> + setup_custom_csr(env, andes_custom_csr_table);
> + env->custom_csr_val = g_malloc(andes_custom_csr_size);
> }
> #endif
>
> diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> new file mode 100644
> index 0000000000..8617f40483
> --- /dev/null
> +++ b/target/riscv/csr_andes.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Andes custom CSR table and handling functions
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "cpu.h"
> +#include "qemu/main-loop.h"
> +#include "exec/exec-all.h"
> +#include "andes_cpu_bits.h"
> +
> +struct andes_csr_val {
> + target_long uitb;
> +};
> +
> +#if !defined(CONFIG_USER_ONLY)
> +static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + /* enable pma probe */
> + *val = 0x40000000;
> + return RISCV_EXCP_NONE;
> +}
> +#endif
> +
> +static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + struct andes_csr_val *andes_csr = env->custom_csr_val;
> + andes_csr->uitb = val;
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + struct andes_csr_val *andes_csr = env->custom_csr_val;
> + *val = andes_csr->uitb;
> + return RISCV_EXCP_NONE;
> +}
> +
> +
> +static RISCVException any(CPURISCVState *env, int csrno)
> +{
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> +{
> + *val = 0;
> + return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
> +{
> + return RISCV_EXCP_NONE;
> +}
> +
> +int andes_custom_csr_size = sizeof(struct andes_csr_val);
I think just drop this value and use sizeof(struct andes_csr_val) in
the other places.
I haven't checked this against the Andes spec, but overall the series
looks good.
Alistair
> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> + /* ========= AndeStar V5 machine mode CSRs ========= */
> + #if !defined(CONFIG_USER_ONLY)
> + /* Configuration Registers */
> + {CSR_MICM_CFG, { "micm_cfg", any, read_zero, write_stub} },
> + {CSR_MDCM_CFG, { "mdcm_cfg", any, read_zero, write_stub} },
> + {CSR_MMSC_CFG, { "mmsc_cfg", any, read_mmsc_cfg, write_stub} },
> + {CSR_MMSC_CFG2, { "mmsc_cfg2", any, read_zero, write_stub} },
> + {CSR_MVEC_CFG, { "mvec_cfg", any, read_zero, write_stub} },
> +
> + /* Crash Debug CSRs */
> + {CSR_MCRASH_STATESAVE, { "mcrash_statesave", any, read_zero, write_stub} },
> + {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
> +
> + /* Memory CSRs */
> + {CSR_MILMB, { "milmb", any, read_zero, write_stub} },
> + {CSR_MDLMB, { "mdlmb", any, read_zero, write_stub} },
> + {CSR_MECC_CODE, { "mecc_code", any, read_zero, write_stub} },
> + {CSR_MNVEC, { "mnvec", any, read_zero, write_stub} },
> + {CSR_MCACHE_CTL, { "mcache_ctl", any, read_zero, write_stub} },
> + {CSR_MCCTLBEGINADDR, { "mcctlbeginaddr", any, read_zero, write_stub} },
> + {CSR_MCCTLCOMMAND, { "mcctlcommand", any, read_zero, write_stub} },
> + {CSR_MCCTLDATA, { "mcctldata", any, read_zero, write_stub} },
> + {CSR_MPPIB, { "mppib", any, read_zero, write_stub} },
> + {CSR_MFIOB, { "mfiob", any, read_zero, write_stub} },
> +
> + /* Hardware Stack Protection & Recording */
> + {CSR_MHSP_CTL, { "mhsp_ctl", any, read_zero, write_stub} },
> + {CSR_MSP_BOUND, { "msp_bound", any, read_zero, write_stub} },
> + {CSR_MSP_BASE, { "msp_base", any, read_zero, write_stub} },
> + {CSR_MXSTATUS, { "mxstatus", any, read_zero, write_stub} },
> + {CSR_MDCAUSE, { "mdcause", any, read_zero, write_stub} },
> + {CSR_MSLIDELEG, { "mslideleg", any, read_zero, write_stub} },
> + {CSR_MSAVESTATUS, { "msavestatus", any, read_zero, write_stub} },
> + {CSR_MSAVEEPC1, { "msaveepc1", any, read_zero, write_stub} },
> + {CSR_MSAVECAUSE1, { "msavecause1", any, read_zero, write_stub} },
> + {CSR_MSAVEEPC2, { "msaveepc2", any, read_zero, write_stub} },
> + {CSR_MSAVECAUSE2, { "msavecause2", any, read_zero, write_stub} },
> + {CSR_MSAVEDCAUSE1, { "msavedcause1", any, read_zero, write_stub} },
> + {CSR_MSAVEDCAUSE2, { "msavedcause2", any, read_zero, write_stub} },
> +
> + /* Control CSRs */
> + {CSR_MPFT_CTL, { "mpft_ctl", any, read_zero, write_stub} },
> + {CSR_MMISC_CTL, { "mmisc_ctl", any, read_zero, write_stub} },
> + {CSR_MCLK_CTL, { "mclk_ctl", any, read_zero, write_stub} },
> +
> + /* Counter related CSRs */
> + {CSR_MCOUNTERWEN, { "mcounterwen", any, read_zero, write_stub} },
> + {CSR_MCOUNTERINTEN, { "mcounterinten", any, read_zero, write_stub} },
> + {CSR_MCOUNTERMASK_M, { "mcountermask_m", any, read_zero, write_stub} },
> + {CSR_MCOUNTERMASK_S, { "mcountermask_s", any, read_zero, write_stub} },
> + {CSR_MCOUNTERMASK_U, { "mcountermask_u", any, read_zero, write_stub} },
> + {CSR_MCOUNTEROVF, { "mcounterovf", any, read_zero, write_stub} },
> +
> + /* Enhanced CLIC CSRs */
> + {CSR_MIRQ_ENTRY, { "mirq_entry", any, read_zero, write_stub} },
> + {CSR_MINTSEL_JAL, { "mintsel_jal", any, read_zero, write_stub} },
> + {CSR_PUSHMCAUSE, { "pushmcause", any, read_zero, write_stub} },
> + {CSR_PUSHMEPC, { "pushmepc", any, read_zero, write_stub} },
> + {CSR_PUSHMXSTATUS, { "pushmxstatus", any, read_zero, write_stub} },
> +
> + /* Andes Physical Memory Attribute(PMA) CSRs */
> + {CSR_PMACFG0, { "pmacfg0", any, read_zero, write_stub} },
> + {CSR_PMACFG1, { "pmacfg1", any, read_zero, write_stub} },
> + {CSR_PMACFG2, { "pmacfg2", any, read_zero, write_stub} },
> + {CSR_PMACFG3, { "pmacfg3", any, read_zero, write_stub} },
> + {CSR_PMAADDR0, { "pmaaddr0", any, read_zero, write_stub} },
> + {CSR_PMAADDR1, { "pmaaddr1", any, read_zero, write_stub} },
> + {CSR_PMAADDR2, { "pmaaddr2", any, read_zero, write_stub} },
> + {CSR_PMAADDR3, { "pmaaddr3", any, read_zero, write_stub} },
> + {CSR_PMAADDR4, { "pmaaddr4", any, read_zero, write_stub} },
> + {CSR_PMAADDR5, { "pmaaddr5", any, read_zero, write_stub} },
> + {CSR_PMAADDR6, { "pmaaddr6", any, read_zero, write_stub} },
> + {CSR_PMAADDR7, { "pmaaddr7", any, read_zero, write_stub} },
> + {CSR_PMAADDR8, { "pmaaddr8", any, read_zero, write_stub} },
> + {CSR_PMAADDR9, { "pmaaddr9", any, read_zero, write_stub} },
> + {CSR_PMAADDR10, { "pmaaddr10", any, read_zero, write_stub} },
> + {CSR_PMAADDR11, { "pmaaddr11", any, read_zero, write_stub} },
> + {CSR_PMAADDR12, { "pmaaddr12", any, read_zero, write_stub} },
> + {CSR_PMAADDR13, { "pmaaddr13", any, read_zero, write_stub} },
> + {CSR_PMAADDR14, { "pmaaddr14", any, read_zero, write_stub} },
> + {CSR_PMAADDR15, { "pmaaddr15", any, read_zero, write_stub} },
> +
> + /* Debug/Trace Registers (shared with Debug Mode) */
> + {CSR_TSELECT, { "tselect", any, read_zero, write_stub} },
> + {CSR_TDATA1, { "tdata1", any, read_zero, write_stub} },
> + {CSR_TDATA2, { "tdata2", any, read_zero, write_stub} },
> + {CSR_TDATA3, { "tdata3", any, read_zero, write_stub} },
> + {CSR_TINFO, { "tinfo", any, read_zero, write_stub} },
> +
> + /* ========= AndeStar V5 supervisor mode CSRs ========= */
> + /* Supervisor trap registers */
> + {CSR_SLIE, { "slie", any, read_zero, write_stub} },
> + {CSR_SLIP, { "slip", any, read_zero, write_stub} },
> + {CSR_SDCAUSE, { "sdcause", any, read_zero, write_stub} },
> +
> + /* Supervisor counter registers */
> + {CSR_SCOUNTERINTEN, { "scounterinten", any, read_zero, write_stub} },
> + {CSR_SCOUNTERMASK_M, { "scountermask_m", any, read_zero, write_stub} },
> + {CSR_SCOUNTERMASK_S, { "scountermask_s", any, read_zero, write_stub} },
> + {CSR_SCOUNTERMASK_U, { "scountermask_u", any, read_zero, write_stub} },
> + {CSR_SCOUNTEROVF, { "scounterovf", any, read_zero, write_stub} },
> + {CSR_SCOUNTINHIBIT, { "scountinhibit", any, read_zero, write_stub} },
> + {CSR_SHPMEVENT3, { "shpmevent3", any, read_zero, write_stub} },
> + {CSR_SHPMEVENT4, { "shpmevent4", any, read_zero, write_stub} },
> + {CSR_SHPMEVENT5, { "shpmevent5", any, read_zero, write_stub} },
> + {CSR_SHPMEVENT6, { "shpmevent6", any, read_zero, write_stub} },
> +
> + /* Supervisor control registers */
> + {CSR_SCCTLDATA, { "scctldata", any, read_zero, write_stub} },
> + {CSR_SMISC_CTL, { "smisc_ctl", any, read_zero, write_stub} },
> + #endif
> +
> + /* ========= AndeStar V5 user mode CSRs ========= */
> + /* User mode control registers */
> + {CSR_UITB, { "uitb", any, read_uitb, write_uitb} },
> + {CSR_UCODE, { "ucode", any, read_zero, write_stub} },
> + {CSR_UDCAUSE, { "udcause", any, read_zero, write_stub} },
> + {CSR_UCCTLBEGINADDR, { "ucctlbeginaddr", any, read_zero, write_stub} },
> + {CSR_UCCTLCOMMAND, { "ucctlcommand", any, read_zero, write_stub} },
> + {CSR_WFE, { "wfe", any, read_zero, write_stub} },
> + {CSR_SLEEPVALUE, { "sleepvalue", any, read_zero, write_stub} },
> + {CSR_TXEVT, { "csr_txevt", any, read_zero, write_stub} },
> + {0, { "", NULL, NULL, NULL } },
> + };
> diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> index 4dbf8cf1fd..b09083585b 100644
> --- a/target/riscv/custom_csr_defs.h
> +++ b/target/riscv/custom_csr_defs.h
> @@ -4,4 +4,5 @@
> * Custom CSR variables provided by <cpu_model_name>_csr.c
> */
>
> -/* Left blank purposely in this commit. */
> +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
> +extern int andes_custom_csr_size;
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index d5e0bc93ea..5c87672ff9 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -9,6 +9,7 @@ gen = [
> riscv_ss = ss.source_set()
> riscv_ss.add(gen)
> riscv_ss.add(files(
> + 'csr_andes.c',
> 'cpu.c',
> 'cpu_helper.c',
> 'csr.c',
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-21 22:47 ` Alistair Francis
-1 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:47 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai
Cc: ycliang, Alan Quey-Liang Kao((((((((((),
wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
open list:RISC-V, Bin Meng
On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Hi Alistair, Bin and all :
>
> Sorry for bumping this stale topic.
> As our last discussion, I have removed Kconfigs and meson options.
> The custom CSR logic is in-built by default and whether a custom CSR
> is presented on the accessing hart will be checked at runtime.
No worries!
This looks great! I had a look through this and I think we are almost
there. I left a few comments, but otherwise I think we are close.
Let's see if anyone else has any comments. Otherwise can you run
checkpatch on each patch and then send a PATCH series (not an RFC) in
a week or so and we can go from there.
>
> Changes from V4 :
> Remove Kconfigs and meson options.
> Make custom CSR handling logic self-contained.
> Use g_hash_table_new instead of g_hash_table_new_full.
>
> The performance slowdown could be easily tested with a simple program
> running on linux-user mode :
>
> /* test_csr.c */
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/time.h>
>
> int main (int ac, char *av[]) {
> struct timeval start;
> struct timeval end;
> gettimeofday(&start,NULL);
> unsigned int loop_n = 999999 ;
> unsigned char i;
> unsigned char o;
> do {
> for(i=0; i<32; i++) {
> #if defined(FCSR)
> __asm__("csrw fcsr, %0;"::"r"(i));
> __asm__("csrr %0, fcsr;":"=r"(o));
> #elif defined(UITB)
> __asm__("csrw 0x800, %0;"::"r"(i));
> __asm__("csrr %0, 0x800;":"=r"(o));
> #endif
> }
> --loop_n;
> } while (loop_n > 0);
> gettimeofday(&end,NULL);
> unsigned long diff = 1000000 *
> (end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec;
> printf("%f\n", (double)(diff)/1000000);
> return 0;
> }
>
> $ riscv64-linux-gnu-gcc -static -DUITB ./test_csr.c -o ./u
> $ riscv64-linux-gnu-gcc -static -DFCSR ./test_csr.c -o ./f
> $ qemu-riscv64 ./{u,f}
Do you have the results?
Alistair
>
> Cordially yours,
> Ruinland Chuan-Tzu Tsai
>
> Ruinland Chuan-Tzu Tsai (3):
> riscv: Adding Andes A25 and AX25 cpu models
> riscv: Introduce custom CSR hooks to riscv_csrrw()
> riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
>
> target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
> target/riscv/cpu.c | 39 +++++++
> target/riscv/cpu.h | 15 ++-
> target/riscv/csr.c | 38 +++++--
> target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
> target/riscv/custom_csr_defs.h | 8 ++
> target/riscv/meson.build | 1 +
> 7 files changed, 404 insertions(+), 9 deletions(-)
> create mode 100644 target/riscv/andes_cpu_bits.h
> create mode 100644 target/riscv/csr_andes.c
> create mode 100644 target/riscv/custom_csr_defs.h
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support
@ 2021-10-21 22:47 ` Alistair Francis
0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2021-10-21 22:47 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai
Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
Dylan Jhong
On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
<ruinland@andestech.com> wrote:
>
> Hi Alistair, Bin and all :
>
> Sorry for bumping this stale topic.
> As our last discussion, I have removed Kconfigs and meson options.
> The custom CSR logic is in-built by default and whether a custom CSR
> is presented on the accessing hart will be checked at runtime.
No worries!
This looks great! I had a look through this and I think we are almost
there. I left a few comments, but otherwise I think we are close.
Let's see if anyone else has any comments. Otherwise can you run
checkpatch on each patch and then send a PATCH series (not an RFC) in
a week or so and we can go from there.
>
> Changes from V4 :
> Remove Kconfigs and meson options.
> Make custom CSR handling logic self-contained.
> Use g_hash_table_new instead of g_hash_table_new_full.
>
> The performance slowdown could be easily tested with a simple program
> running on linux-user mode :
>
> /* test_csr.c */
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/time.h>
>
> int main (int ac, char *av[]) {
> struct timeval start;
> struct timeval end;
> gettimeofday(&start,NULL);
> unsigned int loop_n = 999999 ;
> unsigned char i;
> unsigned char o;
> do {
> for(i=0; i<32; i++) {
> #if defined(FCSR)
> __asm__("csrw fcsr, %0;"::"r"(i));
> __asm__("csrr %0, fcsr;":"=r"(o));
> #elif defined(UITB)
> __asm__("csrw 0x800, %0;"::"r"(i));
> __asm__("csrr %0, 0x800;":"=r"(o));
> #endif
> }
> --loop_n;
> } while (loop_n > 0);
> gettimeofday(&end,NULL);
> unsigned long diff = 1000000 *
> (end.tv_sec-start.tv_sec)+end.tv_usec-start.tv_usec;
> printf("%f\n", (double)(diff)/1000000);
> return 0;
> }
>
> $ riscv64-linux-gnu-gcc -static -DUITB ./test_csr.c -o ./u
> $ riscv64-linux-gnu-gcc -static -DFCSR ./test_csr.c -o ./f
> $ qemu-riscv64 ./{u,f}
Do you have the results?
Alistair
>
> Cordially yours,
> Ruinland Chuan-Tzu Tsai
>
> Ruinland Chuan-Tzu Tsai (3):
> riscv: Adding Andes A25 and AX25 cpu models
> riscv: Introduce custom CSR hooks to riscv_csrrw()
> riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
>
> target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
> target/riscv/cpu.c | 39 +++++++
> target/riscv/cpu.h | 15 ++-
> target/riscv/csr.c | 38 +++++--
> target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
> target/riscv/custom_csr_defs.h | 8 ++
> target/riscv/meson.build | 1 +
> 7 files changed, 404 insertions(+), 9 deletions(-)
> create mode 100644 target/riscv/andes_cpu_bits.h
> create mode 100644 target/riscv/csr_andes.c
> create mode 100644 target/riscv/custom_csr_defs.h
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-22 0:08 ` Richard Henderson
-1 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22 0:08 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai, alistair23, wangjunqiang, bmeng.cn
Cc: qemu-riscv, dylan, ycliang, qemu-devel, alankao
On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> riscv_csrrw() will be called by CSR handling helpers, which is the
> most suitable place for checking wheter a custom CSR is being accessed.
>
> If we're touching a custom CSR, invoke the registered handlers.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> ---
> target/riscv/cpu.c | 19 +++++++++++++++++
> target/riscv/cpu.h | 13 +++++++++++-
> target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
> target/riscv/custom_csr_defs.h | 7 +++++++
> 4 files changed, 68 insertions(+), 9 deletions(-)
> create mode 100644 target/riscv/custom_csr_defs.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0c93b7edd7..a72fd32f01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -34,6 +34,9 @@
>
> static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>
> +GHashTable *custom_csr_map = NULL;
Leftover from a previous revision?
> +#include "custom_csr_defs.h"
I think that the few declarations that are required can just go in internals.h.
> +
> const char * const riscv_int_regnames[] = {
> "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
> "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
> @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> #endif
> }
>
> +static void setup_custom_csr(CPURISCVState *env,
> + riscv_custom_csr_operations csr_map_struct[])
Why is this static? Surely it needs to be called from csr_andes.c, etc?
Oh, I see that in the next patch you call this directly from ax25_cpu_init.
I think the split of declarations is less than ideal. See below.
> +{
> + int i;
> + env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> + for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
Having a hard maximum seems a mistake. You should pass in the array size...
> + if (csr_map_struct[i].csrno != 0) {
> + g_hash_table_insert(env->custom_csr_map,
> + GINT_TO_POINTER(csr_map_struct[i].csrno),
> + &csr_map_struct[i].csr_opset);
> + } else {
> + break;
> + }
... which would also allow you to remove the terminator in the data, and the check here.
> @@ -245,6 +245,11 @@ struct CPURISCVState {
>
> /* Fields from here on are preserved across CPU reset. */
> QEMUTimer *timer; /* Internal timer */
> +
> + /* Custom CSR opset table per hart */
> + GHashTable *custom_csr_map;
I think placing this in the CPURISCVState is incorrect. A much better place would be on
the RISCVCPUClass, so that there is exactly one copy of this per cpu type, i.e. all
A25/AX25 cpus would share the same table.
You would of course need to hook class_init, which the current definition of DEFINE_CPU
does not allow. But that's easy to fix.
> + /* Custom CSR value holder per hart */
> + void *custom_csr_val;
> };
Value singular? Anyhow, I think that it's a mistake trying to hide the value structure in
another file. It complicates allocation of the CPURISCVState, and you have no mechanism
by which to migrate the csr values.
I think you should simply place your structure here in CPURISCVState.
> +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> +{
> + gpointer ret;
> + ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> + return ret;
> +}
Fix the return type; the csr is not gpointer.
It would be better to put the map not null test here.
I think it would be even better to name this find_csr,
and include the normal index of csr_ops[] if the map
test fails.
> @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> return RISCV_EXCP_ILLEGAL_INST;
> }
>
> + /* try to handle_custom_csr */
> + if (unlikely(env->custom_csr_map != NULL)) {
> + riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> + find_custom_csr(env, csrno);
> + if (custom_csr_opset != NULL) {
> + csr_op = custom_csr_opset;
> + } else {
> + csr_op = &csr_ops[csrno];
> + }
> + } else {
> + csr_op = &csr_ops[csrno];
> + }
As Alistair noted, run checkpatch.pl to find all of these indentation errors.
That said, a better structure here would be
csr_op = find_csr(env, csrno);
if (csr_op == NULL) {
return RISCV_EXCP_ILLEGAL_INST;
}
r~
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-22 0:08 ` Richard Henderson
0 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22 0:08 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai, alistair23, wangjunqiang, bmeng.cn
Cc: ycliang, alankao, dylan, qemu-devel, qemu-riscv
On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> riscv_csrrw() will be called by CSR handling helpers, which is the
> most suitable place for checking wheter a custom CSR is being accessed.
>
> If we're touching a custom CSR, invoke the registered handlers.
>
> Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> ---
> target/riscv/cpu.c | 19 +++++++++++++++++
> target/riscv/cpu.h | 13 +++++++++++-
> target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
> target/riscv/custom_csr_defs.h | 7 +++++++
> 4 files changed, 68 insertions(+), 9 deletions(-)
> create mode 100644 target/riscv/custom_csr_defs.h
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0c93b7edd7..a72fd32f01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -34,6 +34,9 @@
>
> static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>
> +GHashTable *custom_csr_map = NULL;
Leftover from a previous revision?
> +#include "custom_csr_defs.h"
I think that the few declarations that are required can just go in internals.h.
> +
> const char * const riscv_int_regnames[] = {
> "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
> "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
> @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> #endif
> }
>
> +static void setup_custom_csr(CPURISCVState *env,
> + riscv_custom_csr_operations csr_map_struct[])
Why is this static? Surely it needs to be called from csr_andes.c, etc?
Oh, I see that in the next patch you call this directly from ax25_cpu_init.
I think the split of declarations is less than ideal. See below.
> +{
> + int i;
> + env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> + for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
Having a hard maximum seems a mistake. You should pass in the array size...
> + if (csr_map_struct[i].csrno != 0) {
> + g_hash_table_insert(env->custom_csr_map,
> + GINT_TO_POINTER(csr_map_struct[i].csrno),
> + &csr_map_struct[i].csr_opset);
> + } else {
> + break;
> + }
... which would also allow you to remove the terminator in the data, and the check here.
> @@ -245,6 +245,11 @@ struct CPURISCVState {
>
> /* Fields from here on are preserved across CPU reset. */
> QEMUTimer *timer; /* Internal timer */
> +
> + /* Custom CSR opset table per hart */
> + GHashTable *custom_csr_map;
I think placing this in the CPURISCVState is incorrect. A much better place would be on
the RISCVCPUClass, so that there is exactly one copy of this per cpu type, i.e. all
A25/AX25 cpus would share the same table.
You would of course need to hook class_init, which the current definition of DEFINE_CPU
does not allow. But that's easy to fix.
> + /* Custom CSR value holder per hart */
> + void *custom_csr_val;
> };
Value singular? Anyhow, I think that it's a mistake trying to hide the value structure in
another file. It complicates allocation of the CPURISCVState, and you have no mechanism
by which to migrate the csr values.
I think you should simply place your structure here in CPURISCVState.
> +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> +{
> + gpointer ret;
> + ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> + return ret;
> +}
Fix the return type; the csr is not gpointer.
It would be better to put the map not null test here.
I think it would be even better to name this find_csr,
and include the normal index of csr_ops[] if the map
test fails.
> @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> return RISCV_EXCP_ILLEGAL_INST;
> }
>
> + /* try to handle_custom_csr */
> + if (unlikely(env->custom_csr_map != NULL)) {
> + riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> + find_custom_csr(env, csrno);
> + if (custom_csr_opset != NULL) {
> + csr_op = custom_csr_opset;
> + } else {
> + csr_op = &csr_ops[csrno];
> + }
> + } else {
> + csr_op = &csr_ops[csrno];
> + }
As Alistair noted, run checkpatch.pl to find all of these indentation errors.
That said, a better structure here would be
csr_op = find_csr(env, csrno);
if (csr_op == NULL) {
return RISCV_EXCP_ILLEGAL_INST;
}
r~
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
@ 2021-10-22 1:12 ` Richard Henderson
-1 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22 1:12 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai, alistair23, wangjunqiang, bmeng.cn
Cc: qemu-riscv, dylan, ycliang, qemu-devel, alankao
On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> new file mode 100644
> index 0000000000..8617f40483
> --- /dev/null
> +++ b/target/riscv/csr_andes.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Andes custom CSR table and handling functions
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "cpu.h"
> +#include "qemu/main-loop.h"
> +#include "exec/exec-all.h"
> +#include "andes_cpu_bits.h"
> +
> +struct andes_csr_val {
> + target_long uitb;
> +};
docs/devel/style.rst: Use a typedef and CamelCase.
And of course per review of patch 2, this needs to go elsewhere.
You need to add a subsection to machine.c to migrate this new state. With respect to the
custom instructions, I suggested adding an ext_andes field. I would expect these CSRs,
which go with those instructions, to use the same predicate.
> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
...
> + {CSR_TXEVT, { "csr_txevt", any, read_zero, write_stub} },
> + {0, { "", NULL, NULL, NULL } },
> + };
Indentation here.
I think you should not export the array itself, but instead
void andes_setup_custom_csrs(RISCVCPUClass *cc)
{
setup_custom_csrs(cc, andes_custom_csr_table,
ARRAY_SIZE(andes_custom_csr_table));
}
r~
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
@ 2021-10-22 1:12 ` Richard Henderson
0 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22 1:12 UTC (permalink / raw)
To: Ruinland Chuan-Tzu Tsai, alistair23, wangjunqiang, bmeng.cn
Cc: ycliang, alankao, dylan, qemu-devel, qemu-riscv
On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> new file mode 100644
> index 0000000000..8617f40483
> --- /dev/null
> +++ b/target/riscv/csr_andes.c
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright (c) 2021 Andes Technology Corp.
> + * SPDX-License-Identifier: GPL-2.0+
> + * Andes custom CSR table and handling functions
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "cpu.h"
> +#include "qemu/main-loop.h"
> +#include "exec/exec-all.h"
> +#include "andes_cpu_bits.h"
> +
> +struct andes_csr_val {
> + target_long uitb;
> +};
docs/devel/style.rst: Use a typedef and CamelCase.
And of course per review of patch 2, this needs to go elsewhere.
You need to add a subsection to machine.c to migrate this new state. With respect to the
custom instructions, I suggested adding an ext_andes field. I would expect these CSRs,
which go with those instructions, to use the same predicate.
> +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
...
> + {CSR_TXEVT, { "csr_txevt", any, read_zero, write_stub} },
> + {0, { "", NULL, NULL, NULL } },
> + };
Indentation here.
I think you should not export the array itself, but instead
void andes_setup_custom_csrs(RISCVCPUClass *cc)
{
setup_custom_csrs(cc, andes_custom_csr_table,
ARRAY_SIZE(andes_custom_csr_table));
}
r~
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
2021-10-22 0:08 ` Richard Henderson
@ 2021-10-22 8:34 ` Ruinland ChuanTzu Tsai
-1 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22 8:34 UTC (permalink / raw)
To: Richard Henderson
Cc: ycliang, qemu-riscv, alankao, wangjunqiang, dylan, qemu-devel,
alistair23, bmeng.cn
On Thu, Oct 21, 2021 at 05:08:09PM -0700, Richard Henderson wrote:
> On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> >
> > If we're touching a custom CSR, invoke the registered handlers.
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> > target/riscv/cpu.c | 19 +++++++++++++++++
> > target/riscv/cpu.h | 13 +++++++++++-
> > target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
> > target/riscv/custom_csr_defs.h | 7 +++++++
> > 4 files changed, 68 insertions(+), 9 deletions(-)
> > create mode 100644 target/riscv/custom_csr_defs.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> > static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> > +GHashTable *custom_csr_map = NULL;
>
> Leftover from a previous revision?
By default there's no custom_csr_map (pointing to NULL) and thus only the
custom CSR equipped CPU models will need to initialize that. Standard CPU will
pass the check of custom_csr_map in riscv_csrrw() by default.
>
> > +#include "custom_csr_defs.h"
>
> I think that the few declarations that are required can just go in internals.h.
Wilco.
>
> > +
> > const char * const riscv_int_regnames[] = {
> > "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
> > "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> > #endif
> > }
> > +static void setup_custom_csr(CPURISCVState *env,
> > + riscv_custom_csr_operations csr_map_struct[])
>
> Why is this static? Surely it needs to be called from csr_andes.c, etc?
> Oh, I see that in the next patch you call this directly from ax25_cpu_init.
>
> I think the split of declarations is less than ideal. See below.
>
> > +{
> > + int i;
> > + env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > + for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
>
> Having a hard maximum seems a mistake. You should pass in the array size...
>
> > + if (csr_map_struct[i].csrno != 0) {
> > + g_hash_table_insert(env->custom_csr_map,
> > + GINT_TO_POINTER(csr_map_struct[i].csrno),
> > + &csr_map_struct[i].csr_opset);
> > + } else {
> > + break;
> > + }
>
> ... which would also allow you to remove the terminator in the data, and the check here.
Wilco.
>
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> > /* Fields from here on are preserved across CPU reset. */
> > QEMUTimer *timer; /* Internal timer */
> > +
> > + /* Custom CSR opset table per hart */
> > + GHashTable *custom_csr_map;
>
> I think placing this in the CPURISCVState is incorrect. A much better place
> would be on the RISCVCPUClass, so that there is exactly one copy of this per
> cpu type, i.e. all A25/AX25 cpus would share the same table.
>
> You would of course need to hook class_init, which the current definition of
> DEFINE_CPU does not allow. But that's easy to fix.
>
> > + /* Custom CSR value holder per hart */
> > + void *custom_csr_val;
> > };
>
> Value singular? Anyhow, I think that it's a mistake trying to hide the
> value structure in another file. It complicates allocation of the
> CPURISCVState, and you have no mechanism by which to migrate the csr values.
What I'm trying to do here is to provide a hook for CSR value storage and let
it being set during CPU initilization. We have heterogeneous harts which
have different sets of CSRs.
>
> I think you should simply place your structure here in CPURISCVState.
>
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > + gpointer ret;
> > + ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > + return ret;
> > +}
>
> Fix the return type; the csr is not gpointer.
> It would be better to put the map not null test here.
>
> I think it would be even better to name this find_csr,
> and include the normal index of csr_ops[] if the map
> test fails.
Wilco.
>
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> > return RISCV_EXCP_ILLEGAL_INST;
> > }
> > + /* try to handle_custom_csr */
> > + if (unlikely(env->custom_csr_map != NULL)) {
> > + riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > + find_custom_csr(env, csrno);
> > + if (custom_csr_opset != NULL) {
> > + csr_op = custom_csr_opset;
> > + } else {
> > + csr_op = &csr_ops[csrno];
> > + }
> > + } else {
> > + csr_op = &csr_ops[csrno];
> > + }
>
> As Alistair noted, run checkpatch.pl to find all of these indentation errors.
>
> That said, a better structure here would be
>
> csr_op = find_csr(env, csrno);
> if (csr_op == NULL) {
> return RISCV_EXCP_ILLEGAL_INST;
> }
Thanks for the tips. Wilco.
>
>
> r~
Cordially yours,
Ruinland
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-22 8:34 ` Ruinland ChuanTzu Tsai
0 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22 8:34 UTC (permalink / raw)
To: Richard Henderson
Cc: alistair23, wangjunqiang, bmeng.cn, ycliang, alankao, dylan,
qemu-devel, qemu-riscv
On Thu, Oct 21, 2021 at 05:08:09PM -0700, Richard Henderson wrote:
> On 10/21/21 8:09 AM, Ruinland Chuan-Tzu Tsai wrote:
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> >
> > If we're touching a custom CSR, invoke the registered handlers.
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> > target/riscv/cpu.c | 19 +++++++++++++++++
> > target/riscv/cpu.h | 13 +++++++++++-
> > target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
> > target/riscv/custom_csr_defs.h | 7 +++++++
> > 4 files changed, 68 insertions(+), 9 deletions(-)
> > create mode 100644 target/riscv/custom_csr_defs.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> > static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> > +GHashTable *custom_csr_map = NULL;
>
> Leftover from a previous revision?
By default there's no custom_csr_map (pointing to NULL) and thus only the
custom CSR equipped CPU models will need to initialize that. Standard CPU will
pass the check of custom_csr_map in riscv_csrrw() by default.
>
> > +#include "custom_csr_defs.h"
>
> I think that the few declarations that are required can just go in internals.h.
Wilco.
>
> > +
> > const char * const riscv_int_regnames[] = {
> > "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
> > "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> > #endif
> > }
> > +static void setup_custom_csr(CPURISCVState *env,
> > + riscv_custom_csr_operations csr_map_struct[])
>
> Why is this static? Surely it needs to be called from csr_andes.c, etc?
> Oh, I see that in the next patch you call this directly from ax25_cpu_init.
>
> I think the split of declarations is less than ideal. See below.
>
> > +{
> > + int i;
> > + env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > + for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
>
> Having a hard maximum seems a mistake. You should pass in the array size...
>
> > + if (csr_map_struct[i].csrno != 0) {
> > + g_hash_table_insert(env->custom_csr_map,
> > + GINT_TO_POINTER(csr_map_struct[i].csrno),
> > + &csr_map_struct[i].csr_opset);
> > + } else {
> > + break;
> > + }
>
> ... which would also allow you to remove the terminator in the data, and the check here.
Wilco.
>
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> > /* Fields from here on are preserved across CPU reset. */
> > QEMUTimer *timer; /* Internal timer */
> > +
> > + /* Custom CSR opset table per hart */
> > + GHashTable *custom_csr_map;
>
> I think placing this in the CPURISCVState is incorrect. A much better place
> would be on the RISCVCPUClass, so that there is exactly one copy of this per
> cpu type, i.e. all A25/AX25 cpus would share the same table.
>
> You would of course need to hook class_init, which the current definition of
> DEFINE_CPU does not allow. But that's easy to fix.
>
> > + /* Custom CSR value holder per hart */
> > + void *custom_csr_val;
> > };
>
> Value singular? Anyhow, I think that it's a mistake trying to hide the
> value structure in another file. It complicates allocation of the
> CPURISCVState, and you have no mechanism by which to migrate the csr values.
What I'm trying to do here is to provide a hook for CSR value storage and let
it being set during CPU initilization. We have heterogeneous harts which
have different sets of CSRs.
>
> I think you should simply place your structure here in CPURISCVState.
>
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > + gpointer ret;
> > + ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > + return ret;
> > +}
>
> Fix the return type; the csr is not gpointer.
> It would be better to put the map not null test here.
>
> I think it would be even better to name this find_csr,
> and include the normal index of csr_ops[] if the map
> test fails.
Wilco.
>
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> > return RISCV_EXCP_ILLEGAL_INST;
> > }
> > + /* try to handle_custom_csr */
> > + if (unlikely(env->custom_csr_map != NULL)) {
> > + riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > + find_custom_csr(env, csrno);
> > + if (custom_csr_opset != NULL) {
> > + csr_op = custom_csr_opset;
> > + } else {
> > + csr_op = &csr_ops[csrno];
> > + }
> > + } else {
> > + csr_op = &csr_ops[csrno];
> > + }
>
> As Alistair noted, run checkpatch.pl to find all of these indentation errors.
>
> That said, a better structure here would be
>
> csr_op = find_csr(env, csrno);
> if (csr_op == NULL) {
> return RISCV_EXCP_ILLEGAL_INST;
> }
Thanks for the tips. Wilco.
>
>
> r~
Cordially yours,
Ruinland
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
2021-10-21 22:43 ` Alistair Francis
@ 2021-10-22 8:36 ` Ruinland ChuanTzu Tsai
-1 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22 8:36 UTC (permalink / raw)
To: Alistair Francis
Cc: ycliang, Alan Quey-Liang Kao((((((((((),
wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
open list:RISC-V, Bin Meng
On Fri, Oct 22, 2021 at 08:43:08AM +1000, Alistair Francis wrote:
> On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> >
> > If we're touching a custom CSR, invoke the registered handlers.
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
>
> Awesome! This looks really good :)
>
> > ---
> > target/riscv/cpu.c | 19 +++++++++++++++++
> > target/riscv/cpu.h | 13 +++++++++++-
> > target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
> > target/riscv/custom_csr_defs.h | 7 +++++++
> > 4 files changed, 68 insertions(+), 9 deletions(-)
> > create mode 100644 target/riscv/custom_csr_defs.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> >
> > static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> >
> > +GHashTable *custom_csr_map = NULL;
> > +#include "custom_csr_defs.h"
> > +
> > const char * const riscv_int_regnames[] = {
> > "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
> > "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> > #endif
> > }
> >
> > +static void setup_custom_csr(CPURISCVState *env,
> > + riscv_custom_csr_operations csr_map_struct[])
> > +{
> > + int i;
> > + env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > + for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> > + if (csr_map_struct[i].csrno != 0) {
> > + g_hash_table_insert(env->custom_csr_map,
> > + GINT_TO_POINTER(csr_map_struct[i].csrno),
> > + &csr_map_struct[i].csr_opset);
> > + } else {
> > + break;
> > + }
> > + }
> > +}
> > +
> > static void riscv_any_cpu_init(Object *obj)
> > {
> > CPURISCVState *env = &RISCV_CPU(obj)->env;
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 3bef0d1265..012be10d0a 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> >
> > /* Fields from here on are preserved across CPU reset. */
> > QEMUTimer *timer; /* Internal timer */
> > +
> > + /* Custom CSR opset table per hart */
> > + GHashTable *custom_csr_map;
> > + /* Custom CSR value holder per hart */
> > + void *custom_csr_val;
> > };
> >
> > OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> > @@ -496,9 +501,15 @@ typedef struct {
> > riscv_csr_op_fn op;
> > } riscv_csr_operations;
> >
> > +typedef struct {
> > + int csrno;
> > + riscv_csr_operations csr_opset;
> > +} riscv_custom_csr_operations;
> > +
> > /* CSR function table constants */
> > enum {
> > - CSR_TABLE_SIZE = 0x1000
> > + CSR_TABLE_SIZE = 0x1000,
> > + MAX_CUSTOM_CSR_NUM = 100
> > };
> >
> > /* CSR function table */
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 23fbbd3216..1048ee3b44 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
> >
> > #endif
> >
> > +/* Custom CSR related routines */
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > + gpointer ret;
> > + ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > + return ret;
>
> You can just return directly here, so:
>
> return g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
>
> Also, I think you need to run checkpatch.pl on this patch (you should
> run it on all patches).
Wilco.
Thanks for the tips.
And sorry for my negligence.
Cordially yours,
Ruinland
>
> Alistair
>
> > +}
> > +
> > /*
> > * riscv_csrrw - read and/or update control and status register
> > *
> > @@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> > RISCVException ret;
> > target_ulong old_value;
> > RISCVCPU *cpu = env_archcpu(env);
> > + riscv_csr_operations *csr_op;
> > int read_only = get_field(csrno, 0xC00) == 3;
> >
> > /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> > return RISCV_EXCP_ILLEGAL_INST;
> > }
> >
> > + /* try to handle_custom_csr */
> > + if (unlikely(env->custom_csr_map != NULL)) {
> > + riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > + find_custom_csr(env, csrno);
> > + if (custom_csr_opset != NULL) {
> > + csr_op = custom_csr_opset;
> > + } else {
> > + csr_op = &csr_ops[csrno];
> > + }
> > + } else {
> > + csr_op = &csr_ops[csrno];
> > + }
> > +
> > /* check predicate */
> > - if (!csr_ops[csrno].predicate) {
> > + if (!csr_op->predicate) {
> > return RISCV_EXCP_ILLEGAL_INST;
> > }
> > - ret = csr_ops[csrno].predicate(env, csrno);
> > + ret = csr_op->predicate(env, csrno);
> > if (ret != RISCV_EXCP_NONE) {
> > return ret;
> > }
> >
> > /* execute combined read/write operation if it exists */
> > - if (csr_ops[csrno].op) {
> > - return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> > + if (csr_op->op) {
> > + return csr_op->op(env, csrno, ret_value, new_value, write_mask);
> > }
> >
> > /* if no accessor exists then return failure */
> > - if (!csr_ops[csrno].read) {
> > + if (!csr_op->read) {
> > return RISCV_EXCP_ILLEGAL_INST;
> > }
> > /* read old value */
> > - ret = csr_ops[csrno].read(env, csrno, &old_value);
> > + ret = csr_op->read(env, csrno, &old_value);
> > if (ret != RISCV_EXCP_NONE) {
> > return ret;
> > }
> > @@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> > /* write value if writable and write mask set, otherwise drop writes */
> > if (write_mask) {
> > new_value = (old_value & ~write_mask) | (new_value & write_mask);
> > - if (csr_ops[csrno].write) {
> > - ret = csr_ops[csrno].write(env, csrno, new_value);
> > + if (csr_op->write) {
> > + ret = csr_op->write(env, csrno, new_value);
> > if (ret != RISCV_EXCP_NONE) {
> > return ret;
> > }
> > diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> > new file mode 100644
> > index 0000000000..4dbf8cf1fd
> > --- /dev/null
> > +++ b/target/riscv/custom_csr_defs.h
> > @@ -0,0 +1,7 @@
> > +/*
> > + * Copyright (c) 2021 Andes Technology Corp.
> > + * SPDX-License-Identifier: GPL-2.0+
> > + * Custom CSR variables provided by <cpu_model_name>_csr.c
> > + */
> > +
> > +/* Left blank purposely in this commit. */
> > --
> > 2.25.1
> >
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-22 8:36 ` Ruinland ChuanTzu Tsai
0 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22 8:36 UTC (permalink / raw)
To: Alistair Francis
Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
Dylan Jhong
On Fri, Oct 22, 2021 at 08:43:08AM +1000, Alistair Francis wrote:
> On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > riscv_csrrw() will be called by CSR handling helpers, which is the
> > most suitable place for checking wheter a custom CSR is being accessed.
> >
> > If we're touching a custom CSR, invoke the registered handlers.
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
>
> Awesome! This looks really good :)
>
> > ---
> > target/riscv/cpu.c | 19 +++++++++++++++++
> > target/riscv/cpu.h | 13 +++++++++++-
> > target/riscv/csr.c | 38 +++++++++++++++++++++++++++-------
> > target/riscv/custom_csr_defs.h | 7 +++++++
> > 4 files changed, 68 insertions(+), 9 deletions(-)
> > create mode 100644 target/riscv/custom_csr_defs.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 0c93b7edd7..a72fd32f01 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,9 @@
> >
> > static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> >
> > +GHashTable *custom_csr_map = NULL;
> > +#include "custom_csr_defs.h"
> > +
> > const char * const riscv_int_regnames[] = {
> > "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
> > "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
> > @@ -149,6 +152,22 @@ static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
> > #endif
> > }
> >
> > +static void setup_custom_csr(CPURISCVState *env,
> > + riscv_custom_csr_operations csr_map_struct[])
> > +{
> > + int i;
> > + env->custom_csr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
> > + for (i = 0; i < MAX_CUSTOM_CSR_NUM; i++) {
> > + if (csr_map_struct[i].csrno != 0) {
> > + g_hash_table_insert(env->custom_csr_map,
> > + GINT_TO_POINTER(csr_map_struct[i].csrno),
> > + &csr_map_struct[i].csr_opset);
> > + } else {
> > + break;
> > + }
> > + }
> > +}
> > +
> > static void riscv_any_cpu_init(Object *obj)
> > {
> > CPURISCVState *env = &RISCV_CPU(obj)->env;
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 3bef0d1265..012be10d0a 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -245,6 +245,11 @@ struct CPURISCVState {
> >
> > /* Fields from here on are preserved across CPU reset. */
> > QEMUTimer *timer; /* Internal timer */
> > +
> > + /* Custom CSR opset table per hart */
> > + GHashTable *custom_csr_map;
> > + /* Custom CSR value holder per hart */
> > + void *custom_csr_val;
> > };
> >
> > OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
> > @@ -496,9 +501,15 @@ typedef struct {
> > riscv_csr_op_fn op;
> > } riscv_csr_operations;
> >
> > +typedef struct {
> > + int csrno;
> > + riscv_csr_operations csr_opset;
> > +} riscv_custom_csr_operations;
> > +
> > /* CSR function table constants */
> > enum {
> > - CSR_TABLE_SIZE = 0x1000
> > + CSR_TABLE_SIZE = 0x1000,
> > + MAX_CUSTOM_CSR_NUM = 100
> > };
> >
> > /* CSR function table */
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 23fbbd3216..1048ee3b44 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -1403,6 +1403,14 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno,
> >
> > #endif
> >
> > +/* Custom CSR related routines */
> > +static gpointer find_custom_csr(CPURISCVState *env, int csrno)
> > +{
> > + gpointer ret;
> > + ret = g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
> > + return ret;
>
> You can just return directly here, so:
>
> return g_hash_table_lookup(env->custom_csr_map, GINT_TO_POINTER(csrno));
>
> Also, I think you need to run checkpatch.pl on this patch (you should
> run it on all patches).
Wilco.
Thanks for the tips.
And sorry for my negligence.
Cordially yours,
Ruinland
>
> Alistair
>
> > +}
> > +
> > /*
> > * riscv_csrrw - read and/or update control and status register
> > *
> > @@ -1419,6 +1427,7 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> > RISCVException ret;
> > target_ulong old_value;
> > RISCVCPU *cpu = env_archcpu(env);
> > + riscv_csr_operations *csr_op;
> > int read_only = get_field(csrno, 0xC00) == 3;
> >
> > /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
> > @@ -1449,26 +1458,39 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> > return RISCV_EXCP_ILLEGAL_INST;
> > }
> >
> > + /* try to handle_custom_csr */
> > + if (unlikely(env->custom_csr_map != NULL)) {
> > + riscv_csr_operations *custom_csr_opset = (riscv_csr_operations *)
> > + find_custom_csr(env, csrno);
> > + if (custom_csr_opset != NULL) {
> > + csr_op = custom_csr_opset;
> > + } else {
> > + csr_op = &csr_ops[csrno];
> > + }
> > + } else {
> > + csr_op = &csr_ops[csrno];
> > + }
> > +
> > /* check predicate */
> > - if (!csr_ops[csrno].predicate) {
> > + if (!csr_op->predicate) {
> > return RISCV_EXCP_ILLEGAL_INST;
> > }
> > - ret = csr_ops[csrno].predicate(env, csrno);
> > + ret = csr_op->predicate(env, csrno);
> > if (ret != RISCV_EXCP_NONE) {
> > return ret;
> > }
> >
> > /* execute combined read/write operation if it exists */
> > - if (csr_ops[csrno].op) {
> > - return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
> > + if (csr_op->op) {
> > + return csr_op->op(env, csrno, ret_value, new_value, write_mask);
> > }
> >
> > /* if no accessor exists then return failure */
> > - if (!csr_ops[csrno].read) {
> > + if (!csr_op->read) {
> > return RISCV_EXCP_ILLEGAL_INST;
> > }
> > /* read old value */
> > - ret = csr_ops[csrno].read(env, csrno, &old_value);
> > + ret = csr_op->read(env, csrno, &old_value);
> > if (ret != RISCV_EXCP_NONE) {
> > return ret;
> > }
> > @@ -1476,8 +1498,8 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> > /* write value if writable and write mask set, otherwise drop writes */
> > if (write_mask) {
> > new_value = (old_value & ~write_mask) | (new_value & write_mask);
> > - if (csr_ops[csrno].write) {
> > - ret = csr_ops[csrno].write(env, csrno, new_value);
> > + if (csr_op->write) {
> > + ret = csr_op->write(env, csrno, new_value);
> > if (ret != RISCV_EXCP_NONE) {
> > return ret;
> > }
> > diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> > new file mode 100644
> > index 0000000000..4dbf8cf1fd
> > --- /dev/null
> > +++ b/target/riscv/custom_csr_defs.h
> > @@ -0,0 +1,7 @@
> > +/*
> > + * Copyright (c) 2021 Andes Technology Corp.
> > + * SPDX-License-Identifier: GPL-2.0+
> > + * Custom CSR variables provided by <cpu_model_name>_csr.c
> > + */
> > +
> > +/* Left blank purposely in this commit. */
> > --
> > 2.25.1
> >
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
2021-10-21 22:44 ` Alistair Francis
@ 2021-10-22 8:37 ` Ruinland ChuanTzu Tsai
-1 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22 8:37 UTC (permalink / raw)
To: Alistair Francis
Cc: ycliang, Alan Quey-Liang Kao((((((((((),
wangjunqiang, Dylan Jhong, qemu-devel@nongnu.org Developers,
open list:RISC-V, Bin Meng
On Fri, Oct 22, 2021 at 08:44:56AM +1000, Alistair Francis wrote:
> On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > Add CSR bits definitions, CSR table and handler functions for Andes
> > AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> > target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
> > target/riscv/cpu.c | 4 +
> > target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
> > target/riscv/custom_csr_defs.h | 3 +-
> > target/riscv/meson.build | 1 +
> > 5 files changed, 319 insertions(+), 1 deletion(-)
> > create mode 100644 target/riscv/andes_cpu_bits.h
> > create mode 100644 target/riscv/csr_andes.c
> >
> > diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> > new file mode 100644
> > index 0000000000..84b0900423
> > --- /dev/null
> > +++ b/target/riscv/andes_cpu_bits.h
> > @@ -0,0 +1,129 @@
> > +/*
> > + * SPDX-License-Identifier: GPL-2.0+
> > + *
> > + * Andes custom CSRs bit definitions
> > + *
> > + */
> > +
> > +/*
> > + * ========= Missing drafted/standard CSR definitions =========
> > + * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
> > + */
> > +#define CSR_TINFO 0x7a4
> > +
> > +#if !defined(CONFIG_USER_ONLY)
> > +/* ========= AndeStar V5 machine mode CSRs ========= */
> > +/* Configuration Registers */
> > +#define CSR_MICM_CFG 0xfc0
> > +#define CSR_MDCM_CFG 0xfc1
> > +#define CSR_MMSC_CFG 0xfc2
> > +#define CSR_MMSC_CFG2 0xfc3
> > +#define CSR_MVEC_CFG 0xfc7
> > +
> > +/* Crash Debug CSRs */
> > +#define CSR_MCRASH_STATESAVE 0xfc8
> > +#define CSR_MSTATUS_CRASHSAVE 0xfc9
> > +
> > +/* Memory CSRs */
> > +#define CSR_MILMB 0x7c0
> > +#define CSR_MDLMB 0x7c1
> > +#define CSR_MECC_CODE 0x7C2
> > +#define CSR_MNVEC 0x7c3
> > +#define CSR_MCACHE_CTL 0x7ca
> > +#define CSR_MCCTLBEGINADDR 0x7cb
> > +#define CSR_MCCTLCOMMAND 0x7cc
> > +#define CSR_MCCTLDATA 0x7cd
> > +#define CSR_MPPIB 0x7f0
> > +#define CSR_MFIOB 0x7f1
> > +
> > +/* Hardware Stack Protection & Recording */
> > +#define CSR_MHSP_CTL 0x7c6
> > +#define CSR_MSP_BOUND 0x7c7
> > +#define CSR_MSP_BASE 0x7c8
> > +#define CSR_MXSTATUS 0x7c4
> > +#define CSR_MDCAUSE 0x7c9
> > +#define CSR_MSLIDELEG 0x7d5
> > +#define CSR_MSAVESTATUS 0x7d6
> > +#define CSR_MSAVEEPC1 0x7d7
> > +#define CSR_MSAVECAUSE1 0x7d8
> > +#define CSR_MSAVEEPC2 0x7d9
> > +#define CSR_MSAVECAUSE2 0x7da
> > +#define CSR_MSAVEDCAUSE1 0x7db
> > +#define CSR_MSAVEDCAUSE2 0x7dc
> > +
> > +/* Control CSRs */
> > +#define CSR_MPFT_CTL 0x7c5
> > +#define CSR_MMISC_CTL 0x7d0
> > +#define CSR_MCLK_CTL 0x7df
> > +
> > +/* Counter related CSRs */
> > +#define CSR_MCOUNTERWEN 0x7ce
> > +#define CSR_MCOUNTERINTEN 0x7cf
> > +#define CSR_MCOUNTERMASK_M 0x7d1
> > +#define CSR_MCOUNTERMASK_S 0x7d2
> > +#define CSR_MCOUNTERMASK_U 0x7d3
> > +#define CSR_MCOUNTEROVF 0x7d4
> > +
> > +/* Enhanced CLIC CSRs */
> > +#define CSR_MIRQ_ENTRY 0x7ec
> > +#define CSR_MINTSEL_JAL 0x7ed
> > +#define CSR_PUSHMCAUSE 0x7ee
> > +#define CSR_PUSHMEPC 0x7ef
> > +#define CSR_PUSHMXSTATUS 0x7eb
> > +
> > +/* Andes Physical Memory Attribute(PMA) CSRs */
> > +#define CSR_PMACFG0 0xbc0
> > +#define CSR_PMACFG1 0xbc1
> > +#define CSR_PMACFG2 0xbc2
> > +#define CSR_PMACFG3 0xbc3
> > +#define CSR_PMAADDR0 0xbd0
> > +#define CSR_PMAADDR1 0xbd1
> > +#define CSR_PMAADDR2 0xbd2
> > +#define CSR_PMAADDR3 0xbd2
> > +#define CSR_PMAADDR4 0xbd4
> > +#define CSR_PMAADDR5 0xbd5
> > +#define CSR_PMAADDR6 0xbd6
> > +#define CSR_PMAADDR7 0xbd7
> > +#define CSR_PMAADDR8 0xbd8
> > +#define CSR_PMAADDR9 0xbd9
> > +#define CSR_PMAADDR10 0xbda
> > +#define CSR_PMAADDR11 0xbdb
> > +#define CSR_PMAADDR12 0xbdc
> > +#define CSR_PMAADDR13 0xbdd
> > +#define CSR_PMAADDR14 0xbde
> > +#define CSR_PMAADDR15 0xbdf
> > +
> > +/* ========= AndeStar V5 supervisor mode CSRs ========= */
> > +/* Supervisor trap registers */
> > +#define CSR_SLIE 0x9c4
> > +#define CSR_SLIP 0x9c5
> > +#define CSR_SDCAUSE 0x9c9
> > +
> > +/* Supervisor counter registers */
> > +#define CSR_SCOUNTERINTEN 0x9cf
> > +#define CSR_SCOUNTERMASK_M 0x9d1
> > +#define CSR_SCOUNTERMASK_S 0x9d2
> > +#define CSR_SCOUNTERMASK_U 0x9d3
> > +#define CSR_SCOUNTEROVF 0x9d4
> > +#define CSR_SCOUNTINHIBIT 0x9e0
> > +#define CSR_SHPMEVENT3 0x9e3
> > +#define CSR_SHPMEVENT4 0x9e4
> > +#define CSR_SHPMEVENT5 0x9e5
> > +#define CSR_SHPMEVENT6 0x9e6
> > +
> > +/* Supervisor control registers */
> > +#define CSR_SCCTLDATA 0x9cd
> > +#define CSR_SMISC_CTL 0x9d0
> > +
> > +#endif /* !defined(CONFIG_USER_ONLY) */
> > +
> > +/* ========= AndeStar V5 user mode CSRs ========= */
> > +/* User mode control registers */
> > +#define CSR_UITB 0x800
> > +#define CSR_UCODE 0x801
> > +#define CSR_UDCAUSE 0x809
> > +#define CSR_UCCTLBEGINADDR 0x80b
> > +#define CSR_UCCTLCOMMAND 0x80c
> > +#define CSR_WFE 0x810
> > +#define CSR_SLEEPVALUE 0x811
> > +#define CSR_TXEVT 0x812
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index a72fd32f01..fe63e68b8e 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -192,6 +192,8 @@ static void ax25_cpu_init(Object *obj)
> > CPURISCVState *env = &RISCV_CPU(obj)->env;
> > set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> > set_priv_version(env, PRIV_VERSION_1_10_0);
> > + setup_custom_csr(env, andes_custom_csr_table);
> > + env->custom_csr_val = g_malloc(andes_custom_csr_size);
> > }
> >
> > static void rv64_sifive_u_cpu_init(Object *obj)
> > @@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
> > CPURISCVState *env = &RISCV_CPU(obj)->env;
> > set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> > set_priv_version(env, PRIV_VERSION_1_10_0);
> > + setup_custom_csr(env, andes_custom_csr_table);
> > + env->custom_csr_val = g_malloc(andes_custom_csr_size);
> > }
> > #endif
> >
> > diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> > new file mode 100644
> > index 0000000000..8617f40483
> > --- /dev/null
> > +++ b/target/riscv/csr_andes.c
> > @@ -0,0 +1,183 @@
> > +/*
> > + * Copyright (c) 2021 Andes Technology Corp.
> > + * SPDX-License-Identifier: GPL-2.0+
> > + * Andes custom CSR table and handling functions
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/log.h"
> > +#include "cpu.h"
> > +#include "qemu/main-loop.h"
> > +#include "exec/exec-all.h"
> > +#include "andes_cpu_bits.h"
> > +
> > +struct andes_csr_val {
> > + target_long uitb;
> > +};
> > +
> > +#if !defined(CONFIG_USER_ONLY)
> > +static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > + /* enable pma probe */
> > + *val = 0x40000000;
> > + return RISCV_EXCP_NONE;
> > +}
> > +#endif
> > +
> > +static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > + struct andes_csr_val *andes_csr = env->custom_csr_val;
> > + andes_csr->uitb = val;
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > + struct andes_csr_val *andes_csr = env->custom_csr_val;
> > + *val = andes_csr->uitb;
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +
> > +static RISCVException any(CPURISCVState *env, int csrno)
> > +{
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > + *val = 0;
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +int andes_custom_csr_size = sizeof(struct andes_csr_val);
>
> I think just drop this value and use sizeof(struct andes_csr_val) in
> the other places.
Wilco.
Thanks for the tips.
Cordially yours,
Ruinland
>
> I haven't checked this against the Andes spec, but overall the series
> looks good.
>
> Alistair
>
> > +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> > + /* ========= AndeStar V5 machine mode CSRs ========= */
> > + #if !defined(CONFIG_USER_ONLY)
> > + /* Configuration Registers */
> > + {CSR_MICM_CFG, { "micm_cfg", any, read_zero, write_stub} },
> > + {CSR_MDCM_CFG, { "mdcm_cfg", any, read_zero, write_stub} },
> > + {CSR_MMSC_CFG, { "mmsc_cfg", any, read_mmsc_cfg, write_stub} },
> > + {CSR_MMSC_CFG2, { "mmsc_cfg2", any, read_zero, write_stub} },
> > + {CSR_MVEC_CFG, { "mvec_cfg", any, read_zero, write_stub} },
> > +
> > + /* Crash Debug CSRs */
> > + {CSR_MCRASH_STATESAVE, { "mcrash_statesave", any, read_zero, write_stub} },
> > + {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
> > +
> > + /* Memory CSRs */
> > + {CSR_MILMB, { "milmb", any, read_zero, write_stub} },
> > + {CSR_MDLMB, { "mdlmb", any, read_zero, write_stub} },
> > + {CSR_MECC_CODE, { "mecc_code", any, read_zero, write_stub} },
> > + {CSR_MNVEC, { "mnvec", any, read_zero, write_stub} },
> > + {CSR_MCACHE_CTL, { "mcache_ctl", any, read_zero, write_stub} },
> > + {CSR_MCCTLBEGINADDR, { "mcctlbeginaddr", any, read_zero, write_stub} },
> > + {CSR_MCCTLCOMMAND, { "mcctlcommand", any, read_zero, write_stub} },
> > + {CSR_MCCTLDATA, { "mcctldata", any, read_zero, write_stub} },
> > + {CSR_MPPIB, { "mppib", any, read_zero, write_stub} },
> > + {CSR_MFIOB, { "mfiob", any, read_zero, write_stub} },
> > +
> > + /* Hardware Stack Protection & Recording */
> > + {CSR_MHSP_CTL, { "mhsp_ctl", any, read_zero, write_stub} },
> > + {CSR_MSP_BOUND, { "msp_bound", any, read_zero, write_stub} },
> > + {CSR_MSP_BASE, { "msp_base", any, read_zero, write_stub} },
> > + {CSR_MXSTATUS, { "mxstatus", any, read_zero, write_stub} },
> > + {CSR_MDCAUSE, { "mdcause", any, read_zero, write_stub} },
> > + {CSR_MSLIDELEG, { "mslideleg", any, read_zero, write_stub} },
> > + {CSR_MSAVESTATUS, { "msavestatus", any, read_zero, write_stub} },
> > + {CSR_MSAVEEPC1, { "msaveepc1", any, read_zero, write_stub} },
> > + {CSR_MSAVECAUSE1, { "msavecause1", any, read_zero, write_stub} },
> > + {CSR_MSAVEEPC2, { "msaveepc2", any, read_zero, write_stub} },
> > + {CSR_MSAVECAUSE2, { "msavecause2", any, read_zero, write_stub} },
> > + {CSR_MSAVEDCAUSE1, { "msavedcause1", any, read_zero, write_stub} },
> > + {CSR_MSAVEDCAUSE2, { "msavedcause2", any, read_zero, write_stub} },
> > +
> > + /* Control CSRs */
> > + {CSR_MPFT_CTL, { "mpft_ctl", any, read_zero, write_stub} },
> > + {CSR_MMISC_CTL, { "mmisc_ctl", any, read_zero, write_stub} },
> > + {CSR_MCLK_CTL, { "mclk_ctl", any, read_zero, write_stub} },
> > +
> > + /* Counter related CSRs */
> > + {CSR_MCOUNTERWEN, { "mcounterwen", any, read_zero, write_stub} },
> > + {CSR_MCOUNTERINTEN, { "mcounterinten", any, read_zero, write_stub} },
> > + {CSR_MCOUNTERMASK_M, { "mcountermask_m", any, read_zero, write_stub} },
> > + {CSR_MCOUNTERMASK_S, { "mcountermask_s", any, read_zero, write_stub} },
> > + {CSR_MCOUNTERMASK_U, { "mcountermask_u", any, read_zero, write_stub} },
> > + {CSR_MCOUNTEROVF, { "mcounterovf", any, read_zero, write_stub} },
> > +
> > + /* Enhanced CLIC CSRs */
> > + {CSR_MIRQ_ENTRY, { "mirq_entry", any, read_zero, write_stub} },
> > + {CSR_MINTSEL_JAL, { "mintsel_jal", any, read_zero, write_stub} },
> > + {CSR_PUSHMCAUSE, { "pushmcause", any, read_zero, write_stub} },
> > + {CSR_PUSHMEPC, { "pushmepc", any, read_zero, write_stub} },
> > + {CSR_PUSHMXSTATUS, { "pushmxstatus", any, read_zero, write_stub} },
> > +
> > + /* Andes Physical Memory Attribute(PMA) CSRs */
> > + {CSR_PMACFG0, { "pmacfg0", any, read_zero, write_stub} },
> > + {CSR_PMACFG1, { "pmacfg1", any, read_zero, write_stub} },
> > + {CSR_PMACFG2, { "pmacfg2", any, read_zero, write_stub} },
> > + {CSR_PMACFG3, { "pmacfg3", any, read_zero, write_stub} },
> > + {CSR_PMAADDR0, { "pmaaddr0", any, read_zero, write_stub} },
> > + {CSR_PMAADDR1, { "pmaaddr1", any, read_zero, write_stub} },
> > + {CSR_PMAADDR2, { "pmaaddr2", any, read_zero, write_stub} },
> > + {CSR_PMAADDR3, { "pmaaddr3", any, read_zero, write_stub} },
> > + {CSR_PMAADDR4, { "pmaaddr4", any, read_zero, write_stub} },
> > + {CSR_PMAADDR5, { "pmaaddr5", any, read_zero, write_stub} },
> > + {CSR_PMAADDR6, { "pmaaddr6", any, read_zero, write_stub} },
> > + {CSR_PMAADDR7, { "pmaaddr7", any, read_zero, write_stub} },
> > + {CSR_PMAADDR8, { "pmaaddr8", any, read_zero, write_stub} },
> > + {CSR_PMAADDR9, { "pmaaddr9", any, read_zero, write_stub} },
> > + {CSR_PMAADDR10, { "pmaaddr10", any, read_zero, write_stub} },
> > + {CSR_PMAADDR11, { "pmaaddr11", any, read_zero, write_stub} },
> > + {CSR_PMAADDR12, { "pmaaddr12", any, read_zero, write_stub} },
> > + {CSR_PMAADDR13, { "pmaaddr13", any, read_zero, write_stub} },
> > + {CSR_PMAADDR14, { "pmaaddr14", any, read_zero, write_stub} },
> > + {CSR_PMAADDR15, { "pmaaddr15", any, read_zero, write_stub} },
> > +
> > + /* Debug/Trace Registers (shared with Debug Mode) */
> > + {CSR_TSELECT, { "tselect", any, read_zero, write_stub} },
> > + {CSR_TDATA1, { "tdata1", any, read_zero, write_stub} },
> > + {CSR_TDATA2, { "tdata2", any, read_zero, write_stub} },
> > + {CSR_TDATA3, { "tdata3", any, read_zero, write_stub} },
> > + {CSR_TINFO, { "tinfo", any, read_zero, write_stub} },
> > +
> > + /* ========= AndeStar V5 supervisor mode CSRs ========= */
> > + /* Supervisor trap registers */
> > + {CSR_SLIE, { "slie", any, read_zero, write_stub} },
> > + {CSR_SLIP, { "slip", any, read_zero, write_stub} },
> > + {CSR_SDCAUSE, { "sdcause", any, read_zero, write_stub} },
> > +
> > + /* Supervisor counter registers */
> > + {CSR_SCOUNTERINTEN, { "scounterinten", any, read_zero, write_stub} },
> > + {CSR_SCOUNTERMASK_M, { "scountermask_m", any, read_zero, write_stub} },
> > + {CSR_SCOUNTERMASK_S, { "scountermask_s", any, read_zero, write_stub} },
> > + {CSR_SCOUNTERMASK_U, { "scountermask_u", any, read_zero, write_stub} },
> > + {CSR_SCOUNTEROVF, { "scounterovf", any, read_zero, write_stub} },
> > + {CSR_SCOUNTINHIBIT, { "scountinhibit", any, read_zero, write_stub} },
> > + {CSR_SHPMEVENT3, { "shpmevent3", any, read_zero, write_stub} },
> > + {CSR_SHPMEVENT4, { "shpmevent4", any, read_zero, write_stub} },
> > + {CSR_SHPMEVENT5, { "shpmevent5", any, read_zero, write_stub} },
> > + {CSR_SHPMEVENT6, { "shpmevent6", any, read_zero, write_stub} },
> > +
> > + /* Supervisor control registers */
> > + {CSR_SCCTLDATA, { "scctldata", any, read_zero, write_stub} },
> > + {CSR_SMISC_CTL, { "smisc_ctl", any, read_zero, write_stub} },
> > + #endif
> > +
> > + /* ========= AndeStar V5 user mode CSRs ========= */
> > + /* User mode control registers */
> > + {CSR_UITB, { "uitb", any, read_uitb, write_uitb} },
> > + {CSR_UCODE, { "ucode", any, read_zero, write_stub} },
> > + {CSR_UDCAUSE, { "udcause", any, read_zero, write_stub} },
> > + {CSR_UCCTLBEGINADDR, { "ucctlbeginaddr", any, read_zero, write_stub} },
> > + {CSR_UCCTLCOMMAND, { "ucctlcommand", any, read_zero, write_stub} },
> > + {CSR_WFE, { "wfe", any, read_zero, write_stub} },
> > + {CSR_SLEEPVALUE, { "sleepvalue", any, read_zero, write_stub} },
> > + {CSR_TXEVT, { "csr_txevt", any, read_zero, write_stub} },
> > + {0, { "", NULL, NULL, NULL } },
> > + };
> > diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> > index 4dbf8cf1fd..b09083585b 100644
> > --- a/target/riscv/custom_csr_defs.h
> > +++ b/target/riscv/custom_csr_defs.h
> > @@ -4,4 +4,5 @@
> > * Custom CSR variables provided by <cpu_model_name>_csr.c
> > */
> >
> > -/* Left blank purposely in this commit. */
> > +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
> > +extern int andes_custom_csr_size;
> > diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> > index d5e0bc93ea..5c87672ff9 100644
> > --- a/target/riscv/meson.build
> > +++ b/target/riscv/meson.build
> > @@ -9,6 +9,7 @@ gen = [
> > riscv_ss = ss.source_set()
> > riscv_ss.add(gen)
> > riscv_ss.add(files(
> > + 'csr_andes.c',
> > 'cpu.c',
> > 'cpu_helper.c',
> > 'csr.c',
> > --
> > 2.25.1
> >
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs
@ 2021-10-22 8:37 ` Ruinland ChuanTzu Tsai
0 siblings, 0 replies; 28+ messages in thread
From: Ruinland ChuanTzu Tsai @ 2021-10-22 8:37 UTC (permalink / raw)
To: Alistair Francis
Cc: wangjunqiang, Bin Meng, qemu-devel@nongnu.org Developers,
open list:RISC-V, ycliang, Alan Quey-Liang Kao((((((((((),
Dylan Jhong
On Fri, Oct 22, 2021 at 08:44:56AM +1000, Alistair Francis wrote:
> On Fri, Oct 22, 2021 at 1:13 AM Ruinland Chuan-Tzu Tsai
> <ruinland@andestech.com> wrote:
> >
> > Add CSR bits definitions, CSR table and handler functions for Andes
> > AX25 and A25 CPUs. Also, enable the logic in a(x)25_cpu_init().
> >
> > Signed-off-by: Ruinland Chuan-Tzu Tsai <ruinland@andestech.com>
> > ---
> > target/riscv/andes_cpu_bits.h | 129 +++++++++++++++++++++++
> > target/riscv/cpu.c | 4 +
> > target/riscv/csr_andes.c | 183 +++++++++++++++++++++++++++++++++
> > target/riscv/custom_csr_defs.h | 3 +-
> > target/riscv/meson.build | 1 +
> > 5 files changed, 319 insertions(+), 1 deletion(-)
> > create mode 100644 target/riscv/andes_cpu_bits.h
> > create mode 100644 target/riscv/csr_andes.c
> >
> > diff --git a/target/riscv/andes_cpu_bits.h b/target/riscv/andes_cpu_bits.h
> > new file mode 100644
> > index 0000000000..84b0900423
> > --- /dev/null
> > +++ b/target/riscv/andes_cpu_bits.h
> > @@ -0,0 +1,129 @@
> > +/*
> > + * SPDX-License-Identifier: GPL-2.0+
> > + *
> > + * Andes custom CSRs bit definitions
> > + *
> > + */
> > +
> > +/*
> > + * ========= Missing drafted/standard CSR definitions =========
> > + * TINFO is in official debug sepc, it's not in cpu_bits.h yet.
> > + */
> > +#define CSR_TINFO 0x7a4
> > +
> > +#if !defined(CONFIG_USER_ONLY)
> > +/* ========= AndeStar V5 machine mode CSRs ========= */
> > +/* Configuration Registers */
> > +#define CSR_MICM_CFG 0xfc0
> > +#define CSR_MDCM_CFG 0xfc1
> > +#define CSR_MMSC_CFG 0xfc2
> > +#define CSR_MMSC_CFG2 0xfc3
> > +#define CSR_MVEC_CFG 0xfc7
> > +
> > +/* Crash Debug CSRs */
> > +#define CSR_MCRASH_STATESAVE 0xfc8
> > +#define CSR_MSTATUS_CRASHSAVE 0xfc9
> > +
> > +/* Memory CSRs */
> > +#define CSR_MILMB 0x7c0
> > +#define CSR_MDLMB 0x7c1
> > +#define CSR_MECC_CODE 0x7C2
> > +#define CSR_MNVEC 0x7c3
> > +#define CSR_MCACHE_CTL 0x7ca
> > +#define CSR_MCCTLBEGINADDR 0x7cb
> > +#define CSR_MCCTLCOMMAND 0x7cc
> > +#define CSR_MCCTLDATA 0x7cd
> > +#define CSR_MPPIB 0x7f0
> > +#define CSR_MFIOB 0x7f1
> > +
> > +/* Hardware Stack Protection & Recording */
> > +#define CSR_MHSP_CTL 0x7c6
> > +#define CSR_MSP_BOUND 0x7c7
> > +#define CSR_MSP_BASE 0x7c8
> > +#define CSR_MXSTATUS 0x7c4
> > +#define CSR_MDCAUSE 0x7c9
> > +#define CSR_MSLIDELEG 0x7d5
> > +#define CSR_MSAVESTATUS 0x7d6
> > +#define CSR_MSAVEEPC1 0x7d7
> > +#define CSR_MSAVECAUSE1 0x7d8
> > +#define CSR_MSAVEEPC2 0x7d9
> > +#define CSR_MSAVECAUSE2 0x7da
> > +#define CSR_MSAVEDCAUSE1 0x7db
> > +#define CSR_MSAVEDCAUSE2 0x7dc
> > +
> > +/* Control CSRs */
> > +#define CSR_MPFT_CTL 0x7c5
> > +#define CSR_MMISC_CTL 0x7d0
> > +#define CSR_MCLK_CTL 0x7df
> > +
> > +/* Counter related CSRs */
> > +#define CSR_MCOUNTERWEN 0x7ce
> > +#define CSR_MCOUNTERINTEN 0x7cf
> > +#define CSR_MCOUNTERMASK_M 0x7d1
> > +#define CSR_MCOUNTERMASK_S 0x7d2
> > +#define CSR_MCOUNTERMASK_U 0x7d3
> > +#define CSR_MCOUNTEROVF 0x7d4
> > +
> > +/* Enhanced CLIC CSRs */
> > +#define CSR_MIRQ_ENTRY 0x7ec
> > +#define CSR_MINTSEL_JAL 0x7ed
> > +#define CSR_PUSHMCAUSE 0x7ee
> > +#define CSR_PUSHMEPC 0x7ef
> > +#define CSR_PUSHMXSTATUS 0x7eb
> > +
> > +/* Andes Physical Memory Attribute(PMA) CSRs */
> > +#define CSR_PMACFG0 0xbc0
> > +#define CSR_PMACFG1 0xbc1
> > +#define CSR_PMACFG2 0xbc2
> > +#define CSR_PMACFG3 0xbc3
> > +#define CSR_PMAADDR0 0xbd0
> > +#define CSR_PMAADDR1 0xbd1
> > +#define CSR_PMAADDR2 0xbd2
> > +#define CSR_PMAADDR3 0xbd2
> > +#define CSR_PMAADDR4 0xbd4
> > +#define CSR_PMAADDR5 0xbd5
> > +#define CSR_PMAADDR6 0xbd6
> > +#define CSR_PMAADDR7 0xbd7
> > +#define CSR_PMAADDR8 0xbd8
> > +#define CSR_PMAADDR9 0xbd9
> > +#define CSR_PMAADDR10 0xbda
> > +#define CSR_PMAADDR11 0xbdb
> > +#define CSR_PMAADDR12 0xbdc
> > +#define CSR_PMAADDR13 0xbdd
> > +#define CSR_PMAADDR14 0xbde
> > +#define CSR_PMAADDR15 0xbdf
> > +
> > +/* ========= AndeStar V5 supervisor mode CSRs ========= */
> > +/* Supervisor trap registers */
> > +#define CSR_SLIE 0x9c4
> > +#define CSR_SLIP 0x9c5
> > +#define CSR_SDCAUSE 0x9c9
> > +
> > +/* Supervisor counter registers */
> > +#define CSR_SCOUNTERINTEN 0x9cf
> > +#define CSR_SCOUNTERMASK_M 0x9d1
> > +#define CSR_SCOUNTERMASK_S 0x9d2
> > +#define CSR_SCOUNTERMASK_U 0x9d3
> > +#define CSR_SCOUNTEROVF 0x9d4
> > +#define CSR_SCOUNTINHIBIT 0x9e0
> > +#define CSR_SHPMEVENT3 0x9e3
> > +#define CSR_SHPMEVENT4 0x9e4
> > +#define CSR_SHPMEVENT5 0x9e5
> > +#define CSR_SHPMEVENT6 0x9e6
> > +
> > +/* Supervisor control registers */
> > +#define CSR_SCCTLDATA 0x9cd
> > +#define CSR_SMISC_CTL 0x9d0
> > +
> > +#endif /* !defined(CONFIG_USER_ONLY) */
> > +
> > +/* ========= AndeStar V5 user mode CSRs ========= */
> > +/* User mode control registers */
> > +#define CSR_UITB 0x800
> > +#define CSR_UCODE 0x801
> > +#define CSR_UDCAUSE 0x809
> > +#define CSR_UCCTLBEGINADDR 0x80b
> > +#define CSR_UCCTLCOMMAND 0x80c
> > +#define CSR_WFE 0x810
> > +#define CSR_SLEEPVALUE 0x811
> > +#define CSR_TXEVT 0x812
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index a72fd32f01..fe63e68b8e 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -192,6 +192,8 @@ static void ax25_cpu_init(Object *obj)
> > CPURISCVState *env = &RISCV_CPU(obj)->env;
> > set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> > set_priv_version(env, PRIV_VERSION_1_10_0);
> > + setup_custom_csr(env, andes_custom_csr_table);
> > + env->custom_csr_val = g_malloc(andes_custom_csr_size);
> > }
> >
> > static void rv64_sifive_u_cpu_init(Object *obj)
> > @@ -254,6 +256,8 @@ static void a25_cpu_init(Object *obj)
> > CPURISCVState *env = &RISCV_CPU(obj)->env;
> > set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
> > set_priv_version(env, PRIV_VERSION_1_10_0);
> > + setup_custom_csr(env, andes_custom_csr_table);
> > + env->custom_csr_val = g_malloc(andes_custom_csr_size);
> > }
> > #endif
> >
> > diff --git a/target/riscv/csr_andes.c b/target/riscv/csr_andes.c
> > new file mode 100644
> > index 0000000000..8617f40483
> > --- /dev/null
> > +++ b/target/riscv/csr_andes.c
> > @@ -0,0 +1,183 @@
> > +/*
> > + * Copyright (c) 2021 Andes Technology Corp.
> > + * SPDX-License-Identifier: GPL-2.0+
> > + * Andes custom CSR table and handling functions
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/log.h"
> > +#include "cpu.h"
> > +#include "qemu/main-loop.h"
> > +#include "exec/exec-all.h"
> > +#include "andes_cpu_bits.h"
> > +
> > +struct andes_csr_val {
> > + target_long uitb;
> > +};
> > +
> > +#if !defined(CONFIG_USER_ONLY)
> > +static RISCVException read_mmsc_cfg(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > + /* enable pma probe */
> > + *val = 0x40000000;
> > + return RISCV_EXCP_NONE;
> > +}
> > +#endif
> > +
> > +static RISCVException write_uitb(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > + struct andes_csr_val *andes_csr = env->custom_csr_val;
> > + andes_csr->uitb = val;
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException read_uitb(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > + struct andes_csr_val *andes_csr = env->custom_csr_val;
> > + *val = andes_csr->uitb;
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +
> > +static RISCVException any(CPURISCVState *env, int csrno)
> > +{
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException read_zero(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > + *val = 0;
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException write_stub(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > + return RISCV_EXCP_NONE;
> > +}
> > +
> > +int andes_custom_csr_size = sizeof(struct andes_csr_val);
>
> I think just drop this value and use sizeof(struct andes_csr_val) in
> the other places.
Wilco.
Thanks for the tips.
Cordially yours,
Ruinland
>
> I haven't checked this against the Andes spec, but overall the series
> looks good.
>
> Alistair
>
> > +riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM] = {
> > + /* ========= AndeStar V5 machine mode CSRs ========= */
> > + #if !defined(CONFIG_USER_ONLY)
> > + /* Configuration Registers */
> > + {CSR_MICM_CFG, { "micm_cfg", any, read_zero, write_stub} },
> > + {CSR_MDCM_CFG, { "mdcm_cfg", any, read_zero, write_stub} },
> > + {CSR_MMSC_CFG, { "mmsc_cfg", any, read_mmsc_cfg, write_stub} },
> > + {CSR_MMSC_CFG2, { "mmsc_cfg2", any, read_zero, write_stub} },
> > + {CSR_MVEC_CFG, { "mvec_cfg", any, read_zero, write_stub} },
> > +
> > + /* Crash Debug CSRs */
> > + {CSR_MCRASH_STATESAVE, { "mcrash_statesave", any, read_zero, write_stub} },
> > + {CSR_MSTATUS_CRASHSAVE, { "mstatus_crashsave", any, read_zero, write_stub} },
> > +
> > + /* Memory CSRs */
> > + {CSR_MILMB, { "milmb", any, read_zero, write_stub} },
> > + {CSR_MDLMB, { "mdlmb", any, read_zero, write_stub} },
> > + {CSR_MECC_CODE, { "mecc_code", any, read_zero, write_stub} },
> > + {CSR_MNVEC, { "mnvec", any, read_zero, write_stub} },
> > + {CSR_MCACHE_CTL, { "mcache_ctl", any, read_zero, write_stub} },
> > + {CSR_MCCTLBEGINADDR, { "mcctlbeginaddr", any, read_zero, write_stub} },
> > + {CSR_MCCTLCOMMAND, { "mcctlcommand", any, read_zero, write_stub} },
> > + {CSR_MCCTLDATA, { "mcctldata", any, read_zero, write_stub} },
> > + {CSR_MPPIB, { "mppib", any, read_zero, write_stub} },
> > + {CSR_MFIOB, { "mfiob", any, read_zero, write_stub} },
> > +
> > + /* Hardware Stack Protection & Recording */
> > + {CSR_MHSP_CTL, { "mhsp_ctl", any, read_zero, write_stub} },
> > + {CSR_MSP_BOUND, { "msp_bound", any, read_zero, write_stub} },
> > + {CSR_MSP_BASE, { "msp_base", any, read_zero, write_stub} },
> > + {CSR_MXSTATUS, { "mxstatus", any, read_zero, write_stub} },
> > + {CSR_MDCAUSE, { "mdcause", any, read_zero, write_stub} },
> > + {CSR_MSLIDELEG, { "mslideleg", any, read_zero, write_stub} },
> > + {CSR_MSAVESTATUS, { "msavestatus", any, read_zero, write_stub} },
> > + {CSR_MSAVEEPC1, { "msaveepc1", any, read_zero, write_stub} },
> > + {CSR_MSAVECAUSE1, { "msavecause1", any, read_zero, write_stub} },
> > + {CSR_MSAVEEPC2, { "msaveepc2", any, read_zero, write_stub} },
> > + {CSR_MSAVECAUSE2, { "msavecause2", any, read_zero, write_stub} },
> > + {CSR_MSAVEDCAUSE1, { "msavedcause1", any, read_zero, write_stub} },
> > + {CSR_MSAVEDCAUSE2, { "msavedcause2", any, read_zero, write_stub} },
> > +
> > + /* Control CSRs */
> > + {CSR_MPFT_CTL, { "mpft_ctl", any, read_zero, write_stub} },
> > + {CSR_MMISC_CTL, { "mmisc_ctl", any, read_zero, write_stub} },
> > + {CSR_MCLK_CTL, { "mclk_ctl", any, read_zero, write_stub} },
> > +
> > + /* Counter related CSRs */
> > + {CSR_MCOUNTERWEN, { "mcounterwen", any, read_zero, write_stub} },
> > + {CSR_MCOUNTERINTEN, { "mcounterinten", any, read_zero, write_stub} },
> > + {CSR_MCOUNTERMASK_M, { "mcountermask_m", any, read_zero, write_stub} },
> > + {CSR_MCOUNTERMASK_S, { "mcountermask_s", any, read_zero, write_stub} },
> > + {CSR_MCOUNTERMASK_U, { "mcountermask_u", any, read_zero, write_stub} },
> > + {CSR_MCOUNTEROVF, { "mcounterovf", any, read_zero, write_stub} },
> > +
> > + /* Enhanced CLIC CSRs */
> > + {CSR_MIRQ_ENTRY, { "mirq_entry", any, read_zero, write_stub} },
> > + {CSR_MINTSEL_JAL, { "mintsel_jal", any, read_zero, write_stub} },
> > + {CSR_PUSHMCAUSE, { "pushmcause", any, read_zero, write_stub} },
> > + {CSR_PUSHMEPC, { "pushmepc", any, read_zero, write_stub} },
> > + {CSR_PUSHMXSTATUS, { "pushmxstatus", any, read_zero, write_stub} },
> > +
> > + /* Andes Physical Memory Attribute(PMA) CSRs */
> > + {CSR_PMACFG0, { "pmacfg0", any, read_zero, write_stub} },
> > + {CSR_PMACFG1, { "pmacfg1", any, read_zero, write_stub} },
> > + {CSR_PMACFG2, { "pmacfg2", any, read_zero, write_stub} },
> > + {CSR_PMACFG3, { "pmacfg3", any, read_zero, write_stub} },
> > + {CSR_PMAADDR0, { "pmaaddr0", any, read_zero, write_stub} },
> > + {CSR_PMAADDR1, { "pmaaddr1", any, read_zero, write_stub} },
> > + {CSR_PMAADDR2, { "pmaaddr2", any, read_zero, write_stub} },
> > + {CSR_PMAADDR3, { "pmaaddr3", any, read_zero, write_stub} },
> > + {CSR_PMAADDR4, { "pmaaddr4", any, read_zero, write_stub} },
> > + {CSR_PMAADDR5, { "pmaaddr5", any, read_zero, write_stub} },
> > + {CSR_PMAADDR6, { "pmaaddr6", any, read_zero, write_stub} },
> > + {CSR_PMAADDR7, { "pmaaddr7", any, read_zero, write_stub} },
> > + {CSR_PMAADDR8, { "pmaaddr8", any, read_zero, write_stub} },
> > + {CSR_PMAADDR9, { "pmaaddr9", any, read_zero, write_stub} },
> > + {CSR_PMAADDR10, { "pmaaddr10", any, read_zero, write_stub} },
> > + {CSR_PMAADDR11, { "pmaaddr11", any, read_zero, write_stub} },
> > + {CSR_PMAADDR12, { "pmaaddr12", any, read_zero, write_stub} },
> > + {CSR_PMAADDR13, { "pmaaddr13", any, read_zero, write_stub} },
> > + {CSR_PMAADDR14, { "pmaaddr14", any, read_zero, write_stub} },
> > + {CSR_PMAADDR15, { "pmaaddr15", any, read_zero, write_stub} },
> > +
> > + /* Debug/Trace Registers (shared with Debug Mode) */
> > + {CSR_TSELECT, { "tselect", any, read_zero, write_stub} },
> > + {CSR_TDATA1, { "tdata1", any, read_zero, write_stub} },
> > + {CSR_TDATA2, { "tdata2", any, read_zero, write_stub} },
> > + {CSR_TDATA3, { "tdata3", any, read_zero, write_stub} },
> > + {CSR_TINFO, { "tinfo", any, read_zero, write_stub} },
> > +
> > + /* ========= AndeStar V5 supervisor mode CSRs ========= */
> > + /* Supervisor trap registers */
> > + {CSR_SLIE, { "slie", any, read_zero, write_stub} },
> > + {CSR_SLIP, { "slip", any, read_zero, write_stub} },
> > + {CSR_SDCAUSE, { "sdcause", any, read_zero, write_stub} },
> > +
> > + /* Supervisor counter registers */
> > + {CSR_SCOUNTERINTEN, { "scounterinten", any, read_zero, write_stub} },
> > + {CSR_SCOUNTERMASK_M, { "scountermask_m", any, read_zero, write_stub} },
> > + {CSR_SCOUNTERMASK_S, { "scountermask_s", any, read_zero, write_stub} },
> > + {CSR_SCOUNTERMASK_U, { "scountermask_u", any, read_zero, write_stub} },
> > + {CSR_SCOUNTEROVF, { "scounterovf", any, read_zero, write_stub} },
> > + {CSR_SCOUNTINHIBIT, { "scountinhibit", any, read_zero, write_stub} },
> > + {CSR_SHPMEVENT3, { "shpmevent3", any, read_zero, write_stub} },
> > + {CSR_SHPMEVENT4, { "shpmevent4", any, read_zero, write_stub} },
> > + {CSR_SHPMEVENT5, { "shpmevent5", any, read_zero, write_stub} },
> > + {CSR_SHPMEVENT6, { "shpmevent6", any, read_zero, write_stub} },
> > +
> > + /* Supervisor control registers */
> > + {CSR_SCCTLDATA, { "scctldata", any, read_zero, write_stub} },
> > + {CSR_SMISC_CTL, { "smisc_ctl", any, read_zero, write_stub} },
> > + #endif
> > +
> > + /* ========= AndeStar V5 user mode CSRs ========= */
> > + /* User mode control registers */
> > + {CSR_UITB, { "uitb", any, read_uitb, write_uitb} },
> > + {CSR_UCODE, { "ucode", any, read_zero, write_stub} },
> > + {CSR_UDCAUSE, { "udcause", any, read_zero, write_stub} },
> > + {CSR_UCCTLBEGINADDR, { "ucctlbeginaddr", any, read_zero, write_stub} },
> > + {CSR_UCCTLCOMMAND, { "ucctlcommand", any, read_zero, write_stub} },
> > + {CSR_WFE, { "wfe", any, read_zero, write_stub} },
> > + {CSR_SLEEPVALUE, { "sleepvalue", any, read_zero, write_stub} },
> > + {CSR_TXEVT, { "csr_txevt", any, read_zero, write_stub} },
> > + {0, { "", NULL, NULL, NULL } },
> > + };
> > diff --git a/target/riscv/custom_csr_defs.h b/target/riscv/custom_csr_defs.h
> > index 4dbf8cf1fd..b09083585b 100644
> > --- a/target/riscv/custom_csr_defs.h
> > +++ b/target/riscv/custom_csr_defs.h
> > @@ -4,4 +4,5 @@
> > * Custom CSR variables provided by <cpu_model_name>_csr.c
> > */
> >
> > -/* Left blank purposely in this commit. */
> > +extern riscv_custom_csr_operations andes_custom_csr_table[MAX_CUSTOM_CSR_NUM];
> > +extern int andes_custom_csr_size;
> > diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> > index d5e0bc93ea..5c87672ff9 100644
> > --- a/target/riscv/meson.build
> > +++ b/target/riscv/meson.build
> > @@ -9,6 +9,7 @@ gen = [
> > riscv_ss = ss.source_set()
> > riscv_ss.add(gen)
> > riscv_ss.add(files(
> > + 'csr_andes.c',
> > 'cpu.c',
> > 'cpu_helper.c',
> > 'csr.c',
> > --
> > 2.25.1
> >
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
2021-10-22 8:34 ` Ruinland ChuanTzu Tsai
@ 2021-10-22 15:59 ` Richard Henderson
-1 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22 15:59 UTC (permalink / raw)
To: Ruinland ChuanTzu Tsai
Cc: ycliang, qemu-riscv, alankao, wangjunqiang, dylan, qemu-devel,
alistair23, bmeng.cn
On 10/22/21 1:34 AM, Ruinland ChuanTzu Tsai wrote:
>>> + /* Custom CSR value holder per hart */
>>> + void *custom_csr_val;
>>> };
>>
>> Value singular? Anyhow, I think that it's a mistake trying to hide the
>> value structure in another file. It complicates allocation of the
>> CPURISCVState, and you have no mechanism by which to migrate the csr values.
>
> What I'm trying to do here is to provide a hook for CSR value storage and let
> it being set during CPU initilization. We have heterogeneous harts which
> have different sets of CSRs.
I understand that, but the common CPURISCVState should contain the storage for all of the
CSRs for every possible hart.
I might have made a different call if we had a more object-y language, but we have C. The
difference in size (here exactly one word) is not worth the complication of splitting
structures apart.
r~
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw()
@ 2021-10-22 15:59 ` Richard Henderson
0 siblings, 0 replies; 28+ messages in thread
From: Richard Henderson @ 2021-10-22 15:59 UTC (permalink / raw)
To: Ruinland ChuanTzu Tsai
Cc: alistair23, wangjunqiang, bmeng.cn, ycliang, alankao, dylan,
qemu-devel, qemu-riscv
On 10/22/21 1:34 AM, Ruinland ChuanTzu Tsai wrote:
>>> + /* Custom CSR value holder per hart */
>>> + void *custom_csr_val;
>>> };
>>
>> Value singular? Anyhow, I think that it's a mistake trying to hide the
>> value structure in another file. It complicates allocation of the
>> CPURISCVState, and you have no mechanism by which to migrate the csr values.
>
> What I'm trying to do here is to provide a hook for CSR value storage and let
> it being set during CPU initilization. We have heterogeneous harts which
> have different sets of CSRs.
I understand that, but the common CPURISCVState should contain the storage for all of the
CSRs for every possible hart.
I might have made a different call if we had a more object-y language, but we have C. The
difference in size (here exactly one word) is not worth the complication of splitting
structures apart.
r~
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2021-10-22 16:03 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-21 15:09 [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support Ruinland Chuan-Tzu Tsai
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
2021-10-21 15:09 ` [RFC PATCH v5 1/3] riscv: Adding Andes A25 and AX25 cpu models Ruinland Chuan-Tzu Tsai
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
2021-10-21 22:33 ` Alistair Francis
2021-10-21 22:33 ` Alistair Francis
2021-10-21 15:09 ` [RFC PATCH v5 2/3] riscv: Introduce custom CSR hooks to riscv_csrrw() Ruinland Chuan-Tzu Tsai
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
2021-10-21 22:43 ` Alistair Francis
2021-10-21 22:43 ` Alistair Francis
2021-10-22 8:36 ` Ruinland ChuanTzu Tsai
2021-10-22 8:36 ` Ruinland ChuanTzu Tsai
2021-10-22 0:08 ` Richard Henderson
2021-10-22 0:08 ` Richard Henderson
2021-10-22 8:34 ` Ruinland ChuanTzu Tsai
2021-10-22 8:34 ` Ruinland ChuanTzu Tsai
2021-10-22 15:59 ` Richard Henderson
2021-10-22 15:59 ` Richard Henderson
2021-10-21 15:09 ` [RFC PATCH v5 3/3] riscv: Enable custom CSR support for Andes AX25 and A25 CPUs Ruinland Chuan-Tzu Tsai
2021-10-21 15:09 ` Ruinland Chuan-Tzu Tsai
2021-10-21 22:44 ` Alistair Francis
2021-10-21 22:44 ` Alistair Francis
2021-10-22 8:37 ` Ruinland ChuanTzu Tsai
2021-10-22 8:37 ` Ruinland ChuanTzu Tsai
2021-10-22 1:12 ` Richard Henderson
2021-10-22 1:12 ` Richard Henderson
2021-10-21 22:47 ` [RFC PATCH v5 0/3] riscv: Add preliminary custom CSR support Alistair Francis
2021-10-21 22:47 ` Alistair Francis
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.