summaryrefslogtreecommitdiff
path: root/src/cpu/checker
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/checker')
-rw-r--r--src/cpu/checker/cpu.cc108
-rw-r--r--src/cpu/checker/cpu.hh16
2 files changed, 88 insertions, 36 deletions
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index bb9ec0445..c94570d7d 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -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);
@@ -133,6 +134,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();
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 2f9689028..704580d80 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -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;