diff options
Diffstat (limited to 'src/arch/arm/isa.cc')
-rw-r--r-- | src/arch/arm/isa.cc | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index c2250e38a..d97c03db5 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -1101,33 +1101,10 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) tc->getITBPtr()->invalidateMiscReg(); tc->getDTBPtr()->invalidateMiscReg(); - // Check if all CPUs are booted with caches enabled - // so we can stop enforcing coherency of some kernel - // structures manually. - sys = tc->getSystemPtr(); - for (x = 0; x < sys->numContexts(); x++) { - oc = sys->getThreadContext(x); - // @todo: double check this for security - SCTLR other_sctlr = oc->readMiscRegNoEffect(MISCREG_SCTLR); - if (!other_sctlr.c && oc->status() != ThreadContext::Halted) - return; - } - - for (x = 0; x < sys->numContexts(); x++) { - oc = sys->getThreadContext(x); - oc->getDTBPtr()->allCpusCaching(); - oc->getITBPtr()->allCpusCaching(); - - // If CheckerCPU is connected, need to notify it. - CheckerCPU *checker = oc->getCheckerCpuPtr(); - if (checker) { - checker->getDTBPtr()->allCpusCaching(); - checker->getITBPtr()->allCpusCaching(); - } - } + if (new_sctlr.c) + updateBootUncacheable(sctlr_idx, tc); return; } - case MISCREG_MIDR: case MISCREG_ID_PFR0: case MISCREG_ID_PFR1: @@ -1674,6 +1651,16 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) } } } + case MISCREG_SCTLR_EL1: + { + tc->getITBPtr()->invalidateMiscReg(); + tc->getDTBPtr()->invalidateMiscReg(); + SCTLR new_sctlr = newVal; + setMiscRegNoEffect(misc_reg, newVal); + if (new_sctlr.c) + updateBootUncacheable(misc_reg, tc); + return; + } case MISCREG_CONTEXTIDR: case MISCREG_PRRR: case MISCREG_NMRR: @@ -1682,12 +1669,11 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) case MISCREG_DACR: case MISCREG_VTTBR: case MISCREG_SCR_EL3: - case MISCREG_SCTLR_EL1: - case MISCREG_SCTLR_EL2: - case MISCREG_SCTLR_EL3: case MISCREG_TCR_EL1: case MISCREG_TCR_EL2: case MISCREG_TCR_EL3: + case MISCREG_SCTLR_EL2: + case MISCREG_SCTLR_EL3: case MISCREG_TTBR0_EL1: case MISCREG_TTBR1_EL1: case MISCREG_TTBR0_EL2: @@ -1922,6 +1908,38 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) } void +ISA::updateBootUncacheable(int sctlr_idx, ThreadContext *tc) +{ + System *sys; + ThreadContext *oc; + + // Check if all CPUs are booted with caches enabled + // so we can stop enforcing coherency of some kernel + // structures manually. + sys = tc->getSystemPtr(); + for (int x = 0; x < sys->numContexts(); x++) { + oc = sys->getThreadContext(x); + // @todo: double check this for security + SCTLR other_sctlr = oc->readMiscRegNoEffect(sctlr_idx); + if (!other_sctlr.c && oc->status() != ThreadContext::Halted) + return; + } + + for (int x = 0; x < sys->numContexts(); x++) { + oc = sys->getThreadContext(x); + oc->getDTBPtr()->allCpusCaching(); + oc->getITBPtr()->allCpusCaching(); + + // If CheckerCPU is connected, need to notify it. + CheckerCPU *checker = oc->getCheckerCpuPtr(); + if (checker) { + checker->getDTBPtr()->allCpusCaching(); + checker->getITBPtr()->allCpusCaching(); + } + } +} + +void ISA::tlbiVA(ThreadContext *tc, MiscReg newVal, uint8_t asid, bool secure_lookup, uint8_t target_el) { |