base.hh revision 5543
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 292665Ssaidi@eecs.umich.edu * Dave Greene 302SN/A * Nathan Binkert 312SN/A */ 322SN/A 332SN/A#ifndef __CPU_SIMPLE_BASE_HH__ 342SN/A#define __CPU_SIMPLE_BASE_HH__ 352SN/A 362SN/A#include "arch/predecoder.hh" 372432SN/A#include "base/statistics.hh" 381147SN/A#include "config/full_system.hh" 393453Sgblack@eecs.umich.edu#include "cpu/base.hh" 402984Sgblack@eecs.umich.edu#include "cpu/simple_thread.hh" 412984Sgblack@eecs.umich.edu#include "cpu/pc_event.hh" 421147SN/A#include "cpu/static_inst.hh" 432517SN/A#include "mem/packet.hh" 442984Sgblack@eecs.umich.edu#include "mem/port.hh" 4556SN/A#include "mem/request.hh" 462SN/A#include "sim/eventq.hh" 472680Sktlim@umich.edu#include "sim/system.hh" 482SN/A 493453Sgblack@eecs.umich.edu// forward declarations 502SN/A#if FULL_SYSTEM 513453Sgblack@eecs.umich.educlass Processor; 522SN/Anamespace TheISA 533453Sgblack@eecs.umich.edu{ 543453Sgblack@eecs.umich.edu class ITB; 553453Sgblack@eecs.umich.edu class DTB; 563453Sgblack@eecs.umich.edu} 573453Sgblack@eecs.umich.educlass MemObject; 582SN/A 593453Sgblack@eecs.umich.edu#else 603453Sgblack@eecs.umich.edu 613453Sgblack@eecs.umich.educlass Process; 622SN/A 633453Sgblack@eecs.umich.edu#endif // FULL_SYSTEM 643453Sgblack@eecs.umich.edu 652SN/Aclass RemoteGDB; 663453Sgblack@eecs.umich.educlass GDBListener; 673453Sgblack@eecs.umich.edu 683453Sgblack@eecs.umich.edunamespace TheISA 692SN/A{ 703453Sgblack@eecs.umich.edu class Predecoder; 712SN/A} 723453Sgblack@eecs.umich.educlass ThreadContext; 733453Sgblack@eecs.umich.educlass Checkpoint; 742SN/A 753453Sgblack@eecs.umich.edunamespace Trace { 763453Sgblack@eecs.umich.edu class InstRecord; 773453Sgblack@eecs.umich.edu} 782SN/A 793453Sgblack@eecs.umich.educlass BaseSimpleCPUParams; 803453Sgblack@eecs.umich.edu 813453Sgblack@eecs.umich.edu 823453Sgblack@eecs.umich.educlass BaseSimpleCPU : public BaseCPU 833453Sgblack@eecs.umich.edu{ 843453Sgblack@eecs.umich.edu protected: 852SN/A typedef TheISA::MiscReg MiscReg; 863453Sgblack@eecs.umich.edu typedef TheISA::FloatReg FloatReg; 872SN/A typedef TheISA::FloatRegBits FloatRegBits; 883453Sgblack@eecs.umich.edu 893453Sgblack@eecs.umich.edu protected: 903453Sgblack@eecs.umich.edu Trace::InstRecord *traceData; 914957Sacolyte@umich.edu 924957Sacolyte@umich.edu inline void checkPcEventQueue() { 934960Sgblack@eecs.umich.edu Addr oldpc; 944960Sgblack@eecs.umich.edu do { 953453Sgblack@eecs.umich.edu oldpc = thread->readPC(); 962SN/A system->pcEventQueue.service(tc); 973453Sgblack@eecs.umich.edu } while (oldpc != thread->readPC()); 983453Sgblack@eecs.umich.edu } 993453Sgblack@eecs.umich.edu 1003453Sgblack@eecs.umich.edu public: 1013453Sgblack@eecs.umich.edu void post_interrupt(int int_num, int index); 1023453Sgblack@eecs.umich.edu 1033453Sgblack@eecs.umich.edu void zero_fill_64(Addr addr) { 1042SN/A static int warned = 0; 1053453Sgblack@eecs.umich.edu if (!warned) { 1063453Sgblack@eecs.umich.edu warn ("WH64 is not implemented"); 1073453Sgblack@eecs.umich.edu warned = 1; 1082SN/A } 1093453Sgblack@eecs.umich.edu }; 1103453Sgblack@eecs.umich.edu 1112SN/A public: 1123453Sgblack@eecs.umich.edu BaseSimpleCPU(BaseSimpleCPUParams *params); 1133453Sgblack@eecs.umich.edu virtual ~BaseSimpleCPU(); 1143453Sgblack@eecs.umich.edu 1153453Sgblack@eecs.umich.edu public: 1163453Sgblack@eecs.umich.edu /** SimpleThread object, provides all the architectural state. */ 1173453Sgblack@eecs.umich.edu SimpleThread *thread; 1183453Sgblack@eecs.umich.edu 1193453Sgblack@eecs.umich.edu /** ThreadContext object, provides an interface for external 1203453Sgblack@eecs.umich.edu * objects to modify this thread's state. 1213453Sgblack@eecs.umich.edu */ 1223453Sgblack@eecs.umich.edu ThreadContext *tc; 1233453Sgblack@eecs.umich.edu protected: 1243453Sgblack@eecs.umich.edu int cpuId; 1253453Sgblack@eecs.umich.edu 1263453Sgblack@eecs.umich.edu enum Status { 1272SN/A Idle, 1283453Sgblack@eecs.umich.edu Running, 1293453Sgblack@eecs.umich.edu IcacheRetry, 1303453Sgblack@eecs.umich.edu IcacheWaitResponse, 1313453Sgblack@eecs.umich.edu IcacheWaitSwitch, 1323453Sgblack@eecs.umich.edu DcacheRetry, 1333453Sgblack@eecs.umich.edu DcacheWaitResponse, 1343453Sgblack@eecs.umich.edu DcacheWaitSwitch, 1352SN/A SwitchedOut 1362SN/A }; 137 138 Status _status; 139 140 public: 141 142#if FULL_SYSTEM 143 Addr dbg_vtophys(Addr addr); 144 145 bool interval_stats; 146#endif 147 148 // current instruction 149 TheISA::MachInst inst; 150 151 // The predecoder 152 TheISA::Predecoder predecoder; 153 154 StaticInstPtr curStaticInst; 155 StaticInstPtr curMacroStaticInst; 156 157 //This is the offset from the current pc that fetch should be performed at 158 Addr fetchOffset; 159 //This flag says to stay at the current pc. This is useful for 160 //instructions which go beyond MachInst boundaries. 161 bool stayAtPC; 162 163 void checkForInterrupts(); 164 Fault setupFetchRequest(Request *req); 165 void preExecute(); 166 void postExecute(); 167 void advancePC(Fault fault); 168 169 virtual void deallocateContext(int thread_num); 170 virtual void haltContext(int thread_num); 171 172 // statistics 173 virtual void regStats(); 174 virtual void resetStats(); 175 176 // number of simulated instructions 177 Counter numInst; 178 Counter startNumInst; 179 Stats::Scalar<> numInsts; 180 181 void countInst() 182 { 183 numInst++; 184 numInsts++; 185 186 thread->funcExeInst++; 187 } 188 189 virtual Counter totalInstructions() const 190 { 191 return numInst - startNumInst; 192 } 193 194 // Mask to align PCs to MachInst sized boundaries 195 static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1); 196 197 // number of simulated memory references 198 Stats::Scalar<> numMemRefs; 199 200 // number of simulated loads 201 Counter numLoad; 202 Counter startNumLoad; 203 204 // number of idle cycles 205 Stats::Average<> notIdleFraction; 206 Stats::Formula idleFraction; 207 208 // number of cycles stalled for I-cache responses 209 Stats::Scalar<> icacheStallCycles; 210 Counter lastIcacheStall; 211 212 // number of cycles stalled for I-cache retries 213 Stats::Scalar<> icacheRetryCycles; 214 Counter lastIcacheRetry; 215 216 // number of cycles stalled for D-cache responses 217 Stats::Scalar<> dcacheStallCycles; 218 Counter lastDcacheStall; 219 220 // number of cycles stalled for D-cache retries 221 Stats::Scalar<> dcacheRetryCycles; 222 Counter lastDcacheRetry; 223 224 virtual void serialize(std::ostream &os); 225 virtual void unserialize(Checkpoint *cp, const std::string §ion); 226 227 // These functions are only used in CPU models that split 228 // effective address computation from the actual memory access. 229 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); } 230 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); 231 M5_DUMMY_RETURN} 232 233 void prefetch(Addr addr, unsigned flags) 234 { 235 // need to do this... 236 } 237 238 void writeHint(Addr addr, int size, unsigned flags) 239 { 240 // need to do this... 241 } 242 243 244 Fault copySrcTranslate(Addr src); 245 246 Fault copy(Addr dest); 247 248 // The register accessor methods provide the index of the 249 // instruction's operand (e.g., 0 or 1), not the architectural 250 // register index, to simplify the implementation of register 251 // renaming. We find the architectural register index by indexing 252 // into the instruction's own operand index table. Note that a 253 // raw pointer to the StaticInst is provided instead of a 254 // ref-counted StaticInstPtr to redice overhead. This is fine as 255 // long as these methods don't copy the pointer into any long-term 256 // storage (which is pretty hard to imagine they would have reason 257 // to do). 258 259 uint64_t readIntRegOperand(const StaticInst *si, int idx) 260 { 261 return thread->readIntReg(si->srcRegIdx(idx)); 262 } 263 264 FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width) 265 { 266 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 267 return thread->readFloatReg(reg_idx, width); 268 } 269 270 FloatReg readFloatRegOperand(const StaticInst *si, int idx) 271 { 272 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 273 return thread->readFloatReg(reg_idx); 274 } 275 276 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, 277 int width) 278 { 279 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 280 return thread->readFloatRegBits(reg_idx, width); 281 } 282 283 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) 284 { 285 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 286 return thread->readFloatRegBits(reg_idx); 287 } 288 289 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 290 { 291 thread->setIntReg(si->destRegIdx(idx), val); 292 } 293 294 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, 295 int width) 296 { 297 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 298 thread->setFloatReg(reg_idx, val, width); 299 } 300 301 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 302 { 303 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 304 thread->setFloatReg(reg_idx, val); 305 } 306 307 void setFloatRegOperandBits(const StaticInst *si, int idx, 308 FloatRegBits val, int width) 309 { 310 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 311 thread->setFloatRegBits(reg_idx, val, width); 312 } 313 314 void setFloatRegOperandBits(const StaticInst *si, int idx, 315 FloatRegBits val) 316 { 317 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 318 thread->setFloatRegBits(reg_idx, val); 319 } 320 321 uint64_t readPC() { return thread->readPC(); } 322 uint64_t readMicroPC() { return thread->readMicroPC(); } 323 uint64_t readNextPC() { return thread->readNextPC(); } 324 uint64_t readNextMicroPC() { return thread->readNextMicroPC(); } 325 uint64_t readNextNPC() { return thread->readNextNPC(); } 326 327 void setPC(uint64_t val) { thread->setPC(val); } 328 void setMicroPC(uint64_t val) { thread->setMicroPC(val); } 329 void setNextPC(uint64_t val) { thread->setNextPC(val); } 330 void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); } 331 void setNextNPC(uint64_t val) { thread->setNextNPC(val); } 332 333 MiscReg readMiscRegNoEffect(int misc_reg) 334 { 335 return thread->readMiscRegNoEffect(misc_reg); 336 } 337 338 MiscReg readMiscReg(int misc_reg) 339 { 340 return thread->readMiscReg(misc_reg); 341 } 342 343 void setMiscRegNoEffect(int misc_reg, const MiscReg &val) 344 { 345 return thread->setMiscRegNoEffect(misc_reg, val); 346 } 347 348 void setMiscReg(int misc_reg, const MiscReg &val) 349 { 350 return thread->setMiscReg(misc_reg, val); 351 } 352 353 MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx) 354 { 355 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 356 return thread->readMiscRegNoEffect(reg_idx); 357 } 358 359 MiscReg readMiscRegOperand(const StaticInst *si, int idx) 360 { 361 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 362 return thread->readMiscReg(reg_idx); 363 } 364 365 void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val) 366 { 367 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 368 return thread->setMiscRegNoEffect(reg_idx, val); 369 } 370 371 void setMiscRegOperand( 372 const StaticInst *si, int idx, const MiscReg &val) 373 { 374 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 375 return thread->setMiscReg(reg_idx, val); 376 } 377 378 void demapPage(Addr vaddr, uint64_t asn) 379 { 380 thread->demapPage(vaddr, asn); 381 } 382 383 void demapInstPage(Addr vaddr, uint64_t asn) 384 { 385 thread->demapInstPage(vaddr, asn); 386 } 387 388 void demapDataPage(Addr vaddr, uint64_t asn) 389 { 390 thread->demapDataPage(vaddr, asn); 391 } 392 393 unsigned readStCondFailures() { 394 return thread->readStCondFailures(); 395 } 396 397 void setStCondFailures(unsigned sc_failures) { 398 thread->setStCondFailures(sc_failures); 399 } 400 401 MiscReg readRegOtherThread(int regIdx, int tid = -1) 402 { 403 panic("Simple CPU models do not support multithreaded " 404 "register access.\n"); 405 } 406 407 void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1) 408 { 409 panic("Simple CPU models do not support multithreaded " 410 "register access.\n"); 411 } 412 413 //Fault CacheOp(uint8_t Op, Addr EA); 414 415#if FULL_SYSTEM 416 Fault hwrei() { return thread->hwrei(); } 417 void ev5_trap(Fault fault) { fault->invoke(tc); } 418 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 419#else 420 void syscall(int64_t callnum) { thread->syscall(callnum); } 421#endif 422 423 bool misspeculating() { return thread->misspeculating(); } 424 ThreadContext *tcBase() { return tc; } 425}; 426 427#endif // __CPU_SIMPLE_BASE_HH__ 428