Configs: Add support for the InOrder CPU model
[gem5.git] / src / mem / physical.cc
index 8c56d340f88e6888b699dcc91afe69164a2a63ee..16ff3de6ddb49520dabe4e734950b662b891bc0c 100644 (file)
@@ -41,6 +41,7 @@
 
 #include "arch/isa_traits.hh"
 #include "base/misc.hh"
+#include "base/random.hh"
 #include "config/full_system.hh"
 #include "mem/packet_access.hh"
 #include "mem/physical.hh"
@@ -51,11 +52,16 @@ using namespace std;
 using namespace TheISA;
 
 PhysicalMemory::PhysicalMemory(const Params *p)
-    : MemObject(p), pmemAddr(NULL), lat(p->latency)
+    : MemObject(p), pmemAddr(NULL), pagePtr(0),
+      lat(p->latency), lat_var(p->latency_var),
+      cachedSize(params()->range.size()), cachedStart(params()->range.start)
 {
     if (params()->range.size() % TheISA::PageBytes != 0)
         panic("Memory Size not divisible by page size\n");
 
+    if (params()->null)
+        return;
+
     int map_flags = MAP_ANON | MAP_PRIVATE;
     pmemAddr = (uint8_t *)mmap(NULL, params()->range.size(),
                                PROT_READ | PROT_WRITE, map_flags, -1, 0);
@@ -68,8 +74,6 @@ PhysicalMemory::PhysicalMemory(const Params *p)
     //If requested, initialize all the memory to 0
     if (p->zero)
         memset(pmemAddr, 0, p->range.size());
-
-    pagePtr = 0;
 }
 
 void
@@ -112,7 +116,10 @@ PhysicalMemory::deviceBlockSize()
 Tick
 PhysicalMemory::calculateLatency(PacketPtr pkt)
 {
-    return lat;
+    Tick latency = lat;
+    if (lat_var != 0)
+        latency += random_mt.random<Tick>(0, lat_var);
+    return latency;
 }
 
 
@@ -132,16 +139,16 @@ PhysicalMemory::trackLoadLocked(PacketPtr pkt)
 
     for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) {
         if (i->matchesContext(req)) {
-            DPRINTF(LLSC, "Modifying lock record: cpu %d thread %d addr %#x\n",
-                    req->getCpuNum(), req->getThreadNum(), paddr);
+            DPRINTF(LLSC, "Modifying lock record: context %d addr %#x\n",
+                    req->contextId(), paddr);
             i->addr = paddr;
             return;
         }
     }
 
     // no record for this xc: need to allocate a new one
-    DPRINTF(LLSC, "Adding lock record: cpu %d thread %d addr %#x\n",
-            req->getCpuNum(), req->getThreadNum(), paddr);
+    DPRINTF(LLSC, "Adding lock record: context %d addr %#x\n",
+            req->contextId(), paddr);
     lockedAddrList.push_front(LockedAddr(req));
 }
 
@@ -176,14 +183,14 @@ PhysicalMemory::checkLockedAddrList(PacketPtr pkt)
                 // it's a store conditional, and as far as the memory
                 // system can tell, the requesting context's lock is
                 // still valid.
-                DPRINTF(LLSC, "StCond success: cpu %d thread %d addr %#x\n",
-                        req->getCpuNum(), req->getThreadNum(), paddr);
+                DPRINTF(LLSC, "StCond success: context %d addr %#x\n",
+                        req->contextId(), paddr);
                 success = true;
             }
 
             // Get rid of our record of this lock and advance to next
-            DPRINTF(LLSC, "Erasing lock record: cpu %d thread %d addr %#x\n",
-                    i->cpuNum, i->threadNum, paddr);
+            DPRINTF(LLSC, "Erasing lock record: context %d addr %#x\n",
+                    i->contextId, paddr);
             i = lockedAddrList.erase(i);
         }
         else {
@@ -248,6 +255,8 @@ PhysicalMemory::doAtomicAccess(PacketPtr pkt)
         uint64_t condition_val64;
         uint32_t condition_val32;
 
+        if (!pmemAddr)
+            panic("Swap only works if there is real memory (i.e. null=False)");
         assert(sizeof(IntReg) >= pkt->getSize());
 
         overwrite_mem = true;
@@ -278,11 +287,13 @@ PhysicalMemory::doAtomicAccess(PacketPtr pkt)
         if (pkt->isLocked()) {
             trackLoadLocked(pkt);
         }
-        memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
+        if (pmemAddr)
+            memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
         TRACE_PACKET("Read");
     } else if (pkt->isWrite()) {
         if (writeOK(pkt)) {
-            memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
+            if (pmemAddr)
+                memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
             TRACE_PACKET("Write");
         }
     } else if (pkt->isInvalidate()) {
@@ -310,18 +321,28 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
 
     uint8_t *hostAddr = pmemAddr + pkt->getAddr() - start();
 
-    if (pkt->cmd == MemCmd::ReadReq) {
-        memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
+    if (pkt->isRead()) {
+        if (pmemAddr)
+            memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
         TRACE_PACKET("Read");
-    } else if (pkt->cmd == MemCmd::WriteReq) {
-        memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
+        pkt->makeAtomicResponse();
+    } else if (pkt->isWrite()) {
+        if (pmemAddr)
+            memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
         TRACE_PACKET("Write");
+        pkt->makeAtomicResponse();
+    } else if (pkt->isPrint()) {
+        Packet::PrintReqState *prs =
+            dynamic_cast<Packet::PrintReqState*>(pkt->senderState);
+        // Need to call printLabels() explicitly since we're not going
+        // through printObj().
+        prs->printLabels();
+        // Right now we just print the single byte at the specified address.
+        ccprintf(prs->os, "%s%#x\n", prs->curPrefix(), *hostAddr);
     } else {
         panic("PhysicalMemory: unimplemented functional command %s",
               pkt->cmdString());
     }
-
-    pkt->makeAtomicResponse();
 }
 
 
@@ -362,7 +383,7 @@ PhysicalMemory::recvStatusChange(Port::Status status)
 
 PhysicalMemory::MemoryPort::MemoryPort(const std::string &_name,
                                        PhysicalMemory *_memory)
-    : SimpleTimingPort(_name), memory(_memory)
+    : SimpleTimingPort(_name, _memory), memory(_memory)
 { }
 
 void
@@ -401,12 +422,16 @@ PhysicalMemory::MemoryPort::recvAtomic(PacketPtr pkt)
 void
 PhysicalMemory::MemoryPort::recvFunctional(PacketPtr pkt)
 {
+    pkt->pushLabel(memory->name());
+
     if (!checkFunctional(pkt)) {
         // Default implementation of SimpleTimingPort::recvFunctional()
         // calls recvAtomic() and throws away the latency; we can save a
         // little here by just not calculating the latency.
         memory->doFunctionalAccess(pkt);
     }
+
+    pkt->popLabel();
 }
 
 unsigned int
@@ -427,6 +452,9 @@ PhysicalMemory::drain(Event *de)
 void
 PhysicalMemory::serialize(ostream &os)
 {
+    if (!pmemAddr)
+        return;
+
     gzFile compressedMem;
     string filename = name() + ".physmem";
 
@@ -459,6 +487,9 @@ PhysicalMemory::serialize(ostream &os)
 void
 PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
 {
+    if (!pmemAddr)
+        return;
+
     gzFile compressedMem;
     long *tempPage;
     long *pmem_current;
@@ -466,7 +497,6 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
     uint32_t bytesRead;
     const int chunkSize = 16384;
 
-
     string filename;
 
     UNSERIALIZE_SCALAR(filename);