base.hh revision 4950
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. 272SN/A * 282SN/A * Authors: Steve Reinhardt 292623SN/A * Dave Greene 302623SN/A * Nathan Binkert 312SN/A */ 321354SN/A 331858SN/A#ifndef __CPU_SIMPLE_BASE_HH__ 341717SN/A#define __CPU_SIMPLE_BASE_HH__ 352190SN/A 361354SN/A#include "arch/predecoder.hh" 371717SN/A#include "base/statistics.hh" 381354SN/A#include "config/full_system.hh" 392387SN/A#include "cpu/base.hh" 402387SN/A#include "cpu/simple_thread.hh" 412387SN/A#include "cpu/pc_event.hh" 4256SN/A#include "cpu/static_inst.hh" 432SN/A#include "mem/packet.hh" 442SN/A#include "mem/port.hh" 451858SN/A#include "mem/request.hh" 462SN/A#include "sim/eventq.hh" 47676SN/A 48676SN/A// forward declarations 492462SN/A#if FULL_SYSTEM 502SN/Aclass Processor; 512SN/Anamespace TheISA 522SN/A{ 53715SN/A class ITB; 54715SN/A class DTB; 55715SN/A} 56715SN/Aclass MemObject; 57715SN/A 582SN/A#else 592SN/A 602190SN/Aclass Process; 61237SN/A 622SN/A#endif // FULL_SYSTEM 632SN/A 642SN/Aclass RemoteGDB; 652SN/Aclass GDBListener; 662SN/A 672420SN/Anamespace TheISA 682623SN/A{ 692SN/A class Predecoder; 702107SN/A} 712107SN/Aclass ThreadContext; 722159SN/Aclass Checkpoint; 732455SN/A 742455SN/Anamespace Trace { 752386SN/A class InstRecord; 762499SN/A} 772386SN/A 782623SN/A 792SN/Aclass BaseSimpleCPU : public BaseCPU 801371SN/A{ 812SN/A protected: 822SN/A typedef TheISA::MiscReg MiscReg; 832SN/A typedef TheISA::FloatReg FloatReg; 842SN/A typedef TheISA::FloatRegBits FloatRegBits; 852SN/A 862SN/A protected: 872SN/A Trace::InstRecord *traceData; 882SN/A 892SN/A public: 902SN/A void post_interrupt(int int_num, int index); 912SN/A 921400SN/A void zero_fill_64(Addr addr) { 931400SN/A static int warned = 0; 941400SN/A if (!warned) { 952542SN/A warn ("WH64 is not implemented"); 961858SN/A warned = 1; 971400SN/A } 981400SN/A }; 992SN/A 1001400SN/A public: 1012SN/A struct Params : public BaseCPU::Params 1021400SN/A { 1032623SN/A#if FULL_SYSTEM 1042623SN/A TheISA::ITB *itb; 1052SN/A TheISA::DTB *dtb; 1061400SN/A#else 1072SN/A Process *process; 1082190SN/A#endif 1092190SN/A }; 1102190SN/A BaseSimpleCPU(Params *params); 1112SN/A virtual ~BaseSimpleCPU(); 1121858SN/A 1132SN/A public: 1142SN/A /** SimpleThread object, provides all the architectural state. */ 1152SN/A SimpleThread *thread; 1162SN/A 1172SN/A /** ThreadContext object, provides an interface for external 1182SN/A * objects to modify this thread's state. 1192SN/A */ 1202SN/A ThreadContext *tc; 1212566SN/A 1222566SN/A#if FULL_SYSTEM 1232566SN/A Addr dbg_vtophys(Addr addr); 1241492SN/A 1251492SN/A bool interval_stats; 1261492SN/A#endif 1271752SN/A 1281492SN/A // current instruction 1292107SN/A TheISA::MachInst inst; 1301469SN/A 1312623SN/A // The predecoder 1322662Sstever@eecs.umich.edu TheISA::Predecoder predecoder; 1332623SN/A 1342623SN/A StaticInstPtr curStaticInst; 1352623SN/A StaticInstPtr curMacroStaticInst; 136180SN/A 137393SN/A //This is the offset from the current pc that fetch should be performed at 138393SN/A Addr fetchOffset; 1392SN/A //This flag says to stay at the current pc. This is useful for 1402SN/A //instructions which go beyond MachInst boundaries. 141334SN/A bool stayAtPC; 142334SN/A 1432SN/A void checkForInterrupts(); 1442SN/A Fault setupFetchRequest(Request *req); 1452SN/A void preExecute(); 146334SN/A void postExecute(); 147729SN/A void advancePC(Fault fault); 148707SN/A 149707SN/A virtual void deallocateContext(int thread_num); 150707SN/A virtual void haltContext(int thread_num); 151707SN/A 152707SN/A // statistics 1532SN/A virtual void regStats(); 1542SN/A virtual void resetStats(); 155729SN/A 1562SN/A // number of simulated instructions 157124SN/A Counter numInst; 158124SN/A Counter startNumInst; 159334SN/A Stats::Scalar<> numInsts; 160124SN/A 1612SN/A virtual Counter totalInstructions() const 162729SN/A { 163729SN/A return numInst - startNumInst; 1642SN/A } 1652390SN/A 166729SN/A // Mask to align PCs to MachInst sized boundaries 1672SN/A static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1); 1682SN/A 1692390SN/A // number of simulated memory references 1702390SN/A Stats::Scalar<> numMemRefs; 1712390SN/A 1722390SN/A // number of simulated loads 1732390SN/A Counter numLoad; 174729SN/A Counter startNumLoad; 1752SN/A 1762SN/A // number of idle cycles 1772390SN/A Stats::Average<> notIdleFraction; 1782390SN/A Stats::Formula idleFraction; 1792390SN/A 1802390SN/A // number of cycles stalled for I-cache responses 181217SN/A Stats::Scalar<> icacheStallCycles; 182237SN/A Counter lastIcacheStall; 1832SN/A 1841371SN/A // number of cycles stalled for I-cache retries 1851371SN/A Stats::Scalar<> icacheRetryCycles; 1862623SN/A Counter lastIcacheRetry; 1872623SN/A 1881371SN/A // number of cycles stalled for D-cache responses 189581SN/A Stats::Scalar<> dcacheStallCycles; 1902SN/A Counter lastDcacheStall; 1912SN/A 1922SN/A // number of cycles stalled for D-cache retries 1932SN/A Stats::Scalar<> dcacheRetryCycles; 194753SN/A Counter lastDcacheRetry; 1952SN/A 1962SN/A virtual void serialize(std::ostream &os); 1972SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 198594SN/A 199595SN/A // These functions are only used in CPU models that split 200594SN/A // effective address computation from the actual memory access. 201595SN/A void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); } 202705SN/A Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n"); 203726SN/A M5_DUMMY_RETURN} 204726SN/A 205726SN/A void prefetch(Addr addr, unsigned flags) 206726SN/A { 207726SN/A // need to do this... 208726SN/A } 209726SN/A 210726SN/A void writeHint(Addr addr, int size, unsigned flags) 211726SN/A { 212726SN/A // need to do this... 213705SN/A } 2142107SN/A 215726SN/A 2162190SN/A Fault copySrcTranslate(Addr src); 217726SN/A 218705SN/A Fault copy(Addr dest); 2192455SN/A 220726SN/A // The register accessor methods provide the index of the 221726SN/A // instruction's operand (e.g., 0 or 1), not the architectural 2222455SN/A // register index, to simplify the implementation of register 223726SN/A // renaming. We find the architectural register index by indexing 224705SN/A // into the instruction's own operand index table. Note that a 2252455SN/A // raw pointer to the StaticInst is provided instead of a 226726SN/A // ref-counted StaticInstPtr to redice overhead. This is fine as 227726SN/A // long as these methods don't copy the pointer into any long-term 2282455SN/A // storage (which is pretty hard to imagine they would have reason 229726SN/A // to do). 230705SN/A 2312455SN/A uint64_t readIntRegOperand(const StaticInst *si, int idx) 232726SN/A { 233726SN/A return thread->readIntReg(si->srcRegIdx(idx)); 2342455SN/A } 2352455SN/A 2362455SN/A FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width) 2372455SN/A { 2382455SN/A int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 2392455SN/A return thread->readFloatReg(reg_idx, width); 2402455SN/A } 241726SN/A 242705SN/A FloatReg readFloatRegOperand(const StaticInst *si, int idx) 2432107SN/A { 244726SN/A int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 2452190SN/A return thread->readFloatReg(reg_idx); 246726SN/A } 247705SN/A 2482455SN/A FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx, 249726SN/A int width) 250726SN/A { 2512455SN/A int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 252726SN/A return thread->readFloatRegBits(reg_idx, width); 253705SN/A } 2542455SN/A 255726SN/A FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) 256726SN/A { 2572455SN/A int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 258726SN/A return thread->readFloatRegBits(reg_idx); 259726SN/A } 2602455SN/A 2612577SN/A void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) 262726SN/A { 263726SN/A thread->setIntReg(si->destRegIdx(idx), val); 2642455SN/A } 2652455SN/A 2662455SN/A void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val, 2672455SN/A int width) 2682455SN/A { 2692455SN/A int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 2702455SN/A thread->setFloatReg(reg_idx, val, width); 271726SN/A } 272705SN/A 2732190SN/A void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) 2742447SN/A { 2752447SN/A int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 2762447SN/A thread->setFloatReg(reg_idx, val); 2772447SN/A } 2782190SN/A 2792447SN/A void setFloatRegOperandBits(const StaticInst *si, int idx, 280705SN/A FloatRegBits val, int width) 2812159SN/A { 2822159SN/A int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 2832190SN/A thread->setFloatRegBits(reg_idx, val, width); 2842159SN/A } 285705SN/A 2862159SN/A void setFloatRegOperandBits(const StaticInst *si, int idx, 2872159SN/A FloatRegBits val) 2882190SN/A { 2892159SN/A int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 2902159SN/A thread->setFloatRegBits(reg_idx, val); 2912159SN/A } 2922159SN/A 2932190SN/A uint64_t readPC() { return thread->readPC(); } 2942159SN/A uint64_t readMicroPC() { return thread->readMicroPC(); } 2952159SN/A uint64_t readNextPC() { return thread->readNextPC(); } 2962159SN/A uint64_t readNextMicroPC() { return thread->readNextMicroPC(); } 2972159SN/A uint64_t readNextNPC() { return thread->readNextNPC(); } 2982190SN/A 2992159SN/A void setPC(uint64_t val) { thread->setPC(val); } 300705SN/A void setMicroPC(uint64_t val) { thread->setMicroPC(val); } 3011858SN/A void setNextPC(uint64_t val) { thread->setNextPC(val); } 3022190SN/A void setNextMicroPC(uint64_t val) { thread->setNextMicroPC(val); } 3032190SN/A void setNextNPC(uint64_t val) { thread->setNextNPC(val); } 3042190SN/A 3052190SN/A MiscReg readMiscRegNoEffect(int misc_reg) 3062234SN/A { 3072190SN/A return thread->readMiscRegNoEffect(misc_reg); 308705SN/A } 3092561SN/A 310705SN/A MiscReg readMiscReg(int misc_reg) 311705SN/A { 3122190SN/A return thread->readMiscReg(misc_reg); 3132190SN/A } 3142SN/A 3152SN/A void setMiscRegNoEffect(int misc_reg, const MiscReg &val) 3162623SN/A { 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 unsigned readStCondFailures() { 351 return thread->readStCondFailures(); 352 } 353 354 void setStCondFailures(unsigned sc_failures) { 355 thread->setStCondFailures(sc_failures); 356 } 357 358 MiscReg readRegOtherThread(int regIdx, int tid = -1) 359 { 360 panic("Simple CPU models do not support multithreaded " 361 "register access.\n"); 362 } 363 364 void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1) 365 { 366 panic("Simple CPU models do not support multithreaded " 367 "register access.\n"); 368 } 369 370#if FULL_SYSTEM 371 Fault hwrei() { return thread->hwrei(); } 372 void ev5_trap(Fault fault) { fault->invoke(tc); } 373 bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); } 374#else 375 void syscall(int64_t callnum) { thread->syscall(callnum); } 376#endif 377 378 bool misspeculating() { return thread->misspeculating(); } 379 ThreadContext *tcBase() { return tc; } 380}; 381 382#endif // __CPU_SIMPLE_BASE_HH__ 383