cpu.cc (2669:f2b336e89d2a) cpu.cc (2679:737e9f158843)
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 50 unchanged lines hidden (view full) ---

59void
60CheckerCPU::init()
61{
62}
63
64CheckerCPU::CheckerCPU(Params *p)
65 : BaseCPU(p), cpuXC(NULL), xcProxy(NULL)
66{
1/*
2 * Copyright (c) 2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 50 unchanged lines hidden (view full) ---

59void
60CheckerCPU::init()
61{
62}
63
64CheckerCPU::CheckerCPU(Params *p)
65 : BaseCPU(p), cpuXC(NULL), xcProxy(NULL)
66{
67 memReq = new Request();
68// memReq->data = new uint8_t[64];
67 memReq = NULL;
69
70 numInst = 0;
71 startNumInst = 0;
72 numLoad = 0;
73 startNumLoad = 0;
74 youngestSN = 0;
75
76 changedPC = willChangePC = changedNextPC = false;
77
78 exitOnError = p->exitOnError;
79#if FULL_SYSTEM
80 itb = p->itb;
81 dtb = p->dtb;
82 systemPtr = NULL;
83 memPtr = NULL;
68
69 numInst = 0;
70 startNumInst = 0;
71 numLoad = 0;
72 startNumLoad = 0;
73 youngestSN = 0;
74
75 changedPC = willChangePC = changedNextPC = false;
76
77 exitOnError = p->exitOnError;
78#if FULL_SYSTEM
79 itb = p->itb;
80 dtb = p->dtb;
81 systemPtr = NULL;
82 memPtr = NULL;
83#else
84 process = p->process;
84#endif
85}
86
87CheckerCPU::~CheckerCPU()
88{
89}
90
91void
92CheckerCPU::setMemory(MemObject *mem)
93{
94 memPtr = mem;
95#if !FULL_SYSTEM
85#endif
86}
87
88CheckerCPU::~CheckerCPU()
89{
90}
91
92void
93CheckerCPU::setMemory(MemObject *mem)
94{
95 memPtr = mem;
96#if !FULL_SYSTEM
96 cpuXC = new CPUExecContext(this, /* thread_num */ 0, NULL,
97 cpuXC = new CPUExecContext(this, /* thread_num */ 0, process,
97 /* asid */ 0, mem);
98
99 cpuXC->setStatus(ExecContext::Suspended);
100 xcProxy = cpuXC->getProxy();
101 execContexts.push_back(xcProxy);
102#else
103 if (systemPtr) {
104 cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false);

--- 23 unchanged lines hidden (view full) ---

128 memReq->xc = xcProxy;
129 delete cpuXC->kernelStats;
130 cpuXC->kernelStats = NULL;
131 }
132}
133#endif
134
135void
98 /* asid */ 0, mem);
99
100 cpuXC->setStatus(ExecContext::Suspended);
101 xcProxy = cpuXC->getProxy();
102 execContexts.push_back(xcProxy);
103#else
104 if (systemPtr) {
105 cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false);

--- 23 unchanged lines hidden (view full) ---

129 memReq->xc = xcProxy;
130 delete cpuXC->kernelStats;
131 cpuXC->kernelStats = NULL;
132 }
133}
134#endif
135
136void
137CheckerCPU::setIcachePort(Port *icache_port)
138{
139 icachePort = icache_port;
140}
141
142void
143CheckerCPU::setDcachePort(Port *dcache_port)
144{
145 dcachePort = dcache_port;
146}
147
148void
136CheckerCPU::serialize(ostream &os)
137{
138/*
139 BaseCPU::serialize(os);
140 SERIALIZE_SCALAR(inst);
141 nameOut(os, csprintf("%s.xc", name()));
142 cpuXC->serialize(os);
143 cacheCompletionEvent.serialize(os);

--- 21 unchanged lines hidden (view full) ---

165{
166 panic("Unimplemented!");
167}
168
169template <class T>
170Fault
171CheckerCPU::read(Addr addr, T &data, unsigned flags)
172{
149CheckerCPU::serialize(ostream &os)
150{
151/*
152 BaseCPU::serialize(os);
153 SERIALIZE_SCALAR(inst);
154 nameOut(os, csprintf("%s.xc", name()));
155 cpuXC->serialize(os);
156 cacheCompletionEvent.serialize(os);

--- 21 unchanged lines hidden (view full) ---

178{
179 panic("Unimplemented!");
180}
181
182template <class T>
183Fault
184CheckerCPU::read(Addr addr, T &data, unsigned flags)
185{
173/*
174 memReq->reset(addr, sizeof(T), flags);
186 // need to fill in CPU & thread IDs here
187 memReq = new Request();
175
188
189 memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
190
176 // translate to physical address
177 translateDataReadReq(memReq);
178
191 // translate to physical address
192 translateDataReadReq(memReq);
193
179 memReq->cmd = Read;
180 memReq->completionEvent = NULL;
181 memReq->time = curTick;
182 memReq->flags &= ~INST_READ;
194 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
183
195
184 if (!(memReq->flags & UNCACHEABLE)) {
196 pkt->dataStatic(&data);
197
198 if (!(memReq->getFlags() & UNCACHEABLE)) {
185 // Access memory to see if we have the same data
199 // Access memory to see if we have the same data
186 cpuXC->read(memReq, data);
200 dcachePort->sendFunctional(pkt);
187 } else {
188 // Assume the data is correct if it's an uncached access
189 memcpy(&data, &unverifiedResult.integer, sizeof(T));
190 }
201 } else {
202 // Assume the data is correct if it's an uncached access
203 memcpy(&data, &unverifiedResult.integer, sizeof(T));
204 }
191*/
205
206 delete pkt;
207
192 return NoFault;
193}
194
195#ifndef DOXYGEN_SHOULD_SKIP_THIS
196
197template
198Fault
199CheckerCPU::read(Addr addr, uint64_t &data, unsigned flags);

--- 32 unchanged lines hidden (view full) ---

232{
233 return read(addr, (uint32_t&)data, flags);
234}
235
236template <class T>
237Fault
238CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
239{
208 return NoFault;
209}
210
211#ifndef DOXYGEN_SHOULD_SKIP_THIS
212
213template
214Fault
215CheckerCPU::read(Addr addr, uint64_t &data, unsigned flags);

--- 32 unchanged lines hidden (view full) ---

248{
249 return read(addr, (uint32_t&)data, flags);
250}
251
252template <class T>
253Fault
254CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
255{
240/*
241 memReq->reset(addr, sizeof(T), flags);
256 // need to fill in CPU & thread IDs here
257 memReq = new Request();
242
258
259 memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
260
243 // translate to physical address
244 cpuXC->translateDataWriteReq(memReq);
245
246 // Can compare the write data and result only if it's cacheable,
247 // not a store conditional, or is a store conditional that
248 // succeeded.
249 // @todo: Verify that actual memory matches up with these values.
250 // Right now it only verifies that the instruction data is the
251 // same as what was in the request that got sent to memory; there
252 // is no verification that it is the same as what is in memory.
253 // This is because the LSQ would have to be snooped in the CPU to
254 // verify this data.
255 if (unverifiedReq &&
261 // translate to physical address
262 cpuXC->translateDataWriteReq(memReq);
263
264 // Can compare the write data and result only if it's cacheable,
265 // not a store conditional, or is a store conditional that
266 // succeeded.
267 // @todo: Verify that actual memory matches up with these values.
268 // Right now it only verifies that the instruction data is the
269 // same as what was in the request that got sent to memory; there
270 // is no verification that it is the same as what is in memory.
271 // This is because the LSQ would have to be snooped in the CPU to
272 // verify this data.
273 if (unverifiedReq &&
256 !(unverifiedReq->flags & UNCACHEABLE) &&
257 (!(unverifiedReq->flags & LOCKED) ||
258 ((unverifiedReq->flags & LOCKED) &&
259 unverifiedReq->result == 1))) {
260#if 0
261 memReq->cmd = Read;
262 memReq->completionEvent = NULL;
263 memReq->time = curTick;
264 memReq->flags &= ~INST_READ;
265 cpuXC->read(memReq, inst_data);
266#endif
274 !(unverifiedReq->getFlags() & UNCACHEABLE) &&
275 (!(unverifiedReq->getFlags() & LOCKED) ||
276 ((unverifiedReq->getFlags() & LOCKED) &&
277 unverifiedReq->getScResult() == 1))) {
267 T inst_data;
278 T inst_data;
268 memcpy(&inst_data, unverifiedReq->data, sizeof(T));
279/*
280 // This code would work if the LSQ allowed for snooping.
281 Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
282 pkt.dataStatic(&inst_data);
269
283
284 dcachePort->sendFunctional(pkt);
285
286 delete pkt;
287*/
288 memcpy(&inst_data, unverifiedMemData, sizeof(T));
289
270 if (data != inst_data) {
271 warn("%lli: Store value does not match value in memory! "
272 "Instruction: %#x, memory: %#x",
273 curTick, inst_data, data);
274 handleError();
275 }
276 }
277
278 // Assume the result was the same as the one passed in. This checker
279 // doesn't check if the SC should succeed or fail, it just checks the
280 // value.
290 if (data != inst_data) {
291 warn("%lli: Store value does not match value in memory! "
292 "Instruction: %#x, memory: %#x",
293 curTick, inst_data, data);
294 handleError();
295 }
296 }
297
298 // Assume the result was the same as the one passed in. This checker
299 // doesn't check if the SC should succeed or fail, it just checks the
300 // value.
281 if (res)
282 *res = unverifiedReq->result;
283 */
301 if (res && unverifiedReq->scResultValid())
302 *res = unverifiedReq->getScResult();
303
284 return NoFault;
285}
286
287
288#ifndef DOXYGEN_SHOULD_SKIP_THIS
289template
290Fault
291CheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);

--- 154 unchanged lines hidden (view full) ---

446 // Try to check all instructions that are completed, ending if we
447 // run out of instructions to check or if an instruction is not
448 // yet completed.
449 while (1) {
450 DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n",
451 inst->seqNum, inst->readPC());
452 unverifiedResult.integer = inst->readIntResult();
453 unverifiedReq = inst->req;
304 return NoFault;
305}
306
307
308#ifndef DOXYGEN_SHOULD_SKIP_THIS
309template
310Fault
311CheckerCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);

--- 154 unchanged lines hidden (view full) ---

466 // Try to check all instructions that are completed, ending if we
467 // run out of instructions to check or if an instruction is not
468 // yet completed.
469 while (1) {
470 DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n",
471 inst->seqNum, inst->readPC());
472 unverifiedResult.integer = inst->readIntResult();
473 unverifiedReq = inst->req;
474 unverifiedMemData = inst->memData;
454 numCycles++;
455
456 Fault fault = NoFault;
457
458 // maintain $r0 semantics
459 cpuXC->setIntReg(ZeroReg, 0);
460#ifdef TARGET_ALPHA
461 cpuXC->setFloatRegDouble(ZeroReg, 0.0);

--- 27 unchanged lines hidden (view full) ---

489 // Try to fetch the instruction
490
491#if FULL_SYSTEM
492#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0
493#else
494#define IFETCH_FLAGS(pc) 0
495#endif
496
475 numCycles++;
476
477 Fault fault = NoFault;
478
479 // maintain $r0 semantics
480 cpuXC->setIntReg(ZeroReg, 0);
481#ifdef TARGET_ALPHA
482 cpuXC->setFloatRegDouble(ZeroReg, 0.0);

--- 27 unchanged lines hidden (view full) ---

510 // Try to fetch the instruction
511
512#if FULL_SYSTEM
513#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0
514#else
515#define IFETCH_FLAGS(pc) 0
516#endif
517
518 uint64_t fetch_PC = cpuXC->readPC() & ~3;
519
497 // set up memory request for instruction fetch
520 // set up memory request for instruction fetch
498// memReq->cmd = Read;
499// memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t),
500// IFETCH_FLAGS(cpuXC->readPC()));
521 memReq = new Request(inst->threadNumber, fetch_PC,
522 sizeof(uint32_t),
523 IFETCH_FLAGS(cpuXC->readPC()),
524 fetch_PC, cpuXC->readCpuId(), inst->threadNumber);
501
502 bool succeeded = translateInstReq(memReq);
503
504 if (!succeeded) {
505 if (inst->getFault() == NoFault) {
506 // In this case the instruction was not a dummy
507 // instruction carrying an ITB fault. In the single
508 // threaded case the ITB should still be able to

--- 12 unchanged lines hidden (view full) ---

521 // The instruction is carrying an ITB fault. Handle
522 // the fault and see if our results match the CPU on
523 // the next tick().
524 fault = inst->getFault();
525 }
526 }
527
528 if (fault == NoFault) {
525
526 bool succeeded = translateInstReq(memReq);
527
528 if (!succeeded) {
529 if (inst->getFault() == NoFault) {
530 // In this case the instruction was not a dummy
531 // instruction carrying an ITB fault. In the single
532 // threaded case the ITB should still be able to

--- 12 unchanged lines hidden (view full) ---

545 // The instruction is carrying an ITB fault. Handle
546 // the fault and see if our results match the CPU on
547 // the next tick().
548 fault = inst->getFault();
549 }
550 }
551
552 if (fault == NoFault) {
529// cpuXC->read(memReq, machInst);
553 Packet *pkt = new Packet(memReq, Packet::ReadReq,
554 Packet::Broadcast);
530
555
556 pkt->dataStatic(&machInst);
557
558 icachePort->sendFunctional(pkt);
559
560 delete pkt;
561
531 // keep an instruction count
532 numInst++;
533
534 // decode the instruction
535 machInst = gtoh(machInst);
536 // Checks that the instruction matches what we expected it to be.
537 // Checks both the machine instruction and the PC.
538 validateInst(inst);
539
540 curStaticInst = StaticInst::decode(makeExtMI(machInst,
541 cpuXC->readPC()));
542
543#if FULL_SYSTEM
544 cpuXC->setInst(machInst);
545#endif // FULL_SYSTEM
546
547 fault = inst->getFault();
548 }
549
562 // keep an instruction count
563 numInst++;
564
565 // decode the instruction
566 machInst = gtoh(machInst);
567 // Checks that the instruction matches what we expected it to be.
568 // Checks both the machine instruction and the PC.
569 validateInst(inst);
570
571 curStaticInst = StaticInst::decode(makeExtMI(machInst,
572 cpuXC->readPC()));
573
574#if FULL_SYSTEM
575 cpuXC->setInst(machInst);
576#endif // FULL_SYSTEM
577
578 fault = inst->getFault();
579 }
580
581 // Discard fetch's memReq.
582 delete memReq;
583 memReq = NULL;
584
550 // Either the instruction was a fault and we should process the fault,
551 // or we should just go ahead execute the instruction. This assumes
552 // that the instruction is properly marked as a fault.
553 if (fault == NoFault) {
554
555 cpuXC->func_exe_inst++;
556
557 fault = curStaticInst->execute(this, NULL);

--- 46 unchanged lines hidden (view full) ---

604 DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC);
605 }
606#endif
607
608 // @todo: Optionally can check all registers. (Or just those
609 // that have been modified).
610 validateState();
611
585 // Either the instruction was a fault and we should process the fault,
586 // or we should just go ahead execute the instruction. This assumes
587 // that the instruction is properly marked as a fault.
588 if (fault == NoFault) {
589
590 cpuXC->func_exe_inst++;
591
592 fault = curStaticInst->execute(this, NULL);

--- 46 unchanged lines hidden (view full) ---

639 DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC);
640 }
641#endif
642
643 // @todo: Optionally can check all registers. (Or just those
644 // that have been modified).
645 validateState();
646
647 if (memReq) {
648 delete memReq;
649 memReq = NULL;
650 }
651
612 // Continue verifying instructions if there's another completed
613 // instruction waiting to be verified.
614 if (instList.empty()) {
615 break;
616 } else if (instList.front()->isCompleted()) {
617 inst = instList.front();
618 instList.pop_front();
619 } else {

--- 54 unchanged lines hidden (view full) ---

674 if (idx < TheISA::FP_Base_DepTag) {
675 cpuXC->setIntReg(idx, inst->readIntResult());
676 } else if (idx < TheISA::Fpcr_DepTag) {
677 cpuXC->setFloatRegBits(idx, inst->readIntResult());
678 } else {
679 cpuXC->setMiscReg(idx, inst->readIntResult());
680 }
681 } else if (result.integer != inst->readIntResult()) {
652 // Continue verifying instructions if there's another completed
653 // instruction waiting to be verified.
654 if (instList.empty()) {
655 break;
656 } else if (instList.front()->isCompleted()) {
657 inst = instList.front();
658 instList.pop_front();
659 } else {

--- 54 unchanged lines hidden (view full) ---

714 if (idx < TheISA::FP_Base_DepTag) {
715 cpuXC->setIntReg(idx, inst->readIntResult());
716 } else if (idx < TheISA::Fpcr_DepTag) {
717 cpuXC->setFloatRegBits(idx, inst->readIntResult());
718 } else {
719 cpuXC->setMiscReg(idx, inst->readIntResult());
720 }
721 } else if (result.integer != inst->readIntResult()) {
682 warn("%lli: Instruction results do not match! (Results may not "
722 warn("%lli: Instruction results do not match! (Values may not "
683 "actually be integers) Inst: %#x, checker: %#x",
684 curTick, inst->readIntResult(), result.integer);
685 handleError();
686 }
687 }
688
689 if (inst->readNextPC() != cpuXC->readNextPC()) {
690 warn("%lli: Instruction next PCs do not match! Inst: %#x, "

--- 67 unchanged lines hidden ---
723 "actually be integers) Inst: %#x, checker: %#x",
724 curTick, inst->readIntResult(), result.integer);
725 handleError();
726 }
727 }
728
729 if (inst->readNextPC() != cpuXC->readNextPC()) {
730 warn("%lli: Instruction next PCs do not match! Inst: %#x, "

--- 67 unchanged lines hidden ---