aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'target/riscv/cpu.h')
-rw-r--r--target/riscv/cpu.h169
1 files changed, 124 insertions, 45 deletions
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 55635d68d5..8183fb86d5 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -78,7 +78,8 @@ enum {
RISCV_FEATURE_MMU,
RISCV_FEATURE_PMP,
RISCV_FEATURE_EPMP,
- RISCV_FEATURE_MISA
+ RISCV_FEATURE_MISA,
+ RISCV_FEATURE_AIA
};
#define PRIV_VERSION_1_10_0 0x00011000
@@ -161,6 +162,7 @@ struct CPURISCVState {
target_ulong priv;
/* This contains QEMU specific information about the virt state. */
target_ulong virt;
+ target_ulong geilen;
target_ulong resetvec;
target_ulong mhartid;
@@ -170,12 +172,12 @@ struct CPURISCVState {
*/
uint64_t mstatus;
- target_ulong mip;
+ uint64_t mip;
- uint32_t miclaim;
+ uint64_t miclaim;
- target_ulong mie;
- target_ulong mideleg;
+ uint64_t mie;
+ uint64_t mideleg;
target_ulong satp; /* since: priv-1.10.0 */
target_ulong stval;
@@ -190,16 +192,30 @@ struct CPURISCVState {
target_ulong mcause;
target_ulong mtval; /* since: priv-1.10.0 */
+ /* Machine and Supervisor interrupt priorities */
+ uint8_t miprio[64];
+ uint8_t siprio[64];
+
+ /* AIA CSRs */
+ target_ulong miselect;
+ target_ulong siselect;
+
/* Hypervisor CSRs */
target_ulong hstatus;
target_ulong hedeleg;
- target_ulong hideleg;
+ uint64_t hideleg;
target_ulong hcounteren;
target_ulong htval;
target_ulong htinst;
target_ulong hgatp;
+ target_ulong hgeie;
+ target_ulong hgeip;
uint64_t htimedelta;
+ /* Hypervisor controlled virtual interrupt priorities */
+ target_ulong hvictl;
+ uint8_t hviprio[64];
+
/* Upper 64-bits of 128-bit CSRs */
uint64_t mscratchh;
uint64_t sscratchh;
@@ -217,6 +233,9 @@ struct CPURISCVState {
target_ulong vstval;
target_ulong vsatp;
+ /* AIA VS-mode CSRs */
+ target_ulong vsiselect;
+
target_ulong mtval2;
target_ulong mtinst;
@@ -252,6 +271,22 @@ struct CPURISCVState {
uint64_t (*rdtime_fn)(uint32_t);
uint32_t rdtime_fn_arg;
+ /* machine specific AIA ireg read-modify-write callback */
+#define AIA_MAKE_IREG(__isel, __priv, __virt, __vgein, __xlen) \
+ ((((__xlen) & 0xff) << 24) | \
+ (((__vgein) & 0x3f) << 20) | \
+ (((__virt) & 0x1) << 18) | \
+ (((__priv) & 0x3) << 16) | \
+ (__isel & 0xffff))
+#define AIA_IREG_ISEL(__ireg) ((__ireg) & 0xffff)
+#define AIA_IREG_PRIV(__ireg) (((__ireg) >> 16) & 0x3)
+#define AIA_IREG_VIRT(__ireg) (((__ireg) >> 18) & 0x1)
+#define AIA_IREG_VGEIN(__ireg) (((__ireg) >> 20) & 0x3f)
+#define AIA_IREG_XLEN(__ireg) (((__ireg) >> 24) & 0xff)
+ int (*aia_ireg_rmw_fn[4])(void *arg, target_ulong reg,
+ target_ulong *val, target_ulong new_val, target_ulong write_mask);
+ void *aia_ireg_rmw_fn_arg[4];
+
/* True if in debugger mode. */
bool debugger;
@@ -303,6 +338,53 @@ struct RISCVCPUClass {
DeviceReset parent_reset;
};
+struct RISCVCPUConfig {
+ bool ext_i;
+ bool ext_e;
+ bool ext_g;
+ bool ext_m;
+ bool ext_a;
+ bool ext_f;
+ bool ext_d;
+ bool ext_c;
+ bool ext_s;
+ bool ext_u;
+ bool ext_h;
+ bool ext_j;
+ bool ext_v;
+ bool ext_zba;
+ bool ext_zbb;
+ bool ext_zbc;
+ bool ext_zbs;
+ bool ext_counters;
+ bool ext_ifencei;
+ bool ext_icsr;
+ bool ext_svinval;
+ bool ext_svnapot;
+ bool ext_svpbmt;
+ bool ext_zfh;
+ bool ext_zfhmin;
+ bool ext_zve32f;
+ bool ext_zve64f;
+
+ /* Vendor-specific custom extensions */
+ bool ext_XVentanaCondOps;
+
+ char *priv_spec;
+ char *user_spec;
+ char *bext_spec;
+ char *vext_spec;
+ uint16_t vlen;
+ uint16_t elen;
+ bool mmu;
+ bool pmp;
+ bool epmp;
+ bool aia;
+ uint64_t resetvec;
+};
+
+typedef struct RISCVCPUConfig RISCVCPUConfig;
+
/**
* RISCVCPU:
* @env: #CPURISCVState
@@ -320,43 +402,7 @@ struct RISCVCPU {
char *dyn_vreg_xml;
/* Configuration Settings */
- struct {
- bool ext_i;
- bool ext_e;
- bool ext_g;
- bool ext_m;
- bool ext_a;
- bool ext_f;
- bool ext_d;
- bool ext_c;
- bool ext_s;
- bool ext_u;
- bool ext_h;
- bool ext_j;
- bool ext_v;
- bool ext_zba;
- bool ext_zbb;
- bool ext_zbc;
- bool ext_zbs;
- bool ext_counters;
- bool ext_ifencei;
- bool ext_icsr;
- bool ext_zfh;
- bool ext_zfhmin;
- bool ext_zve32f;
- bool ext_zve64f;
-
- char *priv_spec;
- char *user_spec;
- char *bext_spec;
- char *vext_spec;
- uint16_t vlen;
- uint16_t elen;
- bool mmu;
- bool pmp;
- bool epmp;
- uint64_t resetvec;
- } cfg;
+ RISCVCPUConfig cfg;
};
static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
@@ -369,6 +415,11 @@ static inline bool riscv_feature(CPURISCVState *env, int feature)
return env->features & (1ULL << feature);
}
+static inline void riscv_set_feature(CPURISCVState *env, int feature)
+{
+ env->features |= (1ULL << feature);
+}
+
#include "cpu_user.h"
extern const char * const riscv_int_regnames[];
@@ -383,7 +434,14 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
int cpuid, void *opaque);
int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero);
+uint8_t riscv_cpu_default_priority(int irq);
+int riscv_cpu_mirq_pending(CPURISCVState *env);
+int riscv_cpu_sirq_pending(CPURISCVState *env);
+int riscv_cpu_vsirq_pending(CPURISCVState *env);
bool riscv_cpu_fp_enabled(CPURISCVState *env);
+target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
+void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
bool riscv_cpu_vector_enabled(CPURISCVState *env);
bool riscv_cpu_virt_enabled(CPURISCVState *env);
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
@@ -410,11 +468,18 @@ void riscv_cpu_list(void);
#ifndef CONFIG_USER_ONLY
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
-int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
-uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
+int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts);
+uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value);
#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
uint32_t arg);
+void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv,
+ int (*rmw_fn)(void *arg,
+ target_ulong reg,
+ target_ulong *val,
+ target_ulong new_val,
+ target_ulong write_mask),
+ void *rmw_fn_arg);
#endif
void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
@@ -459,6 +524,7 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
return env->misa_mxl;
}
#endif
+#define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
#if defined(TARGET_RISCV32)
#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
@@ -495,6 +561,19 @@ static inline int riscv_cpu_xlen(CPURISCVState *env)
return 16 << env->xl;
}
+#ifdef TARGET_RISCV32
+#define riscv_cpu_sxl(env) ((void)(env), MXL_RV32)
+#else
+static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
+{
+#ifdef CONFIG_USER_ONLY
+ return env->misa_mxl;
+#else
+ return get_field(env->mstatus, MSTATUS64_SXL);
+#endif
+}
+#endif
+
/*
* Encode LMUL to lmul as follows:
* LMUL vlmul lmul