base.hh revision 715
1/* 2 * Copyright (c) 2003 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 29#ifndef __SIMPLE_CPU_HH__ 30#define __SIMPLE_CPU_HH__ 31 32#include "cpu/base_cpu.hh" 33#include "sim/eventq.hh" 34#include "base/loader/symtab.hh" 35#include "cpu/pc_event.hh" 36#include "base/statistics.hh" 37#include "cpu/exec_context.hh" 38 39// forward declarations 40#ifdef FULL_SYSTEM 41class Processor; 42class Kernel; 43class AlphaITB; 44class AlphaDTB; 45class PhysicalMemory; 46 47class RemoteGDB; 48class GDBListener; 49 50#else 51 52class Process; 53 54#endif // FULL_SYSTEM 55 56class MemInterface; 57class Checkpoint; 58 59namespace Trace { 60 class InstRecord; 61} 62 63class SimpleCPU : public BaseCPU 64{ 65 public: 66 // main simulation loop (one cycle) 67 void tick(); 68 69 private: 70 class TickEvent : public Event 71 { 72 private: 73 SimpleCPU *cpu; 74 75 public: 76 TickEvent(SimpleCPU *c); 77 void process(); 78 const char *description(); 79 }; 80 81 TickEvent tickEvent; 82 83 /// Schedule tick event, regardless of its current state. 84 void scheduleTickEvent(int delay) 85 { 86 if (tickEvent.squashed()) 87 tickEvent.reschedule(curTick + delay); 88 else if (!tickEvent.scheduled()) 89 tickEvent.schedule(curTick + delay); 90 } 91 92 /// Unschedule tick event, regardless of its current state. 93 void unscheduleTickEvent() 94 { 95 if (tickEvent.scheduled()) 96 tickEvent.squash(); 97 } 98 99 private: 100 Trace::InstRecord *traceData; 101 template<typename T> 102 void trace_data(T data) { 103 if (traceData) { 104 traceData->setData(data); 105 } 106 }; 107 108 public: 109 // 110 enum Status { 111 Running, 112 Idle, 113 IcacheMissStall, 114 IcacheMissComplete, 115 DcacheMissStall, 116 SwitchedOut 117 }; 118 119 private: 120 Status _status; 121 122 public: 123 void post_interrupt(int int_num, int index); 124 125 void zero_fill_64(Addr addr) { 126 static int warned = 0; 127 if (!warned) { 128 warn ("WH64 is not implemented"); 129 warned = 1; 130 } 131 }; 132 133#ifdef FULL_SYSTEM 134 135 SimpleCPU(const std::string &_name, 136 System *_system, 137 Counter max_insts_any_thread, Counter max_insts_all_threads, 138 Counter max_loads_any_thread, Counter max_loads_all_threads, 139 AlphaITB *itb, AlphaDTB *dtb, FunctionalMemory *mem, 140 MemInterface *icache_interface, MemInterface *dcache_interface, 141 bool _def_reg, Tick freq); 142 143#else 144 145 SimpleCPU(const std::string &_name, Process *_process, 146 Counter max_insts_any_thread, 147 Counter max_insts_all_threads, 148 Counter max_loads_any_thread, 149 Counter max_loads_all_threads, 150 MemInterface *icache_interface, MemInterface *dcache_interface, 151 bool _def_reg); 152 153#endif 154 155 virtual ~SimpleCPU(); 156 virtual void init(); 157 158 // execution context 159 ExecContext *xc; 160 161 void switchOut(); 162 void takeOverFrom(BaseCPU *oldCPU); 163 164#ifdef FULL_SYSTEM 165 Addr dbg_vtophys(Addr addr); 166 167 bool interval_stats; 168#endif 169 170 // L1 instruction cache 171 MemInterface *icacheInterface; 172 173 // L1 data cache 174 MemInterface *dcacheInterface; 175 176 bool defer_registration; 177 178 // current instruction 179 MachInst inst; 180 181 // Refcounted pointer to the one memory request. 182 MemReqPtr memReq; 183 184 class CacheCompletionEvent : public Event 185 { 186 private: 187 SimpleCPU *cpu; 188 189 public: 190 CacheCompletionEvent(SimpleCPU *_cpu); 191 192 virtual void process(); 193 virtual const char *description(); 194 }; 195 196 CacheCompletionEvent cacheCompletionEvent; 197 198 Status status() const { return _status; } 199 200 virtual void activateContext(int thread_num, int delay); 201 virtual void suspendContext(int thread_num); 202 virtual void deallocateContext(int thread_num); 203 virtual void haltContext(int thread_num); 204 205 // statistics 206 virtual void regStats(); 207 virtual void resetStats(); 208 209 // number of simulated instructions 210 Counter numInst; 211 Counter startNumInst; 212 Statistics::Scalar<> numInsts; 213 214 virtual Counter totalInstructions() const 215 { 216 return numInst - startNumInst; 217 } 218 219 // number of simulated memory references 220 Statistics::Scalar<> numMemRefs; 221 222 // number of simulated loads 223 Counter numLoad; 224 Counter startNumLoad; 225 226 // number of idle cycles 227 Statistics::Average<> notIdleFraction; 228 Statistics::Formula idleFraction; 229 230 // number of cycles stalled for I-cache misses 231 Statistics::Scalar<> icacheStallCycles; 232 Counter lastIcacheStall; 233 234 // number of cycles stalled for D-cache misses 235 Statistics::Scalar<> dcacheStallCycles; 236 Counter lastDcacheStall; 237 238 void processCacheCompletion(); 239 240 virtual void serialize(std::ostream &os); 241 virtual void unserialize(Checkpoint *cp, const std::string §ion); 242 243 template <class T> 244 Fault read(Addr addr, T &data, unsigned flags); 245 246 template <class T> 247 Fault write(T data, Addr addr, unsigned flags, 248 uint64_t *res); 249 250 void prefetch(Addr addr, unsigned flags) 251 { 252 // need to do this... 253 } 254 255 void writeHint(Addr addr, int size) 256 { 257 // need to do this... 258 } 259 260 Fault copySrcTranslate(Addr src); 261 262 Fault copy(Addr dest); 263 264 uint64_t readIntReg(int reg_idx) { return xc->readIntReg(reg_idx); } 265 266 float readFloatRegSingle(int reg_idx) 267 { return xc->readFloatRegSingle(reg_idx); } 268 269 double readFloatRegDouble(int reg_idx) 270 { return xc->readFloatRegDouble(reg_idx); } 271 272 uint64_t readFloatRegInt(int reg_idx) 273 { return xc->readFloatRegInt(reg_idx); } 274 275 void setIntReg(int reg_idx, uint64_t val) 276 { return xc->setIntReg(reg_idx, val); } 277 278 void setFloatRegSingle(int reg_idx, float val) 279 { return xc->setFloatRegSingle(reg_idx, val); } 280 281 void setFloatRegDouble(int reg_idx, double val) 282 { return xc->setFloatRegDouble(reg_idx, val); } 283 284 void setFloatRegInt(int reg_idx, uint64_t val) 285 { return xc->setFloatRegInt(reg_idx, val); } 286 287 uint64_t readPC() { return xc->readPC(); } 288 void setNextPC(uint64_t val) { return xc->setNextPC(val); } 289 290 uint64_t readUniq() { return xc->readUniq(); } 291 void setUniq(uint64_t val) { return xc->setUniq(val); } 292 293 uint64_t readFpcr() { return xc->readFpcr(); } 294 void setFpcr(uint64_t val) { return xc->setFpcr(val); } 295 296#ifdef FULL_SYSTEM 297 uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } 298 Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } 299 Fault hwrei() { return xc->hwrei(); } 300 int readIntrFlag() { return xc->readIntrFlag(); } 301 void setIntrFlag(int val) { xc->setIntrFlag(val); } 302 bool inPalMode() { return xc->inPalMode(); } 303 void ev5_trap(Fault fault) { return xc->ev5_trap(fault); } 304 bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } 305#else 306 void syscall() { xc->syscall(); } 307#endif 308 309 bool misspeculating() { return xc->misspeculating(); } 310 ExecContext *xcBase() { return xc; } 311}; 312 313#endif // __SIMPLE_CPU_HH__ 314