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; uint64_t length;
} TLBIRange; } 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, static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
uint64_t value) uint64_t value)
{ {
@ -4481,17 +4499,19 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
uint64_t select = sextract64(value, 36, 1); uint64_t select = sextract64(value, 36, 1);
ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true); ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
TLBIRange ret = { }; TLBIRange ret = { };
ARMGranuleSize gran;
page_size_granule = extract64(value, 46, 2); 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. */ /* 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", qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
page_size_granule); page_size_granule);
return ret; return ret;
} }
page_shift = (page_size_granule - 1) * 2 + 12; page_shift = arm_granule_bits(gran);
num = extract64(value, 39, 5); num = extract64(value, 39, 5);
scale = extract64(value, 44, 2); scale = extract64(value, 44, 2);
exponent = (5 * scale) + 1; exponent = (5 * scale) + 1;
@ -10375,7 +10395,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
ARMMMUIdx mmu_idx, bool data) ARMMMUIdx mmu_idx, bool data)
{ {
uint64_t tcr = regime_tcr(env, mmu_idx); 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; int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
ARMGranuleSize gran; ARMGranuleSize gran;
ARMCPU *cpu = env_archcpu(env); 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); gran = sanitize_gran_size(cpu, gran, stage2);
using64k = gran == Gran64K;
using16k = gran == Gran16K;
if (cpu_isar_feature(aa64_st, cpu)) { if (cpu_isar_feature(aa64_st, cpu)) {
max_tsz = 48 - using64k; max_tsz = 48 - (gran == Gran64K);
} else { } else {
max_tsz = 39; max_tsz = 39;
} }
@ -10433,7 +10451,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
* adjust the effective value of DS, as documented. * adjust the effective value of DS, as documented.
*/ */
min_tsz = 16; min_tsz = 16;
if (using64k) { if (gran == Gran64K) {
if (cpu_isar_feature(aa64_lva, cpu)) { if (cpu_isar_feature(aa64_lva, cpu)) {
min_tsz = 12; min_tsz = 12;
} }
@ -10442,14 +10460,14 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
switch (mmu_idx) { switch (mmu_idx) {
case ARMMMUIdx_Stage2: case ARMMMUIdx_Stage2:
case ARMMMUIdx_Stage2_S: case ARMMMUIdx_Stage2_S:
if (using16k) { if (gran == Gran16K) {
ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu); ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
} else { } else {
ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu); ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
} }
break; break;
default: default:
if (using16k) { if (gran == Gran16K) {
ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu); ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
} else { } else {
ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu); ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
@ -10486,10 +10504,9 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
.tbi = tbi, .tbi = tbi,
.epd = epd, .epd = epd,
.hpd = hpd, .hpd = hpd,
.using16k = using16k,
.using64k = using64k,
.tsz_oob = tsz_oob, .tsz_oob = tsz_oob,
.ds = ds, .ds = ds,
.gran = gran,
}; };
} }

View File

@ -1007,6 +1007,26 @@ typedef enum ARMGranuleSize {
GranInvalid, GranInvalid,
} ARMGranuleSize; } 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 * Parameters of a given virtual address, as extracted from the
* translation control register (TCR) for a given regime. * translation control register (TCR) for a given regime.
@ -1019,10 +1039,9 @@ typedef struct ARMVAParameters {
bool tbi : 1; bool tbi : 1;
bool epd : 1; bool epd : 1;
bool hpd : 1; bool hpd : 1;
bool using16k : 1;
bool using64k : 1;
bool tsz_oob : 1; /* tsz has been clamped to legal range */ bool tsz_oob : 1; /* tsz has been clamped to legal range */
bool ds : 1; bool ds : 1;
ARMGranuleSize gran : 2;
} ARMVAParameters; } ARMVAParameters;
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, 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 = arm_granule_bits(param.gran) - 3;
stride = 13;
} else if (param.using16k) {
stride = 11;
} else {
stride = 9;
}
/* /*
* Note that QEMU ignores shareability and cacheability attributes, * Note that QEMU ignores shareability and cacheability attributes,