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 &section);
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