base.hh revision 7664:487916d36377
12131SN/A/* 22131SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32131SN/A * All rights reserved. 42131SN/A * 52131SN/A * Redistribution and use in source and binary forms, with or without 62131SN/A * modification, are permitted provided that the following conditions are 72131SN/A * met: redistributions of source code must retain the above copyright 82131SN/A * notice, this list of conditions and the following disclaimer; 92131SN/A * redistributions in binary form must reproduce the above copyright 102131SN/A * notice, this list of conditions and the following disclaimer in the 112131SN/A * documentation and/or other materials provided with the distribution; 122131SN/A * neither the name of the copyright holders nor the names of its 132131SN/A * contributors may be used to endorse or promote products derived from 142131SN/A * this software without specific prior written permission. 152131SN/A * 162131SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172131SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182131SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192131SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202131SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212131SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222131SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232131SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242131SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252131SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262131SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 292131SN/A * Dave Greene 302131SN/A * Nathan Binkert 312239SN/A */ 322680Sktlim@umich.edu 332447SN/A#ifndef __CPU_SIMPLE_BASE_HH__ 342447SN/A#define __CPU_SIMPLE_BASE_HH__ 352131SN/A 362447SN/A#include "arch/predecoder.hh" 372447SN/A#include "base/statistics.hh" 382131SN/A#include "config/full_system.hh" 392479SN/A#include "config/the_isa.hh" 402447SN/A#include "cpu/base.hh" 412447SN/A#include "cpu/simple_thread.hh" 422131SN/A#include "cpu/pc_event.hh" 432479SN/A#include "cpu/static_inst.hh" 442447SN/A#include "mem/packet.hh" 452447SN/A#include "mem/port.hh" 462447SN/A#include "mem/request.hh" 472447SN/A#include "sim/eventq.hh" 482447SN/A#include "sim/system.hh" 492447SN/A 502447SN/A// forward declarations 512447SN/A#if FULL_SYSTEM 522447SN/Aclass Processor; 532447SN/Anamespace TheISA 542447SN/A{ 552447SN/A class ITB; 562447SN/A class DTB; 572447SN/A} 582447SN/Aclass MemObject; 592447SN/A 602447SN/A#else 612447SN/A 622447SN/Aclass Process; 632447SN/A 642447SN/A#endif // FULL_SYSTEM 652447SN/A 662447SN/Anamespace TheISA 672447SN/A{ 682447SN/A class Predecoder; 692447SN/A} 702447SN/Aclass ThreadContext; 712447SN/Aclass Checkpoint; 722447SN/A 732447SN/Anamespace Trace { 742447SN/A class InstRecord; 752447SN/A} 762447SN/A 772447SN/Aclass BaseSimpleCPUParams; 782447SN/A 792447SN/A 802447SN/Aclass BaseSimpleCPU : public BaseCPU 812447SN/A{ 822447SN/A protected: 832447SN/A typedef TheISA::MiscReg MiscReg; 842447SN/A typedef TheISA::FloatReg FloatReg; 852447SN/A typedef TheISA::FloatRegBits FloatRegBits; 862447SN/A 872447SN/A protected: 882447SN/A Trace::InstRecord *traceData; 892447SN/A 902447SN/A inline void checkPcEventQueue() { 912447SN/A Addr oldpc; 922447SN/A do { 932447SN/A oldpc = thread->readPC(); 942447SN/A system->pcEventQueue.service(tc); 952447SN/A } while (oldpc != thread->readPC()); 962447SN/A } 972447SN/A 982447SN/A public: 992447SN/A void wakeup(); 1002447SN/A 1012447SN/A void zero_fill_64(Addr addr) { 1022447SN/A static int warned = 0; 1032447SN/A if (!warned) { 1042447SN/A warn ("WH64 is not implemented"); 1052680Sktlim@umich.edu warned = 1; 1062447SN/A } 1072680Sktlim@umich.edu }; 1082447SN/A 1092447SN/A public: 1102447SN/A BaseSimpleCPU(BaseSimpleCPUParams *params); 1112680Sktlim@umich.edu virtual ~BaseSimpleCPU(); 1122680Sktlim@umich.edu 1132447SN/A public: 1142447SN/A /** SimpleThread object, provides all the architectural state. */ 1152447SN/A SimpleThread *thread; 1162680Sktlim@umich.edu 1172680Sktlim@umich.edu /** ThreadContext object, provides an interface for external 1182447SN/A * objects to modify this thread's state. 1192447SN/A */ 1202680Sktlim@umich.edu ThreadContext *tc; 1212680Sktlim@umich.edu protected: 1222447SN/A 1232447SN/A enum Status { 1242680Sktlim@umich.edu Idle, 1252447SN/A Running, 1262680Sktlim@umich.edu ITBWaitResponse, 1272447SN/A IcacheRetry, 1282447SN/A IcacheWaitResponse, 1292447SN/A IcacheWaitSwitch, 1302447SN/A DTBWaitResponse, 1312447SN/A DcacheRetry, 1322447SN/A DcacheWaitResponse, 1332447SN/A DcacheWaitSwitch, 134 SwitchedOut 135 }; 136 137 Status _status; 138 139 public: 140 141#if FULL_SYSTEM 142 Addr dbg_vtophys(Addr addr); 143 144 bool interval_stats; 145#endif 146 147 // current instruction 148 TheISA::MachInst inst; 149 150 // The predecoder 151 TheISA::Predecoder predecoder; 152 153 StaticInstPtr curStaticInst; 154 StaticInstPtr curMacroStaticInst; 155 156 //This is the offset from the current pc that fetch should be performed at 157 Addr fetchOffset; 158 //This flag says to stay at the current pc. This is useful for 159 //instructions which go beyond MachInst boundaries. 160 bool stayAtPC; 161 162 void checkForInterrupts(); 163 void setupFetchRequest(Request *req); 164 void preExecute(); 165 void postExecute(); 166 void advancePC(Fault fault); 167 168 virtual void deallocateContext(int thread_num); 169 virtual void haltContext(int thread_num); 170 171 // statistics 172 virtual void regStats(); 173 virtual void resetStats(); 174 175 // number of simulated instructions 176 Counter numInst; 177 Counter startNumInst; 178 Stats::Scalar numInsts; 179 180 void countInst() 181 { 182 numInst++; 183 numInsts++; 184 185 thread->funcExeInst++; 186 } 187 188 virtual Counter totalInstructions() const 189 { 190 return numInst - startNumInst; 191 } 192 193 // Mask to align PCs to MachInst sized boundaries 194 static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1); 195 196 // number of simulated memory references 197 Stats::Scalar numMemRefs; 198 199 // number of simulated loads 200 Counter numLoad; 201 Counter startNumLoad; 202 203 // number of idle cycles 204 Stats::Average notIdleFraction; 205 Stats::Formula idleFraction; 206 207 // number of cycles stalled for I-cache responses 208 Stats::Scalar icacheStallCycles; 209 Counter lastIcacheStall; 210 211 // number of cycles stalled for I-cache retries 212 Stats::Scalar icacheRetryCycles; 213 Counter lastIcacheRetry; 214 215 // number of cycles stalled for D-cache responses 216 Stats::Scalar dcacheStallCycles; 217 Counter lastDcacheStall; 218 219 // number of cycles stalled for D-cache retries 220 Stats::Scalar dcacheRetryCycles; 221 Counter lastDcacheRetry; 222 223 virtual void serialize(std::ostream &os); 224 virtual void unserialize(Checkpoint *cp, const std::string §ion); 225 226 // These functions are only used in CPU models that split 227 // effective address computation from the actual memory access. 228 void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); } 229 Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); 230 M5_DUMMY_RETURN} 231 232 void prefetch(Addr addr, unsigned flags); 233 void writeHint(Addr addr, int size, unsigned flags); 234 235 Fault copySrcTranslate(Addr src); 236 237 Fault copy(Addr dest); 238 239 // The register accessor methods provide the index of the 240 // instruction's operand (e.g., 0 or 1), not the architectural 241 // register index, to simplify the implementation of register 242 // renaming. We find the architectural register index by indexing 243 // into the instruction's own operand index table. Note that a 244 // raw pointer to the StaticInst is provided instead of a 245 // ref-counted StaticInstPtr to redice overhead. This is fine as 246 // long as these methods don't copy the pointer into any long-term 247 // storage (which is pretty hard to imagine they would have reason 248 // to do). 249 250 uint64_t readIntRegOperand(const StaticInst *si, int idx) 251 { 252 return thread->readIntReg(si->srcRegIdx(idx)); 253 } 254 255 FloatReg readFloatRegOperand(const StaticInst *si, int idx) 256 { 257 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 258 return thread->readFloatReg(reg_idx); 259 } 260 261 FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) 262 { 263 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 264 return thread->readFloatRegBits(reg_idx); 265 } 266 267 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 268 { 269 thread->setIntReg(si->destRegIdx(idx), val); 270 } 271 272 void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 273 { 274 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 275 thread->setFloatReg(reg_idx, val); 276 } 277 278 void setFloatRegOperandBits(const StaticInst *si, int idx, 279 FloatRegBits val) 280 { 281 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 282 thread->setFloatRegBits(reg_idx, val); 283 } 284 285 uint64_t readPC() { return thread->readPC(); } 286 uint64_t readMicroPC() { return thread->readMicroPC(); } 287 uint64_t readNextPC() { return thread->readNextPC(); } 288 uint64_t readNextMicroPC() { return thread->readNextMicroPC(); } 289 uint64_t readNextNPC() { return thread->readNextNPC(); } 290 bool readPredicate() { return thread->readPredicate(); } 291 292 void setPC(uint64_t val) { thread->setPC(val); } 293 void setMicroPC(uint64_t val) { thread->setMicroPC(val); } 294 void setNextPC(uint64_t val) { thread->setNextPC(val); } 295 void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); } 296 void setNextNPC(uint64_t val) { thread->setNextNPC(val); } 297 void setPredicate(bool val) 298 { 299 thread->setPredicate(val); 300 if (traceData) { 301 traceData->setPredicate(val); 302 } 303 } 304 305 MiscReg readMiscRegNoEffect(int misc_reg) 306 { 307 return thread->readMiscRegNoEffect(misc_reg); 308 } 309 310 MiscReg readMiscReg(int misc_reg) 311 { 312 return thread->readMiscReg(misc_reg); 313 } 314 315 void setMiscRegNoEffect(int misc_reg, const MiscReg &val) 316 { 317 return thread->setMiscRegNoEffect(misc_reg, val); 318 } 319 320 void setMiscReg(int misc_reg, const MiscReg &val) 321 { 322 return thread->setMiscReg(misc_reg, val); 323 } 324 325 MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx) 326 { 327 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 328 return thread->readMiscRegNoEffect(reg_idx); 329 } 330 331 MiscReg readMiscRegOperand(const StaticInst *si, int idx) 332 { 333 int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 334 return thread->readMiscReg(reg_idx); 335 } 336 337 void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val) 338 { 339 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 340 return thread->setMiscRegNoEffect(reg_idx, val); 341 } 342 343 void setMiscRegOperand( 344 const StaticInst *si, int idx, const MiscReg &val) 345 { 346 int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; 347 return thread->setMiscReg(reg_idx, val); 348 } 349 350 void demapPage(Addr vaddr, uint64_t asn) 351 { 352 thread->demapPage(vaddr, asn); 353 } 354 355 void demapInstPage(Addr vaddr, uint64_t asn) 356 { 357 thread->demapInstPage(vaddr, asn); 358 } 359 360 void demapDataPage(Addr vaddr, uint64_t asn) 361 { 362 thread->demapDataPage(vaddr, asn); 363 } 364 365 unsigned readStCondFailures() { 366 return thread->readStCondFailures(); 367 } 368 369 void setStCondFailures(unsigned sc_failures) { 370 thread->setStCondFailures(sc_failures); 371 } 372 373 MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID) 374 { 375 panic("Simple CPU models do not support multithreaded " 376 "register access.\n"); 377 } 378 379 void setRegOtherThread(int regIdx, const MiscReg &val, 380 ThreadID tid = InvalidThreadID) 381 { 382 panic("Simple CPU models do not support multithreaded " 383 "register access.\n"); 384 } 385 386 //Fault CacheOp(uint8_t Op, Addr EA); 387 388#if FULL_SYSTEM 389 Fault hwrei() { return thread->hwrei(); } 390 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 391#else 392 void syscall(int64_t callnum) { thread->syscall(callnum); } 393#endif 394 395 bool misspeculating() { return thread->misspeculating(); } 396 ThreadContext *tcBase() { return tc; } 397}; 398 399#endif // __CPU_SIMPLE_BASE_HH__ 400