base.hh revision 2455
14952Sgblack@eecs.umich.edu/* 24952Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 34952Sgblack@eecs.umich.edu * All rights reserved. 44952Sgblack@eecs.umich.edu * 54952Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 64952Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 74952Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84952Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 94952Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 104952Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 114952Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 124952Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 134952Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 144952Sgblack@eecs.umich.edu * this software without specific prior written permission. 154952Sgblack@eecs.umich.edu * 164952Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174952Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184952Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194952Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204952Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214952Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224952Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234952Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244952Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254952Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264952Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274952Sgblack@eecs.umich.edu */ 284952Sgblack@eecs.umich.edu 294952Sgblack@eecs.umich.edu#ifndef __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 304952Sgblack@eecs.umich.edu#define __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 314952Sgblack@eecs.umich.edu 324952Sgblack@eecs.umich.edu#include "base/statistics.hh" 334952Sgblack@eecs.umich.edu#include "config/full_system.hh" 344952Sgblack@eecs.umich.edu#include "cpu/base.hh" 354952Sgblack@eecs.umich.edu#include "cpu/cpu_exec_context.hh" 364952Sgblack@eecs.umich.edu#include "cpu/pc_event.hh" 374952Sgblack@eecs.umich.edu#include "cpu/sampler/sampler.hh" 384952Sgblack@eecs.umich.edu#include "cpu/static_inst.hh" 394952Sgblack@eecs.umich.edu#include "mem/packet.hh" 404952Sgblack@eecs.umich.edu#include "mem/port.hh" 414952Sgblack@eecs.umich.edu#include "mem/request.hh" 424952Sgblack@eecs.umich.edu#include "sim/eventq.hh" 434952Sgblack@eecs.umich.edu 444952Sgblack@eecs.umich.edu// forward declarations 454952Sgblack@eecs.umich.edu#if FULL_SYSTEM 464952Sgblack@eecs.umich.educlass Processor; 474952Sgblack@eecs.umich.educlass AlphaITB; 484952Sgblack@eecs.umich.educlass AlphaDTB; 494952Sgblack@eecs.umich.educlass Memory; 504952Sgblack@eecs.umich.edu 514952Sgblack@eecs.umich.educlass RemoteGDB; 524952Sgblack@eecs.umich.educlass GDBListener; 534952Sgblack@eecs.umich.edu 544952Sgblack@eecs.umich.edu#else 554952Sgblack@eecs.umich.edu 564952Sgblack@eecs.umich.educlass Process; 574952Sgblack@eecs.umich.edu 584952Sgblack@eecs.umich.edu#endif // FULL_SYSTEM 594952Sgblack@eecs.umich.edu 604952Sgblack@eecs.umich.educlass ExecContext; 614952Sgblack@eecs.umich.educlass MemInterface; 624952Sgblack@eecs.umich.educlass Checkpoint; 634952Sgblack@eecs.umich.edu 645125Sgblack@eecs.umich.edunamespace Trace { 654952Sgblack@eecs.umich.edu class InstRecord; 664952Sgblack@eecs.umich.edu} 674952Sgblack@eecs.umich.edu 684952Sgblack@eecs.umich.edu 694952Sgblack@eecs.umich.edu// Set exactly one of these symbols to 1 to set the memory access 704952Sgblack@eecs.umich.edu// model. Probably should make these template parameters, or even 714952Sgblack@eecs.umich.edu// just fork the CPU models. 724952Sgblack@eecs.umich.edu// 734952Sgblack@eecs.umich.edu#define SIMPLE_CPU_MEM_TIMING 0 744952Sgblack@eecs.umich.edu#define SIMPLE_CPU_MEM_ATOMIC 0 754952Sgblack@eecs.umich.edu#define SIMPLE_CPU_MEM_IMMEDIATE 1 764952Sgblack@eecs.umich.edu 774952Sgblack@eecs.umich.edu 784952Sgblack@eecs.umich.educlass SimpleCPU : public BaseCPU 794952Sgblack@eecs.umich.edu{ 804952Sgblack@eecs.umich.edu protected: 814952Sgblack@eecs.umich.edu typedef TheISA::MachInst MachInst; 824952Sgblack@eecs.umich.edu typedef TheISA::MiscReg MiscReg; 834952Sgblack@eecs.umich.edu typedef TheISA::FloatReg FloatReg; 844952Sgblack@eecs.umich.edu typedef TheISA::FloatRegBits FloatRegBits; 854952Sgblack@eecs.umich.edu class CpuPort : public Port 864952Sgblack@eecs.umich.edu { 874952Sgblack@eecs.umich.edu 884952Sgblack@eecs.umich.edu SimpleCPU *cpu; 895125Sgblack@eecs.umich.edu 905125Sgblack@eecs.umich.edu public: 915125Sgblack@eecs.umich.edu 925125Sgblack@eecs.umich.edu CpuPort(SimpleCPU *_cpu) 935125Sgblack@eecs.umich.edu : cpu(_cpu) 945125Sgblack@eecs.umich.edu { } 955125Sgblack@eecs.umich.edu 965125Sgblack@eecs.umich.edu protected: 975125Sgblack@eecs.umich.edu 985125Sgblack@eecs.umich.edu virtual bool recvTiming(Packet &pkt); 995125Sgblack@eecs.umich.edu 1005125Sgblack@eecs.umich.edu virtual Tick recvAtomic(Packet &pkt); 1015125Sgblack@eecs.umich.edu 1025125Sgblack@eecs.umich.edu virtual void recvFunctional(Packet &pkt); 1035125Sgblack@eecs.umich.edu 1045125Sgblack@eecs.umich.edu virtual void recvStatusChange(Status status); 1055125Sgblack@eecs.umich.edu 1065125Sgblack@eecs.umich.edu virtual Packet *recvRetry(); 1075125Sgblack@eecs.umich.edu }; 1085125Sgblack@eecs.umich.edu 1095125Sgblack@eecs.umich.edu CpuPort icachePort; 1105125Sgblack@eecs.umich.edu CpuPort dcachePort; 1115125Sgblack@eecs.umich.edu 1125125Sgblack@eecs.umich.edu public: 1135125Sgblack@eecs.umich.edu // main simulation loop (one cycle) 1145125Sgblack@eecs.umich.edu void tick(); 115 virtual void init(); 116 117 private: 118 struct TickEvent : public Event 119 { 120 SimpleCPU *cpu; 121 int width; 122 123 TickEvent(SimpleCPU *c, int w); 124 void process(); 125 const char *description(); 126 }; 127 128 TickEvent tickEvent; 129 130 /// Schedule tick event, regardless of its current state. 131 void scheduleTickEvent(int numCycles) 132 { 133 if (tickEvent.squashed()) 134 tickEvent.reschedule(curTick + cycles(numCycles)); 135 else if (!tickEvent.scheduled()) 136 tickEvent.schedule(curTick + cycles(numCycles)); 137 } 138 139 /// Unschedule tick event, regardless of its current state. 140 void unscheduleTickEvent() 141 { 142 if (tickEvent.scheduled()) 143 tickEvent.squash(); 144 } 145 146 private: 147 Trace::InstRecord *traceData; 148 149 public: 150 // 151 enum Status { 152 Running, 153 Idle, 154 IcacheRetry, 155 IcacheWaitResponse, 156 IcacheAccessComplete, 157 DcacheRetry, 158 DcacheWaitResponse, 159 DcacheWaitSwitch, 160 SwitchedOut 161 }; 162 163 private: 164 Status _status; 165 166 public: 167 void post_interrupt(int int_num, int index); 168 169 void zero_fill_64(Addr addr) { 170 static int warned = 0; 171 if (!warned) { 172 warn ("WH64 is not implemented"); 173 warned = 1; 174 } 175 }; 176 177 public: 178 struct Params : public BaseCPU::Params 179 { 180 int width; 181#if FULL_SYSTEM 182 AlphaITB *itb; 183 AlphaDTB *dtb; 184#else 185 Memory *mem; 186 Process *process; 187#endif 188 }; 189 SimpleCPU(Params *params); 190 virtual ~SimpleCPU(); 191 192 public: 193 // execution context 194 CPUExecContext *cpuXC; 195 196 ExecContext *xcProxy; 197 198 void switchOut(Sampler *s); 199 void takeOverFrom(BaseCPU *oldCPU); 200 201#if FULL_SYSTEM 202 Addr dbg_vtophys(Addr addr); 203 204 bool interval_stats; 205#endif 206 207 // current instruction 208 MachInst inst; 209 210#if SIMPLE_CPU_MEM_TIMING 211 Packet *retry_pkt; 212#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE 213 CpuRequest *ifetch_req; 214 Packet *ifetch_pkt; 215 CpuRequest *data_read_req; 216 Packet *data_read_pkt; 217 CpuRequest *data_write_req; 218 Packet *data_write_pkt; 219#endif 220 221 // Pointer to the sampler that is telling us to switchover. 222 // Used to signal the completion of the pipe drain and schedule 223 // the next switchover 224 Sampler *sampler; 225 226 StaticInstPtr curStaticInst; 227 228 Status status() const { return _status; } 229 230 virtual void activateContext(int thread_num, int delay); 231 virtual void suspendContext(int thread_num); 232 virtual void deallocateContext(int thread_num); 233 virtual void haltContext(int thread_num); 234 235 // statistics 236 virtual void regStats(); 237 virtual void resetStats(); 238 239 // number of simulated instructions 240 Counter numInst; 241 Counter startNumInst; 242 Stats::Scalar<> numInsts; 243 244 virtual Counter totalInstructions() const 245 { 246 return numInst - startNumInst; 247 } 248 249 // number of simulated memory references 250 Stats::Scalar<> numMemRefs; 251 252 // number of simulated loads 253 Counter numLoad; 254 Counter startNumLoad; 255 256 // number of idle cycles 257 Stats::Average<> notIdleFraction; 258 Stats::Formula idleFraction; 259 260 // number of cycles stalled for I-cache responses 261 Stats::Scalar<> icacheStallCycles; 262 Counter lastIcacheStall; 263 264 // number of cycles stalled for I-cache retries 265 Stats::Scalar<> icacheRetryCycles; 266 Counter lastIcacheRetry; 267 268 // number of cycles stalled for D-cache responses 269 Stats::Scalar<> dcacheStallCycles; 270 Counter lastDcacheStall; 271 272 // number of cycles stalled for D-cache retries 273 Stats::Scalar<> dcacheRetryCycles; 274 Counter lastDcacheRetry; 275 276 void sendIcacheRequest(Packet *pkt); 277 void sendDcacheRequest(Packet *pkt); 278 void processResponse(Packet &response); 279 280 Packet * processRetry(); 281 void recvStatusChange(Port::Status status) {} 282 283 virtual void serialize(std::ostream &os); 284 virtual void unserialize(Checkpoint *cp, const std::string §ion); 285 286 template <class T> 287 Fault read(Addr addr, T &data, unsigned flags); 288 289 template <class T> 290 Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 291 292 // These functions are only used in CPU models that split 293 // effective address computation from the actual memory access. 294 void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 295 Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 296 297 void prefetch(Addr addr, unsigned flags) 298 { 299 // need to do this... 300 } 301 302 void writeHint(Addr addr, int size, unsigned flags) 303 { 304 // need to do this... 305 } 306 307 Fault copySrcTranslate(Addr src); 308 309 Fault copy(Addr dest); 310 311 // The register accessor methods provide the index of the 312 // instruction's operand (e.g., 0 or 1), not the architectural 313 // register index, to simplify the implementation of register 314 // renaming. We find the architectural register index by indexing 315 // into the instruction's own operand index table. Note that a 316 // raw pointer to the StaticInst is provided instead of a 317 // ref-counted StaticInstPtr to redice overhead. This is fine as 318 // long as these methods don't copy the pointer into any long-term 319 // storage (which is pretty hard to imagine they would have reason 320 // to do). 321 322 uint64_t readIntReg(const StaticInst *si, int idx) 323 { 324 return cpuXC->readIntReg(si->srcRegIdx(idx)); 325 } 326 327 FloatReg readFloatReg(const StaticInst *si, int idx, int width) 328 { 329 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 330 return cpuXC->readFloatReg(reg_idx, width); 331 } 332 333 FloatReg readFloatReg(const StaticInst *si, int idx) 334 { 335 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 336 return cpuXC->readFloatReg(reg_idx); 337 } 338 339 FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) 340 { 341 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 342 return cpuXC->readFloatRegBits(reg_idx, width); 343 } 344 345 FloatRegBits readFloatRegBits(const StaticInst *si, int idx) 346 { 347 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 348 return cpuXC->readFloatRegBits(reg_idx); 349 } 350 351 void setIntReg(const StaticInst *si, int idx, uint64_t val) 352 { 353 cpuXC->setIntReg(si->destRegIdx(idx), val); 354 } 355 356 void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) 357 { 358 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 359 cpuXC->setFloatReg(reg_idx, val, width); 360 } 361 362 void setFloatReg(const StaticInst *si, int idx, FloatReg val) 363 { 364 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 365 cpuXC->setFloatReg(reg_idx, val); 366 } 367 368 void setFloatRegBits(const StaticInst *si, int idx, 369 FloatRegBits val, int width) 370 { 371 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 372 cpuXC->setFloatRegBits(reg_idx, val, width); 373 } 374 375 void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) 376 { 377 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 378 cpuXC->setFloatRegBits(reg_idx, val); 379 } 380 381 uint64_t readPC() { return cpuXC->readPC(); } 382 uint64_t readNextPC() { return cpuXC->readNextPC(); } 383 uint64_t readNextNPC() { return cpuXC->readNextNPC(); } 384 385 void setPC(uint64_t val) { cpuXC->setPC(val); } 386 void setNextPC(uint64_t val) { cpuXC->setNextPC(val); } 387 void setNextNPC(uint64_t val) { cpuXC->setNextNPC(val); } 388 389 MiscReg readMiscReg(int misc_reg) 390 { 391 return cpuXC->readMiscReg(misc_reg); 392 } 393 394 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 395 { 396 return cpuXC->readMiscRegWithEffect(misc_reg, fault); 397 } 398 399 Fault setMiscReg(int misc_reg, const MiscReg &val) 400 { 401 return cpuXC->setMiscReg(misc_reg, val); 402 } 403 404 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 405 { 406 return cpuXC->setMiscRegWithEffect(misc_reg, val); 407 } 408 409#if FULL_SYSTEM 410 Fault hwrei() { return cpuXC->hwrei(); } 411 int readIntrFlag() { return cpuXC->readIntrFlag(); } 412 void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } 413 bool inPalMode() { return cpuXC->inPalMode(); } 414 void ev5_trap(Fault fault) { fault->invoke(xcProxy); } 415 bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } 416#else 417 void syscall() { cpuXC->syscall(); } 418#endif 419 420 bool misspeculating() { return cpuXC->misspeculating(); } 421 ExecContext *xcBase() { return xcProxy; } 422}; 423 424#endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 425