From: Nathan Rossi <nathan.ro...@xilinx.com> Added Vector Base Address remapping on ARM v7.
Signed-off-by: Nathan Rossi <nathan.ro...@xilinx.com> Signed-off-by: Peter Crosthwaite <peter.crosthwa...@xilinx.com> --- target-arm/cpu.h | 1 + target-arm/helper.c | 14 ++++++++++++++ target-arm/machine.c | 2 ++ 3 files changed, 17 insertions(+), 0 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 2902ba5..57ed2ee 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -138,6 +138,7 @@ typedef struct CPUARMState { uint32_t c9_pmxevtyper; /* perf monitor event type */ uint32_t c9_pmuserenr; /* perf monitor user enable */ uint32_t c9_pminten; /* perf monitor interrupt enables */ + uint32_t c12_vector_base_address; /* vector base address register */ uint32_t c13_fcse; /* FCSE PID. */ uint32_t c13_context; /* Context ID. */ uint32_t c13_tls1; /* User RW Thread register. */ diff --git a/target-arm/helper.c b/target-arm/helper.c index e97e1a5..db2e31d 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -408,6 +408,10 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .resetvalue = 0, .writefn = pmintenclr_write }, + { .name = "VBAR", .cp = 15, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, + .fieldoffset = offsetof(CPUARMState, cp15.c12_vector_base_address), + .resetvalue = 0 }, { .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr), .resetvalue = 0, }, @@ -1892,7 +1896,17 @@ void do_interrupt(CPUARMState *env) } /* High vectors. */ if (env->cp15.c1_sys & (1 << 13)) { + /* when enabled, base address cannot be remapped. */ addr += 0xffff0000; + } else if (arm_feature(env, ARM_FEATURE_V7)) { + /* 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. + * Note: only bits 31:5 are valid. + */ + addr += env->cp15.c12_vector_base_address & 0xffffffe0; } switch_mode (env, new_mode); env->spsr = cpsr_read(env); diff --git a/target-arm/machine.c b/target-arm/machine.c index 68dca7f..2d07c51 100644 --- a/target-arm/machine.c +++ b/target-arm/machine.c @@ -53,6 +53,7 @@ void cpu_save(QEMUFile *f, void *opaque) qemu_put_be32(f, env->cp15.c9_pmxevtyper); qemu_put_be32(f, env->cp15.c9_pmuserenr); qemu_put_be32(f, env->cp15.c9_pminten); + qemu_put_be32(f, env->cp15.c12_vector_base_address); qemu_put_be32(f, env->cp15.c13_fcse); qemu_put_be32(f, env->cp15.c13_context); qemu_put_be32(f, env->cp15.c13_tls1); @@ -173,6 +174,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) env->cp15.c9_pmxevtyper = qemu_get_be32(f); env->cp15.c9_pmuserenr = qemu_get_be32(f); env->cp15.c9_pminten = qemu_get_be32(f); + env->cp15.c12_vector_base_address = qemu_get_be32(f); env->cp15.c13_fcse = qemu_get_be32(f); env->cp15.c13_context = qemu_get_be32(f); env->cp15.c13_tls1 = qemu_get_be32(f); -- 1.7.0.4