target/arm: Use ARMGranuleSize in ARMVAParameters

Now we have an enum for the granule size, use it in the
ARMVAParameters struct instead of the using16k/using64k bools.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20221003162315.2833797-3-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2022-10-03 17:23:14 +01:00
parent 104f703d93
commit 3c003f7029
3 changed files with 50 additions and 20 deletions

View File

@ -4473,6 +4473,24 @@ typedef struct {
uint64_t length;
} TLBIRange;
static ARMGranuleSize tlbi_range_tg_to_gran_size(int tg)
{
/*
* Note that the TLBI range TG field encoding differs from both
* TG0 and TG1 encodings.
*/
switch (tg) {
case 1:
return Gran4K;
case 2:
return Gran16K;
case 3:
return Gran64K;
default:
return GranInvalid;
}
}
static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
uint64_t value)
{
@ -4481,17 +4499,19 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
uint64_t select = sextract64(value, 36, 1);
ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
TLBIRange ret = { };
ARMGranuleSize gran;
page_size_granule = extract64(value, 46, 2);
gran = tlbi_range_tg_to_gran_size(page_size_granule);
/* The granule encoded in value must match the granule in use. */
if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
if (gran != param.gran) {
qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
page_size_granule);
return ret;
}
page_shift = (page_size_granule - 1) * 2 + 12;
page_shift = arm_granule_bits(gran);
num = extract64(value, 39, 5);
scale = extract64(value, 44, 2);
exponent = (5 * scale) + 1;
@ -10375,7 +10395,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
ARMMMUIdx mmu_idx, bool data)
{
uint64_t tcr = regime_tcr(env, mmu_idx);
bool epd, hpd, using16k, using64k, tsz_oob, ds;
bool epd, hpd, tsz_oob, ds;
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
ARMGranuleSize gran;
ARMCPU *cpu = env_archcpu(env);
@ -10419,11 +10439,9 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
}
gran = sanitize_gran_size(cpu, gran, stage2);
using64k = gran == Gran64K;
using16k = gran == Gran16K;
if (cpu_isar_feature(aa64_st, cpu)) {
max_tsz = 48 - using64k;
max_tsz = 48 - (gran == Gran64K);
} else {
max_tsz = 39;
}
@ -10433,7 +10451,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
* adjust the effective value of DS, as documented.
*/
min_tsz = 16;
if (using64k) {
if (gran == Gran64K) {
if (cpu_isar_feature(aa64_lva, cpu)) {
min_tsz = 12;
}
@ -10442,14 +10460,14 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
switch (mmu_idx) {
case ARMMMUIdx_Stage2:
case ARMMMUIdx_Stage2_S:
if (using16k) {
if (gran == Gran16K) {
ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
} else {
ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
}
break;
default:
if (using16k) {
if (gran == Gran16K) {
ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
} else {
ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
@ -10486,10 +10504,9 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
.tbi = tbi,
.epd = epd,
.hpd = hpd,
.using16k = using16k,
.using64k = using64k,
.tsz_oob = tsz_oob,
.ds = ds,
.gran = gran,
};
}

View File

@ -1007,6 +1007,26 @@ typedef enum ARMGranuleSize {
GranInvalid,
} ARMGranuleSize;
/**
* arm_granule_bits: Return address size of the granule in bits
*
* Return the address size of the granule in bits. This corresponds
* to the pseudocode TGxGranuleBits().
*/
static inline int arm_granule_bits(ARMGranuleSize gran)
{
switch (gran) {
case Gran64K:
return 16;
case Gran16K:
return 14;
case Gran4K:
return 12;
default:
g_assert_not_reached();
}
}
/*
* Parameters of a given virtual address, as extracted from the
* translation control register (TCR) for a given regime.
@ -1019,10 +1039,9 @@ typedef struct ARMVAParameters {
bool tbi : 1;
bool epd : 1;
bool hpd : 1;
bool using16k : 1;
bool using64k : 1;
bool tsz_oob : 1; /* tsz has been clamped to legal range */
bool ds : 1;
ARMGranuleSize gran : 2;
} ARMVAParameters;
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,

View File

@ -1062,13 +1062,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
}
}
if (param.using64k) {
stride = 13;
} else if (param.using16k) {
stride = 11;
} else {
stride = 9;
}
stride = arm_granule_bits(param.gran) - 3;
/*
* Note that QEMU ignores shareability and cacheability attributes,