Separate S1 translation from the actual lookup. Will enable lpae hardware updates.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/arm/ptw.c | 92 +++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index d356b0b22d..84b55b640b 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -315,38 +315,29 @@ static bool S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, } /* All loads done in the course of a page table walk go through here. */ -static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure, - ARMMMUIdx mmu_idx, ARMMMUIdx ptw_idx, - bool debug, ARMMMUFaultInfo *fi) +static uint32_t arm_ldl_ptw(CPUARMState *env, const S1TranslateResult *s1, + ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); - S1TranslateResult s1; uint32_t data; - if (!S1_ptw_translate(env, mmu_idx, ptw_idx, addr, is_secure, - debug, &s1, fi)) { - /* Failure. */ - assert(fi->s1ptw); - return 0; - } - - if (likely(s1.hphys)) { + if (likely(s1->hphys)) { /* Page tables are in RAM, and we have the host address. */ - if (s1.be) { - data = ldl_be_p(s1.hphys); + if (s1->be) { + data = ldl_be_p(s1->hphys); } else { - data = ldl_le_p(s1.hphys); + data = ldl_le_p(s1->hphys); } } else { /* Page tables are in MMIO. */ - MemTxAttrs attrs = { .secure = s1.is_secure }; + MemTxAttrs attrs = { .secure = s1->is_secure }; AddressSpace *as = arm_addressspace(cs, attrs); MemTxResult result = MEMTX_OK; - if (s1.be) { - data = address_space_ldl_be(as, s1.gphys, attrs, &result); + if (s1->be) { + data = address_space_ldl_be(as, s1->gphys, attrs, &result); } else { - data = address_space_ldl_le(as, s1.gphys, attrs, &result); + data = address_space_ldl_le(as, s1->gphys, attrs, &result); } if (unlikely(result != MEMTX_OK)) { fi->type = ARMFault_SyncExternalOnWalk; @@ -357,38 +348,29 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure, return data; } -static uint64_t arm_ldq_ptw(CPUARMState *env, hwaddr addr, bool is_secure, - ARMMMUIdx mmu_idx, ARMMMUIdx ptw_idx, - bool debug, ARMMMUFaultInfo *fi) +static uint64_t arm_ldq_ptw(CPUARMState *env, const S1TranslateResult *s1, + ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); - S1TranslateResult s1; uint64_t data; - if (!S1_ptw_translate(env, mmu_idx, ptw_idx, addr, is_secure, - debug, &s1, fi)) { - /* Failure. */ - assert(fi->s1ptw); - return 0; - } - - if (likely(s1.hphys)) { + if (likely(s1->hphys)) { /* Page tables are in RAM, and we have the host address. */ - if (s1.be) { - data = ldq_be_p(s1.hphys); + if (s1->be) { + data = ldq_be_p(s1->hphys); } else { - data = ldq_le_p(s1.hphys); + data = ldq_le_p(s1->hphys); } } else { /* Page tables are in MMIO. */ - MemTxAttrs attrs = { .secure = s1.is_secure }; + MemTxAttrs attrs = { .secure = s1->is_secure }; AddressSpace *as = arm_addressspace(cs, attrs); MemTxResult result = MEMTX_OK; - if (s1.be) { - data = address_space_ldq_be(as, s1.gphys, attrs, &result); + if (s1->be) { + data = address_space_ldq_be(as, s1->gphys, attrs, &result); } else { - data = address_space_ldq_le(as, s1.gphys, attrs, &result); + data = address_space_ldq_le(as, s1->gphys, attrs, &result); } if (unlikely(result != MEMTX_OK)) { fi->type = ARMFault_SyncExternalOnWalk; @@ -520,6 +502,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, int domain = 0; int domain_prot; hwaddr phys_addr; + S1TranslateResult s1; uint32_t dacr; /* Pagetable walk. */ @@ -529,7 +512,11 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, fi->type = ARMFault_Translation; goto do_fault; } - desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, ptw_idx, debug, fi); + if (!S1_ptw_translate(env, mmu_idx, ptw_idx, table, + is_secure, debug, &s1, fi)) { + goto do_fault; + } + desc = arm_ldl_ptw(env, &s1, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -567,7 +554,11 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, /* Fine pagetable. */ table = (desc & 0xfffff000) | ((address >> 8) & 0xffc); } - desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, ptw_idx, debug, fi); + if (!S1_ptw_translate(env, mmu_idx, ptw_idx, table, + is_secure, debug, &s1, fi)) { + goto do_fault; + } + desc = arm_ldl_ptw(env, &s1, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -643,6 +634,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, int domain_prot; hwaddr phys_addr; uint32_t dacr; + S1TranslateResult s1; bool ns; /* Pagetable walk. */ @@ -652,7 +644,11 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, fi->type = ARMFault_Translation; goto do_fault; } - desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, ptw_idx, debug, fi); + if (!S1_ptw_translate(env, mmu_idx, ptw_idx, table, + is_secure, debug, &s1, fi)) { + goto do_fault; + } + desc = arm_ldl_ptw(env, &s1, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -705,7 +701,11 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, ns = extract32(desc, 3, 1); /* Lookup l2 entry. */ table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); - desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, ptw_idx, debug, fi); + if (!S1_ptw_translate(env, mmu_idx, ptw_idx, table, + is_secure, debug, &s1, fi)) { + goto do_fault; + } + desc = arm_ldl_ptw(env, &s1, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -1281,14 +1281,18 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, */ tableattrs = is_secure ? 0 : (1 << 4); for (;;) { + S1TranslateResult s1; uint64_t descriptor; bool nstable; descaddr |= (address >> (stride * (4 - level))) & indexmask; descaddr &= ~7ULL; nstable = extract32(tableattrs, 4, 1); - descriptor = arm_ldq_ptw(env, descaddr, !nstable, mmu_idx, - ptw_idx, debug, fi); + if (!S1_ptw_translate(env, mmu_idx, ptw_idx, descaddr, + !nstable, debug, &s1, fi)) { + goto do_fault; + } + descriptor = arm_ldq_ptw(env, &s1, fi); if (fi->type != ARMFault_None) { goto do_fault; } -- 2.34.1