changeset 818aea9960f5 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=818aea9960f5
description:
        O3: Implement memory mapped IPRs for O3.

diffstat:

 src/cpu/o3/lsq_unit.hh      |  38 ++++++++++++++++++++++++++++++++++++++
 src/cpu/o3/lsq_unit_impl.hh |  32 ++++++++++++++++++++++++++------
 2 files changed, 64 insertions(+), 6 deletions(-)

diffs (122 lines):

diff -r f22c829848a1 -r 818aea9960f5 src/cpu/o3/lsq_unit.hh
--- a/src/cpu/o3/lsq_unit.hh    Sat Jul 30 23:23:01 2011 -0700
+++ b/src/cpu/o3/lsq_unit.hh    Sun Jul 31 19:21:17 2011 -0700
@@ -39,6 +39,7 @@
 
 #include "arch/faults.hh"
 #include "arch/locked_mem.hh"
+#include "arch/mmapped_ipr.hh"
 #include "base/fast_alloc.hh"
 #include "base/hashmap.hh"
 #include "config/full_system.hh"
@@ -578,6 +579,43 @@
         load_inst->recordResult = true;
     }
 
+    if (req->isMmappedIpr()) {
+        assert(!load_inst->memData);
+        load_inst->memData = new uint8_t[64];
+
+        ThreadContext *thread = cpu->tcBase(lsqID);
+        Tick delay;
+        PacketPtr data_pkt =
+            new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
+
+        if (!TheISA::HasUnalignedMemAcc || !sreqLow) {
+            data_pkt->dataStatic(load_inst->memData);
+            delay = TheISA::handleIprRead(thread, data_pkt);
+        } else {
+            assert(sreqLow->isMmappedIpr() && sreqHigh->isMmappedIpr());
+            PacketPtr fst_data_pkt =
+                new Packet(sreqLow, MemCmd::ReadReq, Packet::Broadcast);
+            PacketPtr snd_data_pkt =
+                new Packet(sreqHigh, MemCmd::ReadReq, Packet::Broadcast);
+
+            fst_data_pkt->dataStatic(load_inst->memData);
+            snd_data_pkt->dataStatic(load_inst->memData + sreqLow->getSize());
+
+            delay = TheISA::handleIprRead(thread, fst_data_pkt);
+            unsigned delay2 = TheISA::handleIprRead(thread, snd_data_pkt);
+            if (delay2 > delay)
+                delay = delay2;
+
+            delete sreqLow;
+            delete sreqHigh;
+            delete fst_data_pkt;
+            delete snd_data_pkt;
+        }
+        WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this);
+        cpu->schedule(wb, curTick() + delay);
+        return NoFault;
+    }
+
     while (store_idx != -1) {
         // End once we've reached the top of the LSQ
         if (store_idx == storeWBIdx) {
diff -r f22c829848a1 -r 818aea9960f5 src/cpu/o3/lsq_unit_impl.hh
--- a/src/cpu/o3/lsq_unit_impl.hh       Sat Jul 30 23:23:01 2011 -0700
+++ b/src/cpu/o3/lsq_unit_impl.hh       Sun Jul 31 19:21:17 2011 -0700
@@ -716,6 +716,9 @@
         DynInstPtr inst = storeQueue[storeWBIdx].inst;
 
         Request *req = storeQueue[storeWBIdx].req;
+        RequestPtr sreqLow = storeQueue[storeWBIdx].sreqLow;
+        RequestPtr sreqHigh = storeQueue[storeWBIdx].sreqHigh;
+
         storeQueue[storeWBIdx].committed = true;
 
         assert(!inst->memData);
@@ -741,9 +744,6 @@
             data_pkt->dataStatic(inst->memData);
             data_pkt->senderState = state;
         } else {
-            RequestPtr sreqLow = storeQueue[storeWBIdx].sreqLow;
-            RequestPtr sreqHigh = storeQueue[storeWBIdx].sreqHigh;
-
             // Create two packets if the store is split in two.
             data_pkt = new Packet(sreqLow, command, Packet::Broadcast);
             snd_data_pkt = new Packet(sreqHigh, command, Packet::Broadcast);
@@ -794,20 +794,40 @@
             state->noWB = true;
         }
 
-        if (!sendStore(data_pkt)) {
+        bool split =
+            TheISA::HasUnalignedMemAcc && storeQueue[storeWBIdx].isSplit;
+
+        ThreadContext *thread = cpu->tcBase(lsqID);
+
+        if (req->isMmappedIpr()) {
+            assert(!inst->isStoreConditional());
+            TheISA::handleIprWrite(thread, data_pkt);
+            delete data_pkt;
+            if (split) {
+                assert(snd_data_pkt->req->isMmappedIpr());
+                TheISA::handleIprWrite(thread, snd_data_pkt);
+                delete snd_data_pkt;
+                delete sreqLow;
+                delete sreqHigh;
+            }
+            delete state;
+            delete req;
+            completeStore(storeWBIdx);
+            incrStIdx(storeWBIdx);
+        } else if (!sendStore(data_pkt)) {
             DPRINTF(IEW, "D-Cache became blocked when writing [sn:%lli], will"
                     "retry later\n",
                     inst->seqNum);
 
             // Need to store the second packet, if split.
-            if (TheISA::HasUnalignedMemAcc && storeQueue[storeWBIdx].isSplit) {
+            if (split) {
                 state->pktToSend = true;
                 state->pendingPacket = snd_data_pkt;
             }
         } else {
 
             // If split, try to send the second packet too
-            if (TheISA::HasUnalignedMemAcc && storeQueue[storeWBIdx].isSplit) {
+            if (split) {
                 assert(snd_data_pkt);
 
                 // Ensure there are enough ports to use.
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to