base.hh revision 2566
12068SN/A/* 22068SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32068SN/A * All rights reserved. 42068SN/A * 52068SN/A * Redistribution and use in source and binary forms, with or without 62068SN/A * modification, are permitted provided that the following conditions are 72068SN/A * met: redistributions of source code must retain the above copyright 82068SN/A * notice, this list of conditions and the following disclaimer; 92068SN/A * redistributions in binary form must reproduce the above copyright 102068SN/A * notice, this list of conditions and the following disclaimer in the 112068SN/A * documentation and/or other materials provided with the distribution; 122068SN/A * neither the name of the copyright holders nor the names of its 132068SN/A * contributors may be used to endorse or promote products derived from 142068SN/A * this software without specific prior written permission. 152068SN/A * 162068SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172068SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182068SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192068SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202068SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212068SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222068SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232068SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242068SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252068SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262068SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272068SN/A */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu#ifndef __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 302068SN/A#define __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 312649Ssaidi@eecs.umich.edu 322649Ssaidi@eecs.umich.edu#include "base/statistics.hh" 332649Ssaidi@eecs.umich.edu#include "config/full_system.hh" 342649Ssaidi@eecs.umich.edu#include "cpu/base.hh" 357799Sgblack@eecs.umich.edu#include "cpu/cpu_exec_context.hh" 367799Sgblack@eecs.umich.edu#include "cpu/pc_event.hh" 377799Sgblack@eecs.umich.edu#include "cpu/sampler/sampler.hh" 382649Ssaidi@eecs.umich.edu#include "cpu/static_inst.hh" 392649Ssaidi@eecs.umich.edu#include "mem/packet.hh" 402068SN/A#include "mem/port.hh" 412068SN/A#include "mem/request.hh" 422068SN/A#include "sim/eventq.hh" 432090SN/A 442090SN/A// forward declarations 4510196SCurtis.Dunham@arm.com#if FULL_SYSTEM 462068SN/Aclass Processor; 477799Sgblack@eecs.umich.educlass AlphaITB; 488738Sgblack@eecs.umich.educlass AlphaDTB; 4910474Sandreas.hansson@arm.comclass MemObject; 502068SN/A 512068SN/Aclass RemoteGDB; 522068SN/Aclass GDBListener; 5312110SRekai.GonzalezAlberquilla@arm.com 5412110SRekai.GonzalezAlberquilla@arm.com#else 5512110SRekai.GonzalezAlberquilla@arm.com 562068SN/Aclass Process; 572068SN/A 582068SN/A#endif // FULL_SYSTEM 592068SN/A 602068SN/Aclass ExecContext; 612068SN/Aclass Checkpoint; 622068SN/A 632068SN/Anamespace Trace { 642068SN/A class InstRecord; 652068SN/A} 662068SN/A 672068SN/A 682068SN/A// Set exactly one of these symbols to 1 to set the memory access 692068SN/A// model. Probably should make these template parameters, or even 707799Sgblack@eecs.umich.edu// just fork the CPU models. 712068SN/A// 727799Sgblack@eecs.umich.edu#define SIMPLE_CPU_MEM_TIMING 0 737799Sgblack@eecs.umich.edu#define SIMPLE_CPU_MEM_ATOMIC 0 747799Sgblack@eecs.umich.edu#define SIMPLE_CPU_MEM_IMMEDIATE 1 752068SN/A 762068SN/A 772068SN/Aclass SimpleCPU : public BaseCPU 782068SN/A{ 792068SN/A protected: 802068SN/A typedef TheISA::MachInst MachInst; 812068SN/A typedef TheISA::MiscReg MiscReg; 822068SN/A typedef TheISA::FloatReg FloatReg; 837799Sgblack@eecs.umich.edu typedef TheISA::FloatRegBits FloatRegBits; 842068SN/A class CpuPort : public Port 857799Sgblack@eecs.umich.edu { 867799Sgblack@eecs.umich.edu 872068SN/A SimpleCPU *cpu; 882068SN/A 892068SN/A public: 902068SN/A 912068SN/A CpuPort(SimpleCPU *_cpu) 922068SN/A : cpu(_cpu) 932068SN/A { } 942068SN/A 952068SN/A protected: 962068SN/A 972068SN/A virtual bool recvTiming(Packet &pkt); 982068SN/A 992068SN/A virtual Tick recvAtomic(Packet &pkt); 1002068SN/A 1012068SN/A virtual void recvFunctional(Packet &pkt); 1022068SN/A 1032068SN/A virtual void recvStatusChange(Status status); 1042068SN/A 1052068SN/A virtual Packet *recvRetry(); 1062068SN/A }; 1072068SN/A 1082068SN/A MemObject *mem; 1092068SN/A CpuPort icachePort; 1102068SN/A CpuPort dcachePort; 1112068SN/A 1122068SN/A public: 1132068SN/A // main simulation loop (one cycle) 1142068SN/A void tick(); 1152068SN/A virtual void init(); 1162227SN/A 1172068SN/A private: 1182068SN/A struct TickEvent : public Event 1192068SN/A { 1202068SN/A SimpleCPU *cpu; 1212068SN/A int width; 1222068SN/A 1232068SN/A TickEvent(SimpleCPU *c, int w); 1242068SN/A void process(); 1252068SN/A const char *description(); 1262068SN/A }; 1272068SN/A 1282068SN/A TickEvent tickEvent; 1292068SN/A 1302068SN/A /// Schedule tick event, regardless of its current state. 1312068SN/A void scheduleTickEvent(int numCycles) 1322068SN/A { 1332068SN/A if (tickEvent.squashed()) 1342068SN/A tickEvent.reschedule(curTick + cycles(numCycles)); 1352068SN/A else if (!tickEvent.scheduled()) 1362068SN/A tickEvent.schedule(curTick + cycles(numCycles)); 1372068SN/A } 1382068SN/A 1392068SN/A /// Unschedule tick event, regardless of its current state. 1402068SN/A void unscheduleTickEvent() 1412068SN/A { 1422068SN/A if (tickEvent.scheduled()) 1432068SN/A tickEvent.squash(); 1442068SN/A } 1452068SN/A 1462068SN/A private: 1472068SN/A Trace::InstRecord *traceData; 1482068SN/A 1492068SN/A public: 1502068SN/A // 1512068SN/A enum Status { 1522068SN/A Running, 1532068SN/A Idle, 1542068SN/A IcacheRetry, 15512106SRekai.GonzalezAlberquilla@arm.com IcacheWaitResponse, 1562068SN/A IcacheAccessComplete, 1572068SN/A DcacheRetry, 1582068SN/A DcacheWaitResponse, 1592068SN/A DcacheWaitSwitch, 1602068SN/A SwitchedOut 1612068SN/A }; 1622068SN/A 1632068SN/A private: 1642068SN/A Status _status; 1652068SN/A 1662068SN/A public: 1672068SN/A void post_interrupt(int int_num, int index); 1682068SN/A 1692068SN/A void zero_fill_64(Addr addr) { 1702068SN/A static int warned = 0; 1712068SN/A if (!warned) { 1722068SN/A warn ("WH64 is not implemented"); 1732068SN/A warned = 1; 1742068SN/A } 1752068SN/A }; 1762068SN/A 1772068SN/A public: 1782068SN/A struct Params : public BaseCPU::Params 1792068SN/A { 1802068SN/A int width; 1812068SN/A MemObject *mem; 1822068SN/A#if FULL_SYSTEM 1832068SN/A AlphaITB *itb; 1842068SN/A AlphaDTB *dtb; 1852068SN/A#else 1862068SN/A Process *process; 1872068SN/A#endif 1882068SN/A }; 1892068SN/A SimpleCPU(Params *params); 1902068SN/A virtual ~SimpleCPU(); 1917799Sgblack@eecs.umich.edu 1927799Sgblack@eecs.umich.edu public: 1937799Sgblack@eecs.umich.edu // execution context 1947799Sgblack@eecs.umich.edu CPUExecContext *cpuXC; 1952068SN/A 1962068SN/A ExecContext *xcProxy; 1972068SN/A 1982068SN/A void switchOut(Sampler *s); 1992068SN/A void takeOverFrom(BaseCPU *oldCPU); 2002068SN/A 2012068SN/A#if FULL_SYSTEM 2022068SN/A Addr dbg_vtophys(Addr addr); 2032068SN/A 2042068SN/A bool interval_stats; 2052068SN/A#endif 2062068SN/A 2072068SN/A // current instruction 2082068SN/A MachInst inst; 20910196SCurtis.Dunham@arm.com 2102068SN/A // Static data storage 2112068SN/A TheISA::IntReg dataReg; 2122068SN/A 2132068SN/A#if SIMPLE_CPU_MEM_TIMING 2142068SN/A Packet *retry_pkt; 2152068SN/A#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE 2162068SN/A Request *ifetch_req; 2172068SN/A Packet *ifetch_pkt; 2182132SN/A Request *data_read_req; 2192068SN/A Packet *data_read_pkt; 2202068SN/A Request *data_write_req; 2212068SN/A Packet *data_write_pkt; 2222068SN/A#endif 2232068SN/A 2242068SN/A // Pointer to the sampler that is telling us to switchover. 2252068SN/A // Used to signal the completion of the pipe drain and schedule 2262068SN/A // the next switchover 2274394Ssaidi@eecs.umich.edu Sampler *sampler; 2287783SGiacomo.Gabrielli@arm.com 2292068SN/A StaticInstPtr curStaticInst; 2304394Ssaidi@eecs.umich.edu 2312068SN/A Status status() const { return _status; } 2322068SN/A 2332068SN/A virtual void activateContext(int thread_num, int delay); 2342068SN/A virtual void suspendContext(int thread_num); 2352068SN/A virtual void deallocateContext(int thread_num); 2362068SN/A virtual void haltContext(int thread_num); 2372068SN/A 2382068SN/A // statistics 2392068SN/A virtual void regStats(); 2402068SN/A virtual void resetStats(); 2412090SN/A 2422068SN/A // number of simulated instructions 2432068SN/A Counter numInst; 2442068SN/A Counter startNumInst; 2452068SN/A Stats::Scalar<> numInsts; 2462068SN/A 2472068SN/A virtual Counter totalInstructions() const 2482068SN/A { 2492068SN/A return numInst - startNumInst; 2502068SN/A } 2512068SN/A 2522068SN/A // number of simulated memory references 25310196SCurtis.Dunham@arm.com Stats::Scalar<> numMemRefs; 2542068SN/A 2552068SN/A // number of simulated loads 2562068SN/A Counter numLoad; 2572068SN/A Counter startNumLoad; 2582068SN/A 2592068SN/A // number of idle cycles 2602068SN/A Stats::Average<> notIdleFraction; 2612068SN/A Stats::Formula idleFraction; 2622132SN/A 2632068SN/A // number of cycles stalled for I-cache responses 2642068SN/A Stats::Scalar<> icacheStallCycles; 2652068SN/A Counter lastIcacheStall; 2662068SN/A 2672068SN/A // number of cycles stalled for I-cache retries 2682068SN/A Stats::Scalar<> icacheRetryCycles; 2692090SN/A Counter lastIcacheRetry; 2702068SN/A 2712068SN/A // number of cycles stalled for D-cache responses 2722068SN/A Stats::Scalar<> dcacheStallCycles; 2732068SN/A Counter lastDcacheStall; 2742068SN/A 2752068SN/A // number of cycles stalled for D-cache retries 2762068SN/A Stats::Scalar<> dcacheRetryCycles; 2772068SN/A Counter lastDcacheRetry; 2782068SN/A 2792068SN/A void sendIcacheRequest(Packet *pkt); 2802068SN/A void sendDcacheRequest(Packet *pkt); 2812068SN/A void processResponse(Packet &response); 2822068SN/A 2832068SN/A Packet * processRetry(); 2842068SN/A void recvStatusChange(Port::Status status) {} 2852068SN/A 2862068SN/A virtual void serialize(std::ostream &os); 2872068SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 2882068SN/A 2892068SN/A template <class T> 2902068SN/A Fault read(Addr addr, T &data, unsigned flags); 2912068SN/A 2923953Sstever@eecs.umich.edu template <class T> 2932068SN/A Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 2942068SN/A 2952068SN/A // These functions are only used in CPU models that split 2962068SN/A // effective address computation from the actual memory access. 2972068SN/A void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 2982068SN/A Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 2992068SN/A 3002068SN/A void prefetch(Addr addr, unsigned flags) 3012068SN/A { 3023953Sstever@eecs.umich.edu // need to do this... 3032068SN/A } 3042068SN/A 3052068SN/A void writeHint(Addr addr, int size, unsigned flags) 3062068SN/A { 3072068SN/A // need to do this... 3082068SN/A } 309 310 Fault copySrcTranslate(Addr src); 311 312 Fault copy(Addr dest); 313 314 // The register accessor methods provide the index of the 315 // instruction's operand (e.g., 0 or 1), not the architectural 316 // register index, to simplify the implementation of register 317 // renaming. We find the architectural register index by indexing 318 // into the instruction's own operand index table. Note that a 319 // raw pointer to the StaticInst is provided instead of a 320 // ref-counted StaticInstPtr to redice overhead. This is fine as 321 // long as these methods don't copy the pointer into any long-term 322 // storage (which is pretty hard to imagine they would have reason 323 // to do). 324 325 uint64_t readIntReg(const StaticInst *si, int idx) 326 { 327 return cpuXC->readIntReg(si->srcRegIdx(idx)); 328 } 329 330 FloatReg readFloatReg(const StaticInst *si, int idx, int width) 331 { 332 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 333 return cpuXC->readFloatReg(reg_idx, width); 334 } 335 336 FloatReg readFloatReg(const StaticInst *si, int idx) 337 { 338 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 339 return cpuXC->readFloatReg(reg_idx); 340 } 341 342 FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width) 343 { 344 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 345 return cpuXC->readFloatRegBits(reg_idx, width); 346 } 347 348 FloatRegBits readFloatRegBits(const StaticInst *si, int idx) 349 { 350 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 351 return cpuXC->readFloatRegBits(reg_idx); 352 } 353 354 void setIntReg(const StaticInst *si, int idx, uint64_t val) 355 { 356 cpuXC->setIntReg(si->destRegIdx(idx), val); 357 } 358 359 void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width) 360 { 361 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 362 cpuXC->setFloatReg(reg_idx, val, width); 363 } 364 365 void setFloatReg(const StaticInst *si, int idx, FloatReg val) 366 { 367 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 368 cpuXC->setFloatReg(reg_idx, val); 369 } 370 371 void setFloatRegBits(const StaticInst *si, int idx, 372 FloatRegBits val, int width) 373 { 374 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 375 cpuXC->setFloatRegBits(reg_idx, val, width); 376 } 377 378 void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val) 379 { 380 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 381 cpuXC->setFloatRegBits(reg_idx, val); 382 } 383 384 uint64_t readPC() { return cpuXC->readPC(); } 385 uint64_t readNextPC() { return cpuXC->readNextPC(); } 386 uint64_t readNextNPC() { return cpuXC->readNextNPC(); } 387 388 void setPC(uint64_t val) { cpuXC->setPC(val); } 389 void setNextPC(uint64_t val) { cpuXC->setNextPC(val); } 390 void setNextNPC(uint64_t val) { cpuXC->setNextNPC(val); } 391 392 MiscReg readMiscReg(int misc_reg) 393 { 394 return cpuXC->readMiscReg(misc_reg); 395 } 396 397 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 398 { 399 return cpuXC->readMiscRegWithEffect(misc_reg, fault); 400 } 401 402 Fault setMiscReg(int misc_reg, const MiscReg &val) 403 { 404 return cpuXC->setMiscReg(misc_reg, val); 405 } 406 407 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 408 { 409 return cpuXC->setMiscRegWithEffect(misc_reg, val); 410 } 411 412#if FULL_SYSTEM 413 Fault hwrei() { return cpuXC->hwrei(); } 414 int readIntrFlag() { return cpuXC->readIntrFlag(); } 415 void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } 416 bool inPalMode() { return cpuXC->inPalMode(); } 417 void ev5_trap(Fault fault) { fault->invoke(xcProxy); } 418 bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } 419#else 420 void syscall(int64_t callnum) { cpuXC->syscall(callnum); } 421#endif 422 423 bool misspeculating() { return cpuXC->misspeculating(); } 424 ExecContext *xcBase() { return xcProxy; } 425}; 426 427#endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 428