base.hh revision 8779
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 * Authors: Steve Reinhardt 29 * Dave Greene 30 * Nathan Binkert 31 */ 32 33#ifndef __CPU_SIMPLE_BASE_HH__ 34#define __CPU_SIMPLE_BASE_HH__ 35 36#include "arch/predecoder.hh" 37#include "base/statistics.hh" 38#include "config/the_isa.hh" 39#include "cpu/base.hh" 40#include "cpu/decode.hh" 41#include "cpu/pc_event.hh" 42#include "cpu/simple_thread.hh" 43#include "cpu/static_inst.hh" 44#include "mem/packet.hh" 45#include "mem/port.hh" 46#include "mem/request.hh" 47#include "sim/eventq.hh" 48#include "sim/full_system.hh" 49#include "sim/system.hh" 50 51// forward declarations 52class Checkpoint; 53class MemObject; 54class Process; 55class Processor; 56class ThreadContext; 57 58namespace TheISA 59{ 60 class DTB; 61 class ITB; 62 class Predecoder; 63} 64 65namespace Trace { 66 class InstRecord; 67} 68 69class BaseSimpleCPUParams; 70 71 72class BaseSimpleCPU : public BaseCPU 73{ 74 protected: 75 typedef TheISA::MiscReg MiscReg; 76 typedef TheISA::FloatReg FloatReg; 77 typedef TheISA::FloatRegBits FloatRegBits; 78 79 protected: 80 Trace::InstRecord *traceData; 81 82 inline void checkPcEventQueue() { 83 Addr oldpc, pc = thread->instAddr(); 84 do { 85 oldpc = pc; 86 system->pcEventQueue.service(tc); 87 pc = thread->instAddr(); 88 } while (oldpc != pc); 89 } 90 91 public: 92 void wakeup(); 93 94 void zero_fill_64(Addr addr) { 95 static int warned = 0; 96 if (!warned) { 97 warn ("WH64 is not implemented"); 98 warned = 1; 99 } 100 }; 101 102 public: 103 BaseSimpleCPU(BaseSimpleCPUParams *params); 104 virtual ~BaseSimpleCPU(); 105 106 public: 107 /** SimpleThread object, provides all the architectural state. */ 108 SimpleThread *thread; 109 110 /** ThreadContext object, provides an interface for external 111 * objects to modify this thread's state. 112 */ 113 ThreadContext *tc; 114 protected: 115 116 enum Status { 117 Idle, 118 Running, 119 Faulting, 120 ITBWaitResponse, 121 IcacheRetry, 122 IcacheWaitResponse, 123 IcacheWaitSwitch, 124 DTBWaitResponse, 125 DcacheRetry, 126 DcacheWaitResponse, 127 DcacheWaitSwitch, 128 SwitchedOut 129 }; 130 131 Status _status; 132 133 public: 134 135 Addr dbg_vtophys(Addr addr); 136 137 bool interval_stats; 138 139 // current instruction 140 TheISA::MachInst inst; 141 142 // The predecoder 143 TheISA::Predecoder predecoder; 144 145 StaticInstPtr curStaticInst; 146 StaticInstPtr curMacroStaticInst; 147 148 //This is the offset from the current pc that fetch should be performed at 149 Addr fetchOffset; 150 //This flag says to stay at the current pc. This is useful for 151 //instructions which go beyond MachInst boundaries. 152 bool stayAtPC; 153 154 void checkForInterrupts(); 155 void setupFetchRequest(Request *req); 156 void preExecute(); 157 void postExecute(); 158 void advancePC(Fault fault); 159 160 virtual void deallocateContext(int thread_num); 161 virtual void haltContext(int thread_num); 162 163 // statistics 164 virtual void regStats(); 165 virtual void resetStats(); 166 167 // number of simulated instructions 168 Counter numInst; 169 Counter startNumInst; 170 Stats::Scalar numInsts; 171 172 void countInst() 173 { 174 numInst++; 175 numInsts++; 176 system->totalNumInsts++; 177 thread->funcExeInst++; 178 } 179 180 virtual Counter totalInstructions() const 181 { 182 return numInst - startNumInst; 183 } 184 185 //number of integer alu accesses 186 Stats::Scalar numIntAluAccesses; 187 188 //number of float alu accesses 189 Stats::Scalar numFpAluAccesses; 190 191 //number of function calls/returns 192 Stats::Scalar numCallsReturns; 193 194 //conditional control instructions; 195 Stats::Scalar numCondCtrlInsts; 196 197 //number of int instructions 198 Stats::Scalar numIntInsts; 199 200 //number of float instructions 201 Stats::Scalar numFpInsts; 202 203 //number of integer register file accesses 204 Stats::Scalar numIntRegReads; 205 Stats::Scalar numIntRegWrites; 206 207 //number of float register file accesses 208 Stats::Scalar numFpRegReads; 209 Stats::Scalar numFpRegWrites; 210 211 // number of simulated memory references 212 Stats::Scalar numMemRefs; 213 Stats::Scalar numLoadInsts; 214 Stats::Scalar numStoreInsts; 215 216 // number of idle cycles 217 Stats::Formula numIdleCycles; 218 219 // number of busy cycles 220 Stats::Formula numBusyCycles; 221 222 // number of simulated loads 223 Counter numLoad; 224 Counter startNumLoad; 225 226 // number of idle cycles 227 Stats::Average notIdleFraction; 228 Stats::Formula idleFraction; 229 230 // number of cycles stalled for I-cache responses 231 Stats::Scalar icacheStallCycles; 232 Counter lastIcacheStall; 233 234 // number of cycles stalled for I-cache retries 235 Stats::Scalar icacheRetryCycles; 236 Counter lastIcacheRetry; 237 238 // number of cycles stalled for D-cache responses 239 Stats::Scalar dcacheStallCycles; 240 Counter lastDcacheStall; 241 242 // number of cycles stalled for D-cache retries 243 Stats::Scalar dcacheRetryCycles; 244 Counter lastDcacheRetry; 245 246 virtual void serialize(std::ostream &os); 247 virtual void unserialize(Checkpoint *cp, const std::string §ion); 248 249 // These functions are only used in CPU models that split 250 // effective address computation from the actual memory access. 251 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); } 252 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); 253 M5_DUMMY_RETURN} 254 255 // The register accessor methods provide the index of the 256 // instruction's operand (e.g., 0 or 1), not the architectural 257 // register index, to simplify the implementation of register 258 // renaming. We find the architectural register index by indexing 259 // into the instruction's own operand index table. Note that a 260 // raw pointer to the StaticInst is provided instead of a 261 // ref-counted StaticInstPtr to redice overhead. This is fine as 262 // long as these methods don't copy the pointer into any long-term 263 // storage (which is pretty hard to imagine they would have reason 264 // to do). 265 266 uint64_t readIntRegOperand(const StaticInst *si, int idx) 267 { 268 numIntRegReads++; 269 return thread->readIntReg(si->srcRegIdx(idx)); 270 } 271 272 FloatReg readFloatRegOperand(const StaticInst *si, int idx) 273 { 274 numFpRegReads++; 275 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 276 return thread->readFloatReg(reg_idx); 277 } 278 279 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) 280 { 281 numFpRegReads++; 282 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 283 return thread->readFloatRegBits(reg_idx); 284 } 285 286 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 287 { 288 numIntRegWrites++; 289 thread->setIntReg(si->destRegIdx(idx), val); 290 } 291 292 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 293 { 294 numFpRegWrites++; 295 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 296 thread->setFloatReg(reg_idx, val); 297 } 298 299 void setFloatRegOperandBits(const StaticInst *si, int idx, 300 FloatRegBits val) 301 { 302 numFpRegWrites++; 303 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 304 thread->setFloatRegBits(reg_idx, val); 305 } 306 307 bool readPredicate() { return thread->readPredicate(); } 308 void setPredicate(bool val) 309 { 310 thread->setPredicate(val); 311 if (traceData) { 312 traceData->setPredicate(val); 313 } 314 } 315 TheISA::PCState pcState() { return thread->pcState(); } 316 void pcState(const TheISA::PCState &val) { thread->pcState(val); } 317 Addr instAddr() { return thread->instAddr(); } 318 Addr nextInstAddr() { return thread->nextInstAddr(); } 319 MicroPC microPC() { return thread->microPC(); } 320 321 MiscReg readMiscRegNoEffect(int misc_reg) 322 { 323 return thread->readMiscRegNoEffect(misc_reg); 324 } 325 326 MiscReg readMiscReg(int misc_reg) 327 { 328 numIntRegReads++; 329 return thread->readMiscReg(misc_reg); 330 } 331 332 void setMiscReg(int misc_reg, const MiscReg &val) 333 { 334 numIntRegWrites++; 335 return thread->setMiscReg(misc_reg, val); 336 } 337 338 MiscReg readMiscRegOperand(const StaticInst *si, int idx) 339 { 340 numIntRegReads++; 341 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 342 return thread->readMiscReg(reg_idx); 343 } 344 345 void setMiscRegOperand( 346 const StaticInst *si, int idx, const MiscReg &val) 347 { 348 numIntRegWrites++; 349 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 350 return thread->setMiscReg(reg_idx, val); 351 } 352 353 void demapPage(Addr vaddr, uint64_t asn) 354 { 355 thread->demapPage(vaddr, asn); 356 } 357 358 void demapInstPage(Addr vaddr, uint64_t asn) 359 { 360 thread->demapInstPage(vaddr, asn); 361 } 362 363 void demapDataPage(Addr vaddr, uint64_t asn) 364 { 365 thread->demapDataPage(vaddr, asn); 366 } 367 368 unsigned readStCondFailures() { 369 return thread->readStCondFailures(); 370 } 371 372 void setStCondFailures(unsigned sc_failures) { 373 thread->setStCondFailures(sc_failures); 374 } 375 376 MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID) 377 { 378 panic("Simple CPU models do not support multithreaded " 379 "register access.\n"); 380 } 381 382 void setRegOtherThread(int regIdx, const MiscReg &val, 383 ThreadID tid = InvalidThreadID) 384 { 385 panic("Simple CPU models do not support multithreaded " 386 "register access.\n"); 387 } 388 389 //Fault CacheOp(uint8_t Op, Addr EA); 390 391 Fault hwrei() { return thread->hwrei(); } 392 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 393 394 void 395 syscall(int64_t callnum) 396 { 397 if (FullSystem) 398 panic("Syscall emulation isn't available in FS mode.\n"); 399 else 400 thread->syscall(callnum); 401 } 402 403 bool misspeculating() { return thread->misspeculating(); } 404 ThreadContext *tcBase() { return tc; } 405}; 406 407#endif // __CPU_SIMPLE_BASE_HH__ 408