mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-24 10:32:02 -06:00
target/riscv: generalize custom CSR functionality
While at it, constify it so that the RISCVCSR array in RISCVCPUDef can also be const. Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
1d84c2401c
commit
1016b0364f
4 changed files with 40 additions and 23 deletions
|
@ -485,6 +485,19 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
static void riscv_register_custom_csrs(RISCVCPU *cpu, const RISCVCSR *csr_list)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; csr_list[i].csr_ops.name; i++) {
|
||||||
|
int csrno = csr_list[i].csrno;
|
||||||
|
const riscv_csr_operations *csr_ops = &csr_list[i].csr_ops;
|
||||||
|
if (!csr_list[i].insertion_test || csr_list[i].insertion_test(cpu)) {
|
||||||
|
riscv_set_csr_ops(csrno, csr_ops);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TARGET_RISCV64)
|
#if defined(TARGET_RISCV64)
|
||||||
static void rv64_thead_c906_cpu_init(Object *obj)
|
static void rv64_thead_c906_cpu_init(Object *obj)
|
||||||
{
|
{
|
||||||
|
@ -511,7 +524,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
|
||||||
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
|
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
|
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
|
||||||
th_register_custom_csrs(cpu);
|
riscv_register_custom_csrs(cpu, th_csr_list);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* inherited from parent obj via riscv_cpu_init() */
|
/* inherited from parent obj via riscv_cpu_init() */
|
||||||
|
@ -1304,6 +1317,11 @@ static void riscv_cpu_init(Object *obj)
|
||||||
if (mcc->def->vext_spec != RISCV_PROFILE_ATTR_UNUSED) {
|
if (mcc->def->vext_spec != RISCV_PROFILE_ATTR_UNUSED) {
|
||||||
cpu->env.vext_ver = mcc->def->vext_spec;
|
cpu->env.vext_ver = mcc->def->vext_spec;
|
||||||
}
|
}
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
if (mcc->def->custom_csrs) {
|
||||||
|
riscv_register_custom_csrs(cpu, mcc->def->custom_csrs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct misa_ext_info {
|
typedef struct misa_ext_info {
|
||||||
|
@ -2906,6 +2924,11 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data)
|
||||||
mcc->def->misa_ext |= def->misa_ext;
|
mcc->def->misa_ext |= def->misa_ext;
|
||||||
|
|
||||||
riscv_cpu_cfg_merge(&mcc->def->cfg, &def->cfg);
|
riscv_cpu_cfg_merge(&mcc->def->cfg, &def->cfg);
|
||||||
|
|
||||||
|
if (def->custom_csrs) {
|
||||||
|
assert(!mcc->def->custom_csrs);
|
||||||
|
mcc->def->custom_csrs = def->custom_csrs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!object_class_is_abstract(c)) {
|
if (!object_class_is_abstract(c)) {
|
||||||
|
|
|
@ -538,6 +538,8 @@ struct ArchCPU {
|
||||||
const GPtrArray *decoders;
|
const GPtrArray *decoders;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct RISCVCSR RISCVCSR;
|
||||||
|
|
||||||
typedef struct RISCVCPUDef {
|
typedef struct RISCVCPUDef {
|
||||||
RISCVMXL misa_mxl_max; /* max mxl for this cpu */
|
RISCVMXL misa_mxl_max; /* max mxl for this cpu */
|
||||||
RISCVCPUProfile *profile;
|
RISCVCPUProfile *profile;
|
||||||
|
@ -546,6 +548,7 @@ typedef struct RISCVCPUDef {
|
||||||
int32_t vext_spec;
|
int32_t vext_spec;
|
||||||
RISCVCPUConfig cfg;
|
RISCVCPUConfig cfg;
|
||||||
bool bare;
|
bool bare;
|
||||||
|
const RISCVCSR *custom_csrs;
|
||||||
} RISCVCPUDef;
|
} RISCVCPUDef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -893,6 +896,12 @@ typedef struct {
|
||||||
uint32_t min_priv_ver;
|
uint32_t min_priv_ver;
|
||||||
} riscv_csr_operations;
|
} riscv_csr_operations;
|
||||||
|
|
||||||
|
struct RISCVCSR {
|
||||||
|
int csrno;
|
||||||
|
bool (*insertion_test)(RISCVCPU *cpu);
|
||||||
|
riscv_csr_operations csr_ops;
|
||||||
|
};
|
||||||
|
|
||||||
/* CSR function table constants */
|
/* CSR function table constants */
|
||||||
enum {
|
enum {
|
||||||
CSR_TABLE_SIZE = 0x1000
|
CSR_TABLE_SIZE = 0x1000
|
||||||
|
@ -947,7 +956,7 @@ extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
|
||||||
extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
|
extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
|
||||||
|
|
||||||
void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
|
void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
|
||||||
void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
|
void riscv_set_csr_ops(int csrno, const riscv_csr_operations *ops);
|
||||||
|
|
||||||
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
|
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
|
||||||
|
|
||||||
|
@ -956,8 +965,8 @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
|
||||||
|
|
||||||
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
|
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
|
||||||
|
|
||||||
/* Implemented in th_csr.c */
|
/* In th_csr.c */
|
||||||
void th_register_custom_csrs(RISCVCPU *cpu);
|
extern const RISCVCSR th_csr_list[];
|
||||||
|
|
||||||
const char *priv_spec_to_str(int priv_version);
|
const char *priv_spec_to_str(int priv_version);
|
||||||
#endif /* RISCV_CPU_H */
|
#endif /* RISCV_CPU_H */
|
||||||
|
|
|
@ -40,7 +40,7 @@ void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
|
||||||
*ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
|
*ops = csr_ops[csrno & (CSR_TABLE_SIZE - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
|
void riscv_set_csr_ops(int csrno, const riscv_csr_operations *ops)
|
||||||
{
|
{
|
||||||
csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
|
csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,6 @@
|
||||||
#define TH_SXSTATUS_MAEE BIT(21)
|
#define TH_SXSTATUS_MAEE BIT(21)
|
||||||
#define TH_SXSTATUS_THEADISAEE BIT(22)
|
#define TH_SXSTATUS_THEADISAEE BIT(22)
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int csrno;
|
|
||||||
bool (*insertion_test)(RISCVCPU *cpu);
|
|
||||||
riscv_csr_operations csr_ops;
|
|
||||||
} riscv_csr;
|
|
||||||
|
|
||||||
static RISCVException smode(CPURISCVState *env, int csrno)
|
static RISCVException smode(CPURISCVState *env, int csrno)
|
||||||
{
|
{
|
||||||
if (riscv_has_ext(env, RVS)) {
|
if (riscv_has_ext(env, RVS)) {
|
||||||
|
@ -55,20 +49,11 @@ static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
|
||||||
return RISCV_EXCP_NONE;
|
return RISCV_EXCP_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static riscv_csr th_csr_list[] = {
|
const RISCVCSR th_csr_list[] = {
|
||||||
{
|
{
|
||||||
.csrno = CSR_TH_SXSTATUS,
|
.csrno = CSR_TH_SXSTATUS,
|
||||||
.insertion_test = test_thead_mvendorid,
|
.insertion_test = test_thead_mvendorid,
|
||||||
.csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
|
.csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
|
||||||
}
|
},
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
void th_register_custom_csrs(RISCVCPU *cpu)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
|
|
||||||
int csrno = th_csr_list[i].csrno;
|
|
||||||
riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
|
|
||||||
if (!th_csr_list[i].insertion_test || th_csr_list[i].insertion_test(cpu)) {
|
|
||||||
riscv_set_csr_ops(csrno, csr_ops);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue