cpu.hh revision 2315
1/* 2 * Copyright (c) 2002-2005 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 29#ifndef __CPU_CHECKER_CPU_HH__ 30#define __CPU_CHECKER_CPU_HH__ 31 32#include <list> 33#include <queue> 34#include <map> 35 36#include "base/statistics.hh" 37#include "config/full_system.hh" 38#include "cpu/base.hh" 39#include "cpu/base_dyn_inst.hh" 40#include "cpu/cpu_exec_context.hh" 41#include "cpu/pc_event.hh" 42#include "cpu/sampler/sampler.hh" 43#include "cpu/static_inst.hh" 44#include "sim/eventq.hh" 45 46// forward declarations 47#if FULL_SYSTEM 48class Processor; 49class AlphaITB; 50class AlphaDTB; 51class PhysicalMemory; 52 53class RemoteGDB; 54class GDBListener; 55 56#else 57 58class Process; 59 60#endif // FULL_SYSTEM 61template <class> 62class BaseDynInst; 63class ExecContext; 64class MemInterface; 65class Checkpoint; 66 67class CheckerCPU : public BaseCPU 68{ 69 protected: 70 typedef TheISA::MachInst MachInst; 71 typedef TheISA::MiscReg MiscReg; 72 public: 73 // main simulation loop (one cycle) 74 virtual void init(); 75 76 struct Params : public BaseCPU::Params 77 { 78#if FULL_SYSTEM 79 AlphaITB *itb; 80 AlphaDTB *dtb; 81 FunctionalMemory *mem; 82#else 83 Process *process; 84#endif 85 bool exitOnError; 86 }; 87 88 public: 89 void post_interrupt(int int_num, int index); 90 91 CheckerCPU(Params *p); 92 virtual ~CheckerCPU(); 93 94 void setMemory(FunctionalMemory *mem); 95 96 FunctionalMemory *memPtr; 97 98#if FULL_SYSTEM 99 void setSystem(System *system); 100 101 System *systemPtr; 102#endif 103 public: 104 // execution context 105 CPUExecContext *cpuXC; 106 107 ExecContext *xcProxy; 108 109 AlphaITB *itb; 110 AlphaDTB *dtb; 111 112#if FULL_SYSTEM 113 Addr dbg_vtophys(Addr addr); 114 115 bool interval_stats; 116#endif 117 118 union Result { 119 uint64_t integer; 120 float fp; 121 double dbl; 122 }; 123 124 Result result; 125 126 // current instruction 127 MachInst machInst; 128 129 // Refcounted pointer to the one memory request. 130 MemReqPtr memReq; 131 132 // Pointer to the sampler that is telling us to switchover. 133 // Used to signal the completion of the pipe drain and schedule 134 // the next switchover 135 Sampler *sampler; 136 137 StaticInstPtr curStaticInst; 138 139 // number of simulated instructions 140 Counter numInst; 141 Counter startNumInst; 142 143 std::queue<int> miscRegIdxs; 144 145 virtual Counter totalInstructions() const 146 { 147 return numInst - startNumInst; 148 } 149 150 // number of simulated loads 151 Counter numLoad; 152 Counter startNumLoad; 153 154 virtual void serialize(std::ostream &os); 155 virtual void unserialize(Checkpoint *cp, const std::string §ion); 156 157 template <class T> 158 Fault read(Addr addr, T &data, unsigned flags); 159 160 template <class T> 161 Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 162 163 // These functions are only used in CPU models that split 164 // effective address computation from the actual memory access. 165 void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 166 Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 167 168 void prefetch(Addr addr, unsigned flags) 169 { 170 // need to do this... 171 } 172 173 void writeHint(Addr addr, int size, unsigned flags) 174 { 175 // need to do this... 176 } 177 178 Fault copySrcTranslate(Addr src); 179 180 Fault copy(Addr dest); 181 182 // The register accessor methods provide the index of the 183 // instruction's operand (e.g., 0 or 1), not the architectural 184 // register index, to simplify the implementation of register 185 // renaming. We find the architectural register index by indexing 186 // into the instruction's own operand index table. Note that a 187 // raw pointer to the StaticInst is provided instead of a 188 // ref-counted StaticInstPtr to redice overhead. This is fine as 189 // long as these methods don't copy the pointer into any long-term 190 // storage (which is pretty hard to imagine they would have reason 191 // to do). 192 193 uint64_t readIntReg(const StaticInst *si, int idx) 194 { 195 return cpuXC->readIntReg(si->srcRegIdx(idx)); 196 } 197 198 float readFloatRegSingle(const StaticInst *si, int idx) 199 { 200 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 201 return cpuXC->readFloatRegSingle(reg_idx); 202 } 203 204 double readFloatRegDouble(const StaticInst *si, int idx) 205 { 206 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 207 return cpuXC->readFloatRegDouble(reg_idx); 208 } 209 210 uint64_t readFloatRegInt(const StaticInst *si, int idx) 211 { 212 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 213 return cpuXC->readFloatRegInt(reg_idx); 214 } 215 216 void setIntReg(const StaticInst *si, int idx, uint64_t val) 217 { 218 cpuXC->setIntReg(si->destRegIdx(idx), val); 219 result.integer = val; 220 } 221 222 void setFloatRegSingle(const StaticInst *si, int idx, float val) 223 { 224 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 225 cpuXC->setFloatRegSingle(reg_idx, val); 226 result.fp = val; 227 } 228 229 void setFloatRegDouble(const StaticInst *si, int idx, double val) 230 { 231 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 232 cpuXC->setFloatRegDouble(reg_idx, val); 233 result.dbl = val; 234 } 235 236 void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) 237 { 238 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 239 cpuXC->setFloatRegInt(reg_idx, val); 240 result.integer = val; 241 } 242 243 uint64_t readPC() { return cpuXC->readPC(); } 244 void setNextPC(uint64_t val) { 245 cpuXC->setNextPC(val); 246 } 247 248 MiscReg readMiscReg(int misc_reg) 249 { 250 return cpuXC->readMiscReg(misc_reg); 251 } 252 253 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 254 { 255 return cpuXC->readMiscRegWithEffect(misc_reg, fault); 256 } 257 258 Fault setMiscReg(int misc_reg, const MiscReg &val) 259 { 260 result.integer = val; 261 miscRegIdxs.push(misc_reg); 262 return cpuXC->setMiscReg(misc_reg, val); 263 } 264 265 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 266 { 267 miscRegIdxs.push(misc_reg); 268 return cpuXC->setMiscRegWithEffect(misc_reg, val); 269 } 270 271 void recordPCChange(uint64_t val) { changedPC = true; } 272 void recordNextPCChange(uint64_t val) { changedNextPC = true; } 273 274 bool translateInstReq(MemReqPtr &req); 275 void translateDataWriteReq(MemReqPtr &req); 276 void translateDataReadReq(MemReqPtr &req); 277 278#if FULL_SYSTEM 279 Fault hwrei() { return cpuXC->hwrei(); } 280 int readIntrFlag() { return cpuXC->readIntrFlag(); } 281 void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } 282 bool inPalMode() { return cpuXC->inPalMode(); } 283 void ev5_trap(Fault fault) { fault->invoke(xcProxy); } 284 bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } 285#else 286 // Assume that the normal CPU's call to syscall was successful. 287 void syscall() { } 288#endif 289 290 void handleError() 291 { 292 if (exitOnError) 293 panic("Checker found error!"); 294 } 295 bool checkFlags(MemReqPtr &req); 296 297 ExecContext *xcBase() { return xcProxy; } 298 CPUExecContext *cpuXCBase() { return cpuXC; } 299 300 Result unverifiedResult; 301 MemReqPtr unverifiedReq; 302 303 bool changedPC; 304 bool willChangePC; 305 uint64_t newPC; 306 bool changedNextPC; 307 bool exitOnError; 308 309 InstSeqNum youngestSN; 310// std::map<Addr, uint64_t> storeBuff; 311// typedef std::map<Addr, uint64_t>::iterator map_it; 312}; 313 314template <class DynInstPtr> 315class Checker : public CheckerCPU 316{ 317 public: 318 Checker(Params *p) 319 : CheckerCPU(p) 320 { } 321 322 void switchOut(Sampler *s); 323 void takeOverFrom(BaseCPU *oldCPU); 324 325 void tick(DynInstPtr &inst); 326 327 void validateInst(DynInstPtr &inst); 328 void validateExecution(DynInstPtr &inst); 329 void validateState(); 330 331 std::list<DynInstPtr> instList; 332 typedef typename std::list<DynInstPtr>::iterator InstListIt; 333 void dumpInsts(); 334}; 335 336#endif // __CPU_CHECKER_CPU_HH__ 337