summaryrefslogtreecommitdiff
path: root/target-arm
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/helper.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index eaded41969..19d5d525f3 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -7237,7 +7237,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
CPUState *cs = CPU(cpu);
/* Read an LPAE long-descriptor translation table. */
MMUFaultType fault_type = translation_fault;
- uint32_t level = 1;
+ uint32_t level;
uint32_t epd = 0;
int32_t t0sz, t1sz;
uint32_t tg;
@@ -7248,7 +7248,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
target_ulong page_size;
uint32_t attrs;
int32_t stride = 9;
- int32_t va_size = 32;
+ int32_t va_size;
int inputsize;
int32_t tbi = 0;
TCR *tcr = regime_tcr(env, mmu_idx);
@@ -7264,6 +7264,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
* support for those page table walks.
*/
if (arm_el_is_aa64(env, el)) {
+ level = 0;
va_size = 64;
if (el > 1) {
if (mmu_idx != ARMMMUIdx_S2NS) {
@@ -7285,6 +7286,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
ttbr1_valid = false;
}
} else {
+ level = 1;
+ va_size = 32;
/* There is no TTBR1 for EL2 */
if (el == 2) {
ttbr1_valid = false;
@@ -7407,27 +7410,26 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
/* For stage 2 translations the starting level is specified by the
* VTCR_EL2.SL0 field (whose interpretation depends on the page size)
*/
- int startlevel = extract32(tcr->raw_tcr, 6, 2);
+ uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
+ uint32_t startlevel;
bool ok;
if (va_size == 32 || stride == 9) {
/* AArch32 or 4KB pages */
- level = 2 - startlevel;
+ startlevel = 2 - sl0;
} else {
/* 16KB or 64KB pages */
- level = 3 - startlevel;
+ startlevel = 3 - sl0;
}
/* Check that the starting level is valid. */
- ok = check_s2_mmu_setup(cpu, va_size == 64, level, inputsize, stride);
+ ok = check_s2_mmu_setup(cpu, va_size == 64, startlevel,
+ inputsize, stride);
if (!ok) {
- /* AArch64 reports these as level 0 faults.
- * AArch32 reports these as level 1 faults.
- */
- level = va_size == 64 ? 0 : 1;
fault_type = translation_fault;
goto do_fault;
}
+ level = startlevel;
}
/* Clear the vaddr bits which aren't part of the within-region address,