base.hh revision 2462
12SN/A/* 29448SAndreas.Sandberg@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 37338SAli.Saidi@ARM.com * All rights reserved. 47338SAli.Saidi@ARM.com * 57338SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 67338SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 77338SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 87338SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 97338SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 107338SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 117338SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 127338SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 137338SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 141762SN/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 292SN/A#ifndef __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 302SN/A#define __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 312SN/A 322SN/A#include "base/statistics.hh" 332SN/A#include "config/full_system.hh" 342SN/A#include "cpu/base.hh" 352SN/A#include "cpu/cpu_exec_context.hh" 362SN/A#include "cpu/pc_event.hh" 372SN/A#include "cpu/sampler/sampler.hh" 382SN/A#include "cpu/static_inst.hh" 392665Ssaidi@eecs.umich.edu#include "mem/packet.hh" 402665Ssaidi@eecs.umich.edu#include "mem/port.hh" 412SN/A#include "mem/request.hh" 422SN/A#include "sim/eventq.hh" 438779Sgblack@eecs.umich.edu 448779Sgblack@eecs.umich.edu// forward declarations 458779Sgblack@eecs.umich.edu#if FULL_SYSTEM 462439SN/Aclass Processor; 478779Sgblack@eecs.umich.educlass AlphaITB; 488229Snate@binkert.orgclass AlphaDTB; 496216Snate@binkert.orgclass MemObject; 50146SN/A 51146SN/Aclass RemoteGDB; 52146SN/Aclass GDBListener; 53146SN/A 54146SN/A#else 556216Snate@binkert.org 566658Snate@binkert.orgclass Process; 578229Snate@binkert.org 581717SN/A#endif // FULL_SYSTEM 598887Sgeoffrey.blake@arm.com 608887Sgeoffrey.blake@arm.comclass ExecContext; 61146SN/Aclass Checkpoint; 621977SN/A 632683Sktlim@umich.edunamespace Trace { 641717SN/A class InstRecord; 65146SN/A} 662683Sktlim@umich.edu 678232Snate@binkert.org 688232Snate@binkert.org// Set exactly one of these symbols to 1 to set the memory access 698232Snate@binkert.org// model. Probably should make these template parameters, or even 708779Sgblack@eecs.umich.edu// just fork the CPU models. 713348Sbinkertn@umich.edu// 726105Ssteve.reinhardt@amd.com#define SIMPLE_CPU_MEM_TIMING 0 736216Snate@binkert.org#define SIMPLE_CPU_MEM_ATOMIC 0 742036SN/A#define SIMPLE_CPU_MEM_IMMEDIATE 1 75146SN/A 768817Sgblack@eecs.umich.edu 778793Sgblack@eecs.umich.educlass SimpleCPU : public BaseCPU 7856SN/A{ 7956SN/A protected: 80695SN/A typedef TheISA::MachInst MachInst; 812901Ssaidi@eecs.umich.edu typedef TheISA::MiscReg MiscReg; 822SN/A class CpuPort : public Port 832SN/A { 842449SN/A 851355SN/A SimpleCPU *cpu; 865529Snate@binkert.org 879023Sgblack@eecs.umich.edu public: 88224SN/A 898793Sgblack@eecs.umich.edu CpuPort(SimpleCPU *_cpu) 909384SAndreas.Sandberg@arm.com : cpu(_cpu) 919384SAndreas.Sandberg@arm.com { } 928793Sgblack@eecs.umich.edu 938820Sgblack@eecs.umich.edu protected: 949384SAndreas.Sandberg@arm.com 952SN/A virtual bool recvTiming(Packet &pkt); 966029Ssteve.reinhardt@amd.com 972672Sktlim@umich.edu virtual Tick recvAtomic(Packet &pkt); 982683Sktlim@umich.edu 992SN/A virtual void recvFunctional(Packet &pkt); 1008733Sgeoffrey.blake@arm.com 1018733Sgeoffrey.blake@arm.com virtual void recvStatusChange(Status status); 1028733Sgeoffrey.blake@arm.com 1038733Sgeoffrey.blake@arm.com virtual Packet *recvRetry(); 1048733Sgeoffrey.blake@arm.com }; 1058733Sgeoffrey.blake@arm.com 1068733Sgeoffrey.blake@arm.com CpuPort icachePort; 1078733Sgeoffrey.blake@arm.com CpuPort dcachePort; 1088733Sgeoffrey.blake@arm.com 1098733Sgeoffrey.blake@arm.com public: 1108733Sgeoffrey.blake@arm.com // main simulation loop (one cycle) 1112SN/A void tick(); 112334SN/A virtual void init(); 1138834Satgutier@umich.edu 1148834Satgutier@umich.edu private: 115140SN/A struct TickEvent : public Event 116334SN/A { 1172SN/A SimpleCPU *cpu; 1182SN/A int width; 1192SN/A 1202680Sktlim@umich.edu TickEvent(SimpleCPU *c, int w); 1214377Sgblack@eecs.umich.edu void process(); 1225169Ssaidi@eecs.umich.edu const char *description(); 1234377Sgblack@eecs.umich.edu }; 1244377Sgblack@eecs.umich.edu 1252SN/A TickEvent tickEvent; 1262SN/A 1272623SN/A /// Schedule tick event, regardless of its current state. 1282SN/A void scheduleTickEvent(int numCycles) 1292SN/A { 1302SN/A if (tickEvent.squashed()) 131180SN/A tickEvent.reschedule(curTick + cycles(numCycles)); 1328737Skoansin.tan@gmail.com else if (!tickEvent.scheduled()) 133393SN/A tickEvent.schedule(curTick + cycles(numCycles)); 134393SN/A } 135393SN/A 136393SN/A /// Unschedule tick event, regardless of its current state. 137384SN/A void unscheduleTickEvent() 138384SN/A { 139393SN/A if (tickEvent.scheduled()) 1408737Skoansin.tan@gmail.com tickEvent.squash(); 141393SN/A } 142393SN/A 143393SN/A private: 144393SN/A Trace::InstRecord *traceData; 145384SN/A 146189SN/A public: 147189SN/A // 1482623SN/A enum Status { 1492SN/A Running, 150729SN/A Idle, 151334SN/A IcacheRetry, 1522SN/A IcacheWaitResponse, 1532SN/A IcacheAccessComplete, 1542SN/A DcacheRetry, 1558834Satgutier@umich.edu DcacheWaitResponse, 1568834Satgutier@umich.edu DcacheWaitSwitch, 1578834Satgutier@umich.edu SwitchedOut 1588834Satgutier@umich.edu }; 1598834Satgutier@umich.edu 1608834Satgutier@umich.edu private: 1618834Satgutier@umich.edu Status _status; 1622SN/A 1632SN/A public: 1647897Shestness@cs.utexas.edu void post_interrupt(int int_num, int index); 1657897Shestness@cs.utexas.edu 1667897Shestness@cs.utexas.edu void zero_fill_64(Addr addr) { 1677897Shestness@cs.utexas.edu static int warned = 0; 1687897Shestness@cs.utexas.edu if (!warned) { 1697897Shestness@cs.utexas.edu warn ("WH64 is not implemented"); 1707897Shestness@cs.utexas.edu warned = 1; 1717897Shestness@cs.utexas.edu } 1727897Shestness@cs.utexas.edu }; 1737897Shestness@cs.utexas.edu 1747897Shestness@cs.utexas.edu public: 1757897Shestness@cs.utexas.edu struct Params : public BaseCPU::Params 1767897Shestness@cs.utexas.edu { 1777897Shestness@cs.utexas.edu int width; 1787897Shestness@cs.utexas.edu#if FULL_SYSTEM 1797897Shestness@cs.utexas.edu AlphaITB *itb; 1807897Shestness@cs.utexas.edu AlphaDTB *dtb; 1817897Shestness@cs.utexas.edu#else 1827897Shestness@cs.utexas.edu MemObject *mem; 1837897Shestness@cs.utexas.edu Process *process; 1847897Shestness@cs.utexas.edu#endif 1857897Shestness@cs.utexas.edu }; 1867897Shestness@cs.utexas.edu SimpleCPU(Params *params); 1877897Shestness@cs.utexas.edu virtual ~SimpleCPU(); 1887897Shestness@cs.utexas.edu 1897897Shestness@cs.utexas.edu public: 1907897Shestness@cs.utexas.edu // execution context 1917897Shestness@cs.utexas.edu CPUExecContext *cpuXC; 1927897Shestness@cs.utexas.edu 1937897Shestness@cs.utexas.edu ExecContext *xcProxy; 1947897Shestness@cs.utexas.edu 1957897Shestness@cs.utexas.edu void switchOut(Sampler *s); 1967897Shestness@cs.utexas.edu void takeOverFrom(BaseCPU *oldCPU); 1977897Shestness@cs.utexas.edu 1987897Shestness@cs.utexas.edu#if FULL_SYSTEM 1997897Shestness@cs.utexas.edu Addr dbg_vtophys(Addr addr); 2007897Shestness@cs.utexas.edu 2017897Shestness@cs.utexas.edu bool interval_stats; 2027897Shestness@cs.utexas.edu#endif 2037897Shestness@cs.utexas.edu 2047897Shestness@cs.utexas.edu // current instruction 2057897Shestness@cs.utexas.edu MachInst inst; 2067897Shestness@cs.utexas.edu 2077897Shestness@cs.utexas.edu#if SIMPLE_CPU_MEM_TIMING 2087897Shestness@cs.utexas.edu Packet *retry_pkt; 2097897Shestness@cs.utexas.edu#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE 2107897Shestness@cs.utexas.edu CpuRequest *ifetch_req; 2117897Shestness@cs.utexas.edu Packet *ifetch_pkt; 2127897Shestness@cs.utexas.edu CpuRequest *data_read_req; 2137897Shestness@cs.utexas.edu Packet *data_read_pkt; 2142SN/A CpuRequest *data_write_req; 2157897Shestness@cs.utexas.edu Packet *data_write_pkt; 2167897Shestness@cs.utexas.edu#endif 2177897Shestness@cs.utexas.edu 2187897Shestness@cs.utexas.edu // Pointer to the sampler that is telling us to switchover. 2197897Shestness@cs.utexas.edu // Used to signal the completion of the pipe drain and schedule 2207897Shestness@cs.utexas.edu // the next switchover 2217897Shestness@cs.utexas.edu Sampler *sampler; 2227897Shestness@cs.utexas.edu 2237897Shestness@cs.utexas.edu StaticInstPtr curStaticInst; 2247897Shestness@cs.utexas.edu 2257897Shestness@cs.utexas.edu Status status() const { return _status; } 2267897Shestness@cs.utexas.edu 2272SN/A virtual void activateContext(int thread_num, int delay); 2282SN/A virtual void suspendContext(int thread_num); 2291001SN/A virtual void deallocateContext(int thread_num); 2301001SN/A virtual void haltContext(int thread_num); 2311001SN/A 2321001SN/A // statistics 2331001SN/A virtual void regStats(); 2342SN/A virtual void resetStats(); 2352SN/A 2362SN/A // number of simulated instructions 2372SN/A Counter numInst; 2382SN/A Counter startNumInst; 2397897Shestness@cs.utexas.edu Stats::Scalar<> numInsts; 2407897Shestness@cs.utexas.edu 2417897Shestness@cs.utexas.edu virtual Counter totalInstructions() const 2427897Shestness@cs.utexas.edu { 2437897Shestness@cs.utexas.edu return numInst - startNumInst; 2447897Shestness@cs.utexas.edu } 2457897Shestness@cs.utexas.edu 2467897Shestness@cs.utexas.edu // number of simulated memory references 2477897Shestness@cs.utexas.edu Stats::Scalar<> numMemRefs; 2487897Shestness@cs.utexas.edu 2492SN/A // number of simulated loads 2502SN/A Counter numLoad; 2512SN/A Counter startNumLoad; 2522SN/A 2532SN/A // number of idle cycles 2542SN/A Stats::Average<> notIdleFraction; 2552SN/A Stats::Formula idleFraction; 2562SN/A 2572SN/A // number of cycles stalled for I-cache responses 2582SN/A Stats::Scalar<> icacheStallCycles; 2592SN/A Counter lastIcacheStall; 2602SN/A 2612390SN/A // number of cycles stalled for I-cache retries 2622390SN/A Stats::Scalar<> icacheRetryCycles; 2632390SN/A Counter lastIcacheRetry; 2642390SN/A 2652390SN/A // number of cycles stalled for D-cache responses 2662390SN/A Stats::Scalar<> dcacheStallCycles; 2672390SN/A Counter lastDcacheStall; 2682390SN/A 2692390SN/A // number of cycles stalled for D-cache retries 2702390SN/A Stats::Scalar<> dcacheRetryCycles; 2712390SN/A Counter lastDcacheRetry; 2722390SN/A 273385SN/A void sendIcacheRequest(Packet *pkt); 2747897Shestness@cs.utexas.edu void sendDcacheRequest(Packet *pkt); 2757897Shestness@cs.utexas.edu void processResponse(Packet &response); 2762SN/A 2772SN/A Packet * processRetry(); 2782SN/A void recvStatusChange(Port::Status status) {} 2792623SN/A 280334SN/A virtual void serialize(std::ostream &os); 2812361SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 2825496Ssaidi@eecs.umich.edu 283334SN/A template <class T> 284334SN/A Fault read(Addr addr, T &data, unsigned flags); 285334SN/A 2869448SAndreas.Sandberg@ARM.com template <class T> 2872SN/A Fault write(T data, Addr addr, unsigned flags, uint64_t *res); 2889448SAndreas.Sandberg@ARM.com 2899448SAndreas.Sandberg@ARM.com // These functions are only used in CPU models that split 2909448SAndreas.Sandberg@ARM.com // effective address computation from the actual memory access. 2912683Sktlim@umich.edu void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); } 2922SN/A Addr getEA() { panic("SimpleCPU::getEA() not implemented\n"); } 2932SN/A 2942SN/A void prefetch(Addr addr, unsigned flags) 2959448SAndreas.Sandberg@ARM.com { 2969448SAndreas.Sandberg@ARM.com // need to do this... 2972SN/A } 2989448SAndreas.Sandberg@ARM.com 2999448SAndreas.Sandberg@ARM.com void writeHint(Addr addr, int size, unsigned flags) 3009448SAndreas.Sandberg@ARM.com { 3012SN/A // need to do this... 3022SN/A } 3032SN/A 3046221Snate@binkert.org Fault copySrcTranslate(Addr src); 3052SN/A 3062SN/A Fault copy(Addr dest); 3072SN/A 3082SN/A // The register accessor methods provide the index of the 3092623SN/A // instruction's operand (e.g., 0 or 1), not the architectural 3102SN/A // register index, to simplify the implementation of register 3112680Sktlim@umich.edu // renaming. We find the architectural register index by indexing 3122SN/A // into the instruction's own operand index table. Note that a 3132SN/A // raw pointer to the StaticInst is provided instead of a 3142SN/A // ref-counted StaticInstPtr to redice overhead. This is fine as 3155807Snate@binkert.org // long as these methods don't copy the pointer into any long-term 3162SN/A // storage (which is pretty hard to imagine they would have reason 3175807Snate@binkert.org // to do). 3185807Snate@binkert.org 3192SN/A uint64_t readIntReg(const StaticInst *si, int idx) 3205807Snate@binkert.org { 3215807Snate@binkert.org return cpuXC->readIntReg(si->srcRegIdx(idx)); 3222SN/A } 3232SN/A 3242SN/A float readFloatRegSingle(const StaticInst *si, int idx) 3252623SN/A { 3262SN/A int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 3275704Snate@binkert.org return cpuXC->readFloatRegSingle(reg_idx); 3285647Sgblack@eecs.umich.edu } 3292SN/A 3303520Sgblack@eecs.umich.edu double readFloatRegDouble(const StaticInst *si, int idx) 3317338SAli.Saidi@ARM.com { 3325647Sgblack@eecs.umich.edu int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 3333520Sgblack@eecs.umich.edu return cpuXC->readFloatRegDouble(reg_idx); 3349023Sgblack@eecs.umich.edu } 3352SN/A 3362SN/A uint64_t readFloatRegInt(const StaticInst *si, int idx) 3372623SN/A { 3382SN/A int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; 3392623SN/A return cpuXC->readFloatRegInt(reg_idx); 3405894Sgblack@eecs.umich.edu } 3412662Sstever@eecs.umich.edu 3422623SN/A void setIntReg(const StaticInst *si, int idx, uint64_t val) 3437720Sgblack@eecs.umich.edu { 3444495Sacolyte@umich.edu cpuXC->setIntReg(si->destRegIdx(idx), val); 3452623SN/A } 3467720Sgblack@eecs.umich.edu 3472623SN/A void setFloatRegSingle(const StaticInst *si, int idx, float val) 3487720Sgblack@eecs.umich.edu { 3498832SAli.Saidi@ARM.com int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 3508832SAli.Saidi@ARM.com cpuXC->setFloatRegSingle(reg_idx, val); 3512623SN/A } 3522623SN/A 3532623SN/A void setFloatRegDouble(const StaticInst *si, int idx, double val) 3542623SN/A { 3552623SN/A int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 3562623SN/A cpuXC->setFloatRegDouble(reg_idx, val); 3572SN/A } 3582683Sktlim@umich.edu 3592427SN/A void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) 3602683Sktlim@umich.edu { 3612427SN/A int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; 3622SN/A cpuXC->setFloatRegInt(reg_idx, val); 3632623SN/A } 3642623SN/A 3657897Shestness@cs.utexas.edu uint64_t readPC() { return cpuXC->readPC(); } 3662SN/A uint64_t readNextPC() { return cpuXC->readNextPC(); } 3672623SN/A uint64_t readNextNPC() { return cpuXC->readNextNPC(); } 3682623SN/A 3694377Sgblack@eecs.umich.edu void setPC(uint64_t val) { cpuXC->setPC(val); } 3707720Sgblack@eecs.umich.edu void setNextPC(uint64_t val) { cpuXC->setNextPC(val); } 3714377Sgblack@eecs.umich.edu void setNextNPC(uint64_t val) { cpuXC->setNextNPC(val); } 3727720Sgblack@eecs.umich.edu 3735665Sgblack@eecs.umich.edu MiscReg readMiscReg(int misc_reg) 3747720Sgblack@eecs.umich.edu { 3757720Sgblack@eecs.umich.edu return cpuXC->readMiscReg(misc_reg); 3765665Sgblack@eecs.umich.edu } 3775665Sgblack@eecs.umich.edu 3784181Sgblack@eecs.umich.edu MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 3794181Sgblack@eecs.umich.edu { 3809023Sgblack@eecs.umich.edu return cpuXC->readMiscRegWithEffect(misc_reg, fault); 3819023Sgblack@eecs.umich.edu } 3824181Sgblack@eecs.umich.edu 3834182Sgblack@eecs.umich.edu Fault setMiscReg(int misc_reg, const MiscReg &val) 3847720Sgblack@eecs.umich.edu { 3859023Sgblack@eecs.umich.edu return cpuXC->setMiscReg(misc_reg, val); 3869023Sgblack@eecs.umich.edu } 3874593Sgblack@eecs.umich.edu 3889023Sgblack@eecs.umich.edu Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 3894377Sgblack@eecs.umich.edu { 3909023Sgblack@eecs.umich.edu return cpuXC->setMiscRegWithEffect(misc_reg, val); 3914377Sgblack@eecs.umich.edu } 3929023Sgblack@eecs.umich.edu 3939023Sgblack@eecs.umich.edu#if FULL_SYSTEM 3944377Sgblack@eecs.umich.edu Fault hwrei() { return cpuXC->hwrei(); } 3957720Sgblack@eecs.umich.edu int readIntrFlag() { return cpuXC->readIntrFlag(); } 3964377Sgblack@eecs.umich.edu void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } 3974377Sgblack@eecs.umich.edu bool inPalMode() { return cpuXC->inPalMode(); } 3984377Sgblack@eecs.umich.edu void ev5_trap(Fault fault) { fault->invoke(xcProxy); } 3994377Sgblack@eecs.umich.edu bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } 4004181Sgblack@eecs.umich.edu#else 4014181Sgblack@eecs.umich.edu void syscall() { cpuXC->syscall(); } 4024181Sgblack@eecs.umich.edu#endif 4034539Sgblack@eecs.umich.edu 4043276Sgblack@eecs.umich.edu bool misspeculating() { return cpuXC->misspeculating(); } 4057720Sgblack@eecs.umich.edu ExecContext *xcBase() { return xcProxy; } 4063280Sgblack@eecs.umich.edu}; 4073280Sgblack@eecs.umich.edu 4083276Sgblack@eecs.umich.edu#endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ 4093276Sgblack@eecs.umich.edu