Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cdae491
target/riscv: Define simpler privileged spec version numbering
atishp04 Mar 3, 2022
bed347c
target/riscv: Add the privileged spec version 1.12.0
atishp04 Mar 3, 2022
0aad94d
target/riscv: Introduce privilege version field in the CSR ops.
atishp04 Mar 3, 2022
409917c
target/riscv: Enable privileged spec version 1.12
atishp04 Mar 3, 2022
7224187
target/riscv: Implement mcountinhibit CSR
atishp04 Jun 20, 2022
dd96dae
target/riscv: Set minumum priv spec version for mcountinhibit
avpatel Jun 28, 2022
d46cac9
riscv: add dummy henvcfg
martin-kaiser Jan 23, 2025
2ec78cc
RVY: move MSECCFG_CRE to mseccfg_field_t
arichardson Nov 4, 2025
5e03f60
target/riscv: Add *envcfg* CSRs support
atishp04 Mar 3, 2022
5029a3a
target/riscv: Add isa extenstion strings to the device tree
atishp04 Mar 29, 2022
4ef565a
RVY 0.9.3: Add CHERI isa extension strings
Oct 3, 2024
be69871
RVY 0.9.3: Add zcheripte extension string
buxtonpaul Jan 9, 2025
9fffb1d
RVY 0.9.3: Add zcherilevels to isa string if enabled
martin-kaiser Jan 9, 2025
f82e604
target/riscv: implement Zicboz extension
cmuellner Feb 24, 2023
f2c8a03
target/riscv: implement Zicbom extension
cmuellner Jan 21, 2025
5cec02c
riscv: cboz_blocksize must be a power of two
martin-kaiser Jan 27, 2025
b683fb9
riscv: cbom_blocksize must be a power of two
martin-kaiser Jan 27, 2025
fe39ebd
riscv: move cbo zero handling into a helper
martin-kaiser Jan 22, 2025
e01ad58
riscv: cbo: move some checks out of do_cbo_zero
martin-kaiser Jan 22, 2025
7b26f5d
riscv: cheri: helper for capability version of cbo.zero
martin-kaiser Jan 22, 2025
35210ed
riscv: cheri: clear tags during cbo.zero
martin-kaiser Jan 24, 2025
0fdb822
riscv: cheri: call cheri or non-cheri helper for cbo.zero
martin-kaiser Jan 22, 2025
44bfd09
riscv: cheri: Add cheri support for zicbom instructions
martin-kaiser Jan 23, 2025
63cb322
target/riscv: fix -Wunused function for is_cap_csr
arichardson Nov 4, 2025
4cf4ae6
target/riscv: Switch Codasip A730 to privileged spec version 1.12
Mar 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 75 additions & 6 deletions target/riscv/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@

static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";

struct isa_ext_data {
const char *name;
bool enabled;
};

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",
Expand Down Expand Up @@ -188,7 +193,7 @@ static void riscv_any_cpu_init(Object *obj)
#elif defined(TARGET_RISCV64)
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
#endif
set_priv_version(env, PRIV_VERSION_1_11_0);
set_priv_version(env, PRIV_VERSION_1_12_0);
}

#if defined(TARGET_RISCV64)
Expand Down Expand Up @@ -220,8 +225,7 @@ static void rv64_codasip_a730_cpu_init(Object *obj)

set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);

/* This CPU supports priv v1.12. QEMU 6.x supports only up to 1.11. */
set_priv_version(env, PRIV_VERSION_1_11_0);
set_priv_version(env, PRIV_VERSION_1_12_0);

qdev_prop_set_bit(DEVICE(obj), "mmu", true);
qdev_prop_set_bit(DEVICE(obj), "pmp", false);
Expand Down Expand Up @@ -786,6 +790,7 @@ static void riscv_cpu_reset(DeviceState *dev)
env->mseccfg = 0;
env->menvcfg = 0;
env->senvcfg = 0;
env->henvcfg = 0;
// All general purpose capability registers are reset to NULL:
reset_capregs(env);
/*
Expand Down Expand Up @@ -862,7 +867,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
}

if (cpu->cfg.priv_spec) {
if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
priv_version = PRIV_VERSION_1_12_0;
} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
priv_version = PRIV_VERSION_1_11_0;
} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
priv_version = PRIV_VERSION_1_10_0;
Expand All @@ -877,7 +884,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
if (priv_version) {
set_priv_version(env, priv_version);
} else if (!env->priv_ver) {
set_priv_version(env, PRIV_VERSION_1_11_0);
set_priv_version(env, PRIV_VERSION_1_12_0);
}

if (cpu->cfg.mmu) {
Expand Down Expand Up @@ -1017,6 +1024,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
set_misa(env, env->misa_mxl, ext);
}

CHK_BLK_POW2(cbom_blocksize);
CHK_BLK_POW2(cboz_blocksize);

#ifdef TARGET_CHERI
if (cpu->cfg.ext_cheri) {
set_feature(env, RISCV_FEATURE_CHERI);
Expand Down Expand Up @@ -1125,6 +1135,9 @@ static Property riscv_cpu_properties[] = {
#endif
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),

DEFINE_PROP_BOOL("zicbom", RISCVCPU, cfg.ext_icbom, true),
DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),

/* These are experimental so mark with 'x-' */
DEFINE_PROP_BOOL("x-zba", RISCVCPU, cfg.ext_zba, false),
DEFINE_PROP_BOOL("x-zbb", RISCVCPU, cfg.ext_zbb, false),
Expand All @@ -1133,6 +1146,10 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),

DEFINE_PROP_BOOL("zicboz", RISCVCPU, cfg.ext_icboz, true),
DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),

#ifdef TARGET_CHERI_RISCV_V9
DEFINE_PROP_BOOL("Xcheri", RISCVCPU, cfg.ext_cheri, true),
DEFINE_PROP_BOOL("Xcheri_v9", RISCVCPU, cfg.ext_cheri_v9, true),
Expand Down Expand Up @@ -1247,6 +1264,58 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
device_class_set_props(dc, riscv_cpu_properties);
}

#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop}

static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len)
{
char *old = *isa_str;
char *new = *isa_str;
int i;

/**
* Here are the ordering rules of extension naming defined by RISC-V
* specification :
* 1. All extensions should be separated from other multi-letter extensions
* by an underscore.
* 2. The first letter following the 'Z' conventionally indicates the most
* closely related alphabetical extension category, IMAFDQLCBKJTPVH.
* If multiple 'Z' extensions are named, they should be ordered first
* by category, then alphabetically within a category.
* 3. Standard supervisor-level extensions (starts with 'S') should be
* listed after standard unprivileged extensions. If multiple
* supervisor-level extensions are listed, they should be ordered
* alphabetically.
* 4. Non-standard extensions (starts with 'X') must be listed after all
* standard extensions. They must be separated from other multi-letter
* extensions by an underscore.
*/
struct isa_ext_data isa_edata_arr[] = {
ISA_EDATA_ENTRY(zba, ext_zba),
ISA_EDATA_ENTRY(zbb, ext_zbb),
ISA_EDATA_ENTRY(zbc, ext_zbc),
ISA_EDATA_ENTRY(zbs, ext_zbs),
ISA_EDATA_ENTRY(zicbom, ext_icbom),
ISA_EDATA_ENTRY(zicboz, ext_icboz),
#ifdef TARGET_CHERI_RISCV_STD_093
{"zcherihybrid", cpu->cfg.ext_zyhybrid},
{"zcheripurecap", cpu->cfg.ext_cheri},
{"zcheripte", cpu->cfg.cheri_pte },
{"zcherilevels", cpu->cfg.lvbits > 0 },
ISA_EDATA_ENTRY(zish4add, ext_zish4add),
#endif
};

for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
if (isa_edata_arr[i].enabled) {
new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
g_free(old);
old = new;
}
}

*isa_str = new;
}

char *riscv_isa_string(RISCVCPU *cpu)
{
int i;
Expand All @@ -1259,7 +1328,7 @@ char *riscv_isa_string(RISCVCPU *cpu)
}
}
*p = '\0';
// TODO: add Xcheri?
riscv_isa_string_ext(cpu, &isa_str, maxlen);
return isa_str;
}

Expand Down
30 changes: 28 additions & 2 deletions target/riscv/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@ enum {
RISCV_FEATURE_STID,
};

#define PRIV_VERSION_1_10_0 0x00011000
#define PRIV_VERSION_1_11_0 0x00011100
/* Privileged specification version */
enum {
PRIV_VERSION_1_10_0 = 0,
PRIV_VERSION_1_11_0,
PRIV_VERSION_1_12_0,
};

#define VEXT_VERSION_0_07_1 0x00000701

Expand Down Expand Up @@ -290,6 +294,9 @@ struct CPURISCVState {
target_ulong scounteren;
target_ulong mcounteren;

target_ulong mcountinhibit;


#ifdef TARGET_CHERI
/* zstid registers */
cap_register_t mtidc;
Expand Down Expand Up @@ -336,8 +343,10 @@ struct CPURISCVState {
target_ulong upmmask;
target_ulong upmbase;

/* CSRs for execution enviornment configuration */
uint64_t menvcfg;
target_ulong senvcfg;
uint64_t henvcfg;
#endif

float_status fp_status;
Expand Down Expand Up @@ -459,6 +468,9 @@ struct RISCVCPU {
bool ext_counters;
bool ext_ifencei;
bool ext_icsr;
bool ext_icbom;
bool ext_icboz;
#ifdef TARGET_CHERI
#ifdef TARGET_CHERI_RISCV_V9
bool ext_cheri;
bool ext_cheri_v9; /* Temporary flag to support new semantics. */
Expand All @@ -471,6 +483,7 @@ struct RISCVCPU {
uint8_t lvbits; /* Only 0 and 1 (Zylevels1) are currently supported. */
bool cheri_pte;
#endif
#endif
#if defined(TARGET_CHERI_RISCV_STD_093)
bool ext_zish4add;
#endif
Expand All @@ -480,6 +493,8 @@ struct RISCVCPU {
char *vext_spec;
uint16_t vlen;
uint16_t elen;
uint16_t cbom_blocksize;
uint16_t cboz_blocksize;
bool mmu;
bool pmp;
bool epmp;
Expand Down Expand Up @@ -519,6 +534,15 @@ void riscv_log_instr_csr_changed(CPURISCVState *env, int csrno);
#define riscv_log_instr_csr_changed(env, csrno) ((void)0)
#endif /* !CONFIG_TCG_LOG_INSTR */

#define CHK_BLK_POW2(prop) \
do { \
if ((cpu->cfg.prop == 0) || \
(cpu->cfg.prop & (cpu->cfg.prop - 1))) { \
error_setg(errp, "%s must be a power of 2.", tostring(prop)); \
return; \
} \
} while (0)

/*
* From 5.3.6 Special Capability Registers (SCRs)
* Where an SCR extends a RISC-V CSR, e.g. MTCC extending mtvec, any read to the
Expand Down Expand Up @@ -850,6 +874,8 @@ typedef struct {
riscv_csr_write_fn write;
riscv_csr_op_fn op;
riscv_csr_log_update_fn log_update;
/* The default priv spec version should be PRIV_VERSION_1_10_0 (i.e 0) */
uint32_t min_priv_ver;
} riscv_csr_operations;

/* CSR function table constants */
Expand Down
58 changes: 45 additions & 13 deletions target/riscv/cpu_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@
#define CSR_STVEC 0x105
#define CSR_SCOUNTEREN 0x106

/* Supervisor Configuration CSRs */
#define CSR_SENVCFG 0x10A

/* Supervisor Trap Handling */
#define CSR_SSCRATCH 0x140
#define CSR_SEPC 0x141
Expand Down Expand Up @@ -209,6 +212,10 @@
#define CSR_HTIMEDELTA 0x605
#define CSR_HTIMEDELTAH 0x615

/* Hypervisor Configuration CSRs */
#define CSR_HENVCFG 0x60A
#define CSR_HENVCFGH 0x61A

/* Virtual CSRs */
#define CSR_VSSTATUS 0x200
#define CSR_VSIE 0x204
Expand All @@ -226,8 +233,9 @@
#define CSR_VSEPCC CSR_VSEPC
#endif

#define CSR_MENVCFG 0x30a
#define CSR_SENVCFG 0x10a
/* Machine Configuration CSRs */
#define CSR_MENVCFG 0x30A
#define CSR_MENVCFGH 0x31A

#ifdef TARGET_CHERI_RISCV_STD_093
#define CSR_STVAL2 0x14b
Expand Down Expand Up @@ -346,6 +354,10 @@
#define CSR_MHPMCOUNTER29 0xb1d
#define CSR_MHPMCOUNTER30 0xb1e
#define CSR_MHPMCOUNTER31 0xb1f

/* Machine counter-inhibit register */
#define CSR_MCOUNTINHIBIT 0x320

#define CSR_MHPMEVENT3 0x323
#define CSR_MHPMEVENT4 0x324
#define CSR_MHPMEVENT5 0x325
Expand Down Expand Up @@ -689,6 +701,37 @@ typedef enum RISCVException {
#define PM_EXT_CLEAN 0x00000002ULL
#define PM_EXT_DIRTY 0x00000003ULL

/* Execution enviornment configuration bits */
#define MENVCFG_FIOM BIT(0)
#define MENVCFG_CBIE (3UL << 4)
#define MENVCFG_CBCFE BIT(6)
#define MENVCFG_CBZE BIT(7)
#define MENVCFG_CRE BIT(28)
#define MENVCFG_PBMTE (1ULL << 62)
#define MENVCFG_STCE (1ULL << 63)

/* For RV32 */
#define MENVCFGH_PBMTE BIT(30)
#define MENVCFGH_STCE BIT(31)

#define SENVCFG_FIOM MENVCFG_FIOM
#define SENVCFG_CBIE MENVCFG_CBIE
#define SENVCFG_CBCFE MENVCFG_CBCFE
#define SENVCFG_CBZE MENVCFG_CBZE
#define SENVCFG_CRE MENVCFG_CRE

#define HENVCFG_FIOM MENVCFG_FIOM
#define HENVCFG_CBIE MENVCFG_CBIE
#define HENVCFG_CBCFE MENVCFG_CBCFE
#define HENVCFG_CBZE MENVCFG_CBZE
#define HENVCFG_CRE MENVCFG_CRE
#define HENVCFG_PBMTE MENVCFG_PBMTE
#define HENVCFG_STCE MENVCFG_STCE

/* For RV32 */
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
#define HENVCFGH_STCE MENVCFGH_STCE

/* Offsets for every pair of control bits per each priv level */
#define XS_OFFSET 0ULL
#define U_OFFSET 2ULL
Expand Down Expand Up @@ -741,15 +784,4 @@ typedef enum RISCVException {
#define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN)


/*
* The CRE bits are used only if cheri is enabled. Together with the M bit,
* they define if the system operates in integer or capability pointer mode.
*
* The size of the corresponding CSRs depends on (M)XLEN. As the CRE bits are
* always in the lower 32 bits, the definitions don't have to take this into
* account.
*/
#define MSECCFG_CRE (1 << 3)
#define MENVCFG_CRE (1 << 28)
#define SENVCFG_CRE (1 << 28)
#endif
Loading
Loading