2 * Copyright (c) 2011, 2016-2017 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
15 * Copyright (c) 2006 The Regents of The University of Michigan
16 * All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 #ifndef __CPU_CHECKER_CPU_HH__
45 #define __CPU_CHECKER_CPU_HH__
51 #include "arch/types.hh"
52 #include "base/statistics.hh"
53 #include "cpu/base.hh"
54 #include "cpu/base_dyn_inst.hh"
55 #include "cpu/exec_context.hh"
56 #include "cpu/inst_res.hh"
57 #include "cpu/pc_event.hh"
58 #include "cpu/simple_thread.hh"
59 #include "cpu/static_inst.hh"
60 #include "debug/Checker.hh"
61 #include "mem/request.hh"
62 #include "params/CheckerCPU.hh"
63 #include "sim/eventq.hh"
72 * CheckerCPU class. Dynamically verifies instructions as they are
73 * completed by making sure that the instruction and its results match
74 * the independent execution of the benchmark inside the checker. The
75 * checker verifies instructions in order, regardless of the order in
76 * which instructions complete. There are certain results that can
77 * not be verified, specifically the result of a store conditional or
78 * the values of uncached accesses. In these cases, and with
79 * instructions marked as "IsUnverifiable", the checker assumes that
80 * the value from the main CPU's execution is correct and simply
81 * copies that value. It provides a CheckerThreadContext (see
82 * checker/thread_context.hh) that provides hooks for updating the
83 * Checker's state through any ThreadContext accesses. This allows the
84 * checker to be able to correctly verify instructions, even with
85 * external accesses to the ThreadContext that change state.
87 class CheckerCPU : public BaseCPU, public ExecContext
90 typedef TheISA::MachInst MachInst;
91 using VecRegContainer = TheISA::VecRegContainer;
93 /** id attached to all issued requests */
98 typedef CheckerCPUParams Params;
99 CheckerCPU(Params *p);
100 virtual ~CheckerCPU();
102 void setSystem(System *system);
104 void setIcachePort(MasterPort *icache_port);
106 void setDcachePort(MasterPort *dcache_port);
108 MasterPort &getDataPort() override
110 // the checker does not have ports on its own so return the
111 // data port of the actual CPU core
116 MasterPort &getInstPort() override
118 // the checker does not have ports on its own so return the
119 // data port of the actual CPU core
126 std::vector<Process*> workload;
130 MasterPort *icachePort;
131 MasterPort *dcachePort;
138 Addr dbg_vtophys(Addr addr);
140 // ISAs like ARM can have multiple destination registers to check,
141 // keep them all in a std::queue
142 std::queue<InstResult> result;
144 StaticInstPtr curStaticInst;
145 StaticInstPtr curMacroStaticInst;
147 // number of simulated instructions
149 Counter startNumInst;
151 std::queue<int> miscRegIdxs;
155 // Primary thread being run.
156 SimpleThread *thread;
158 BaseTLB* getITBPtr() { return itb; }
159 BaseTLB* getDTBPtr() { return dtb; }
161 virtual Counter totalInsts() const override
166 virtual Counter totalOps() const override
171 // number of simulated loads
173 Counter startNumLoad;
175 void serialize(CheckpointOut &cp) const override;
176 void unserialize(CheckpointIn &cp) override;
178 // The register accessor methods provide the index of the
179 // instruction's operand (e.g., 0 or 1), not the architectural
180 // register index, to simplify the implementation of register
181 // renaming. We find the architectural register index by indexing
182 // into the instruction's own operand index table. Note that a
183 // raw pointer to the StaticInst is provided instead of a
184 // ref-counted StaticInstPtr to redice overhead. This is fine as
185 // long as these methods don't copy the pointer into any long-term
186 // storage (which is pretty hard to imagine they would have reason
190 readIntRegOperand(const StaticInst *si, int idx) override
192 const RegId& reg = si->srcRegIdx(idx);
193 assert(reg.isIntReg());
194 return thread->readIntReg(reg.index());
198 readFloatRegOperandBits(const StaticInst *si, int idx) override
200 const RegId& reg = si->srcRegIdx(idx);
201 assert(reg.isFloatReg());
202 return thread->readFloatRegBits(reg.index());
206 * Read source vector register operand.
208 const VecRegContainer &
209 readVecRegOperand(const StaticInst *si, int idx) const override
211 const RegId& reg = si->srcRegIdx(idx);
212 assert(reg.isVecReg());
213 return thread->readVecReg(reg);
217 * Read destination vector register operand for modification.
220 getWritableVecRegOperand(const StaticInst *si, int idx) override
222 const RegId& reg = si->destRegIdx(idx);
223 assert(reg.isVecReg());
224 return thread->getWritableVecReg(reg);
227 /** Vector Register Lane Interfaces. */
229 /** Reads source vector 8bit operand. */
230 virtual ConstVecLane8
231 readVec8BitLaneOperand(const StaticInst *si, int idx) const override
233 const RegId& reg = si->destRegIdx(idx);
234 assert(reg.isVecReg());
235 return thread->readVec8BitLaneReg(reg);
238 /** Reads source vector 16bit operand. */
239 virtual ConstVecLane16
240 readVec16BitLaneOperand(const StaticInst *si, int idx) const override
242 const RegId& reg = si->destRegIdx(idx);
243 assert(reg.isVecReg());
244 return thread->readVec16BitLaneReg(reg);
247 /** Reads source vector 32bit operand. */
248 virtual ConstVecLane32
249 readVec32BitLaneOperand(const StaticInst *si, int idx) const override
251 const RegId& reg = si->destRegIdx(idx);
252 assert(reg.isVecReg());
253 return thread->readVec32BitLaneReg(reg);
256 /** Reads source vector 64bit operand. */
257 virtual ConstVecLane64
258 readVec64BitLaneOperand(const StaticInst *si, int idx) const override
260 const RegId& reg = si->destRegIdx(idx);
261 assert(reg.isVecReg());
262 return thread->readVec64BitLaneReg(reg);
265 /** Write a lane of the destination vector operand. */
266 template <typename LD>
268 setVecLaneOperandT(const StaticInst *si, int idx, const LD& val)
270 const RegId& reg = si->destRegIdx(idx);
271 assert(reg.isVecReg());
272 return thread->setVecLane(reg, val);
275 setVecLaneOperand(const StaticInst *si, int idx,
276 const LaneData<LaneSize::Byte>& val) override
278 setVecLaneOperandT(si, idx, val);
281 setVecLaneOperand(const StaticInst *si, int idx,
282 const LaneData<LaneSize::TwoByte>& val) override
284 setVecLaneOperandT(si, idx, val);
287 setVecLaneOperand(const StaticInst *si, int idx,
288 const LaneData<LaneSize::FourByte>& val) override
290 setVecLaneOperandT(si, idx, val);
293 setVecLaneOperand(const StaticInst *si, int idx,
294 const LaneData<LaneSize::EightByte>& val) override
296 setVecLaneOperandT(si, idx, val);
301 readVecElemOperand(const StaticInst *si, int idx) const override
303 const RegId& reg = si->srcRegIdx(idx);
304 return thread->readVecElem(reg);
307 const VecPredRegContainer&
308 readVecPredRegOperand(const StaticInst *si, int idx) const override
310 const RegId& reg = si->srcRegIdx(idx);
311 assert(reg.isVecPredReg());
312 return thread->readVecPredReg(reg);
316 getWritableVecPredRegOperand(const StaticInst *si, int idx) override
318 const RegId& reg = si->destRegIdx(idx);
319 assert(reg.isVecPredReg());
320 return thread->getWritableVecPredReg(reg);
324 readCCRegOperand(const StaticInst *si, int idx) override
326 const RegId& reg = si->srcRegIdx(idx);
327 assert(reg.isCCReg());
328 return thread->readCCReg(reg.index());
333 setScalarResult(T&& t)
335 result.push(InstResult(std::forward<T>(t),
336 InstResult::ResultType::Scalar));
343 result.push(InstResult(std::forward<T>(t),
344 InstResult::ResultType::VecReg));
349 setVecElemResult(T&& t)
351 result.push(InstResult(std::forward<T>(t),
352 InstResult::ResultType::VecElem));
357 setVecPredResult(T&& t)
359 result.push(InstResult(std::forward<T>(t),
360 InstResult::ResultType::VecPredReg));
364 setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
366 const RegId& reg = si->destRegIdx(idx);
367 assert(reg.isIntReg());
368 thread->setIntReg(reg.index(), val);
369 setScalarResult(val);
373 setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
375 const RegId& reg = si->destRegIdx(idx);
376 assert(reg.isFloatReg());
377 thread->setFloatRegBits(reg.index(), val);
378 setScalarResult(val);
382 setCCRegOperand(const StaticInst *si, int idx, CCReg val) override
384 const RegId& reg = si->destRegIdx(idx);
385 assert(reg.isCCReg());
386 thread->setCCReg(reg.index(), val);
387 setScalarResult((uint64_t)val);
391 setVecRegOperand(const StaticInst *si, int idx,
392 const VecRegContainer& val) override
394 const RegId& reg = si->destRegIdx(idx);
395 assert(reg.isVecReg());
396 thread->setVecReg(reg, val);
401 setVecElemOperand(const StaticInst *si, int idx,
402 const VecElem val) override
404 const RegId& reg = si->destRegIdx(idx);
405 assert(reg.isVecElem());
406 thread->setVecElem(reg, val);
407 setVecElemResult(val);
410 void setVecPredRegOperand(const StaticInst *si, int idx,
411 const VecPredRegContainer& val) override
413 const RegId& reg = si->destRegIdx(idx);
414 assert(reg.isVecPredReg());
415 thread->setVecPredReg(reg, val);
416 setVecPredResult(val);
419 bool readPredicate() const override { return thread->readPredicate(); }
422 setPredicate(bool val) override
424 thread->setPredicate(val);
427 TheISA::PCState pcState() const override { return thread->pcState(); }
429 pcState(const TheISA::PCState &val) override
431 DPRINTF(Checker, "Changing PC to %s, old PC %s.\n",
432 val, thread->pcState());
433 thread->pcState(val);
435 Addr instAddr() { return thread->instAddr(); }
436 Addr nextInstAddr() { return thread->nextInstAddr(); }
437 MicroPC microPC() { return thread->microPC(); }
438 //////////////////////////////////////////
441 readMiscRegNoEffect(int misc_reg) const
443 return thread->readMiscRegNoEffect(misc_reg);
447 readMiscReg(int misc_reg) override
449 return thread->readMiscReg(misc_reg);
453 setMiscRegNoEffect(int misc_reg, RegVal val)
455 DPRINTF(Checker, "Setting misc reg %d with no effect to check later\n",
457 miscRegIdxs.push(misc_reg);
458 return thread->setMiscRegNoEffect(misc_reg, val);
462 setMiscReg(int misc_reg, RegVal val) override
464 DPRINTF(Checker, "Setting misc reg %d with effect to check later\n",
466 miscRegIdxs.push(misc_reg);
467 return thread->setMiscReg(misc_reg, val);
471 readMiscRegOperand(const StaticInst *si, int idx) override
473 const RegId& reg = si->srcRegIdx(idx);
474 assert(reg.isMiscReg());
475 return thread->readMiscReg(reg.index());
479 setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
481 const RegId& reg = si->destRegIdx(idx);
482 assert(reg.isMiscReg());
483 return this->setMiscReg(reg.index(), val);
486 #if THE_ISA == MIPS_ISA
488 readRegOtherThread(const RegId &misc_reg, ThreadID tid) override
490 panic("MIPS MT not defined for CheckerCPU.\n");
495 setRegOtherThread(const RegId& misc_reg, RegVal val, ThreadID tid) override
497 panic("MIPS MT not defined for CheckerCPU.\n");
501 /////////////////////////////////////////
504 recordPCChange(const TheISA::PCState &val)
511 demapPage(Addr vaddr, uint64_t asn) override
513 this->itb->demapPage(vaddr, asn);
514 this->dtb->demapPage(vaddr, asn);
517 // monitor/mwait funtions
518 void armMonitor(Addr address) override { BaseCPU::armMonitor(0, address); }
519 bool mwait(PacketPtr pkt) override { return BaseCPU::mwait(0, pkt); }
520 void mwaitAtomic(ThreadContext *tc) override
521 { return BaseCPU::mwaitAtomic(0, tc, thread->dtb); }
522 AddressMonitor *getAddrMonitor() override
523 { return BaseCPU::getCpuAddrMonitor(0); }
526 demapInstPage(Addr vaddr, uint64_t asn)
528 this->itb->demapPage(vaddr, asn);
532 demapDataPage(Addr vaddr, uint64_t asn)
534 this->dtb->demapPage(vaddr, asn);
537 Fault readMem(Addr addr, uint8_t *data, unsigned size,
538 Request::Flags flags) override;
539 Fault writeMem(uint8_t *data, unsigned size, Addr addr,
540 Request::Flags flags, uint64_t *res) override;
543 readStCondFailures() const override {
544 return thread->readStCondFailures();
547 void setStCondFailures(unsigned int sc_failures) override {}
548 /////////////////////////////////////////////////////
550 Fault hwrei() override { return thread->hwrei(); }
551 bool simPalCheck(int palFunc) override
552 { return thread->simPalCheck(palFunc); }
553 void wakeup(ThreadID tid) override { }
554 // Assume that the normal CPU's call to syscall was successful.
555 // The checker's state would have already been updated by the syscall.
556 void syscall(int64_t callnum, Fault *fault) override { }
565 bool checkFlags(const RequestPtr &unverified_req, Addr vAddr,
566 Addr pAddr, int flags);
570 ThreadContext *tcBase() override { return tc; }
571 SimpleThread *threadBase() { return thread; }
573 InstResult unverifiedResult;
574 RequestPtr unverifiedReq;
575 uint8_t *unverifiedMemData;
579 TheISA::PCState newPCState;
582 bool warnOnlyOnLoadError;
584 InstSeqNum youngestSN;
588 * Templated Checker class. This Checker class is templated on the
589 * DynInstPtr of the instruction type that will be verified. Proper
590 * template instantiations of the Checker must be placed at the bottom
593 template <class Impl>
594 class Checker : public CheckerCPU
597 typedef typename Impl::DynInstPtr DynInstPtr;
601 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
605 void takeOverFrom(BaseCPU *oldCPU);
607 void advancePC(const Fault &fault);
609 void verify(const DynInstPtr &inst);
611 void validateInst(const DynInstPtr &inst);
612 void validateExecution(const DynInstPtr &inst);
613 void validateState();
615 void copyResult(const DynInstPtr &inst, const InstResult& mismatch_val,
617 void handlePendingInt();
620 void handleError(const DynInstPtr &inst)
624 } else if (updateOnError) {
625 updateThisCycle = true;
629 void dumpAndExit(const DynInstPtr &inst);
631 bool updateThisCycle;
633 DynInstPtr unverifiedInst;
635 std::list<DynInstPtr> instList;
636 typedef typename std::list<DynInstPtr>::iterator InstListIt;
640 #endif // __CPU_CHECKER_CPU_HH__