mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 20:25:38 +00:00
target/arm: Split out aa64_va_parameter_tbi, aa64_va_parameter_tbid
For the purpose of rebuild_hflags_a64, we do not need to compute all of the va parameters, only tbi. Moreover, we can compute them in a form that is more useful to storing in hflags. This eliminates the need for aa64_va_parameter_both, so fold that in to aa64_va_parameter. The remaining calls to aa64_va_parameter are in get_phys_addr_lpae and in pauth_helper.c. This reduces the total cpu consumption of aa64_va_parameter in a kernel boot plus a kvm guest kernel boot from 3% to 0.5%. Backports commit b830a5ee82e66f54697dcc6450fe9239b7412d13 from qemu
This commit is contained in:
parent
2cce7e0dd0
commit
0131e804fb
|
@ -10089,12 +10089,34 @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
|
|||
}
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
|
||||
ARMMMUIdx mmu_idx)
|
||||
static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
|
||||
{
|
||||
if (regime_has_2_ranges(mmu_idx)) {
|
||||
return extract64(tcr, 37, 2);
|
||||
} else if (mmu_idx == ARMMMUIdx_Stage2) {
|
||||
return 0; /* VTCR_EL2 */
|
||||
} else {
|
||||
return extract32(tcr, 20, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
|
||||
{
|
||||
if (regime_has_2_ranges(mmu_idx)) {
|
||||
return extract64(tcr, 51, 2);
|
||||
} else if (mmu_idx == ARMMMUIdx_Stage2) {
|
||||
return 0; /* VTCR_EL2 */
|
||||
} else {
|
||||
return extract32(tcr, 29, 1);
|
||||
}
|
||||
}
|
||||
|
||||
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
|
||||
ARMMMUIdx mmu_idx, bool data)
|
||||
{
|
||||
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
|
||||
bool tbi, tbid, epd, hpd, using16k, using64k;
|
||||
int select, tsz;
|
||||
bool epd, hpd, using16k, using64k;
|
||||
int select, tsz, tbi;
|
||||
|
||||
if (!regime_has_2_ranges(mmu_idx)) {
|
||||
select = 0;
|
||||
|
@ -10103,11 +10125,9 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
|
|||
using16k = extract32(tcr, 15, 1);
|
||||
if (mmu_idx == ARMMMUIdx_Stage2) {
|
||||
/* VTCR_EL2 */
|
||||
tbi = tbid = hpd = false;
|
||||
hpd = false;
|
||||
} else {
|
||||
tbi = extract32(tcr, 20, 1);
|
||||
hpd = extract32(tcr, 24, 1);
|
||||
tbid = extract32(tcr, 29, 1);
|
||||
}
|
||||
epd = false;
|
||||
} else {
|
||||
|
@ -10121,28 +10141,30 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
|
|||
epd = extract32(tcr, 7, 1);
|
||||
using64k = extract32(tcr, 14, 1);
|
||||
using16k = extract32(tcr, 15, 1);
|
||||
tbi = extract64(tcr, 37, 1);
|
||||
hpd = extract64(tcr, 41, 1);
|
||||
tbid = extract64(tcr, 51, 1);
|
||||
} else {
|
||||
int tg = extract32(tcr, 30, 2);
|
||||
using16k = tg == 1;
|
||||
using64k = tg == 3;
|
||||
tsz = extract32(tcr, 16, 6);
|
||||
epd = extract32(tcr, 23, 1);
|
||||
tbi = extract64(tcr, 38, 1);
|
||||
hpd = extract64(tcr, 42, 1);
|
||||
tbid = extract64(tcr, 52, 1);
|
||||
}
|
||||
}
|
||||
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
|
||||
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
|
||||
|
||||
/* Present TBI as a composite with TBID. */
|
||||
tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
|
||||
if (!data) {
|
||||
tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
|
||||
}
|
||||
tbi = (tbi >> select) & 1;
|
||||
|
||||
return (ARMVAParameters) {
|
||||
.tsz = tsz,
|
||||
.select = select,
|
||||
.tbi = tbi,
|
||||
.tbid = tbid,
|
||||
.epd = epd,
|
||||
.hpd = hpd,
|
||||
.using16k = using16k,
|
||||
|
@ -10150,16 +10172,6 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
|
|||
};
|
||||
}
|
||||
|
||||
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
|
||||
ARMMMUIdx mmu_idx, bool data)
|
||||
{
|
||||
ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
|
||||
|
||||
/* Present TBI as a composite with TBID. */
|
||||
ret.tbi &= (data || !ret.tbid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
|
||||
ARMMMUIdx mmu_idx)
|
||||
|
@ -11940,18 +11952,12 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|
|||
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
|
||||
|
||||
{
|
||||
ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
|
||||
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
|
||||
int tbii, tbid;
|
||||
|
||||
/* Get control bits for tagged addresses. */
|
||||
if (regime_has_2_ranges(mmu_idx)) {
|
||||
ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
|
||||
tbid = (p1.tbi << 1) | p0.tbi;
|
||||
tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
|
||||
} else {
|
||||
tbid = p0.tbi;
|
||||
tbii = tbid & !p0.tbid;
|
||||
}
|
||||
tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
|
||||
tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
|
||||
|
||||
flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
|
||||
flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
|
||||
|
|
|
@ -1129,15 +1129,12 @@ typedef struct ARMVAParameters {
|
|||
unsigned tsz : 8;
|
||||
unsigned select : 1;
|
||||
bool tbi : 1;
|
||||
bool tbid : 1;
|
||||
bool epd : 1;
|
||||
bool hpd : 1;
|
||||
bool using16k : 1;
|
||||
bool using64k : 1;
|
||||
} ARMVAParameters;
|
||||
|
||||
ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
|
||||
ARMMMUIdx mmu_idx);
|
||||
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
|
||||
ARMMMUIdx mmu_idx, bool data);
|
||||
|
||||
|
|
Loading…
Reference in a new issue