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