CPU: fix sparc_fs booting with SimpleTimingCPU.
authorAli Saidi <saidi@eecs.umich.edu>
Mon, 1 Oct 2007 06:55:27 +0000 (02:55 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Mon, 1 Oct 2007 06:55:27 +0000 (02:55 -0400)
--HG--
extra : convert_revision : 3d95f6daa7f0e8e376d1a880f64c056619263885

src/cpu/simple/timing.cc
src/cpu/simple/timing.hh
src/dev/sparc/iob.cc

index b70fc2a414ebb6a1ba1e791e5a1cd1598c261846..30100e6c9aaf014fece2a94aa3859674784c20e4 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include "arch/locked_mem.hh"
+#include "arch/mmaped_ipr.hh"
 #include "arch/utility.hh"
 #include "base/bigint.hh"
 #include "cpu/exetrace.hh"
@@ -266,7 +267,13 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
                        Packet::Broadcast);
         pkt->dataDynamic<T>(new T);
 
-        if (!dcachePort.sendTiming(pkt)) {
+        if (req->isMmapedIpr()) {
+            Tick delay;
+            delay = TheISA::handleIprRead(thread->getTC(), pkt);
+            new IprEvent(pkt, this, nextCycle(curTick + delay));
+            _status = DcacheWaitResponse;
+            dcache_pkt = NULL;
+        } else if (!dcachePort.sendTiming(pkt)) {
             _status = DcacheRetry;
             dcache_pkt = pkt;
         } else {
@@ -375,7 +382,14 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
         dcache_pkt->set(data);
 
         if (do_access) {
-            if (!dcachePort.sendTiming(dcache_pkt)) {
+            if (req->isMmapedIpr()) {
+                Tick delay;
+                dcache_pkt->set(htog(data));
+                delay = TheISA::handleIprWrite(thread->getTC(), dcache_pkt);
+                new IprEvent(dcache_pkt, this, nextCycle(curTick + delay));
+                _status = DcacheWaitResponse;
+                dcache_pkt = NULL;
+            } else if (!dcachePort.sendTiming(dcache_pkt)) {
                 _status = DcacheRetry;
             } else {
                 _status = DcacheWaitResponse;
@@ -551,6 +565,10 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
             }
 
             postExecute();
+            // @todo remove me after debugging with legion done
+            if (curStaticInst && (!curStaticInst->isMicroop() ||
+                        curStaticInst->isFirstMicroop()))
+                instCnt++;
             advanceInst(fault);
         }
     } else {
@@ -567,6 +585,10 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
         }
 
         postExecute();
+        // @todo remove me after debugging with legion done
+        if (curStaticInst && (!curStaticInst->isMicroop() ||
+                    curStaticInst->isFirstMicroop()))
+            instCnt++;
         advanceInst(fault);
     }
 
@@ -730,6 +752,24 @@ TimingSimpleCPU::DcachePort::recvRetry()
     }
 }
 
+TimingSimpleCPU::IprEvent::IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
+    : Event(&mainEventQueue), pkt(_pkt), cpu(_cpu)
+{
+    schedule(t);
+}
+
+void
+TimingSimpleCPU::IprEvent::process()
+{
+    cpu->completeDataAccess(pkt);
+}
+
+const char *
+TimingSimpleCPU::IprEvent::description()
+{
+    return "Timing Simple CPU Delay IPR event";
+}
+
 
 ////////////////////////////////////////////////////////////////////////
 //
index ba194b3fa3a15d637a468a08826faa62f3f00530..4a4c276fd5d4533490ece280f33382a602665366 100644 (file)
@@ -203,6 +203,14 @@ class TimingSimpleCPU : public BaseSimpleCPU
     typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> FetchEvent;
     FetchEvent *fetchEvent;
 
+    struct IprEvent : Event {
+        Packet *pkt;
+        TimingSimpleCPU *cpu;
+        IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t);
+        virtual void process();
+        virtual const char *description();
+    };
+
     void completeDrain();
 };
 
index d0182770fb3b4cdde3ad1953fb26e817e4318781..6608fc64add79c9561dfb93fae093086586e4231 100644 (file)
@@ -56,6 +56,9 @@ Iob::Iob(const Params *p)
     iobJBusAddr = ULL(0x9F00000000);
     iobJBusSize = ULL(0x0100000000);
     assert (params()->system->threadContexts.size() <= MaxNiagaraProcs);
+
+    pioDelay = p->pio_latency;
+
     // Get the interrupt controller from the platform
     ic = platform->intrctrl;