summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa.cc
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2014-10-29 23:18:26 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2014-10-29 23:18:26 -0500
commitbaf88e908d285191c13b5e96c16065957e5af7a6 (patch)
tree7361d43b795f80a80a89995eb6865d51a972f36a /src/arch/arm/isa.cc
parent3a5c975fd7a0e6c8f25067c1794581056c01c22c (diff)
downloadgem5-baf88e908d285191c13b5e96c16065957e5af7a6.tar.xz
arm: Fix multi-system AArch64 boot w/caches.
Automatically extract cpu release address from DTB file. Check SCTLR_EL1 to verify all caches are enabled.
Diffstat (limited to 'src/arch/arm/isa.cc')
-rw-r--r--src/arch/arm/isa.cc74
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)
{