Message ID | 1361949376-25680-1-git-send-email-peter.crosthwaite@xilinx.com |
---|---|
State | New |
Headers | show |
On 27 February 2013 07:16, Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote: > From: Nathan Rossi <nathan.rossi@xilinx.com> > > Added Vector Base Address remapping on ARM v7. This one's tricky because the VBAR only exists in CPUs with TrustZone, and strictly speaking QEMU models a non-TrustZone core. However we already have some dummy cp15 registers which are really TZ-only just to get guests working, and this may well fall into that category. I need to have a think about how we can coherently define what QEMU does about TZ so we can have a better idea of what should and shouldn't be implemented. (If you have any suggestions I'm open to them.) On the patch itself: * you've forgotten to bump the cpu vmstate version * I'm trying to move towards using the official register abbreviations in cpu struct member names * the low bits of VBAR are "UNK/SBZP", which means our implementation must ignore writes and read as zeroes. So you need to do the masking in the write-accessor, not at point of use * we can just rely on the fact that the vbar field will be zero when QEMU is emulating a pre-v7 core, so you can avoid the feature check on use thanks -- PMM
Hi Peter, (Sorry about the delay), On Wed, Feb 27, 2013 at 8:10 PM, Peter Maydell <peter.maydell@linaro.org> wrote: > On 27 February 2013 07:16, Peter Crosthwaite > <peter.crosthwaite@xilinx.com> wrote: >> From: Nathan Rossi <nathan.rossi@xilinx.com> >> >> Added Vector Base Address remapping on ARM v7. > > This one's tricky because the VBAR only exists in CPUs with > TrustZone, and strictly speaking QEMU models a non-TrustZone > core. However we already have some dummy cp15 registers which > are really TZ-only just to get guests working, and this may > well fall into that category. > > I need to have a think about how we can coherently define > what QEMU does about TZ so we can have a better idea of > what should and shouldn't be implemented. (If you have any > suggestions I'm open to them.) > ARM_FEATURE_TZ? > On the patch itself: > * you've forgotten to bump the cpu vmstate version > * I'm trying to move towards using the official register > abbreviations in cpu struct member names > * the low bits of VBAR are "UNK/SBZP", which means our > implementation must ignore writes and read as zeroes. So > you need to do the masking in the write-accessor, not at > point of use Fixed. > * we can just rely on the fact that the vbar field will be > zero when QEMU is emulating a pre-v7 core, so you can > avoid the feature check on use > Fixed. Regards, Peter > thanks > -- PMM >
On 26 June 2013 02:57, Peter Crosthwaite <peter.crosthwaite@xilinx.com> wrote: > On Wed, Feb 27, 2013 at 8:10 PM, Peter Maydell <peter.maydell@linaro.org> wrote: >> This one's tricky because the VBAR only exists in CPUs with >> TrustZone, and strictly speaking QEMU models a non-TrustZone >> core. However we already have some dummy cp15 registers which >> are really TZ-only just to get guests working, and this may >> well fall into that category. >> >> I need to have a think about how we can coherently define >> what QEMU does about TZ so we can have a better idea of >> what should and shouldn't be implemented. (If you have any >> suggestions I'm open to them.) >> > > ARM_FEATURE_TZ? Yes, but what should this imply about QEMU's behaviour? Naming a feature switch is easy, semantics are hard. -- PMM
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);