cpu.hh (3126:756092c6383c) | cpu.hh (3402:db60546818d0) |
---|---|
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; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 */ 30 31#ifndef __CPU_CHECKER_CPU_HH__ 32#define __CPU_CHECKER_CPU_HH__ 33 34#include <list> 35#include <queue> 36#include <map> 37 38#include "arch/types.hh" 39#include "base/statistics.hh" 40#include "config/full_system.hh" 41#include "cpu/base.hh" 42#include "cpu/base_dyn_inst.hh" 43#include "cpu/simple_thread.hh" 44#include "cpu/pc_event.hh" 45#include "cpu/static_inst.hh" 46#include "sim/eventq.hh" 47 48// forward declarations 49#if FULL_SYSTEM 50class Processor; 51class AlphaITB; 52class AlphaDTB; 53class PhysicalMemory; 54 55class RemoteGDB; 56class GDBListener; 57 58#else 59 60class Process; 61 62#endif // FULL_SYSTEM 63template <class> 64class BaseDynInst; 65class ThreadContext; 66class MemInterface; 67class Checkpoint; 68class Request; 69 70/** 71 * CheckerCPU class. Dynamically verifies instructions as they are 72 * completed by making sure that the instruction and its results match 73 * the independent execution of the benchmark inside the checker. The 74 * checker verifies instructions in order, regardless of the order in 75 * which instructions complete. There are certain results that can 76 * not be verified, specifically the result of a store conditional or 77 * the values of uncached accesses. In these cases, and with 78 * instructions marked as "IsUnverifiable", the checker assumes that 79 * the value from the main CPU's execution is correct and simply 80 * copies that value. It provides a CheckerThreadContext (see 81 * checker/thread_context.hh) that provides hooks for updating the 82 * Checker's state through any ThreadContext accesses. This allows the 83 * checker to be able to correctly verify instructions, even with 84 * external accesses to the ThreadContext that change state. 85 */ 86class CheckerCPU : public BaseCPU 87{ 88 protected: 89 typedef TheISA::MachInst MachInst; 90 typedef TheISA::FloatReg FloatReg; 91 typedef TheISA::FloatRegBits FloatRegBits; 92 typedef TheISA::MiscReg MiscReg; 93 public: 94 virtual void init(); 95 96 struct Params : public BaseCPU::Params 97 { 98#if FULL_SYSTEM 99 AlphaITB *itb; 100 AlphaDTB *dtb; 101#else 102 Process *process; 103#endif 104 bool exitOnError; 105 bool updateOnError; 106 bool warnOnlyOnLoadError; 107 }; 108 109 public: 110 CheckerCPU(Params *p); 111 virtual ~CheckerCPU(); 112 113 Process *process; 114 | 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; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 */ 30 31#ifndef __CPU_CHECKER_CPU_HH__ 32#define __CPU_CHECKER_CPU_HH__ 33 34#include <list> 35#include <queue> 36#include <map> 37 38#include "arch/types.hh" 39#include "base/statistics.hh" 40#include "config/full_system.hh" 41#include "cpu/base.hh" 42#include "cpu/base_dyn_inst.hh" 43#include "cpu/simple_thread.hh" 44#include "cpu/pc_event.hh" 45#include "cpu/static_inst.hh" 46#include "sim/eventq.hh" 47 48// forward declarations 49#if FULL_SYSTEM 50class Processor; 51class AlphaITB; 52class AlphaDTB; 53class PhysicalMemory; 54 55class RemoteGDB; 56class GDBListener; 57 58#else 59 60class Process; 61 62#endif // FULL_SYSTEM 63template <class> 64class BaseDynInst; 65class ThreadContext; 66class MemInterface; 67class Checkpoint; 68class Request; 69 70/** 71 * CheckerCPU class. Dynamically verifies instructions as they are 72 * completed by making sure that the instruction and its results match 73 * the independent execution of the benchmark inside the checker. The 74 * checker verifies instructions in order, regardless of the order in 75 * which instructions complete. There are certain results that can 76 * not be verified, specifically the result of a store conditional or 77 * the values of uncached accesses. In these cases, and with 78 * instructions marked as "IsUnverifiable", the checker assumes that 79 * the value from the main CPU's execution is correct and simply 80 * copies that value. It provides a CheckerThreadContext (see 81 * checker/thread_context.hh) that provides hooks for updating the 82 * Checker's state through any ThreadContext accesses. This allows the 83 * checker to be able to correctly verify instructions, even with 84 * external accesses to the ThreadContext that change state. 85 */ 86class CheckerCPU : public BaseCPU 87{ 88 protected: 89 typedef TheISA::MachInst MachInst; 90 typedef TheISA::FloatReg FloatReg; 91 typedef TheISA::FloatRegBits FloatRegBits; 92 typedef TheISA::MiscReg MiscReg; 93 public: 94 virtual void init(); 95 96 struct Params : public BaseCPU::Params 97 { 98#if FULL_SYSTEM 99 AlphaITB *itb; 100 AlphaDTB *dtb; 101#else 102 Process *process; 103#endif 104 bool exitOnError; 105 bool updateOnError; 106 bool warnOnlyOnLoadError; 107 }; 108 109 public: 110 CheckerCPU(Params *p); 111 virtual ~CheckerCPU(); 112 113 Process *process; 114 |
115 void setMemory(MemObject *mem); 116 117 MemObject *memPtr; 118 | |
119 void setSystem(System *system); 120 121 System *systemPtr; 122 123 void setIcachePort(Port *icache_port); 124 125 Port *icachePort; 126 127 void setDcachePort(Port *dcache_port); 128 129 Port *dcachePort; 130 131 virtual Port *getPort(const std::string &name, int idx) 132 { 133 panic("Not supported on checker!"); 134 return NULL; 135 } 136 137 public: 138 // Primary thread being run. 139 SimpleThread *thread; 140 141 ThreadContext *tc; 142 143 AlphaITB *itb; 144 AlphaDTB *dtb; 145 146#if FULL_SYSTEM 147 Addr dbg_vtophys(Addr addr); 148#endif 149 150 union Result { 151 uint64_t integer; 152// float fp; 153 double dbl; 154 }; 155 156 Result result; 157 158 // current instruction 159 MachInst machInst; 160 161 // Pointer to the one memory request. 162 RequestPtr memReq; 163 164 StaticInstPtr curStaticInst; 165 166 // number of simulated instructions 167 Counter numInst; 168 Counter startNumInst; 169 170 std::queue<int> miscRegIdxs; 171 172 virtual Counter totalInstructions() const 173 { 174 return 0; 175 } 176 177 // number of simulated loads 178 Counter numLoad; 179 Counter startNumLoad; 180 181 virtual void serialize(std::ostream &os); 182 virtual void unserialize(Checkpoint *cp, const std::string §ion); 183 184 template <class T> 185 Fault read(Addr addr, T &data, unsigned flags); 186 187 template <class T> 188 Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 189 190 // These functions are only used in CPU models that split 191 // effective address computation from the actual memory access. 192 void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 193 Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 194 195 void prefetch(Addr addr, unsigned flags) 196 { 197 // need to do this... 198 } 199 200 void writeHint(Addr addr, int size, unsigned flags) 201 { 202 // need to do this... 203 } 204 205 Fault copySrcTranslate(Addr src); 206 207 Fault copy(Addr dest); 208 209 // The register accessor methods provide the index of the 210 // instruction's operand (e.g., 0 or 1), not the architectural 211 // register index, to simplify the implementation of register 212 // renaming. We find the architectural register index by indexing 213 // into the instruction's own operand index table. Note that a 214 // raw pointer to the StaticInst is provided instead of a 215 // ref-counted StaticInstPtr to redice overhead. This is fine as 216 // long as these methods don't copy the pointer into any long-term 217 // storage (which is pretty hard to imagine they would have reason 218 // to do). 219 220 uint64_t readIntReg(const StaticInst *si, int idx) 221 { 222 return thread->readIntReg(si->srcRegIdx(idx)); 223 } 224 225 FloatReg readFloatReg(const StaticInst *si, int idx, int width) 226 { 227 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 228 return thread->readFloatReg(reg_idx, width); 229 } 230 231 FloatReg readFloatReg(const StaticInst *si, int idx) 232 { 233 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 234 return thread->readFloatReg(reg_idx); 235 } 236 237 FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) 238 { 239 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 240 return thread->readFloatRegBits(reg_idx, width); 241 } 242 243 FloatRegBits readFloatRegBits(const StaticInst *si, int idx) 244 { 245 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 246 return thread->readFloatRegBits(reg_idx); 247 } 248 249 void setIntReg(const StaticInst *si, int idx, uint64_t val) 250 { 251 thread->setIntReg(si->destRegIdx(idx), val); 252 result.integer = val; 253 } 254 255 void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) 256 { 257 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 258 thread->setFloatReg(reg_idx, val, width); 259 switch(width) { 260 case 32: 261 result.dbl = (double)val; 262 break; 263 case 64: 264 result.dbl = val; 265 break; 266 }; 267 } 268 269 void setFloatReg(const StaticInst *si, int idx, FloatReg val) 270 { 271 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 272 thread->setFloatReg(reg_idx, val); 273 result.dbl = (double)val; 274 } 275 276 void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val, 277 int width) 278 { 279 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 280 thread->setFloatRegBits(reg_idx, val, width); 281 result.integer = val; 282 } 283 284 void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) 285 { 286 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 287 thread->setFloatRegBits(reg_idx, val); 288 result.integer = val; 289 } 290 291 uint64_t readPC() { return thread->readPC(); } 292 293 uint64_t readNextPC() { return thread->readNextPC(); } 294 295 void setNextPC(uint64_t val) { 296 thread->setNextPC(val); 297 } 298 299 MiscReg readMiscReg(int misc_reg) 300 { 301 return thread->readMiscReg(misc_reg); 302 } 303 304 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 305 { 306 return thread->readMiscRegWithEffect(misc_reg, fault); 307 } 308 309 Fault setMiscReg(int misc_reg, const MiscReg &val) 310 { 311 result.integer = val; 312 miscRegIdxs.push(misc_reg); 313 return thread->setMiscReg(misc_reg, val); 314 } 315 316 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 317 { 318 miscRegIdxs.push(misc_reg); 319 return thread->setMiscRegWithEffect(misc_reg, val); 320 } 321 322 void recordPCChange(uint64_t val) { changedPC = true; newPC = val; } 323 void recordNextPCChange(uint64_t val) { changedNextPC = true; } 324 325 bool translateInstReq(Request *req); 326 void translateDataWriteReq(Request *req); 327 void translateDataReadReq(Request *req); 328 329#if FULL_SYSTEM 330 Fault hwrei() { return thread->hwrei(); } 331 int readIntrFlag() { return thread->readIntrFlag(); } 332 void setIntrFlag(int val) { thread->setIntrFlag(val); } 333 bool inPalMode() { return thread->inPalMode(); } 334 void ev5_trap(Fault fault) { fault->invoke(tc); } 335 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 336#else 337 // Assume that the normal CPU's call to syscall was successful. 338 // The checker's state would have already been updated by the syscall. 339 void syscall(uint64_t callnum) { } 340#endif 341 342 void handleError() 343 { 344 if (exitOnError) 345 dumpAndExit(); 346 } 347 348 bool checkFlags(Request *req); 349 350 void dumpAndExit(); 351 352 ThreadContext *tcBase() { return tc; } 353 SimpleThread *threadBase() { return thread; } 354 355 Result unverifiedResult; 356 Request *unverifiedReq; 357 uint8_t *unverifiedMemData; 358 359 bool changedPC; 360 bool willChangePC; 361 uint64_t newPC; 362 bool changedNextPC; 363 bool exitOnError; 364 bool updateOnError; 365 bool warnOnlyOnLoadError; 366 367 InstSeqNum youngestSN; 368}; 369 370/** 371 * Templated Checker class. This Checker class is templated on the 372 * DynInstPtr of the instruction type that will be verified. Proper 373 * template instantiations of the Checker must be placed at the bottom 374 * of checker/cpu.cc. 375 */ 376template <class DynInstPtr> 377class Checker : public CheckerCPU 378{ 379 public: 380 Checker(Params *p) 381 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL) 382 { } 383 384 void switchOut(); 385 void takeOverFrom(BaseCPU *oldCPU); 386 387 void verify(DynInstPtr &inst); 388 389 void validateInst(DynInstPtr &inst); 390 void validateExecution(DynInstPtr &inst); 391 void validateState(); 392 393 void copyResult(DynInstPtr &inst); 394 395 private: 396 void handleError(DynInstPtr &inst) 397 { 398 if (exitOnError) { 399 dumpAndExit(inst); 400 } else if (updateOnError) { 401 updateThisCycle = true; 402 } 403 } 404 405 void dumpAndExit(DynInstPtr &inst); 406 407 bool updateThisCycle; 408 409 DynInstPtr unverifiedInst; 410 411 std::list<DynInstPtr> instList; 412 typedef typename std::list<DynInstPtr>::iterator InstListIt; 413 void dumpInsts(); 414}; 415 416#endif // __CPU_CHECKER_CPU_HH__ | 115 void setSystem(System *system); 116 117 System *systemPtr; 118 119 void setIcachePort(Port *icache_port); 120 121 Port *icachePort; 122 123 void setDcachePort(Port *dcache_port); 124 125 Port *dcachePort; 126 127 virtual Port *getPort(const std::string &name, int idx) 128 { 129 panic("Not supported on checker!"); 130 return NULL; 131 } 132 133 public: 134 // Primary thread being run. 135 SimpleThread *thread; 136 137 ThreadContext *tc; 138 139 AlphaITB *itb; 140 AlphaDTB *dtb; 141 142#if FULL_SYSTEM 143 Addr dbg_vtophys(Addr addr); 144#endif 145 146 union Result { 147 uint64_t integer; 148// float fp; 149 double dbl; 150 }; 151 152 Result result; 153 154 // current instruction 155 MachInst machInst; 156 157 // Pointer to the one memory request. 158 RequestPtr memReq; 159 160 StaticInstPtr curStaticInst; 161 162 // number of simulated instructions 163 Counter numInst; 164 Counter startNumInst; 165 166 std::queue<int> miscRegIdxs; 167 168 virtual Counter totalInstructions() const 169 { 170 return 0; 171 } 172 173 // number of simulated loads 174 Counter numLoad; 175 Counter startNumLoad; 176 177 virtual void serialize(std::ostream &os); 178 virtual void unserialize(Checkpoint *cp, const std::string §ion); 179 180 template <class T> 181 Fault read(Addr addr, T &data, unsigned flags); 182 183 template <class T> 184 Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 185 186 // These functions are only used in CPU models that split 187 // effective address computation from the actual memory access. 188 void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 189 Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 190 191 void prefetch(Addr addr, unsigned flags) 192 { 193 // need to do this... 194 } 195 196 void writeHint(Addr addr, int size, unsigned flags) 197 { 198 // need to do this... 199 } 200 201 Fault copySrcTranslate(Addr src); 202 203 Fault copy(Addr dest); 204 205 // The register accessor methods provide the index of the 206 // instruction's operand (e.g., 0 or 1), not the architectural 207 // register index, to simplify the implementation of register 208 // renaming. We find the architectural register index by indexing 209 // into the instruction's own operand index table. Note that a 210 // raw pointer to the StaticInst is provided instead of a 211 // ref-counted StaticInstPtr to redice overhead. This is fine as 212 // long as these methods don't copy the pointer into any long-term 213 // storage (which is pretty hard to imagine they would have reason 214 // to do). 215 216 uint64_t readIntReg(const StaticInst *si, int idx) 217 { 218 return thread->readIntReg(si->srcRegIdx(idx)); 219 } 220 221 FloatReg readFloatReg(const StaticInst *si, int idx, int width) 222 { 223 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 224 return thread->readFloatReg(reg_idx, width); 225 } 226 227 FloatReg readFloatReg(const StaticInst *si, int idx) 228 { 229 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 230 return thread->readFloatReg(reg_idx); 231 } 232 233 FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) 234 { 235 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 236 return thread->readFloatRegBits(reg_idx, width); 237 } 238 239 FloatRegBits readFloatRegBits(const StaticInst *si, int idx) 240 { 241 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 242 return thread->readFloatRegBits(reg_idx); 243 } 244 245 void setIntReg(const StaticInst *si, int idx, uint64_t val) 246 { 247 thread->setIntReg(si->destRegIdx(idx), val); 248 result.integer = val; 249 } 250 251 void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) 252 { 253 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 254 thread->setFloatReg(reg_idx, val, width); 255 switch(width) { 256 case 32: 257 result.dbl = (double)val; 258 break; 259 case 64: 260 result.dbl = val; 261 break; 262 }; 263 } 264 265 void setFloatReg(const StaticInst *si, int idx, FloatReg val) 266 { 267 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 268 thread->setFloatReg(reg_idx, val); 269 result.dbl = (double)val; 270 } 271 272 void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val, 273 int width) 274 { 275 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 276 thread->setFloatRegBits(reg_idx, val, width); 277 result.integer = val; 278 } 279 280 void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) 281 { 282 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 283 thread->setFloatRegBits(reg_idx, val); 284 result.integer = val; 285 } 286 287 uint64_t readPC() { return thread->readPC(); } 288 289 uint64_t readNextPC() { return thread->readNextPC(); } 290 291 void setNextPC(uint64_t val) { 292 thread->setNextPC(val); 293 } 294 295 MiscReg readMiscReg(int misc_reg) 296 { 297 return thread->readMiscReg(misc_reg); 298 } 299 300 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 301 { 302 return thread->readMiscRegWithEffect(misc_reg, fault); 303 } 304 305 Fault setMiscReg(int misc_reg, const MiscReg &val) 306 { 307 result.integer = val; 308 miscRegIdxs.push(misc_reg); 309 return thread->setMiscReg(misc_reg, val); 310 } 311 312 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 313 { 314 miscRegIdxs.push(misc_reg); 315 return thread->setMiscRegWithEffect(misc_reg, val); 316 } 317 318 void recordPCChange(uint64_t val) { changedPC = true; newPC = val; } 319 void recordNextPCChange(uint64_t val) { changedNextPC = true; } 320 321 bool translateInstReq(Request *req); 322 void translateDataWriteReq(Request *req); 323 void translateDataReadReq(Request *req); 324 325#if FULL_SYSTEM 326 Fault hwrei() { return thread->hwrei(); } 327 int readIntrFlag() { return thread->readIntrFlag(); } 328 void setIntrFlag(int val) { thread->setIntrFlag(val); } 329 bool inPalMode() { return thread->inPalMode(); } 330 void ev5_trap(Fault fault) { fault->invoke(tc); } 331 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 332#else 333 // Assume that the normal CPU's call to syscall was successful. 334 // The checker's state would have already been updated by the syscall. 335 void syscall(uint64_t callnum) { } 336#endif 337 338 void handleError() 339 { 340 if (exitOnError) 341 dumpAndExit(); 342 } 343 344 bool checkFlags(Request *req); 345 346 void dumpAndExit(); 347 348 ThreadContext *tcBase() { return tc; } 349 SimpleThread *threadBase() { return thread; } 350 351 Result unverifiedResult; 352 Request *unverifiedReq; 353 uint8_t *unverifiedMemData; 354 355 bool changedPC; 356 bool willChangePC; 357 uint64_t newPC; 358 bool changedNextPC; 359 bool exitOnError; 360 bool updateOnError; 361 bool warnOnlyOnLoadError; 362 363 InstSeqNum youngestSN; 364}; 365 366/** 367 * Templated Checker class. This Checker class is templated on the 368 * DynInstPtr of the instruction type that will be verified. Proper 369 * template instantiations of the Checker must be placed at the bottom 370 * of checker/cpu.cc. 371 */ 372template <class DynInstPtr> 373class Checker : public CheckerCPU 374{ 375 public: 376 Checker(Params *p) 377 : CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL) 378 { } 379 380 void switchOut(); 381 void takeOverFrom(BaseCPU *oldCPU); 382 383 void verify(DynInstPtr &inst); 384 385 void validateInst(DynInstPtr &inst); 386 void validateExecution(DynInstPtr &inst); 387 void validateState(); 388 389 void copyResult(DynInstPtr &inst); 390 391 private: 392 void handleError(DynInstPtr &inst) 393 { 394 if (exitOnError) { 395 dumpAndExit(inst); 396 } else if (updateOnError) { 397 updateThisCycle = true; 398 } 399 } 400 401 void dumpAndExit(DynInstPtr &inst); 402 403 bool updateThisCycle; 404 405 DynInstPtr unverifiedInst; 406 407 std::list<DynInstPtr> instList; 408 typedef typename std::list<DynInstPtr>::iterator InstListIt; 409 void dumpInsts(); 410}; 411 412#endif // __CPU_CHECKER_CPU_HH__ |