mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 17:25:27 +00:00
target/arm: Implement HCR.FB
The HCR.FB virtualization configuration register bit requests that TLB maintenance, branch predictor invalidate-all and icache invalidate-all operations performed in NS EL1 should be upgraded from "local CPU only to "broadcast within Inner Shareable domain". For QEMU we NOP the branch predictor and icache operations, so we only need to upgrade the TLB invalidates: AArch32 TLBIALL, TLBIMVA, TLBIASID, DTLBIALL, DTLBIMVA, DTLBIASID, ITLBIALL, ITLBIMVA, ITLBIASID, TLBIMVAA, TLBIMVAL, TLBIMVAAL AArch64 TLBI VMALLE1, TLBI VAE1, TLBI ASIDE1, TLBI VAAE1, TLBI VALE1, TLBI VAALE1 Backports commit b4ab8ce98b8c482c8986785800f238d32a1578a9 from qemu
This commit is contained in:
parent
a0358202a7
commit
b9e7fa2d80
|
@ -428,12 +428,61 @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
raw_write(env, ri, value);
|
||||
}
|
||||
|
||||
/* IS variants of TLB operations must affect all cores */
|
||||
static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
//CPUState *cs = ENV_GET_CPU(env);
|
||||
|
||||
//tlb_flush_all_cpus_synced(cs);
|
||||
}
|
||||
|
||||
static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
//CPUState *cs = ENV_GET_CPU(env);
|
||||
|
||||
//tlb_flush_all_cpus_synced(cs);
|
||||
}
|
||||
|
||||
static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
//CPUState *cs = ENV_GET_CPU(env);
|
||||
|
||||
//tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
|
||||
}
|
||||
|
||||
static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
//CPUState *cs = ENV_GET_CPU(env);
|
||||
|
||||
//tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-IS variants of TLB operations are upgraded to
|
||||
* IS versions if we are at NS EL1 and HCR_EL2.FB is set to
|
||||
* force broadcast of these operations.
|
||||
*/
|
||||
static bool tlb_force_broadcast(CPUARMState *env)
|
||||
{
|
||||
return (env->cp15.hcr_el2 & HCR_FB) &&
|
||||
arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
|
||||
}
|
||||
|
||||
static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
/* Invalidate all (TLBIALL) */
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
|
||||
if (tlb_force_broadcast(env)) {
|
||||
tlbiall_is_write(env, NULL, value);
|
||||
return;
|
||||
}
|
||||
|
||||
tlb_flush(CPU(cpu));
|
||||
}
|
||||
|
||||
|
@ -443,6 +492,11 @@ static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
/* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
|
||||
if (tlb_force_broadcast(env)) {
|
||||
tlbimva_is_write(env, NULL, value);
|
||||
return;
|
||||
}
|
||||
|
||||
tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
|
||||
}
|
||||
|
||||
|
@ -452,6 +506,11 @@ static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
/* Invalidate by ASID (TLBIASID) */
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
|
||||
if (tlb_force_broadcast(env)) {
|
||||
tlbiasid_is_write(env, NULL, value);
|
||||
return;
|
||||
}
|
||||
|
||||
tlb_flush(CPU(cpu));
|
||||
}
|
||||
|
||||
|
@ -461,42 +520,14 @@ static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
/* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
|
||||
if (tlb_force_broadcast(env)) {
|
||||
tlbimvaa_is_write(env, NULL, value);
|
||||
return;
|
||||
}
|
||||
|
||||
tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
|
||||
}
|
||||
|
||||
/* IS variants of TLB operations must affect all cores */
|
||||
static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
//struct uc_struct *uc = env->uc;
|
||||
// TODO: issue #642
|
||||
// tlb_flush(other_cpu);
|
||||
}
|
||||
|
||||
static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
//struct uc_struct *uc = env->uc;
|
||||
// TODO: issue #642
|
||||
// tlb_flush(other_cpu);
|
||||
}
|
||||
|
||||
static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
//struct uc_struct *uc = env->uc;
|
||||
// TODO: issue #642
|
||||
// tlb_flush(other_cpu);
|
||||
}
|
||||
|
||||
static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
//struct uc_struct *uc = env->uc;
|
||||
// TODO: issue #642
|
||||
// tlb_flush(other_cpu);
|
||||
}
|
||||
|
||||
static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
|
@ -2733,23 +2764,6 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
|
|||
* Page D4-1736 (DDI0487A.b)
|
||||
*/
|
||||
|
||||
static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
tlb_flush_by_mmuidx(cs,
|
||||
ARMMMUIdxBit_S1SE1 |
|
||||
ARMMMUIdxBit_S1SE0);
|
||||
} else {
|
||||
tlb_flush_by_mmuidx(cs,
|
||||
ARMMMUIdxBit_S12NSE1 |
|
||||
ARMMMUIdxBit_S12NSE0);
|
||||
}
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
|
@ -2770,6 +2784,27 @@ static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
#endif
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
CPUState *cs = ENV_GET_CPU(env);
|
||||
|
||||
if (tlb_force_broadcast(env)) {
|
||||
tlbi_aa64_vmalle1_write(env, NULL, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
tlb_flush_by_mmuidx(cs,
|
||||
ARMMMUIdxBit_S1SE1 |
|
||||
ARMMMUIdxBit_S1SE0);
|
||||
} else {
|
||||
tlb_flush_by_mmuidx(cs,
|
||||
ARMMMUIdxBit_S12NSE1 |
|
||||
ARMMMUIdxBit_S12NSE0);
|
||||
}
|
||||
}
|
||||
|
||||
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
|
@ -2868,29 +2903,6 @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
#endif
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
/* Invalidate by VA, EL1&0 (AArch64 version).
|
||||
* Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
|
||||
* since we don't support flush-for-specific-ASID-only or
|
||||
* flush-last-level-only.
|
||||
*/
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
uint64_t pageaddr = sextract64(value << 12, 0, 56);
|
||||
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
tlb_flush_page_by_mmuidx(cs, pageaddr,
|
||||
ARMMMUIdxBit_S1SE1 |
|
||||
ARMMMUIdxBit_S1SE0);
|
||||
} else {
|
||||
tlb_flush_page_by_mmuidx(cs, pageaddr,
|
||||
ARMMMUIdxBit_S12NSE1 |
|
||||
ARMMMUIdxBit_S12NSE0);
|
||||
}
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
|
@ -2940,6 +2952,34 @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
#endif
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
/* Invalidate by VA, EL1&0 (AArch64 version).
|
||||
* Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
|
||||
* since we don't support flush-for-specific-ASID-only or
|
||||
* flush-last-level-only.
|
||||
*/
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
uint64_t pageaddr = sextract64(value << 12, 0, 56);
|
||||
|
||||
if (tlb_force_broadcast(env)) {
|
||||
tlbi_aa64_vae1is_write(env, NULL, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (arm_is_secure_below_el3(env)) {
|
||||
tlb_flush_page_by_mmuidx(cs, pageaddr,
|
||||
ARMMMUIdxBit_S1SE1 |
|
||||
ARMMMUIdxBit_S1SE0);
|
||||
} else {
|
||||
tlb_flush_page_by_mmuidx(cs, pageaddr,
|
||||
ARMMMUIdxBit_S12NSE1 |
|
||||
ARMMMUIdxBit_S12NSE0);
|
||||
}
|
||||
}
|
||||
|
||||
static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue