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

Reply via email to