X86: Don't fetch in the simple CPU if you're in the ROM.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 13 Oct 2008 02:32:06 +0000 (19:32 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 13 Oct 2008 02:32:06 +0000 (19:32 -0700)
src/cpu/simple/atomic.cc
src/cpu/simple/timing.cc

index 154a66162f359a83321d3e8ab51e4b2a1e7d4d53..878f69f0c16cd62fbf0264f3396da7739d8f13a1 100644 (file)
@@ -718,31 +718,37 @@ AtomicSimpleCPU::tick()
 
         checkPcEventQueue();
 
-        Fault fault = setupFetchRequest(&ifetch_req);
+        Fault fault = NoFault;
+
+        bool fromRom = isRomMicroPC(thread->readMicroPC());
+        if (!fromRom)
+            fault = setupFetchRequest(&ifetch_req);
 
         if (fault == NoFault) {
             Tick icache_latency = 0;
             bool icache_access = false;
             dcache_access = false; // assume no dcache access
 
-            //Fetch more instruction memory if necessary
-            //if(predecoder.needMoreBytes())
-            //{
-                icache_access = true;
-                Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq,
-                                           Packet::Broadcast);
-                ifetch_pkt.dataStatic(&inst);
-
-                if (hasPhysMemPort && ifetch_pkt.getAddr() == physMemAddr)
-                    icache_latency = physmemPort.sendAtomic(&ifetch_pkt);
-                else
-                    icache_latency = icachePort.sendAtomic(&ifetch_pkt);
+            if (!fromRom) {
+                //Fetch more instruction memory if necessary
+                //if(predecoder.needMoreBytes())
+                //{
+                    icache_access = true;
+                    Packet ifetch_pkt = Packet(&ifetch_req, MemCmd::ReadReq,
+                                               Packet::Broadcast);
+                    ifetch_pkt.dataStatic(&inst);
+
+                    if (hasPhysMemPort && ifetch_pkt.getAddr() == physMemAddr)
+                        icache_latency = physmemPort.sendAtomic(&ifetch_pkt);
+                    else
+                        icache_latency = icachePort.sendAtomic(&ifetch_pkt);
 
-                assert(!ifetch_pkt.isError());
+                    assert(!ifetch_pkt.isError());
 
-                // ifetch_req is initialized to read the instruction directly
-                // into the CPU object's inst field.
-            //}
+                    // ifetch_req is initialized to read the instruction directly
+                    // into the CPU object's inst field.
+                //}
+            }
 
             preExecute();
 
index c4635d6a377667f0c1e486892b75387cc5b5fe8a..0cda9a0a384fb87dd83b6f8739a48ae41a1ed259 100644 (file)
@@ -531,28 +531,35 @@ TimingSimpleCPU::fetch()
 
     checkPcEventQueue();
 
-    Request *ifetch_req = new Request();
-    ifetch_req->setThreadContext(cpuId, /* thread ID */ 0);
-    Fault fault = setupFetchRequest(ifetch_req);
+    bool fromRom = isRomMicroPC(thread->readMicroPC());
 
-    ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
-    ifetch_pkt->dataStatic(&inst);
+    if (!fromRom) {
+        Request *ifetch_req = new Request();
+        ifetch_req->setThreadContext(cpuId, /* thread ID */ 0);
+        Fault fault = setupFetchRequest(ifetch_req);
 
-    if (fault == NoFault) {
-        if (!icachePort.sendTiming(ifetch_pkt)) {
-            // Need to wait for retry
-            _status = IcacheRetry;
+        ifetch_pkt = new Packet(ifetch_req, MemCmd::ReadReq, Packet::Broadcast);
+        ifetch_pkt->dataStatic(&inst);
+
+        if (fault == NoFault) {
+            if (!icachePort.sendTiming(ifetch_pkt)) {
+                // Need to wait for retry
+                _status = IcacheRetry;
+            } else {
+                // Need to wait for cache to respond
+                _status = IcacheWaitResponse;
+                // ownership of packet transferred to memory system
+                ifetch_pkt = NULL;
+            }
         } else {
-            // Need to wait for cache to respond
-            _status = IcacheWaitResponse;
-            // ownership of packet transferred to memory system
-            ifetch_pkt = NULL;
+            delete ifetch_req;
+            delete ifetch_pkt;
+            // fetch fault: advance directly to next instruction (fault handler)
+            advanceInst(fault);
         }
     } else {
-        delete ifetch_req;
-        delete ifetch_pkt;
-        // fetch fault: advance directly to next instruction (fault handler)
-        advanceInst(fault);
+        _status = IcacheWaitResponse;
+        completeIfetch(NULL);
     }
 
     numCycles += tickToCycles(curTick - previousTick);
@@ -581,7 +588,8 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
 
     // received a response from the icache: execute the received
     // instruction
-    assert(!pkt->isError());
+
+    assert(!pkt || !pkt->isError());
     assert(_status == IcacheWaitResponse);
 
     _status = Running;
@@ -590,8 +598,10 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
     previousTick = curTick;
 
     if (getState() == SimObject::Draining) {
-        delete pkt->req;
-        delete pkt;
+        if (pkt) {
+            delete pkt->req;
+            delete pkt;
+        }
 
         completeDrain();
         return;
@@ -658,8 +668,10 @@ TimingSimpleCPU::completeIfetch(PacketPtr pkt)
         advanceInst(fault);
     }
 
-    delete pkt->req;
-    delete pkt;
+    if (pkt) {
+        delete pkt->req;
+        delete pkt;
+    }
 }
 
 void