hvf: arm: Raise an exception for sysreg by default
Any sysreg access results in an exception unless defined otherwise so we should raise an exception by default. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
0d2aac4ab1
commit
e9e640148c
@ -1199,57 +1199,56 @@ static bool hvf_sysreg_read_cp(CPUState *cpu, uint32_t reg, uint64_t *val)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
|
||||
static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint64_t *val)
|
||||
{
|
||||
ARMCPU *arm_cpu = ARM_CPU(cpu);
|
||||
CPUARMState *env = &arm_cpu->env;
|
||||
uint64_t val = 0;
|
||||
|
||||
switch (reg) {
|
||||
case SYSREG_CNTPCT_EL0:
|
||||
val = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
|
||||
*val = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
|
||||
gt_cntfrq_period_ns(arm_cpu);
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMCR_EL0:
|
||||
val = env->cp15.c9_pmcr;
|
||||
break;
|
||||
*val = env->cp15.c9_pmcr;
|
||||
return 0;
|
||||
case SYSREG_PMCCNTR_EL0:
|
||||
pmu_op_start(env);
|
||||
val = env->cp15.c15_ccnt;
|
||||
*val = env->cp15.c15_ccnt;
|
||||
pmu_op_finish(env);
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMCNTENCLR_EL0:
|
||||
val = env->cp15.c9_pmcnten;
|
||||
break;
|
||||
*val = env->cp15.c9_pmcnten;
|
||||
return 0;
|
||||
case SYSREG_PMOVSCLR_EL0:
|
||||
val = env->cp15.c9_pmovsr;
|
||||
break;
|
||||
*val = env->cp15.c9_pmovsr;
|
||||
return 0;
|
||||
case SYSREG_PMSELR_EL0:
|
||||
val = env->cp15.c9_pmselr;
|
||||
break;
|
||||
*val = env->cp15.c9_pmselr;
|
||||
return 0;
|
||||
case SYSREG_PMINTENCLR_EL1:
|
||||
val = env->cp15.c9_pminten;
|
||||
break;
|
||||
*val = env->cp15.c9_pminten;
|
||||
return 0;
|
||||
case SYSREG_PMCCFILTR_EL0:
|
||||
val = env->cp15.pmccfiltr_el0;
|
||||
break;
|
||||
*val = env->cp15.pmccfiltr_el0;
|
||||
return 0;
|
||||
case SYSREG_PMCNTENSET_EL0:
|
||||
val = env->cp15.c9_pmcnten;
|
||||
break;
|
||||
*val = env->cp15.c9_pmcnten;
|
||||
return 0;
|
||||
case SYSREG_PMUSERENR_EL0:
|
||||
val = env->cp15.c9_pmuserenr;
|
||||
break;
|
||||
*val = env->cp15.c9_pmuserenr;
|
||||
return 0;
|
||||
case SYSREG_PMCEID0_EL0:
|
||||
case SYSREG_PMCEID1_EL0:
|
||||
/* We can't really count anything yet, declare all events invalid */
|
||||
val = 0;
|
||||
break;
|
||||
*val = 0;
|
||||
return 0;
|
||||
case SYSREG_OSLSR_EL1:
|
||||
val = env->cp15.oslsr_el1;
|
||||
break;
|
||||
*val = env->cp15.oslsr_el1;
|
||||
return 0;
|
||||
case SYSREG_OSDLR_EL1:
|
||||
/* Dummy register */
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_ICC_AP0R0_EL1:
|
||||
case SYSREG_ICC_AP0R1_EL1:
|
||||
case SYSREG_ICC_AP0R2_EL1:
|
||||
@ -1276,9 +1275,8 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
|
||||
case SYSREG_ICC_SRE_EL1:
|
||||
case SYSREG_ICC_CTLR_EL1:
|
||||
/* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
|
||||
if (!hvf_sysreg_read_cp(cpu, reg, &val)) {
|
||||
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
|
||||
return 1;
|
||||
if (hvf_sysreg_read_cp(cpu, reg, &val)) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case SYSREG_DBGBVR0_EL1:
|
||||
@ -1297,8 +1295,8 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
|
||||
case SYSREG_DBGBVR13_EL1:
|
||||
case SYSREG_DBGBVR14_EL1:
|
||||
case SYSREG_DBGBVR15_EL1:
|
||||
val = env->cp15.dbgbvr[SYSREG_CRM(reg)];
|
||||
break;
|
||||
*val = env->cp15.dbgbvr[SYSREG_CRM(reg)];
|
||||
return 0;
|
||||
case SYSREG_DBGBCR0_EL1:
|
||||
case SYSREG_DBGBCR1_EL1:
|
||||
case SYSREG_DBGBCR2_EL1:
|
||||
@ -1315,8 +1313,8 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
|
||||
case SYSREG_DBGBCR13_EL1:
|
||||
case SYSREG_DBGBCR14_EL1:
|
||||
case SYSREG_DBGBCR15_EL1:
|
||||
val = env->cp15.dbgbcr[SYSREG_CRM(reg)];
|
||||
break;
|
||||
*val = env->cp15.dbgbcr[SYSREG_CRM(reg)];
|
||||
return 0;
|
||||
case SYSREG_DBGWVR0_EL1:
|
||||
case SYSREG_DBGWVR1_EL1:
|
||||
case SYSREG_DBGWVR2_EL1:
|
||||
@ -1333,8 +1331,8 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
|
||||
case SYSREG_DBGWVR13_EL1:
|
||||
case SYSREG_DBGWVR14_EL1:
|
||||
case SYSREG_DBGWVR15_EL1:
|
||||
val = env->cp15.dbgwvr[SYSREG_CRM(reg)];
|
||||
break;
|
||||
*val = env->cp15.dbgwvr[SYSREG_CRM(reg)];
|
||||
return 0;
|
||||
case SYSREG_DBGWCR0_EL1:
|
||||
case SYSREG_DBGWCR1_EL1:
|
||||
case SYSREG_DBGWCR2_EL1:
|
||||
@ -1351,35 +1349,25 @@ static int hvf_sysreg_read(CPUState *cpu, uint32_t reg, uint32_t rt)
|
||||
case SYSREG_DBGWCR13_EL1:
|
||||
case SYSREG_DBGWCR14_EL1:
|
||||
case SYSREG_DBGWCR15_EL1:
|
||||
val = env->cp15.dbgwcr[SYSREG_CRM(reg)];
|
||||
break;
|
||||
*val = env->cp15.dbgwcr[SYSREG_CRM(reg)];
|
||||
return 0;
|
||||
default:
|
||||
if (is_id_sysreg(reg)) {
|
||||
/* ID system registers read as RES0 */
|
||||
val = 0;
|
||||
break;
|
||||
*val = 0;
|
||||
return 0;
|
||||
}
|
||||
cpu_synchronize_state(cpu);
|
||||
trace_hvf_unhandled_sysreg_read(env->pc, reg,
|
||||
SYSREG_OP0(reg),
|
||||
SYSREG_OP1(reg),
|
||||
SYSREG_CRN(reg),
|
||||
SYSREG_CRM(reg),
|
||||
SYSREG_OP2(reg));
|
||||
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
|
||||
return 1;
|
||||
}
|
||||
|
||||
trace_hvf_sysreg_read(reg,
|
||||
SYSREG_OP0(reg),
|
||||
SYSREG_OP1(reg),
|
||||
SYSREG_CRN(reg),
|
||||
SYSREG_CRM(reg),
|
||||
SYSREG_OP2(reg),
|
||||
val);
|
||||
hvf_set_reg(cpu, rt, val);
|
||||
|
||||
return 0;
|
||||
cpu_synchronize_state(cpu);
|
||||
trace_hvf_unhandled_sysreg_read(env->pc, reg,
|
||||
SYSREG_OP0(reg),
|
||||
SYSREG_OP1(reg),
|
||||
SYSREG_CRN(reg),
|
||||
SYSREG_CRM(reg),
|
||||
SYSREG_OP2(reg));
|
||||
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pmu_update_irq(CPUARMState *env)
|
||||
@ -1503,7 +1491,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
|
||||
pmu_op_start(env);
|
||||
env->cp15.c15_ccnt = val;
|
||||
pmu_op_finish(env);
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMCR_EL0:
|
||||
pmu_op_start(env);
|
||||
|
||||
@ -1523,45 +1511,45 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
|
||||
env->cp15.c9_pmcr |= (val & PMCR_WRITABLE_MASK);
|
||||
|
||||
pmu_op_finish(env);
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMUSERENR_EL0:
|
||||
env->cp15.c9_pmuserenr = val & 0xf;
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMCNTENSET_EL0:
|
||||
env->cp15.c9_pmcnten |= (val & pmu_counter_mask(env));
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMCNTENCLR_EL0:
|
||||
env->cp15.c9_pmcnten &= ~(val & pmu_counter_mask(env));
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMINTENCLR_EL1:
|
||||
pmu_op_start(env);
|
||||
env->cp15.c9_pminten |= val;
|
||||
pmu_op_finish(env);
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMOVSCLR_EL0:
|
||||
pmu_op_start(env);
|
||||
env->cp15.c9_pmovsr &= ~val;
|
||||
pmu_op_finish(env);
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMSWINC_EL0:
|
||||
pmu_op_start(env);
|
||||
pmswinc_write(env, val);
|
||||
pmu_op_finish(env);
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMSELR_EL0:
|
||||
env->cp15.c9_pmselr = val & 0x1f;
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_PMCCFILTR_EL0:
|
||||
pmu_op_start(env);
|
||||
env->cp15.pmccfiltr_el0 = val & PMCCFILTR_EL0;
|
||||
pmu_op_finish(env);
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_OSLAR_EL1:
|
||||
env->cp15.oslsr_el1 = val & 1;
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_OSDLR_EL1:
|
||||
/* Dummy register */
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_ICC_AP0R0_EL1:
|
||||
case SYSREG_ICC_AP0R1_EL1:
|
||||
case SYSREG_ICC_AP0R2_EL1:
|
||||
@ -1591,10 +1579,10 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
|
||||
if (!hvf_sysreg_write_cp(cpu, reg, val)) {
|
||||
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
|
||||
}
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_MDSCR_EL1:
|
||||
env->cp15.mdscr_el1 = val;
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_DBGBVR0_EL1:
|
||||
case SYSREG_DBGBVR1_EL1:
|
||||
case SYSREG_DBGBVR2_EL1:
|
||||
@ -1612,7 +1600,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
|
||||
case SYSREG_DBGBVR14_EL1:
|
||||
case SYSREG_DBGBVR15_EL1:
|
||||
env->cp15.dbgbvr[SYSREG_CRM(reg)] = val;
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_DBGBCR0_EL1:
|
||||
case SYSREG_DBGBCR1_EL1:
|
||||
case SYSREG_DBGBCR2_EL1:
|
||||
@ -1630,7 +1618,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
|
||||
case SYSREG_DBGBCR14_EL1:
|
||||
case SYSREG_DBGBCR15_EL1:
|
||||
env->cp15.dbgbcr[SYSREG_CRM(reg)] = val;
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_DBGWVR0_EL1:
|
||||
case SYSREG_DBGWVR1_EL1:
|
||||
case SYSREG_DBGWVR2_EL1:
|
||||
@ -1648,7 +1636,7 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
|
||||
case SYSREG_DBGWVR14_EL1:
|
||||
case SYSREG_DBGWVR15_EL1:
|
||||
env->cp15.dbgwvr[SYSREG_CRM(reg)] = val;
|
||||
break;
|
||||
return 0;
|
||||
case SYSREG_DBGWCR0_EL1:
|
||||
case SYSREG_DBGWCR1_EL1:
|
||||
case SYSREG_DBGWCR2_EL1:
|
||||
@ -1666,20 +1654,18 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, uint64_t val)
|
||||
case SYSREG_DBGWCR14_EL1:
|
||||
case SYSREG_DBGWCR15_EL1:
|
||||
env->cp15.dbgwcr[SYSREG_CRM(reg)] = val;
|
||||
break;
|
||||
default:
|
||||
cpu_synchronize_state(cpu);
|
||||
trace_hvf_unhandled_sysreg_write(env->pc, reg,
|
||||
SYSREG_OP0(reg),
|
||||
SYSREG_OP1(reg),
|
||||
SYSREG_CRN(reg),
|
||||
SYSREG_CRM(reg),
|
||||
SYSREG_OP2(reg));
|
||||
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
cpu_synchronize_state(cpu);
|
||||
trace_hvf_unhandled_sysreg_write(env->pc, reg,
|
||||
SYSREG_OP0(reg),
|
||||
SYSREG_OP1(reg),
|
||||
SYSREG_CRN(reg),
|
||||
SYSREG_CRM(reg),
|
||||
SYSREG_OP2(reg));
|
||||
hvf_raise_exception(cpu, EXCP_UDEF, syn_uncategorized());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int hvf_inject_interrupts(CPUState *cpu)
|
||||
@ -1944,7 +1930,17 @@ int hvf_vcpu_exec(CPUState *cpu)
|
||||
int sysreg_ret = 0;
|
||||
|
||||
if (isread) {
|
||||
sysreg_ret = hvf_sysreg_read(cpu, reg, rt);
|
||||
sysreg_ret = hvf_sysreg_read(cpu, reg, &val);
|
||||
if (!sysreg_ret) {
|
||||
trace_hvf_sysreg_read(reg,
|
||||
SYSREG_OP0(reg),
|
||||
SYSREG_OP1(reg),
|
||||
SYSREG_CRN(reg),
|
||||
SYSREG_CRM(reg),
|
||||
SYSREG_OP2(reg),
|
||||
val);
|
||||
hvf_set_reg(cpu, rt, val);
|
||||
}
|
||||
} else {
|
||||
val = hvf_get_reg(cpu, rt);
|
||||
sysreg_ret = hvf_sysreg_write(cpu, reg, val);
|
||||
|
Loading…
Reference in New Issue
Block a user