base.hh revision 3468
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 "base/statistics.hh" 37#include "config/full_system.hh" 38#include "cpu/base.hh" 39#include "cpu/simple_thread.hh" 40#include "cpu/pc_event.hh" 41#include "cpu/static_inst.hh" 42#include "mem/packet.hh" 43#include "mem/port.hh" 44#include "mem/request.hh" 45#include "sim/eventq.hh" 46 47// forward declarations 48#if FULL_SYSTEM 49class Processor; 50namespace TheISA 51{ 52 class ITB; 53 class DTB; 54} 55class MemObject; 56 57class RemoteGDB; 58class GDBListener; 59 60#else 61 62class Process; 63 64#endif // FULL_SYSTEM 65 66class ThreadContext; 67class Checkpoint; 68 69namespace Trace { 70 class InstRecord; 71} 72 73 74class BaseSimpleCPU : public BaseCPU 75{ 76 protected: 77 typedef TheISA::MachInst MachInst; 78 typedef TheISA::MiscReg MiscReg; 79 typedef TheISA::FloatReg FloatReg; 80 typedef TheISA::FloatRegBits FloatRegBits; 81 82 MemObject *mem; 83 84 protected: 85 Trace::InstRecord *traceData; 86 87 public: 88 void post_interrupt(int int_num, int index); 89 90 void zero_fill_64(Addr addr) { 91 static int warned = 0; 92 if (!warned) { 93 warn ("WH64 is not implemented"); 94 warned = 1; 95 } 96 }; 97 98 public: 99 struct Params : public BaseCPU::Params 100 { 101 MemObject *mem; 102#if FULL_SYSTEM 103 TheISA::ITB *itb; 104 TheISA::DTB *dtb; 105#else 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 MachInst inst; 129 130 // Static data storage 131 TheISA::IntReg dataReg; 132 133 StaticInstPtr curStaticInst; 134 StaticInstPtr curMacroStaticInst; 135 136 void checkForInterrupts(); 137 Fault setupFetchRequest(Request *req); 138 void preExecute(); 139 void postExecute(); 140 void advancePC(Fault fault); 141 142 virtual void deallocateContext(int thread_num); 143 virtual void haltContext(int thread_num); 144 145 // statistics 146 virtual void regStats(); 147 virtual void resetStats(); 148 149 // number of simulated instructions 150 Counter numInst; 151 Counter startNumInst; 152 Stats::Scalar<> numInsts; 153 154 virtual Counter totalInstructions() const 155 { 156 return numInst - startNumInst; 157 } 158 159 // number of simulated memory references 160 Stats::Scalar<> numMemRefs; 161 162 // number of simulated loads 163 Counter numLoad; 164 Counter startNumLoad; 165 166 // number of idle cycles 167 Stats::Average<> notIdleFraction; 168 Stats::Formula idleFraction; 169 170 // number of cycles stalled for I-cache responses 171 Stats::Scalar<> icacheStallCycles; 172 Counter lastIcacheStall; 173 174 // number of cycles stalled for I-cache retries 175 Stats::Scalar<> icacheRetryCycles; 176 Counter lastIcacheRetry; 177 178 // number of cycles stalled for D-cache responses 179 Stats::Scalar<> dcacheStallCycles; 180 Counter lastDcacheStall; 181 182 // number of cycles stalled for D-cache retries 183 Stats::Scalar<> dcacheRetryCycles; 184 Counter lastDcacheRetry; 185 186 virtual void serialize(std::ostream &os); 187 virtual void unserialize(Checkpoint *cp, const std::string §ion); 188 189 // These functions are only used in CPU models that split 190 // effective address computation from the actual memory access. 191 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); } 192 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); } 193 194 void prefetch(Addr addr, unsigned flags) 195 { 196 // need to do this... 197 } 198 199 void writeHint(Addr addr, int size, unsigned flags) 200 { 201 // need to do this... 202 } 203 204 Fault copySrcTranslate(Addr src); 205 206 Fault copy(Addr dest); 207 208 // The register accessor methods provide the index of the 209 // instruction's operand (e.g., 0 or 1), not the architectural 210 // register index, to simplify the implementation of register 211 // renaming. We find the architectural register index by indexing 212 // into the instruction's own operand index table. Note that a 213 // raw pointer to the StaticInst is provided instead of a 214 // ref-counted StaticInstPtr to redice overhead. This is fine as 215 // long as these methods don't copy the pointer into any long-term 216 // storage (which is pretty hard to imagine they would have reason 217 // to do). 218 219 uint64_t readIntReg(const StaticInst *si, int idx) 220 { 221 return thread->readIntReg(si->srcRegIdx(idx)); 222 } 223 224 FloatReg readFloatReg(const StaticInst *si, int idx, int width) 225 { 226 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 227 return thread->readFloatReg(reg_idx, width); 228 } 229 230 FloatReg readFloatReg(const StaticInst *si, int idx) 231 { 232 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 233 return thread->readFloatReg(reg_idx); 234 } 235 236 FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) 237 { 238 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 239 return thread->readFloatRegBits(reg_idx, width); 240 } 241 242 FloatRegBits readFloatRegBits(const StaticInst *si, int idx) 243 { 244 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 245 return thread->readFloatRegBits(reg_idx); 246 } 247 248 void setIntReg(const StaticInst *si, int idx, uint64_t val) 249 { 250 thread->setIntReg(si->destRegIdx(idx), val); 251 } 252 253 void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) 254 { 255 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 256 thread->setFloatReg(reg_idx, val, width); 257 } 258 259 void setFloatReg(const StaticInst *si, int idx, FloatReg val) 260 { 261 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 262 thread->setFloatReg(reg_idx, val); 263 } 264 265 void setFloatRegBits(const StaticInst *si, int idx, 266 FloatRegBits val, int width) 267 { 268 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 269 thread->setFloatRegBits(reg_idx, val, width); 270 } 271 272 void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) 273 { 274 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 275 thread->setFloatRegBits(reg_idx, val); 276 } 277 278 uint64_t readPC() { return thread->readPC(); } 279 uint64_t readNextPC() { return thread->readNextPC(); } 280 uint64_t readNextNPC() { return thread->readNextNPC(); } 281 282 void setPC(uint64_t val) { thread->setPC(val); } 283 void setNextPC(uint64_t val) { thread->setNextPC(val); } 284 void setNextNPC(uint64_t val) { thread->setNextNPC(val); } 285 286 MiscReg readMiscReg(int misc_reg) 287 { 288 return thread->readMiscReg(misc_reg); 289 } 290 291 MiscReg readMiscRegWithEffect(int misc_reg) 292 { 293 return thread->readMiscRegWithEffect(misc_reg); 294 } 295 296 void setMiscReg(int misc_reg, const MiscReg &val) 297 { 298 return thread->setMiscReg(misc_reg, val); 299 } 300 301 void setMiscRegWithEffect(int misc_reg, const MiscReg &val) 302 { 303 return thread->setMiscRegWithEffect(misc_reg, val); 304 } 305 306#if FULL_SYSTEM 307 Fault hwrei() { return thread->hwrei(); } 308 bool inPalMode() { return thread->inPalMode(); } 309 void ev5_trap(Fault fault) { fault->invoke(tc); } 310 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 311#else 312 void syscall(int64_t callnum) { thread->syscall(callnum); } 313#endif 314 315 bool misspeculating() { return thread->misspeculating(); } 316 ThreadContext *tcBase() { return tc; } 317}; 318 319#endif // __CPU_SIMPLE_BASE_HH__ 320