base.hh revision 8733
1/* 2 * Copyright (c) 2011 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2002-2005 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Steve Reinhardt 41 * Dave Greene 42 * Nathan Binkert 43 */ 44 45#ifndef __CPU_SIMPLE_BASE_HH__ 46#define __CPU_SIMPLE_BASE_HH__ 47 48#include "arch/predecoder.hh" 49#include "base/statistics.hh" 50#include "config/full_system.hh" 51#include "config/the_isa.hh" 52#include "config/use_checker.hh" 53#include "cpu/base.hh" 54#include "cpu/decode.hh" 55#include "cpu/pc_event.hh" 56#include "cpu/simple_thread.hh" 57#include "cpu/static_inst.hh" 58#include "mem/packet.hh" 59#include "mem/port.hh" 60#include "mem/request.hh" 61#include "sim/eventq.hh" 62#include "sim/system.hh" 63 64#if USE_CHECKER 65#include "cpu/checker/cpu.hh" 66#endif 67 68// forward declarations 69#if FULL_SYSTEM 70class Processor; 71namespace TheISA 72{ 73 class ITB; 74 class DTB; 75} 76class MemObject; 77 78#else 79 80class Process; 81 82#endif // FULL_SYSTEM 83 84namespace TheISA 85{ 86 class Predecoder; 87} 88class ThreadContext; 89class Checkpoint; 90 91namespace Trace { 92 class InstRecord; 93} 94 95class BaseSimpleCPUParams; 96 97 98class BaseSimpleCPU : public BaseCPU 99{ 100 protected: 101 typedef TheISA::MiscReg MiscReg; 102 typedef TheISA::FloatReg FloatReg; 103 typedef TheISA::FloatRegBits FloatRegBits; 104 105 protected: 106 Trace::InstRecord *traceData; 107 108 inline void checkPcEventQueue() { 109 Addr oldpc, pc = thread->instAddr(); 110 do { 111 oldpc = pc; 112 system->pcEventQueue.service(tc); 113 pc = thread->instAddr(); 114 } while (oldpc != pc); 115 } 116 117 public: 118 void wakeup(); 119 120 void zero_fill_64(Addr addr) { 121 static int warned = 0; 122 if (!warned) { 123 warn ("WH64 is not implemented"); 124 warned = 1; 125 } 126 }; 127 128 public: 129 BaseSimpleCPU(BaseSimpleCPUParams *params); 130 virtual ~BaseSimpleCPU(); 131 132 public: 133 /** SimpleThread object, provides all the architectural state. */ 134 SimpleThread *thread; 135 136 /** ThreadContext object, provides an interface for external 137 * objects to modify this thread's state. 138 */ 139 ThreadContext *tc; 140 141#if USE_CHECKER 142 CheckerCPU *checker; 143#endif 144 protected: 145 146 enum Status { 147 Idle, 148 Running, 149 Faulting, 150 ITBWaitResponse, 151 IcacheRetry, 152 IcacheWaitResponse, 153 IcacheWaitSwitch, 154 DTBWaitResponse, 155 DcacheRetry, 156 DcacheWaitResponse, 157 DcacheWaitSwitch, 158 SwitchedOut 159 }; 160 161 Status _status; 162 163 public: 164 165#if FULL_SYSTEM 166 Addr dbg_vtophys(Addr addr); 167 168 bool interval_stats; 169#endif 170 171 // current instruction 172 TheISA::MachInst inst; 173 174 // The predecoder 175 TheISA::Predecoder predecoder; 176 177 StaticInstPtr curStaticInst; 178 StaticInstPtr curMacroStaticInst; 179 180 //This is the offset from the current pc that fetch should be performed at 181 Addr fetchOffset; 182 //This flag says to stay at the current pc. This is useful for 183 //instructions which go beyond MachInst boundaries. 184 bool stayAtPC; 185 186 void checkForInterrupts(); 187 void setupFetchRequest(Request *req); 188 void preExecute(); 189 void postExecute(); 190 void advancePC(Fault fault); 191 192 virtual void deallocateContext(int thread_num); 193 virtual void haltContext(int thread_num); 194 195 // statistics 196 virtual void regStats(); 197 virtual void resetStats(); 198 199 // number of simulated instructions 200 Counter numInst; 201 Counter startNumInst; 202 Stats::Scalar numInsts; 203 204 void countInst() 205 { 206 numInst++; 207 numInsts++; 208 system->totalNumInsts++; 209 thread->funcExeInst++; 210 } 211 212 virtual Counter totalInstructions() const 213 { 214 return numInst - startNumInst; 215 } 216 217 //number of integer alu accesses 218 Stats::Scalar numIntAluAccesses; 219 220 //number of float alu accesses 221 Stats::Scalar numFpAluAccesses; 222 223 //number of function calls/returns 224 Stats::Scalar numCallsReturns; 225 226 //conditional control instructions; 227 Stats::Scalar numCondCtrlInsts; 228 229 //number of int instructions 230 Stats::Scalar numIntInsts; 231 232 //number of float instructions 233 Stats::Scalar numFpInsts; 234 235 //number of integer register file accesses 236 Stats::Scalar numIntRegReads; 237 Stats::Scalar numIntRegWrites; 238 239 //number of float register file accesses 240 Stats::Scalar numFpRegReads; 241 Stats::Scalar numFpRegWrites; 242 243 // number of simulated memory references 244 Stats::Scalar numMemRefs; 245 Stats::Scalar numLoadInsts; 246 Stats::Scalar numStoreInsts; 247 248 // number of idle cycles 249 Stats::Formula numIdleCycles; 250 251 // number of busy cycles 252 Stats::Formula numBusyCycles; 253 254 // number of simulated loads 255 Counter numLoad; 256 Counter startNumLoad; 257 258 // number of idle cycles 259 Stats::Average notIdleFraction; 260 Stats::Formula idleFraction; 261 262 // number of cycles stalled for I-cache responses 263 Stats::Scalar icacheStallCycles; 264 Counter lastIcacheStall; 265 266 // number of cycles stalled for I-cache retries 267 Stats::Scalar icacheRetryCycles; 268 Counter lastIcacheRetry; 269 270 // number of cycles stalled for D-cache responses 271 Stats::Scalar dcacheStallCycles; 272 Counter lastDcacheStall; 273 274 // number of cycles stalled for D-cache retries 275 Stats::Scalar dcacheRetryCycles; 276 Counter lastDcacheRetry; 277 278 virtual void serialize(std::ostream &os); 279 virtual void unserialize(Checkpoint *cp, const std::string §ion); 280 281 // These functions are only used in CPU models that split 282 // effective address computation from the actual memory access. 283 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); } 284 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); 285 M5_DUMMY_RETURN} 286 287 // The register accessor methods provide the index of the 288 // instruction's operand (e.g., 0 or 1), not the architectural 289 // register index, to simplify the implementation of register 290 // renaming. We find the architectural register index by indexing 291 // into the instruction's own operand index table. Note that a 292 // raw pointer to the StaticInst is provided instead of a 293 // ref-counted StaticInstPtr to redice overhead. This is fine as 294 // long as these methods don't copy the pointer into any long-term 295 // storage (which is pretty hard to imagine they would have reason 296 // to do). 297 298 uint64_t readIntRegOperand(const StaticInst *si, int idx) 299 { 300 numIntRegReads++; 301 return thread->readIntReg(si->srcRegIdx(idx)); 302 } 303 304 FloatReg readFloatRegOperand(const StaticInst *si, int idx) 305 { 306 numFpRegReads++; 307 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 308 return thread->readFloatReg(reg_idx); 309 } 310 311 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) 312 { 313 numFpRegReads++; 314 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 315 return thread->readFloatRegBits(reg_idx); 316 } 317 318 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 319 { 320 numIntRegWrites++; 321 thread->setIntReg(si->destRegIdx(idx), val); 322 } 323 324 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 325 { 326 numFpRegWrites++; 327 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 328 thread->setFloatReg(reg_idx, val); 329 } 330 331 void setFloatRegOperandBits(const StaticInst *si, int idx, 332 FloatRegBits val) 333 { 334 numFpRegWrites++; 335 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 336 thread->setFloatRegBits(reg_idx, val); 337 } 338 339 bool readPredicate() { return thread->readPredicate(); } 340 void setPredicate(bool val) 341 { 342 thread->setPredicate(val); 343 if (traceData) { 344 traceData->setPredicate(val); 345 } 346 } 347 TheISA::PCState pcState() { return thread->pcState(); } 348 void pcState(const TheISA::PCState &val) { thread->pcState(val); } 349 Addr instAddr() { return thread->instAddr(); } 350 Addr nextInstAddr() { return thread->nextInstAddr(); } 351 MicroPC microPC() { return thread->microPC(); } 352 353 MiscReg readMiscRegNoEffect(int misc_reg) 354 { 355 return thread->readMiscRegNoEffect(misc_reg); 356 } 357 358 MiscReg readMiscReg(int misc_reg) 359 { 360 numIntRegReads++; 361 return thread->readMiscReg(misc_reg); 362 } 363 364 void setMiscReg(int misc_reg, const MiscReg &val) 365 { 366 numIntRegWrites++; 367 return thread->setMiscReg(misc_reg, val); 368 } 369 370 MiscReg readMiscRegOperand(const StaticInst *si, int idx) 371 { 372 numIntRegReads++; 373 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 374 return thread->readMiscReg(reg_idx); 375 } 376 377 void setMiscRegOperand( 378 const StaticInst *si, int idx, const MiscReg &val) 379 { 380 numIntRegWrites++; 381 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 382 return thread->setMiscReg(reg_idx, val); 383 } 384 385 void demapPage(Addr vaddr, uint64_t asn) 386 { 387 thread->demapPage(vaddr, asn); 388 } 389 390 void demapInstPage(Addr vaddr, uint64_t asn) 391 { 392 thread->demapInstPage(vaddr, asn); 393 } 394 395 void demapDataPage(Addr vaddr, uint64_t asn) 396 { 397 thread->demapDataPage(vaddr, asn); 398 } 399 400 unsigned readStCondFailures() { 401 return thread->readStCondFailures(); 402 } 403 404 void setStCondFailures(unsigned sc_failures) { 405 thread->setStCondFailures(sc_failures); 406 } 407 408 MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID) 409 { 410 panic("Simple CPU models do not support multithreaded " 411 "register access.\n"); 412 } 413 414 void setRegOtherThread(int regIdx, const MiscReg &val, 415 ThreadID tid = InvalidThreadID) 416 { 417 panic("Simple CPU models do not support multithreaded " 418 "register access.\n"); 419 } 420 421 //Fault CacheOp(uint8_t Op, Addr EA); 422 423#if FULL_SYSTEM 424 Fault hwrei() { return thread->hwrei(); } 425 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 426#endif 427 428 void 429 syscall(int64_t callnum) 430 { 431#if FULL_SYSTEM 432 panic("Syscall emulation isn't available in FS mode.\n"); 433#else 434 thread->syscall(callnum); 435#endif 436 } 437 438 bool misspeculating() { return thread->misspeculating(); } 439 ThreadContext *tcBase() { return tc; } 440}; 441 442#endif // __CPU_SIMPLE_BASE_HH__ 443