cpu.hh revision 2332
12SN/A/* 21762SN/A * Copyright (c) 2006 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A */ 282665SN/A 292665SN/A#ifndef __CPU_CHECKER_CPU_HH__ 302SN/A#define __CPU_CHECKER_CPU_HH__ 312SN/A 322SN/A#include <list> 332SN/A#include <queue> 342SN/A#include <map> 352SN/A 3611263Sandreas.sandberg@arm.com#include "base/statistics.hh" 3711263Sandreas.sandberg@arm.com#include "config/full_system.hh" 382SN/A#include "cpu/base.hh" 396216SN/A#include "cpu/base_dyn_inst.hh" 40572SN/A#include "cpu/cpu_exec_context.hh" 412SN/A#include "cpu/pc_event.hh" 422SN/A#include "cpu/static_inst.hh" 436214SN/A#include "sim/eventq.hh" 4410905SN/A 45837SN/A// forward declarations 462SN/A#if FULL_SYSTEM 472SN/Aclass Processor; 482SN/Aclass AlphaITB; 4910469SN/Aclass AlphaDTB; 502SN/Aclass PhysicalMemory; 512SN/A 5211701Smichael.lebeane@amd.comclass RemoteGDB; 532007SN/Aclass GDBListener; 542007SN/A 552SN/A#else 562007SN/A 5711701Smichael.lebeane@amd.comclass Process; 5811701Smichael.lebeane@amd.com 592007SN/A#endif // FULL_SYSTEM 606227SN/Atemplate <class> 612SN/Aclass BaseDynInst; 6211701Smichael.lebeane@amd.comclass ExecContext; 6311701Smichael.lebeane@amd.comclass MemInterface; 6411701Smichael.lebeane@amd.comclass Checkpoint; 6511701Smichael.lebeane@amd.comclass Sampler; 6611701Smichael.lebeane@amd.com 6711701Smichael.lebeane@amd.comclass CheckerCPU : public BaseCPU 6811701Smichael.lebeane@amd.com{ 6911701Smichael.lebeane@amd.com protected: 7011701Smichael.lebeane@amd.com typedef TheISA::MachInst MachInst; 715483SN/A typedef TheISA::MiscReg MiscReg; 7211701Smichael.lebeane@amd.com public: 734981SN/A // main simulation loop (one cycle) 744981SN/A virtual void init(); 756227SN/A 7611701Smichael.lebeane@amd.com struct Params : public BaseCPU::Params 774981SN/A { 784981SN/A#if FULL_SYSTEM 792566SN/A AlphaITB *itb; 80228SN/A AlphaDTB *dtb; 8110905SN/A FunctionalMemory *mem; 8210905SN/A#else 832SN/A Process *process; 842SN/A#endif 8510469SN/A bool exitOnError; 862SN/A }; 8711263Sandreas.sandberg@arm.com 88 public: 89 CheckerCPU(Params *p); 90 virtual ~CheckerCPU(); 91 92 void setMemory(FunctionalMemory *mem); 93 94 FunctionalMemory *memPtr; 95 96#if FULL_SYSTEM 97 void setSystem(System *system); 98 99 System *systemPtr; 100#endif 101 public: 102 // execution context 103 CPUExecContext *cpuXC; 104 105 ExecContext *xcProxy; 106 107 AlphaITB *itb; 108 AlphaDTB *dtb; 109 110#if FULL_SYSTEM 111 Addr dbg_vtophys(Addr addr); 112#endif 113 114 union Result { 115 uint64_t integer; 116 float fp; 117 double dbl; 118 }; 119 120 Result result; 121 122 // current instruction 123 MachInst machInst; 124 125 // Refcounted pointer to the one memory request. 126 MemReqPtr memReq; 127 128 StaticInstPtr curStaticInst; 129 130 // number of simulated instructions 131 Counter numInst; 132 Counter startNumInst; 133 134 std::queue<int> miscRegIdxs; 135 136 virtual Counter totalInstructions() const 137 { 138 return numInst - startNumInst; 139 } 140 141 // number of simulated loads 142 Counter numLoad; 143 Counter startNumLoad; 144 145 virtual void serialize(std::ostream &os); 146 virtual void unserialize(Checkpoint *cp, const std::string §ion); 147 148 template <class T> 149 Fault read(Addr addr, T &data, unsigned flags); 150 151 template <class T> 152 Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 153 154 // These functions are only used in CPU models that split 155 // effective address computation from the actual memory access. 156 void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 157 Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 158 159 void prefetch(Addr addr, unsigned flags) 160 { 161 // need to do this... 162 } 163 164 void writeHint(Addr addr, int size, unsigned flags) 165 { 166 // need to do this... 167 } 168 169 Fault copySrcTranslate(Addr src); 170 171 Fault copy(Addr dest); 172 173 // The register accessor methods provide the index of the 174 // instruction's operand (e.g., 0 or 1), not the architectural 175 // register index, to simplify the implementation of register 176 // renaming. We find the architectural register index by indexing 177 // into the instruction's own operand index table. Note that a 178 // raw pointer to the StaticInst is provided instead of a 179 // ref-counted StaticInstPtr to redice overhead. This is fine as 180 // long as these methods don't copy the pointer into any long-term 181 // storage (which is pretty hard to imagine they would have reason 182 // to do). 183 184 uint64_t readIntReg(const StaticInst *si, int idx) 185 { 186 return cpuXC->readIntReg(si->srcRegIdx(idx)); 187 } 188 189 float readFloatRegSingle(const StaticInst *si, int idx) 190 { 191 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 192 return cpuXC->readFloatRegSingle(reg_idx); 193 } 194 195 double readFloatRegDouble(const StaticInst *si, int idx) 196 { 197 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 198 return cpuXC->readFloatRegDouble(reg_idx); 199 } 200 201 uint64_t readFloatRegInt(const StaticInst *si, int idx) 202 { 203 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 204 return cpuXC->readFloatRegInt(reg_idx); 205 } 206 207 void setIntReg(const StaticInst *si, int idx, uint64_t val) 208 { 209 cpuXC->setIntReg(si->destRegIdx(idx), val); 210 result.integer = val; 211 } 212 213 void setFloatRegSingle(const StaticInst *si, int idx, float val) 214 { 215 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 216 cpuXC->setFloatRegSingle(reg_idx, val); 217 result.fp = val; 218 } 219 220 void setFloatRegDouble(const StaticInst *si, int idx, double val) 221 { 222 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 223 cpuXC->setFloatRegDouble(reg_idx, val); 224 result.dbl = val; 225 } 226 227 void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) 228 { 229 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 230 cpuXC->setFloatRegInt(reg_idx, val); 231 result.integer = val; 232 } 233 234 uint64_t readPC() { return cpuXC->readPC(); } 235 void setNextPC(uint64_t val) { 236 cpuXC->setNextPC(val); 237 } 238 239 MiscReg readMiscReg(int misc_reg) 240 { 241 return cpuXC->readMiscReg(misc_reg); 242 } 243 244 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 245 { 246 return cpuXC->readMiscRegWithEffect(misc_reg, fault); 247 } 248 249 Fault setMiscReg(int misc_reg, const MiscReg &val) 250 { 251 result.integer = val; 252 miscRegIdxs.push(misc_reg); 253 return cpuXC->setMiscReg(misc_reg, val); 254 } 255 256 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 257 { 258 miscRegIdxs.push(misc_reg); 259 return cpuXC->setMiscRegWithEffect(misc_reg, val); 260 } 261 262 void recordPCChange(uint64_t val) { changedPC = true; } 263 void recordNextPCChange(uint64_t val) { changedNextPC = true; } 264 265 bool translateInstReq(MemReqPtr &req); 266 void translateDataWriteReq(MemReqPtr &req); 267 void translateDataReadReq(MemReqPtr &req); 268 269#if FULL_SYSTEM 270 Fault hwrei() { return cpuXC->hwrei(); } 271 int readIntrFlag() { return cpuXC->readIntrFlag(); } 272 void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } 273 bool inPalMode() { return cpuXC->inPalMode(); } 274 void ev5_trap(Fault fault) { fault->invoke(xcProxy); } 275 bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } 276#else 277 // Assume that the normal CPU's call to syscall was successful. 278 // The checker's state would have already been updated by the syscall. 279 void syscall() { } 280#endif 281 282 void handleError() 283 { 284 if (exitOnError) 285 panic("Checker found error!"); 286 } 287 bool checkFlags(MemReqPtr &req); 288 289 ExecContext *xcBase() { return xcProxy; } 290 CPUExecContext *cpuXCBase() { return cpuXC; } 291 292 Result unverifiedResult; 293 MemReqPtr unverifiedReq; 294 295 bool changedPC; 296 bool willChangePC; 297 uint64_t newPC; 298 bool changedNextPC; 299 bool exitOnError; 300 301 InstSeqNum youngestSN; 302}; 303 304template <class DynInstPtr> 305class Checker : public CheckerCPU 306{ 307 public: 308 Checker(Params *p) 309 : CheckerCPU(p) 310 { } 311 312 void switchOut(Sampler *s); 313 void takeOverFrom(BaseCPU *oldCPU); 314 315 void tick(DynInstPtr &inst); 316 317 void validateInst(DynInstPtr &inst); 318 void validateExecution(DynInstPtr &inst); 319 void validateState(); 320 321 std::list<DynInstPtr> instList; 322 typedef typename std::list<DynInstPtr>::iterator InstListIt; 323 void dumpInsts(); 324}; 325 326#endif // __CPU_CHECKER_CPU_HH__ 327