diff --git a/qemu/target-arm/cpu.h b/qemu/target-arm/cpu.h index ee7bf419..fd3d57cf 100644 --- a/qemu/target-arm/cpu.h +++ b/qemu/target-arm/cpu.h @@ -213,6 +213,7 @@ typedef struct CPUARMState { uint32_t c9_pminten; /* perf monitor interrupt enables */ uint64_t mair_el1; uint64_t vbar_el[4]; /* vector base address register */ + uint32_t mvbar; /* (monitor) vector base address register */ uint32_t c13_fcse; /* FCSE PID. */ uint64_t contextidr_el1; /* Context ID. */ uint64_t tpidr_el0; /* User RW Thread register. */ diff --git a/qemu/target-arm/helper.c b/qemu/target-arm/helper.c index d840d84c..4c72e7f0 100644 --- a/qemu/target-arm/helper.c +++ b/qemu/target-arm/helper.c @@ -2003,7 +2003,10 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { /* TODO: Implement NSACR trapping of secure EL1 accesses to EL3 */ { "NSACR", 15,1,1, 0,0,2, 0,0, PL3_W | PL1_R, 0, NULL, 0, - offsetof(CPUARMState, cp15.nsacr), }, + offsetof(CPUARMState, cp15.nsacr) }, + { "MVBAR", 15,12,0, 0,0,1, 0,0, + PL3_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.mvbar), {0, 0}, + NULL, NULL, vbar_write }, REGINFO_SENTINEL }; @@ -3781,15 +3784,15 @@ void arm_cpu_do_interrupt(CPUState *cs) return; /* Never happens. Keep compiler happy. */ } /* High vectors. */ - if (env->cp15.c1_sys & SCTLR_V) { - /* when enabled, base address cannot be remapped. */ + if (new_mode == ARM_CPU_MODE_MON) { + addr += env->cp15.mvbar; + } else if (env->cp15.c1_sys & SCTLR_V) { + /* High vectors. When enabled, base address cannot be remapped. */ addr += 0xffff0000; } else { /* ARM v7 architectures provide a vector base address register to remap * the interrupt vector table. - * This register is only followed in non-monitor mode, and has a secure - * and un-secure copy. Since the cpu is always in a un-secure operation - * and is never in monitor mode this feature is always active. + * This register is only followed in non-monitor mode, and is banked. * Note: only bits 31:5 are valid. */ addr += env->cp15.vbar_el[1];