target/arm: Remove loop from get_phys_addr_lpae
The unconditional loop was used both to iterate over levels and to control parsing of attributes. Use an explicit goto in both cases. While this appears less clean for iterating over levels, we will need to jump back into the middle of this loop for atomic updates, which is even uglier. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20221024051851.3074715-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
f0a398a249
commit
fe4ddc151b
@ -1061,6 +1061,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
|
||||
uint64_t descaddrmask;
|
||||
bool aarch64 = arm_el_is_aa64(env, el);
|
||||
bool guarded = false;
|
||||
uint64_t descriptor;
|
||||
bool nstable;
|
||||
|
||||
/* TODO: This code does not support shareability levels. */
|
||||
if (aarch64) {
|
||||
@ -1253,10 +1255,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
|
||||
* bits at each step.
|
||||
*/
|
||||
tableattrs = is_secure ? 0 : (1 << 4);
|
||||
for (;;) {
|
||||
uint64_t descriptor;
|
||||
bool nstable;
|
||||
|
||||
next_level:
|
||||
descaddr |= (address >> (stride * (4 - level))) & indexmask;
|
||||
descaddr &= ~7ULL;
|
||||
nstable = extract32(tableattrs, 4, 1);
|
||||
@ -1280,8 +1280,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
|
||||
goto do_fault;
|
||||
}
|
||||
|
||||
if (!(descriptor & 1) ||
|
||||
(!(descriptor & 2) && (level == 3))) {
|
||||
if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) {
|
||||
/* Invalid, or the Reserved level 3 encoding */
|
||||
goto do_fault;
|
||||
}
|
||||
@ -1315,8 +1314,9 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
|
||||
tableattrs |= extract64(descriptor, 59, 5);
|
||||
level++;
|
||||
indexmask = indexmask_grainsize;
|
||||
continue;
|
||||
goto next_level;
|
||||
}
|
||||
|
||||
/*
|
||||
* Block entry at level 1 or 2, or page entry at level 3.
|
||||
* These are basically the same thing, although the number
|
||||
@ -1335,14 +1335,14 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
|
||||
|
||||
if (regime_is_stage2(mmu_idx)) {
|
||||
/* Stage 2 table descriptors do not include any attribute fields */
|
||||
break;
|
||||
goto skip_attrs;
|
||||
}
|
||||
/* Merge in attributes from table descriptors */
|
||||
attrs |= nstable << 3; /* NS */
|
||||
guarded = extract64(descriptor, 50, 1); /* GP */
|
||||
if (param.hpd) {
|
||||
/* HPD disables all the table attributes except NSTable. */
|
||||
break;
|
||||
goto skip_attrs;
|
||||
}
|
||||
attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
|
||||
/*
|
||||
@ -1351,8 +1351,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
|
||||
*/
|
||||
attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
|
||||
attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
|
||||
break;
|
||||
}
|
||||
skip_attrs:
|
||||
|
||||
/*
|
||||
* Here descaddr is the final physical address, and attributes
|
||||
* are all in attrs.
|
||||
|
Loading…
Reference in New Issue
Block a user