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