On 3 September 2015 at 21:14, Edgar E. Iglesias <edgar.igles...@gmail.com> wrote: > From: "Edgar E. Iglesias" <edgar.igles...@xilinx.com> > > Signed-off-by: Edgar E. Iglesias <edgar.igles...@xilinx.com> > --- > target-arm/cpu.h | 1 + > target-arm/helper.c | 34 ++++++++++++++++++++++++++++++++-- > 2 files changed, 33 insertions(+), 2 deletions(-) > > diff --git a/target-arm/cpu.h b/target-arm/cpu.h > index ba22e12..0ebdaf7 100644 > --- a/target-arm/cpu.h > +++ b/target-arm/cpu.h > @@ -221,6 +221,7 @@ typedef struct CPUARMState { > }; > uint64_t ttbr1_el[4]; > }; > + uint64_t vttbr_el2; /* Virtualization Translation Table Base. */ > /* MMU translation table base control. */ > TCR tcr_el[4]; > TCR vtcr_el2; /* Virtualization Translation Control. */ > diff --git a/target-arm/helper.c b/target-arm/helper.c > index c82aa1d..ec19e68 100644 > --- a/target-arm/helper.c > +++ b/target-arm/helper.c > @@ -2200,6 +2200,19 @@ static void vmsa_ttbr_write(CPUARMState *env, const > ARMCPRegInfo *ri, > raw_write(env, ri, value); > } > > +static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, > + uint64_t value) > +{ > + ARMCPU *cpu = arm_env_get_cpu(env); > + CPUState *cs = CPU(cpu); > + > + if (raw_read(env, ri) != value) { > + tlb_flush_by_mmuidx(cs, ARMMMUIdx_S12NSE1, ARMMMUIdx_S12NSE0, > + ARMMMUIdx_S2NS, -1);
We only need the TLB flush because this could change the VMID and our TLB doesn't handle VMIDs, right? That could use a comment (compare the remark about ASIDs in vmsa_ttbr_write()). > + raw_write(env, ri, value); > + } > +} > + > static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = { > { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0, > .access = PL1_RW, .type = ARM_CP_ALIAS, > @@ -3131,6 +3144,14 @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = { > .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2, > .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, > .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, > + { .name = "VTTBR", .state = ARM_CP_STATE_AA32, .type = ARM_CP_64BIT, > + .cp = 15, .opc1 = 6, .crm = 2, > + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, > + .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, > + { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64, > + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0, > + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, > + .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore }, RAZ/WI registers not using ARM_CP_CONST again... > { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH, > .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0, > .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, > @@ -3271,6 +3292,16 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { > .writefn = vmsa_tcr_el1_write, > .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write, > .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) }, > + { .name = "VTTBR", .state = ARM_CP_STATE_AA32, .type = ARM_CP_64BIT, > + .cp = 15, .opc1 = 6, .crm = 2, > + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, > + .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2), > + .writefn = vttbr_write }, > + { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64, > + .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0, > + .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any, > + .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2), > + .writefn = vttbr_write }, > { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH, > .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0, > .access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write, > @@ -5770,8 +5801,7 @@ static inline uint64_t regime_ttbr(CPUARMState *env, > ARMMMUIdx mmu_idx, > int ttbrn) > { > if (mmu_idx == ARMMMUIdx_S2NS) { > - /* TODO: return VTTBR_EL2 */ > - g_assert_not_reached(); > + return env->cp15.vttbr_el2; > } > if (ttbrn == 0) { > return env->cp15.ttbr0_el[regime_el(env, mmu_idx)]; > -- > 1.9.1 > thanks -- PMM