Fix checker to work in newmem in SE mode.
authorKevin Lim <ktlim@umich.edu>
Tue, 6 Jun 2006 18:06:30 +0000 (14:06 -0400)
committerKevin Lim <ktlim@umich.edu>
Tue, 6 Jun 2006 18:06:30 +0000 (14:06 -0400)
src/cpu/o3/fetch_impl.hh:
    Give the checker a pointer to the icachePort.
src/cpu/o3/lsq_unit_impl.hh:
    Give the checker a pointer to the dcachePort.
src/mem/request.hh:
    Allow checking for the scResult being valid prior to accessing it.

--HG--
extra : convert_revision : ced4180588d242111ecba4a11586823badd6cf15

src/cpu/checker/cpu.cc
src/cpu/checker/cpu.hh
src/cpu/o3/fetch_impl.hh
src/cpu/o3/lsq_unit_impl.hh
src/mem/request.hh

index bb9ec044519f579933ff7c5fbe9579b532186b38..c94570d7d45e848aa79c89cec647bea887598023 100644 (file)
@@ -64,8 +64,7 @@ CheckerCPU::init()
 CheckerCPU::CheckerCPU(Params *p)
     : BaseCPU(p), cpuXC(NULL), xcProxy(NULL)
 {
-    memReq = new Request();
-//    memReq->data = new uint8_t[64];
+    memReq = NULL;
 
     numInst = 0;
     startNumInst = 0;
@@ -81,6 +80,8 @@ CheckerCPU::CheckerCPU(Params *p)
     dtb = p->dtb;
     systemPtr = NULL;
     memPtr = NULL;
+#else
+    process = p->process;
 #endif
 }
 
@@ -93,7 +94,7 @@ CheckerCPU::setMemory(MemObject *mem)
 {
     memPtr = mem;
 #if !FULL_SYSTEM
-    cpuXC = new CPUExecContext(this, /* thread_num */ 0, NULL,
+    cpuXC = new CPUExecContext(this, /* thread_num */ 0, process,
                                /* asid */ 0, mem);
 
     cpuXC->setStatus(ExecContext::Suspended);
@@ -132,6 +133,18 @@ CheckerCPU::setSystem(System *system)
 }
 #endif
 
+void
+CheckerCPU::setIcachePort(Port *icache_port)
+{
+    icachePort = icache_port;
+}
+
+void
+CheckerCPU::setDcachePort(Port *dcache_port)
+{
+    dcachePort = dcache_port;
+}
+
 void
 CheckerCPU::serialize(ostream &os)
 {
@@ -170,25 +183,28 @@ template <class T>
 Fault
 CheckerCPU::read(Addr addr, T &data, unsigned flags)
 {
-/*
-    memReq->reset(addr, sizeof(T), flags);
+    // need to fill in CPU & thread IDs here
+    memReq = new Request();
+
+    memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
 
     // translate to physical address
     translateDataReadReq(memReq);
 
-    memReq->cmd = Read;
-    memReq->completionEvent = NULL;
-    memReq->time = curTick;
-    memReq->flags &= ~INST_READ;
+    Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
 
-    if (!(memReq->flags & UNCACHEABLE)) {
+    pkt->dataStatic(&data);
+
+    if (!(memReq->getFlags() & UNCACHEABLE)) {
         // Access memory to see if we have the same data
-        cpuXC->read(memReq, data);
+        dcachePort->sendFunctional(pkt);
     } else {
         // Assume the data is correct if it's an uncached access
         memcpy(&data, &unverifiedResult.integer, sizeof(T));
     }
-*/
+
+    delete pkt;
+
     return NoFault;
 }
 
@@ -237,8 +253,10 @@ template <class T>
 Fault
 CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
 {
-/*
-    memReq->reset(addr, sizeof(T), flags);
+    // need to fill in CPU & thread IDs here
+    memReq = new Request();
+
+    memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
 
     // translate to physical address
     cpuXC->translateDataWriteReq(memReq);
@@ -253,19 +271,21 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
     // This is because the LSQ would have to be snooped in the CPU to
     // verify this data.
     if (unverifiedReq &&
-        !(unverifiedReq->flags & UNCACHEABLE) &&
-        (!(unverifiedReq->flags & LOCKED) ||
-         ((unverifiedReq->flags & LOCKED) &&
-          unverifiedReq->result == 1))) {
-#if 0
-        memReq->cmd = Read;
-        memReq->completionEvent = NULL;
-        memReq->time = curTick;
-        memReq->flags &= ~INST_READ;
-        cpuXC->read(memReq, inst_data);
-#endif
+        !(unverifiedReq->getFlags() & UNCACHEABLE) &&
+        (!(unverifiedReq->getFlags() & LOCKED) ||
+         ((unverifiedReq->getFlags() & LOCKED) &&
+          unverifiedReq->getScResult() == 1))) {
         T inst_data;
-        memcpy(&inst_data, unverifiedReq->data, sizeof(T));
+/*
+        // This code would work if the LSQ allowed for snooping.
+        Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
+        pkt.dataStatic(&inst_data);
+
+        dcachePort->sendFunctional(pkt);
+
+        delete pkt;
+*/
+        memcpy(&inst_data, unverifiedMemData, sizeof(T));
 
         if (data != inst_data) {
             warn("%lli: Store value does not match value in memory! "
@@ -278,9 +298,9 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
     // Assume the result was the same as the one passed in.  This checker
     // doesn't check if the SC should succeed or fail, it just checks the
     // value.
-    if (res)
-        *res = unverifiedReq->result;
-        */
+    if (res && unverifiedReq->scResultValid())
+        *res = unverifiedReq->getScResult();
+
     return NoFault;
 }
 
@@ -451,6 +471,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
                 inst->seqNum, inst->readPC());
         unverifiedResult.integer = inst->readIntResult();
         unverifiedReq = inst->req;
+        unverifiedMemData = inst->memData;
         numCycles++;
 
         Fault fault = NoFault;
@@ -494,10 +515,13 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
 #define IFETCH_FLAGS(pc)       0
 #endif
 
+        uint64_t fetch_PC = cpuXC->readPC() & ~3;
+
         // set up memory request for instruction fetch
-//        memReq->cmd = Read;
-//        memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t),
-//                      IFETCH_FLAGS(cpuXC->readPC()));
+        memReq = new Request(inst->threadNumber, fetch_PC,
+                             sizeof(uint32_t),
+                             IFETCH_FLAGS(cpuXC->readPC()),
+                             fetch_PC, cpuXC->readCpuId(), inst->threadNumber);
 
         bool succeeded = translateInstReq(memReq);
 
@@ -526,7 +550,14 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
         }
 
         if (fault == NoFault) {
-//            cpuXC->read(memReq, machInst);
+            Packet *pkt = new Packet(memReq, Packet::ReadReq,
+                                     Packet::Broadcast);
+
+            pkt->dataStatic(&machInst);
+
+            icachePort->sendFunctional(pkt);
+
+            delete pkt;
 
             // keep an instruction count
             numInst++;
@@ -547,6 +578,10 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
             fault = inst->getFault();
         }
 
+        // Discard fetch's memReq.
+        delete memReq;
+        memReq = NULL;
+
         // Either the instruction was a fault and we should process the fault,
         // or we should just go ahead execute the instruction.  This assumes
         // that the instruction is properly marked as a fault.
@@ -609,6 +644,11 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
         // that have been modified).
         validateState();
 
+        if (memReq) {
+            delete memReq;
+            memReq = NULL;
+        }
+
         // Continue verifying instructions if there's another completed
         // instruction waiting to be verified.
         if (instList.empty()) {
@@ -679,7 +719,7 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
                 cpuXC->setMiscReg(idx, inst->readIntResult());
             }
         } else if (result.integer != inst->readIntResult()) {
-            warn("%lli: Instruction results do not match! (Results may not "
+            warn("%lli: Instruction results do not match! (Values may not "
                  "actually be integers) Inst: %#x, checker: %#x",
                  curTick, inst->readIntResult(), result.integer);
             handleError();
index 2f9689028964135f081108233fd176ff54ecaaa1..704580d8011dff0191fbbee3a850b03d5170f064 100644 (file)
@@ -108,6 +108,8 @@ class CheckerCPU : public BaseCPU
     CheckerCPU(Params *p);
     virtual ~CheckerCPU();
 
+    Process *process;
+
     void setMemory(MemObject *mem);
 
     MemObject *memPtr;
@@ -117,6 +119,15 @@ class CheckerCPU : public BaseCPU
 
     System *systemPtr;
 #endif
+
+    void setIcachePort(Port *icache_port);
+
+    Port *icachePort;
+
+    void setDcachePort(Port *dcache_port);
+
+    Port *dcachePort;
+
   public:
     // execution context
     CPUExecContext *cpuXC;
@@ -141,8 +152,8 @@ class CheckerCPU : public BaseCPU
     // current instruction
     MachInst machInst;
 
-    // Refcounted pointer to the one memory request.
-    Request *memReq;
+    // Pointer to the one memory request.
+    RequestPtr memReq;
 
     StaticInstPtr curStaticInst;
 
@@ -334,6 +345,7 @@ class CheckerCPU : public BaseCPU
 
     Result unverifiedResult;
     Request *unverifiedReq;
+    uint8_t *unverifiedMemData;
 
     bool changedPC;
     bool willChangePC;
index 84f2c3b7e9b2b1f7a8a636828c302b65bb4d0d01..3a41de721fcf34c61a1a602d42c4de64f10b56f8 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "arch/isa_traits.hh"
 #include "arch/utility.hh"
+#include "cpu/checker/cpu.hh"
 #include "cpu/exetrace.hh"
 #include "cpu/o3/fetch.hh"
 #include "mem/packet.hh"
@@ -289,6 +290,10 @@ DefaultFetch<Impl>::setCPU(FullCPU *cpu_ptr)
     icachePort->setPeer(mem_dport);
     mem_dport->setPeer(icachePort);
 
+    if (cpu->checker) {
+        cpu->checker->setIcachePort(icachePort);
+    }
+
     // Fetch needs to start fetching instructions at the very beginning,
     // so it must start up in active state.
     switchToActive();
index 5398426e256ce48df1b26277f25388db5a54b5fc..2679eb52b555228ec4903106e06856b197fa51ae 100644 (file)
@@ -186,6 +186,10 @@ LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr)
     Port *mem_dport = mem->getPort("");
     dcachePort->setPeer(mem_dport);
     mem_dport->setPeer(dcachePort);
+
+    if (cpu->checker) {
+        cpu->checker->setDcachePort(dcachePort);
+    }
 }
 
 template<class Impl>
index e8f4daacb32adc282e1c06c53805e59d457ced9a..af1d6d8a852c2b7cbeb7c7b1b8adc439e855bfab 100644 (file)
@@ -208,6 +208,8 @@ class Request
     /** Accessor function for asid.*/
     int getAsid() { assert(validAsidVaddr); return asid; }
 
+    /** Accessor function to check if sc result is valid. */
+    bool scResultValid() { return validScResult; }
     /** Accessor function for store conditional return value.*/
     uint64_t getScResult() { assert(validScResult); return scResult; }
     /** Accessor function for store conditional return value.*/