@@ -268,37 +268,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,
+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, &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;
@@ -309,37 +301,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,
+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, &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;
@@ -467,6 +451,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. */
@@ -476,7 +461,10 @@ 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, fi);
+ if (!S1_ptw_translate(env, mmu_idx, ptw_idx, table, is_secure, &s1, fi)) {
+ goto do_fault;
+ }
+ desc = arm_ldl_ptw(env, &s1, fi);
if (fi->type != ARMFault_None) {
goto do_fault;
}
@@ -514,7 +502,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, fi);
+ if (!S1_ptw_translate(env, mmu_idx, ptw_idx, table,
+ is_secure, &s1, fi)) {
+ goto do_fault;
+ }
+ desc = arm_ldl_ptw(env, &s1, fi);
if (fi->type != ARMFault_None) {
goto do_fault;
}
@@ -590,6 +582,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. */
@@ -599,7 +592,10 @@ 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, fi);
+ if (!S1_ptw_translate(env, mmu_idx, ptw_idx, table, is_secure, &s1, fi)) {
+ goto do_fault;
+ }
+ desc = arm_ldl_ptw(env, &s1, fi);
if (fi->type != ARMFault_None) {
goto do_fault;
}
@@ -652,7 +648,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, fi);
+ if (!S1_ptw_translate(env, mmu_idx, ptw_idx, table,
+ is_secure, &s1, fi)) {
+ goto do_fault;
+ }
+ desc = arm_ldl_ptw(env, &s1, fi);
if (fi->type != ARMFault_None) {
goto do_fault;
}
@@ -1228,13 +1228,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, fi);
+ if (!S1_ptw_translate(env, mmu_idx, ptw_idx, descaddr,
+ !nstable, &s1, fi)) {
+ goto do_fault;
+ }
+ descriptor = arm_ldq_ptw(env, &s1, fi);
if (fi->type != ARMFault_None) {
goto do_fault;
}
Separate S1 translation from the actual lookup. Will enable lpae hardware updates. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/ptw.c | 83 +++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 39 deletions(-)