changeset aa46a8ae3487 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=aa46a8ae3487
description:
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:
src/arch/arm/isa.cc | 74 ++++++++++++++++++++++++++----------------
src/arch/arm/isa.hh | 8 ++++
src/arch/arm/linux/system.cc | 4 ++
src/arch/arm/tlb.cc | 9 ++++-
src/base/loader/dtb_object.cc | 21 ++++++++++++
src/base/loader/dtb_object.hh | 7 ++++
6 files changed, 94 insertions(+), 29 deletions(-)
diffs (216 lines):
diff -r f33fab6214c4 -r aa46a8ae3487 src/arch/arm/isa.cc
--- a/src/arch/arm/isa.cc Wed Oct 29 23:18:26 2014 -0500
+++ b/src/arch/arm/isa.cc Wed Oct 29 23:18:26 2014 -0500
@@ -1101,33 +1101,10 @@
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 @@
}
}
}
+ 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 @@
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 @@
}
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)
{
diff -r f33fab6214c4 -r aa46a8ae3487 src/arch/arm/isa.hh
--- a/src/arch/arm/isa.hh Wed Oct 29 23:18:26 2014 -0500
+++ b/src/arch/arm/isa.hh Wed Oct 29 23:18:26 2014 -0500
@@ -429,6 +429,14 @@
void startup(ThreadContext *tc) {}
+ /** Check if all CPUs have their caches enabled and if they do
+ * disable the bootAddrUncacheability flag because it's no longer
+ * needed.
+ * @s_idx the register number of the SCTLR that we are checking
+ * @tc Threadcontext to use to get access to the system and other cpus
+ */
+ void updateBootUncacheable(int sctlr_idx, ThreadContext *tc);
+
/// Explicitly import the otherwise hidden startup
using SimObject::startup;
diff -r f33fab6214c4 -r aa46a8ae3487 src/arch/arm/linux/system.cc
--- a/src/arch/arm/linux/system.cc Wed Oct 29 23:18:26 2014 -0500
+++ b/src/arch/arm/linux/system.cc Wed Oct 29 23:18:26 2014 -0500
@@ -175,6 +175,10 @@
"to DTB file: %s\n", params()->dtb_filename);
}
+ Addr ra = _dtb_file->findReleaseAddr();
+ if (ra)
+ bootReleaseAddr = ra & ~ULL(0x7F);
+
dtb_file->setTextBase(params()->atags_addr + loadAddrOffset);
dtb_file->loadSections(physProxy);
delete dtb_file;
diff -r f33fab6214c4 -r aa46a8ae3487 src/arch/arm/tlb.cc
--- a/src/arch/arm/tlb.cc Wed Oct 29 23:18:26 2014 -0500
+++ b/src/arch/arm/tlb.cc Wed Oct 29 23:18:26 2014 -0500
@@ -1089,7 +1089,14 @@
req->setFlags(Request::UNCACHEABLE);
}
- req->setPaddr(te->pAddr(vaddr));
+ Addr pa = te->pAddr(vaddr);
+ req->setPaddr(pa);
+
+ if (!bootUncacheability &&
+ ((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(pa)) {
+ req->setFlags(Request::UNCACHEABLE);
+ }
+
if (isSecure && !te->ns) {
req->setFlags(Request::SECURE);
}
diff -r f33fab6214c4 -r aa46a8ae3487 src/base/loader/dtb_object.cc
--- a/src/base/loader/dtb_object.cc Wed Oct 29 23:18:26 2014 -0500
+++ b/src/base/loader/dtb_object.cc Wed Oct 29 23:18:26 2014 -0500
@@ -35,6 +35,7 @@
#include <cassert>
#include "base/loader/dtb_object.hh"
+#include "sim/byteswap.hh"
#include "fdt.h"
#include "libfdt.h"
@@ -154,6 +155,26 @@
return true;
}
+Addr
+DtbObject::findReleaseAddr()
+{
+ void *fd = (void*)fileData;
+
+ int offset = fdt_path_offset(fd, "/cpus/cpu@0");
+ int len;
+
+ const void* temp = fdt_getprop(fd, offset, "cpu-release-addr", &len);
+ Addr rel_addr = 0;
+
+ if (len > 3)
+ rel_addr = betoh(*static_cast<const uint32_t*>(temp));
+ if (len == 8)
+ rel_addr = (rel_addr << 32) | betoh(*(static_cast<const
uint32_t*>(temp)+1));
+
+ return rel_addr;
+}
+
+
bool
DtbObject::loadGlobalSymbols(SymbolTable *symtab, Addr addrMask)
{
diff -r f33fab6214c4 -r aa46a8ae3487 src/base/loader/dtb_object.hh
--- a/src/base/loader/dtb_object.hh Wed Oct 29 23:18:26 2014 -0500
+++ b/src/base/loader/dtb_object.hh Wed Oct 29 23:18:26 2014 -0500
@@ -60,6 +60,13 @@
* @return returns true on success, false otherwise
*/
bool addBootCmdLine(const char* _args, size_t len);
+
+ /** Parse the DTB file enough to find the provided release
+ * address and return it.
+ * @return release address for SMP boot
+ */
+ Addr findReleaseAddr();
+
bool loadGlobalSymbols(SymbolTable *symtab,
Addr addrMask = std::numeric_limits<Addr>::max());
bool loadLocalSymbols(SymbolTable *symtab,
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev