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 gem5-dev@gem5.org http://m5sim.org/mailman/listinfo/gem5-dev