base.hh revision 2447
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
292665Ssaidi@eecs.umich.edu#ifndef __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
302665Ssaidi@eecs.umich.edu#define __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
312SN/A
322SN/A#include "base/statistics.hh"
332623SN/A#include "config/full_system.hh"
342623SN/A#include "cpu/base.hh"
352SN/A#include "cpu/cpu_exec_context.hh"
364182Sgblack@eecs.umich.edu#include "cpu/pc_event.hh"
371354SN/A#include "cpu/sampler/sampler.hh"
381858SN/A#include "cpu/static_inst.hh"
391717SN/A#include "mem/packet.hh"
402683Sktlim@umich.edu#include "mem/port.hh"
411354SN/A#include "mem/request.hh"
421354SN/A#include "sim/eventq.hh"
432387SN/A
442387SN/A// forward declarations
452387SN/A#if FULL_SYSTEM
4656SN/Aclass Processor;
472SN/Aclass AlphaITB;
482SN/Aclass AlphaDTB;
491858SN/Aclass Memory;
502SN/A
513453Sgblack@eecs.umich.educlass RemoteGDB;
523453Sgblack@eecs.umich.educlass GDBListener;
533453Sgblack@eecs.umich.edu
543453Sgblack@eecs.umich.edu#else
553453Sgblack@eecs.umich.edu
562462SN/Aclass Process;
572SN/A
58715SN/A#endif // FULL_SYSTEM
59715SN/A
60715SN/Aclass ExecContext;
61715SN/Aclass MemInterface;
622SN/Aclass Checkpoint;
632SN/A
643960Sgblack@eecs.umich.edunamespace Trace {
653960Sgblack@eecs.umich.edu    class InstRecord;
663960Sgblack@eecs.umich.edu}
674182Sgblack@eecs.umich.edu
684182Sgblack@eecs.umich.edu
694182Sgblack@eecs.umich.edu// Set exactly one of these symbols to 1 to set the memory access
704182Sgblack@eecs.umich.edu// model.  Probably should make these template parameters, or even
712680Sktlim@umich.edu// just fork the CPU models.
72237SN/A//
732SN/A#define SIMPLE_CPU_MEM_TIMING    0
742SN/A#define SIMPLE_CPU_MEM_ATOMIC    0
752SN/A#define SIMPLE_CPU_MEM_IMMEDIATE 1
762SN/A
772SN/A
782420SN/Aclass SimpleCPU : public BaseCPU
792623SN/A{
802SN/A  protected:
812107SN/A    typedef TheISA::MachInst MachInst;
822159SN/A    typedef TheISA::MiscReg MiscReg;
832455SN/A    class CpuPort : public Port
842455SN/A    {
852386SN/A
862623SN/A        SimpleCPU *cpu;
872SN/A
881371SN/A      public:
892SN/A
902SN/A        CpuPort(SimpleCPU *_cpu)
912SN/A            : cpu(_cpu)
922SN/A        { }
932SN/A
942SN/A      protected:
952SN/A
962SN/A        virtual bool recvTiming(Packet &pkt);
972SN/A
982SN/A        virtual Tick recvAtomic(Packet &pkt);
992SN/A
1001400SN/A        virtual void recvFunctional(Packet &pkt);
1011400SN/A
1021400SN/A        virtual void recvStatusChange(Status status);
1033453Sgblack@eecs.umich.edu
1043453Sgblack@eecs.umich.edu        virtual Packet *recvRetry();
1054997Sgblack@eecs.umich.edu    };
1061400SN/A
1072SN/A    CpuPort icachePort;
1081400SN/A    CpuPort dcachePort;
1092623SN/A
1102623SN/A  public:
1112SN/A    // main simulation loop (one cycle)
1121400SN/A    void tick();
1132683Sktlim@umich.edu    virtual void init();
1142683Sktlim@umich.edu
1152190SN/A  private:
1162683Sktlim@umich.edu    struct TickEvent : public Event
1172683Sktlim@umich.edu    {
1182683Sktlim@umich.edu        SimpleCPU *cpu;
1192680Sktlim@umich.edu        int width;
1202SN/A
1211858SN/A        TickEvent(SimpleCPU *c, int w);
1222SN/A        void process();
1232SN/A        const char *description();
1242SN/A    };
1252SN/A
1262SN/A    TickEvent tickEvent;
1272SN/A
1284181Sgblack@eecs.umich.edu    /// Schedule tick event, regardless of its current state.
1294181Sgblack@eecs.umich.edu    void scheduleTickEvent(int numCycles)
1304182Sgblack@eecs.umich.edu    {
1314182Sgblack@eecs.umich.edu        if (tickEvent.squashed())
1322SN/A            tickEvent.reschedule(curTick + cycles(numCycles));
1332107SN/A        else if (!tickEvent.scheduled())
1343276Sgblack@eecs.umich.edu            tickEvent.schedule(curTick + cycles(numCycles));
1351469SN/A    }
1364377Sgblack@eecs.umich.edu
1374377Sgblack@eecs.umich.edu    /// Unschedule tick event, regardless of its current state.
1384377Sgblack@eecs.umich.edu    void unscheduleTickEvent()
1394377Sgblack@eecs.umich.edu    {
1404377Sgblack@eecs.umich.edu        if (tickEvent.scheduled())
1414377Sgblack@eecs.umich.edu            tickEvent.squash();
1422623SN/A    }
1432662Sstever@eecs.umich.edu
1442623SN/A  private:
1452623SN/A    Trace::InstRecord *traceData;
1462623SN/A
147180SN/A  public:
148393SN/A    //
149393SN/A    enum Status {
1502SN/A        Running,
1512SN/A        Idle,
152334SN/A        IcacheRetry,
153334SN/A        IcacheWaitResponse,
1542SN/A        IcacheAccessComplete,
1552SN/A        DcacheRetry,
1562SN/A        DcacheWaitResponse,
157334SN/A        DcacheWaitSwitch,
158729SN/A        SwitchedOut
159707SN/A    };
160707SN/A
161707SN/A  private:
162707SN/A    Status _status;
163707SN/A
1642SN/A  public:
1654564Sgblack@eecs.umich.edu    void post_interrupt(int int_num, int index);
1664564Sgblack@eecs.umich.edu
1674564Sgblack@eecs.umich.edu    void zero_fill_64(Addr addr) {
1682SN/A      static int warned = 0;
169729SN/A      if (!warned) {
1702SN/A        warn ("WH64 is not implemented");
171124SN/A        warned = 1;
172124SN/A      }
173334SN/A    };
174124SN/A
1752SN/A  public:
176729SN/A    struct Params : public BaseCPU::Params
177729SN/A    {
1782SN/A        int width;
1792390SN/A#if FULL_SYSTEM
180729SN/A        AlphaITB *itb;
1812SN/A        AlphaDTB *dtb;
1822SN/A#else
1832390SN/A        Memory *mem;
1842390SN/A        Process *process;
1852390SN/A#endif
1862390SN/A    };
1872390SN/A    SimpleCPU(Params *params);
188729SN/A    virtual ~SimpleCPU();
1892SN/A
1902SN/A  public:
1912390SN/A    // execution context
1922390SN/A    CPUExecContext *cpuXC;
1932390SN/A
1942390SN/A    ExecContext *xcProxy;
195217SN/A
196237SN/A    void switchOut(Sampler *s);
1972SN/A    void takeOverFrom(BaseCPU *oldCPU);
1981371SN/A
1991371SN/A#if FULL_SYSTEM
2002623SN/A    Addr dbg_vtophys(Addr addr);
2013918Ssaidi@eecs.umich.edu
2023918Ssaidi@eecs.umich.edu    bool interval_stats;
2031371SN/A#endif
204581SN/A
2052SN/A    // current instruction
2062SN/A    MachInst inst;
2072SN/A
2082SN/A#if SIMPLE_CPU_MEM_TIMING
209753SN/A    Packet *retry_pkt;
2102SN/A#elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE
2112SN/A    CpuRequest *ifetch_req;
2122SN/A    Packet     *ifetch_pkt;
213594SN/A    CpuRequest *data_read_req;
2144661Sksewell@umich.edu    Packet     *data_read_pkt;
215595SN/A    CpuRequest *data_write_req;
216594SN/A    Packet     *data_write_pkt;
217595SN/A#endif
218705SN/A
219726SN/A    // Pointer to the sampler that is telling us to switchover.
220726SN/A    // Used to signal the completion of the pipe drain and schedule
221726SN/A    // the next switchover
222726SN/A    Sampler *sampler;
223726SN/A
224726SN/A    StaticInstPtr curStaticInst;
225726SN/A
226726SN/A    Status status() const { return _status; }
227726SN/A
228726SN/A    virtual void activateContext(int thread_num, int delay);
229705SN/A    virtual void suspendContext(int thread_num);
2303735Sstever@eecs.umich.edu    virtual void deallocateContext(int thread_num);
231726SN/A    virtual void haltContext(int thread_num);
2322683Sktlim@umich.edu
233726SN/A    // statistics
234705SN/A    virtual void regStats();
2353735Sstever@eecs.umich.edu    virtual void resetStats();
236726SN/A
237726SN/A    // number of simulated instructions
2382683Sktlim@umich.edu    Counter numInst;
239726SN/A    Counter startNumInst;
240705SN/A    Stats::Scalar<> numInsts;
2413735Sstever@eecs.umich.edu
242726SN/A    virtual Counter totalInstructions() const
243726SN/A    {
2442683Sktlim@umich.edu        return numInst - startNumInst;
245726SN/A    }
246705SN/A
2473735Sstever@eecs.umich.edu    // number of simulated memory references
2483735Sstever@eecs.umich.edu    Stats::Scalar<> numMemRefs;
249726SN/A
250726SN/A    // number of simulated loads
2512683Sktlim@umich.edu    Counter numLoad;
2522455SN/A    Counter startNumLoad;
2532455SN/A
2543735Sstever@eecs.umich.edu    // number of idle cycles
2552455SN/A    Stats::Average<> notIdleFraction;
2562455SN/A    Stats::Formula idleFraction;
2572683Sktlim@umich.edu
258726SN/A    // number of cycles stalled for I-cache responses
259705SN/A    Stats::Scalar<> icacheStallCycles;
2603735Sstever@eecs.umich.edu    Counter lastIcacheStall;
261726SN/A
2622683Sktlim@umich.edu    // number of cycles stalled for I-cache retries
263726SN/A    Stats::Scalar<> icacheRetryCycles;
264705SN/A    Counter lastIcacheRetry;
2653735Sstever@eecs.umich.edu
2663735Sstever@eecs.umich.edu    // number of cycles stalled for D-cache responses
267726SN/A    Stats::Scalar<> dcacheStallCycles;
268726SN/A    Counter lastDcacheStall;
2692683Sktlim@umich.edu
270726SN/A    // number of cycles stalled for D-cache retries
271705SN/A    Stats::Scalar<> dcacheRetryCycles;
2723735Sstever@eecs.umich.edu    Counter lastDcacheRetry;
273726SN/A
274726SN/A    void sendIcacheRequest(Packet *pkt);
2752683Sktlim@umich.edu    void sendDcacheRequest(Packet *pkt);
276726SN/A    void processResponse(Packet &response);
277726SN/A
2783735Sstever@eecs.umich.edu    Packet * processRetry();
2793735Sstever@eecs.umich.edu    void recvStatusChange(Port::Status status) {}
280726SN/A
281726SN/A    virtual void serialize(std::ostream &os);
2822683Sktlim@umich.edu    virtual void unserialize(Checkpoint *cp, const std::string &section);
2832455SN/A
2842455SN/A    template <class T>
2853735Sstever@eecs.umich.edu    Fault read(Addr addr, T &data, unsigned flags);
2863735Sstever@eecs.umich.edu
2872455SN/A    template <class T>
2882455SN/A    Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
2892683Sktlim@umich.edu
290726SN/A    // These functions are only used in CPU models that split
291705SN/A    // effective address computation from the actual memory access.
2922683Sktlim@umich.edu    void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
2934950Sgblack@eecs.umich.edu    Addr getEA() 	{ panic("SimpleCPU::getEA() not implemented\n"); }
2942683Sktlim@umich.edu
2954950Sgblack@eecs.umich.edu    void prefetch(Addr addr, unsigned flags)
2962683Sktlim@umich.edu    {
2972447SN/A        // need to do this...
2982683Sktlim@umich.edu    }
2994950Sgblack@eecs.umich.edu
3002683Sktlim@umich.edu    void writeHint(Addr addr, int size, unsigned flags)
3014950Sgblack@eecs.umich.edu    {
3022683Sktlim@umich.edu        // need to do this...
303705SN/A    }
3044172Ssaidi@eecs.umich.edu
3054172Ssaidi@eecs.umich.edu    Fault copySrcTranslate(Addr src);
3064172Ssaidi@eecs.umich.edu
3074172Ssaidi@eecs.umich.edu    Fault copy(Addr dest);
3084172Ssaidi@eecs.umich.edu
3092159SN/A    // The register accessor methods provide the index of the
3102159SN/A    // instruction's operand (e.g., 0 or 1), not the architectural
3112683Sktlim@umich.edu    // register index, to simplify the implementation of register
3122159SN/A    // renaming.  We find the architectural register index by indexing
313705SN/A    // into the instruction's own operand index table.  Note that a
3144172Ssaidi@eecs.umich.edu    // raw pointer to the StaticInst is provided instead of a
3152159SN/A    // ref-counted StaticInstPtr to redice overhead.  This is fine as
3164172Ssaidi@eecs.umich.edu    // long as these methods don't copy the pointer into any long-term
3172159SN/A    // storage (which is pretty hard to imagine they would have reason
3182159SN/A    // to do).
3193468Sgblack@eecs.umich.edu
3202159SN/A    uint64_t readIntReg(const StaticInst *si, int idx)
3212683Sktlim@umich.edu    {
3222159SN/A        return cpuXC->readIntReg(si->srcRegIdx(idx));
3232159SN/A    }
3244185Ssaidi@eecs.umich.edu
3252159SN/A    float readFloatRegSingle(const StaticInst *si, int idx)
3264172Ssaidi@eecs.umich.edu    {
3274172Ssaidi@eecs.umich.edu        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
3282159SN/A        return cpuXC->readFloatRegSingle(reg_idx);
329705SN/A    }
3304185Ssaidi@eecs.umich.edu
3313792Sgblack@eecs.umich.edu    double readFloatRegDouble(const StaticInst *si, int idx)
3323792Sgblack@eecs.umich.edu    {
3333792Sgblack@eecs.umich.edu        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
3343792Sgblack@eecs.umich.edu        return cpuXC->readFloatRegDouble(reg_idx);
3353792Sgblack@eecs.umich.edu    }
3364185Ssaidi@eecs.umich.edu
3373792Sgblack@eecs.umich.edu    uint64_t readFloatRegInt(const StaticInst *si, int idx)
3383792Sgblack@eecs.umich.edu    {
3394172Ssaidi@eecs.umich.edu        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
3403792Sgblack@eecs.umich.edu        return cpuXC->readFloatRegInt(reg_idx);
3413792Sgblack@eecs.umich.edu    }
3424185Ssaidi@eecs.umich.edu
3433792Sgblack@eecs.umich.edu    void setIntReg(const StaticInst *si, int idx, uint64_t val)
3443792Sgblack@eecs.umich.edu    {
3453792Sgblack@eecs.umich.edu        cpuXC->setIntReg(si->destRegIdx(idx), val);
3464172Ssaidi@eecs.umich.edu    }
3473792Sgblack@eecs.umich.edu
3483792Sgblack@eecs.umich.edu    void setFloatRegSingle(const StaticInst *si, int idx, float val)
3494027Sstever@eecs.umich.edu    {
3504027Sstever@eecs.umich.edu        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
3514027Sstever@eecs.umich.edu        cpuXC->setFloatRegSingle(reg_idx, val);
3524027Sstever@eecs.umich.edu    }
3534027Sstever@eecs.umich.edu
3544027Sstever@eecs.umich.edu    void setFloatRegDouble(const StaticInst *si, int idx, double val)
3554027Sstever@eecs.umich.edu    {
3564027Sstever@eecs.umich.edu        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
3574661Sksewell@umich.edu        cpuXC->setFloatRegDouble(reg_idx, val);
3584661Sksewell@umich.edu    }
3594661Sksewell@umich.edu
3604661Sksewell@umich.edu    void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
3614661Sksewell@umich.edu    {
3624661Sksewell@umich.edu        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
3634661Sksewell@umich.edu        cpuXC->setFloatRegInt(reg_idx, val);
3644661Sksewell@umich.edu    }
3654661Sksewell@umich.edu
3664661Sksewell@umich.edu    uint64_t readPC() { return cpuXC->readPC(); }
3674661Sksewell@umich.edu    uint64_t readNextPC() { return cpuXC->readNextPC(); }
3684661Sksewell@umich.edu    uint64_t readNextNPC() { return cpuXC->readNextNPC(); }
3691858SN/A
3702683Sktlim@umich.edu    void setPC(uint64_t val) { cpuXC->setPC(val); }
3712680Sktlim@umich.edu    void setNextPC(uint64_t val) { cpuXC->setNextPC(val); }
3722683Sktlim@umich.edu    void setNextNPC(uint64_t val) { cpuXC->setNextNPC(val); }
373705SN/A
3742683Sktlim@umich.edu    MiscReg readMiscReg(int misc_reg)
375705SN/A    {
376705SN/A        return cpuXC->readMiscReg(misc_reg);
3772683Sktlim@umich.edu    }
3782680Sktlim@umich.edu
3792SN/A    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
3802SN/A    {
3812623SN/A        return cpuXC->readMiscRegWithEffect(misc_reg, fault);
382    }
383
384    Fault setMiscReg(int misc_reg, const MiscReg &val)
385    {
386        return cpuXC->setMiscReg(misc_reg, val);
387    }
388
389    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
390    {
391        return cpuXC->setMiscRegWithEffect(misc_reg, val);
392    }
393
394#if FULL_SYSTEM
395    Fault hwrei() { return cpuXC->hwrei(); }
396    int readIntrFlag() { return cpuXC->readIntrFlag(); }
397    void setIntrFlag(int val) { cpuXC->setIntrFlag(val); }
398    bool inPalMode() { return cpuXC->inPalMode(); }
399    void ev5_trap(Fault fault) { fault->invoke(xcProxy); }
400    bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); }
401#else
402    void syscall() { cpuXC->syscall(); }
403#endif
404
405    bool misspeculating() { return cpuXC->misspeculating(); }
406    ExecContext *xcBase() { return xcProxy; }
407};
408
409#endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
410