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