changeset b531e328342d in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=b531e328342d
description:
cpu: Add CPU support for generatig wake up events when LLSC adresses
are snooped.
This patch add support for generating wake-up events in the CPU when an
address
that is currently in the exclusive state is hit by a snoop. This
mechanism is required
for ARMv8 multi-processor support.
diffstat:
src/arch/alpha/locked_mem.hh | 7 +++++-
src/arch/arm/locked_mem.hh | 20 +++++++++++-------
src/arch/mips/locked_mem.hh | 8 ++++++-
src/arch/power/locked_mem.hh | 8 ++++++-
src/arch/sparc/locked_mem.hh | 8 ++++++-
src/arch/x86/locked_mem.hh | 8 ++++++-
src/cpu/base.hh | 3 ++
src/cpu/base_dyn_inst.hh | 2 +
src/cpu/inorder/resources/cache_unit.cc | 14 ++++++++++++-
src/cpu/o3/lsq_unit_impl.hh | 32 +++++++++++++++++++++++++-----
src/cpu/simple/atomic.cc | 34 +++++++++++++++++++++++++++++++-
src/cpu/simple/atomic.hh | 33 ++++++++++++++++++++++++-------
src/cpu/simple/timing.cc | 12 +++++++++-
src/cpu/simple/timing.hh | 12 +++++++++-
14 files changed, 167 insertions(+), 34 deletions(-)
diffs (truncated from 478 to 300 lines):
diff -r 45779e2f844b -r b531e328342d src/arch/alpha/locked_mem.hh
--- a/src/arch/alpha/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/arch/alpha/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
@@ -93,10 +93,15 @@
xc->setMiscReg(MISCREG_LOCKFLAG, true);
}
+template <class XC>
+inline void
+handleLockedSnoopHit(XC *xc)
+{
+}
template <class XC>
inline bool
-handleLockedWrite(XC *xc, Request *req)
+handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask)
{
if (req->isUncacheable()) {
// Funky Turbolaser mailbox access...don't update
diff -r 45779e2f844b -r b531e328342d src/arch/arm/locked_mem.hh
--- a/src/arch/arm/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/arch/arm/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -66,9 +66,7 @@
return;
Addr locked_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask;
- Addr snoop_addr = pkt->getAddr();
-
- assert((cacheBlockMask & snoop_addr) == snoop_addr);
+ Addr snoop_addr = pkt->getAddr() & cacheBlockMask;
if (locked_addr == snoop_addr)
xc->setMiscReg(MISCREG_LOCKFLAG, false);
@@ -76,16 +74,22 @@
template <class XC>
inline void
+handleLockedSnoopHit(XC *xc)
+{
+}
+
+template <class XC>
+inline void
handleLockedRead(XC *xc, Request *req)
{
- xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf);
+ xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr());
xc->setMiscReg(MISCREG_LOCKFLAG, true);
}
template <class XC>
inline bool
-handleLockedWrite(XC *xc, Request *req)
+handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask)
{
if (req->isSwap())
return true;
@@ -93,8 +97,8 @@
// Verify that the lock flag is still set and the address
// is correct
bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG);
- Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR);
- if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) {
+ Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask;
+ if (!lock_flag || (req->getPaddr() & cacheBlockMask) != lock_addr) {
// Lock flag not set or addr mismatch in CPU;
// don't even bother sending to memory system
req->setExtraData(0);
diff -r 45779e2f844b -r b531e328342d src/arch/mips/locked_mem.hh
--- a/src/arch/mips/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/arch/mips/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
@@ -87,8 +87,14 @@
}
template <class XC>
+inline void
+handleLockedSnoopHit(XC *xc)
+{
+}
+
+template <class XC>
inline bool
-handleLockedWrite(XC *xc, Request *req)
+handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask)
{
if (req->isUncacheable()) {
// Funky Turbolaser mailbox access...don't update
diff -r 45779e2f844b -r b531e328342d src/arch/power/locked_mem.hh
--- a/src/arch/power/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/arch/power/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
@@ -60,8 +60,14 @@
}
template <class XC>
+inline void
+handleLockedSnoopHit(XC *xc)
+{
+}
+
+template <class XC>
inline bool
-handleLockedWrite(XC *xc, Request *req)
+handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask)
{
return true;
}
diff -r 45779e2f844b -r b531e328342d src/arch/sparc/locked_mem.hh
--- a/src/arch/sparc/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/arch/sparc/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
@@ -54,10 +54,16 @@
{
}
+template <class XC>
+inline void
+handleLockedSnoopHit(XC *xc)
+{
+}
+
template <class XC>
inline bool
-handleLockedWrite(XC *xc, Request *req)
+handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask)
{
return true;
}
diff -r 45779e2f844b -r b531e328342d src/arch/x86/locked_mem.hh
--- a/src/arch/x86/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/arch/x86/locked_mem.hh Fri Jan 24 15:29:30 2014 -0600
@@ -56,10 +56,16 @@
template <class XC>
inline bool
- handleLockedWrite(XC *xc, Request *req)
+ handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask)
{
return true;
}
+
+ template <class XC>
+ inline void
+ handleLockedSnoopHit(XC *xc)
+ {
+ }
}
#endif // __ARCH_X86_LOCKEDMEM_HH__
diff -r 45779e2f844b -r b531e328342d src/cpu/base.hh
--- a/src/cpu/base.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/cpu/base.hh Fri Jan 24 15:29:30 2014 -0600
@@ -261,6 +261,9 @@
/// Given a thread num get tho thread context for it
virtual ThreadContext *getContext(int tn) { return threadContexts[tn]; }
+ /// Get the number of thread contexts available
+ unsigned numContexts() { return threadContexts.size(); }
+
public:
typedef BaseCPUParams Params;
const Params *params() const
diff -r 45779e2f844b -r b531e328342d src/cpu/base_dyn_inst.hh
--- a/src/cpu/base_dyn_inst.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/cpu/base_dyn_inst.hh Fri Jan 24 15:29:30 2014 -0600
@@ -164,6 +164,8 @@
/** Pointer to the Impl's CPU object. */
ImplCPU *cpu;
+ BaseCPU *getCpuPtr() { return cpu; }
+
/** Pointer to the thread state. */
ImplState *thread;
diff -r 45779e2f844b -r b531e328342d src/cpu/inorder/resources/cache_unit.cc
--- a/src/cpu/inorder/resources/cache_unit.cc Fri Jan 24 15:29:30 2014 -0600
+++ b/src/cpu/inorder/resources/cache_unit.cc Fri Jan 24 15:29:30 2014 -0600
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2013 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2007 MIPS Technologies, Inc.
* All rights reserved.
*
@@ -863,7 +875,7 @@
if (mem_req->isLLSC()) {
assert(cache_req->inst->isStoreConditional());
DPRINTF(InOrderCachePort, "Evaluating Store Conditional access\n");
- do_access = TheISA::handleLockedWrite(inst.get(), mem_req);
+ do_access = TheISA::handleLockedWrite(inst.get(), mem_req,
cacheBlkSize);
}
}
diff -r 45779e2f844b -r b531e328342d src/cpu/o3/lsq_unit_impl.hh
--- a/src/cpu/o3/lsq_unit_impl.hh Fri Jan 24 15:29:30 2014 -0600
+++ b/src/cpu/o3/lsq_unit_impl.hh Fri Jan 24 15:29:30 2014 -0600
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2010-2012 ARM Limited
+ * Copyright (c) 2010-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -433,12 +433,13 @@
LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
{
int load_idx = loadHead;
+ DPRINTF(LSQUnit, "Got snoop for address %#x\n", pkt->getAddr());
// Unlock the cpu-local monitor when the CPU sees a snoop to a locked
// address. The CPU can speculatively execute a LL operation after a
pending
// SC operation in the pipeline and that can make the cache monitor the CPU
// is connected to valid while it really shouldn't be.
- for (int x = 0; x < cpu->numActiveThreads(); x++) {
+ for (int x = 0; x < cpu->numContexts(); x++) {
ThreadContext *tc = cpu->getContext(x);
bool no_squash = cpu->thread[x]->noSquashFromTC;
cpu->thread[x]->noSquashFromTC = true;
@@ -446,13 +447,23 @@
cpu->thread[x]->noSquashFromTC = no_squash;
}
+ Addr invalidate_addr = pkt->getAddr() & cacheBlockMask;
+
+ DynInstPtr ld_inst = loadQueue[load_idx];
+ if (ld_inst) {
+ Addr load_addr = ld_inst->physEffAddr & cacheBlockMask;
+ // Check that this snoop didn't just invalidate our lock flag
+ if (ld_inst->effAddrValid() && load_addr == invalidate_addr &&
+ ld_inst->memReqFlags & Request::LLSC)
+ TheISA::handleLockedSnoopHit(ld_inst.get());
+ }
+
// If this is the only load in the LSQ we don't care
if (load_idx == loadTail)
return;
+
incrLdIdx(load_idx);
- DPRINTF(LSQUnit, "Got snoop for address %#x\n", pkt->getAddr());
- Addr invalidate_addr = pkt->getAddr() & cacheBlockMask;
while (load_idx != loadTail) {
DynInstPtr ld_inst = loadQueue[load_idx];
@@ -468,11 +479,20 @@
if (load_addr == invalidate_addr) {
if (ld_inst->possibleLoadViolation()) {
DPRINTF(LSQUnit, "Conflicting load at addr %#x [sn:%lli]\n",
- ld_inst->physEffAddr, pkt->getAddr(), ld_inst->seqNum);
+ pkt->getAddr(), ld_inst->seqNum);
// Mark the load for re-execution
ld_inst->fault = new ReExec;
} else {
+ DPRINTF(LSQUnit, "HitExternal Snoop for addr %#x [sn:%lli]\n",
+ pkt->getAddr(), ld_inst->seqNum);
+
+ // Make sure that we don't lose a snoop hitting a LOCKED
+ // address since the LOCK* flags don't get updated until
+ // commit.
+ if (ld_inst->memReqFlags & Request::LLSC)
+ TheISA::handleLockedSnoopHit(ld_inst.get());
+
// If a older load checks this and it's true
// then we might have missed the snoop
// in which case we need to invalidate to be sure
@@ -849,7 +869,7 @@
// misc regs normally updates the result, but this is not
// the desired behavior when handling store conditionals.
inst->recordResult(false);
- bool success = TheISA::handleLockedWrite(inst.get(), req);
+ bool success = TheISA::handleLockedWrite(inst.get(), req,
cacheBlockMask);
inst->recordResult(true);
if (!success) {
diff -r 45779e2f844b -r b531e328342d src/cpu/simple/atomic.cc
--- a/src/cpu/simple/atomic.cc Fri Jan 24 15:29:30 2014 -0600
+++ b/src/cpu/simple/atomic.cc Fri Jan 24 15:29:30 2014 -0600
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 ARM Limited
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev