base.hh revision 6658
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/simple_thread.hh" 42#include "cpu/pc_event.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 66class RemoteGDB; 67class GDBListener; 68 69namespace TheISA 70{ 71 class Predecoder; 72} 73class ThreadContext; 74class Checkpoint; 75 76namespace Trace { 77 class InstRecord; 78} 79 80class BaseSimpleCPUParams; 81 82 83class BaseSimpleCPU : public BaseCPU 84{ 85 protected: 86 typedef TheISA::MiscReg MiscReg; 87 typedef TheISA::FloatReg FloatReg; 88 typedef TheISA::FloatRegBits FloatRegBits; 89 90 protected: 91 Trace::InstRecord *traceData; 92 93 inline void checkPcEventQueue() { 94 Addr oldpc; 95 do { 96 oldpc = thread->readPC(); 97 system->pcEventQueue.service(tc); 98 } while (oldpc != thread->readPC()); 99 } 100 101 public: 102 void wakeup(); 103 104 void zero_fill_64(Addr addr) { 105 static int warned = 0; 106 if (!warned) { 107 warn ("WH64 is not implemented"); 108 warned = 1; 109 } 110 }; 111 112 public: 113 BaseSimpleCPU(BaseSimpleCPUParams *params); 114 virtual ~BaseSimpleCPU(); 115 116 public: 117 /** SimpleThread object, provides all the architectural state. */ 118 SimpleThread *thread; 119 120 /** ThreadContext object, provides an interface for external 121 * objects to modify this thread's state. 122 */ 123 ThreadContext *tc; 124 protected: 125 126 enum Status { 127 Idle, 128 Running, 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 188 thread->funcExeInst++; 189 } 190 191 virtual Counter totalInstructions() const 192 { 193 return numInst - startNumInst; 194 } 195 196 // Mask to align PCs to MachInst sized boundaries 197 static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1); 198 199 // number of simulated memory references 200 Stats::Scalar numMemRefs; 201 202 // number of simulated loads 203 Counter numLoad; 204 Counter startNumLoad; 205 206 // number of idle cycles 207 Stats::Average notIdleFraction; 208 Stats::Formula idleFraction; 209 210 // number of cycles stalled for I-cache responses 211 Stats::Scalar icacheStallCycles; 212 Counter lastIcacheStall; 213 214 // number of cycles stalled for I-cache retries 215 Stats::Scalar icacheRetryCycles; 216 Counter lastIcacheRetry; 217 218 // number of cycles stalled for D-cache responses 219 Stats::Scalar dcacheStallCycles; 220 Counter lastDcacheStall; 221 222 // number of cycles stalled for D-cache retries 223 Stats::Scalar dcacheRetryCycles; 224 Counter lastDcacheRetry; 225 226 virtual void serialize(std::ostream &os); 227 virtual void unserialize(Checkpoint *cp, const std::string §ion); 228 229 // These functions are only used in CPU models that split 230 // effective address computation from the actual memory access. 231 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); } 232 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); 233 M5_DUMMY_RETURN} 234 235 void prefetch(Addr addr, unsigned flags) 236 { 237 // need to do this... 238 } 239 240 void writeHint(Addr addr, int size, unsigned flags) 241 { 242 // need to do this... 243 } 244 245 246 Fault copySrcTranslate(Addr src); 247 248 Fault copy(Addr dest); 249 250 // The register accessor methods provide the index of the 251 // instruction's operand (e.g., 0 or 1), not the architectural 252 // register index, to simplify the implementation of register 253 // renaming. We find the architectural register index by indexing 254 // into the instruction's own operand index table. Note that a 255 // raw pointer to the StaticInst is provided instead of a 256 // ref-counted StaticInstPtr to redice overhead. This is fine as 257 // long as these methods don't copy the pointer into any long-term 258 // storage (which is pretty hard to imagine they would have reason 259 // to do). 260 261 uint64_t readIntRegOperand(const StaticInst *si, int idx) 262 { 263 return thread->readIntReg(si->srcRegIdx(idx)); 264 } 265 266 FloatReg readFloatRegOperand(const StaticInst *si, int idx) 267 { 268 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 269 return thread->readFloatReg(reg_idx); 270 } 271 272 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) 273 { 274 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 275 return thread->readFloatRegBits(reg_idx); 276 } 277 278 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 279 { 280 thread->setIntReg(si->destRegIdx(idx), val); 281 } 282 283 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 284 { 285 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 286 thread->setFloatReg(reg_idx, val); 287 } 288 289 void setFloatRegOperandBits(const StaticInst *si, int idx, 290 FloatRegBits val) 291 { 292 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 293 thread->setFloatRegBits(reg_idx, val); 294 } 295 296 uint64_t readPC() { return thread->readPC(); } 297 uint64_t readMicroPC() { return thread->readMicroPC(); } 298 uint64_t readNextPC() { return thread->readNextPC(); } 299 uint64_t readNextMicroPC() { return thread->readNextMicroPC(); } 300 uint64_t readNextNPC() { return thread->readNextNPC(); } 301 302 void setPC(uint64_t val) { thread->setPC(val); } 303 void setMicroPC(uint64_t val) { thread->setMicroPC(val); } 304 void setNextPC(uint64_t val) { thread->setNextPC(val); } 305 void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); } 306 void setNextNPC(uint64_t val) { thread->setNextNPC(val); } 307 308 MiscReg readMiscRegNoEffect(int misc_reg) 309 { 310 return thread->readMiscRegNoEffect(misc_reg); 311 } 312 313 MiscReg readMiscReg(int misc_reg) 314 { 315 return thread->readMiscReg(misc_reg); 316 } 317 318 void setMiscRegNoEffect(int misc_reg, const MiscReg &val) 319 { 320 return thread->setMiscRegNoEffect(misc_reg, val); 321 } 322 323 void setMiscReg(int misc_reg, const MiscReg &val) 324 { 325 return thread->setMiscReg(misc_reg, val); 326 } 327 328 MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx) 329 { 330 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 331 return thread->readMiscRegNoEffect(reg_idx); 332 } 333 334 MiscReg readMiscRegOperand(const StaticInst *si, int idx) 335 { 336 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 337 return thread->readMiscReg(reg_idx); 338 } 339 340 void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val) 341 { 342 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 343 return thread->setMiscRegNoEffect(reg_idx, val); 344 } 345 346 void setMiscRegOperand( 347 const StaticInst *si, int idx, const MiscReg &val) 348 { 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#if FULL_SYSTEM 392 Fault hwrei() { return thread->hwrei(); } 393 void ev5_trap(Fault fault) { fault->invoke(tc); } 394 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 395#else 396 void syscall(int64_t callnum) { thread->syscall(callnum); } 397#endif 398 399 bool misspeculating() { return thread->misspeculating(); } 400 ThreadContext *tcBase() { return tc; } 401}; 402 403#endif // __CPU_SIMPLE_BASE_HH__ 404