aboutsummaryrefslogtreecommitdiff
path: root/target/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'target/riscv')
-rw-r--r--target/riscv/cpu.c31
-rw-r--r--target/riscv/cpu_bits.h12
-rw-r--r--target/riscv/cpu_helper.c3
-rw-r--r--target/riscv/csr.c26
4 files changed, 52 insertions, 20 deletions
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 13575c1..7c626d8 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -567,11 +567,41 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
mcc->parent_realize(dev, errp);
}
+#ifndef CONFIG_USER_ONLY
+static void riscv_cpu_set_irq(void *opaque, int irq, int level)
+{
+ RISCVCPU *cpu = RISCV_CPU(opaque);
+
+ switch (irq) {
+ case IRQ_U_SOFT:
+ case IRQ_S_SOFT:
+ case IRQ_VS_SOFT:
+ case IRQ_M_SOFT:
+ case IRQ_U_TIMER:
+ case IRQ_S_TIMER:
+ case IRQ_VS_TIMER:
+ case IRQ_M_TIMER:
+ case IRQ_U_EXT:
+ case IRQ_S_EXT:
+ case IRQ_VS_EXT:
+ case IRQ_M_EXT:
+ riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+#endif /* CONFIG_USER_ONLY */
+
static void riscv_cpu_init(Object *obj)
{
RISCVCPU *cpu = RISCV_CPU(obj);
cpu_set_cpustate_pointers(cpu);
+
+#ifndef CONFIG_USER_ONLY
+ qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, 12);
+#endif /* CONFIG_USER_ONLY */
}
static Property riscv_cpu_properties[] = {
@@ -599,6 +629,7 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+ /* ePMP 0.9.3 */
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 7330ff5..999187a 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -210,8 +210,8 @@
#define CSR_MTVAL2 0x34b
/* Enhanced Physical Memory Protection (ePMP) */
-#define CSR_MSECCFG 0x390
-#define CSR_MSECCFGH 0x391
+#define CSR_MSECCFG 0x747
+#define CSR_MSECCFGH 0x757
/* Physical Memory Protection */
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
@@ -397,10 +397,10 @@
#define HSTATUS32_WPRI 0xFF8FF87E
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
-#define HCOUNTEREN_CY (1 << 0)
-#define HCOUNTEREN_TM (1 << 1)
-#define HCOUNTEREN_IR (1 << 2)
-#define HCOUNTEREN_HPM3 (1 << 3)
+#define COUNTEREN_CY (1 << 0)
+#define COUNTEREN_TM (1 << 1)
+#define COUNTEREN_IR (1 << 2)
+#define COUNTEREN_HPM3 (1 << 3)
/* Privilege modes */
#define PRV_U 0
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 701858d..d41d5cd 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -106,9 +106,10 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
{
+ uint64_t sd = riscv_cpu_is_32bit(env) ? MSTATUS32_SD : MSTATUS64_SD;
uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
- MSTATUS64_UXL;
+ MSTATUS64_UXL | sd;
bool current_virt = riscv_cpu_virt_enabled(env);
g_assert(riscv_has_ext(env, RVH));
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 50a2c3a..23fbbd3 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -71,20 +71,20 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
if (riscv_cpu_virt_enabled(env)) {
switch (csrno) {
case CSR_CYCLE:
- if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
- get_field(env->mcounteren, HCOUNTEREN_CY)) {
+ if (!get_field(env->hcounteren, COUNTEREN_CY) &&
+ get_field(env->mcounteren, COUNTEREN_CY)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_TIME:
- if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
- get_field(env->mcounteren, HCOUNTEREN_TM)) {
+ if (!get_field(env->hcounteren, COUNTEREN_TM) &&
+ get_field(env->mcounteren, COUNTEREN_TM)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_INSTRET:
- if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
- get_field(env->mcounteren, HCOUNTEREN_IR)) {
+ if (!get_field(env->hcounteren, COUNTEREN_IR) &&
+ get_field(env->mcounteren, COUNTEREN_IR)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
@@ -98,20 +98,20 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
if (riscv_cpu_is_32bit(env)) {
switch (csrno) {
case CSR_CYCLEH:
- if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
- get_field(env->mcounteren, HCOUNTEREN_CY)) {
+ if (!get_field(env->hcounteren, COUNTEREN_CY) &&
+ get_field(env->mcounteren, COUNTEREN_CY)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_TIMEH:
- if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
- get_field(env->mcounteren, HCOUNTEREN_TM)) {
+ if (!get_field(env->hcounteren, COUNTEREN_TM) &&
+ get_field(env->mcounteren, COUNTEREN_TM)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
case CSR_INSTRETH:
- if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
- get_field(env->mcounteren, HCOUNTEREN_IR)) {
+ if (!get_field(env->hcounteren, COUNTEREN_IR) &&
+ get_field(env->mcounteren, COUNTEREN_IR)) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
break;
@@ -986,7 +986,7 @@ static RISCVException read_satp(CPURISCVState *env, int csrno,
static RISCVException write_satp(CPURISCVState *env, int csrno,
target_ulong val)
{
- int vm, mask, asid;
+ target_ulong vm, mask, asid;
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
return RISCV_EXCP_NONE;