changeset 6bac5b04d588 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=6bac5b04d588
description:
ARM: Mark some variables uncacheable until boot all CPUs are enabled.
There are a set of locations is the linux kernel that are managed via
cache maintence instructions until all processors enable their MMUs &
TLBs.
Writes to these locations are manually flushed from the cache to main
memory when the occur so that cores operating without their MMU enabled
and only issuing uncached accesses can receive the correct data.
Unfortuantely,
gem5 doesn't support any kind of software directed maintence of the
cache.
Until such time as that support exists this patch marks the specific
cache blocks
that need to be coherent as non-cacheable until all CPUs enable their
MMU and
thus allows gem5 to boot MP systems with caches enabled (a requirement
for
booting an O3 cpu and thus an O3 CPU regression).
diffstat:
src/arch/arm/isa.cc | 17 +++++++++++++++++
src/arch/arm/linux/system.cc | 21 +++++++++++++++++++++
src/arch/arm/linux/system.hh | 11 +++++++++++
src/arch/arm/system.hh | 9 +++++++++
src/arch/arm/tlb.cc | 10 ++++++++--
src/arch/arm/tlb.hh | 3 +++
6 files changed, 69 insertions(+), 2 deletions(-)
diffs (166 lines):
diff -r 2e5d41fbc4a5 -r 6bac5b04d588 src/arch/arm/isa.cc
--- a/src/arch/arm/isa.cc Fri Aug 19 15:08:08 2011 -0500
+++ b/src/arch/arm/isa.cc Fri Aug 19 15:08:08 2011 -0500
@@ -360,6 +360,23 @@
miscRegs[MISCREG_SCTLR] = (MiscReg)new_sctlr;
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);
+ 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();
+ }
return;
}
case MISCREG_TLBTR:
diff -r 2e5d41fbc4a5 -r 6bac5b04d588 src/arch/arm/linux/system.cc
--- a/src/arch/arm/linux/system.cc Fri Aug 19 15:08:08 2011 -0500
+++ b/src/arch/arm/linux/system.cc Fri Aug 19 15:08:08 2011 -0500
@@ -117,6 +117,27 @@
} else {
panic("couldn't find kernel symbol \'udelay\'");
}
+
+ secDataPtrAddr = 0;
+ secDataAddr = 0;
+ penReleaseAddr = 0;
+ kernelSymtab->findAddress("__secondary_data", secDataPtrAddr);
+ kernelSymtab->findAddress("secondary_data", secDataAddr);
+ kernelSymtab->findAddress("pen_release", penReleaseAddr);
+
+ secDataPtrAddr &= ~ULL(0x7F);
+ secDataAddr &= ~ULL(0x7F);
+ penReleaseAddr &= ~ULL(0x7F);
+}
+
+bool
+LinuxArmSystem::adderBootUncacheable(Addr a)
+{
+ Addr block = a & ~ULL(0x7F);
+ if (block == secDataPtrAddr || block == secDataAddr ||
+ block == penReleaseAddr)
+ return true;
+ return false;
}
void
diff -r 2e5d41fbc4a5 -r 6bac5b04d588 src/arch/arm/linux/system.hh
--- a/src/arch/arm/linux/system.hh Fri Aug 19 15:08:08 2011 -0500
+++ b/src/arch/arm/linux/system.hh Fri Aug 19 15:08:08 2011 -0500
@@ -69,6 +69,8 @@
void initState();
+ bool adderBootUncacheable(Addr a);
+
private:
#ifndef NDEBUG
/** Event to halt the simulator if the kernel calls panic() */
@@ -87,6 +89,15 @@
* Thus we need to do some division to get back to us.
*/
Linux::UDelayEvent *constUDelaySkipEvent;
+
+ /** These variables store addresses of important data structures
+ * that are normaly kept coherent at boot with cache mainetence operations.
+ * Since these operations aren't supported in gem5, we keep them coherent
+ * by making them uncacheable until all processors in the system boot.
+ */
+ Addr secDataPtrAddr;
+ Addr secDataAddr;
+ Addr penReleaseAddr;
};
#endif // __ARCH_ARM_LINUX_SYSTEM_HH__
diff -r 2e5d41fbc4a5 -r 6bac5b04d588 src/arch/arm/system.hh
--- a/src/arch/arm/system.hh Fri Aug 19 15:08:08 2011 -0500
+++ b/src/arch/arm/system.hh Fri Aug 19 15:08:08 2011 -0500
@@ -78,6 +78,15 @@
void initState();
+ /** Check if an address should be uncacheable until all caches are enabled.
+ * This exits because coherence on some addresses at boot is maintained via
+ * sw coherence until the caches are enbaled. Since we don't support sw
+ * coherence operations in gem5, this is a method that allows a system
+ * type to designate certain addresses that should remain uncachebale
+ * for a while.
+ */
+ virtual bool adderBootUncacheable(Addr a) { return false; }
+
virtual Addr fixFuncEventAddr(Addr addr)
{
// Remove the low bit that thumb symbols have set
diff -r 2e5d41fbc4a5 -r 6bac5b04d588 src/arch/arm/tlb.cc
--- a/src/arch/arm/tlb.cc Fri Aug 19 15:08:08 2011 -0500
+++ b/src/arch/arm/tlb.cc Fri Aug 19 15:08:08 2011 -0500
@@ -61,6 +61,7 @@
#include "sim/process.hh"
#if FULL_SYSTEM
+#include "arch/arm/system.hh"
#include "arch/arm/table_walker.hh"
#endif
@@ -72,7 +73,7 @@
#if FULL_SYSTEM
, tableWalker(p->walker)
#endif
- , rangeMRU(1), miscRegValid(false)
+ , rangeMRU(1), bootUncacheability(false), miscRegValid(false)
{
table = new TlbEntry[size];
memset(table, 0, sizeof(TlbEntry) * size);
@@ -575,6 +576,11 @@
}
}
+
+ if (!bootUncacheability &&
+ ((ArmSystem*)tc->getSystemPtr())->adderBootUncacheable(vaddr))
+ req->setFlags(Request::UNCACHEABLE);
+
switch ( (dacr >> (te->domain * 2)) & 0x3) {
case 0:
domainFaults++;
@@ -704,7 +710,7 @@
#else
fault = translateSe(req, tc, mode, translation, delay, true);
#endif
- DPRINTF(TLB, "Translation returning delay=%d fault=%d\n", delay, fault !=
+ DPRINTF(TLBVerbose, "Translation returning delay=%d fault=%d\n", delay,
fault !=
NoFault);
if (!delay)
translation->finish(fault, req, tc, mode);
diff -r 2e5d41fbc4a5 -r 6bac5b04d588 src/arch/arm/tlb.hh
--- a/src/arch/arm/tlb.hh Fri Aug 19 15:08:08 2011 -0500
+++ b/src/arch/arm/tlb.hh Fri Aug 19 15:08:08 2011 -0500
@@ -128,6 +128,8 @@
int rangeMRU; //On lookup, only move entries ahead when outside rangeMRU
+ bool bootUncacheability;
+
public:
typedef ArmTLBParams Params;
TLB(const Params *p);
@@ -162,6 +164,7 @@
void printTlb();
+ void allCpusCaching() { bootUncacheability = true; }
void demapPage(Addr vaddr, uint64_t asn)
{
flushMvaAsid(vaddr, asn);
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev