base.hh revision 2107
16019SN/A/*
26019SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
37134Sgblack@eecs.umich.edu * All rights reserved.
47134Sgblack@eecs.umich.edu *
57134Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67134Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77134Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87134Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97134Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107134Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117134Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127134Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137134Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147134Sgblack@eecs.umich.edu * this software without specific prior written permission.
156019SN/A *
166019SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176019SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186019SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196019SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206019SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216019SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226019SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236019SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246019SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256019SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266019SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276019SN/A */
286019SN/A
296019SN/A#ifndef __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
306019SN/A#define __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
316019SN/A
326019SN/A#include "base/statistics.hh"
336019SN/A#include "config/full_system.hh"
346019SN/A#include "cpu/base.hh"
356019SN/A#include "cpu/exec_context.hh"
366019SN/A#include "cpu/pc_event.hh"
376019SN/A#include "cpu/sampler/sampler.hh"
386019SN/A#include "cpu/static_inst.hh"
396019SN/A#include "sim/eventq.hh"
406019SN/A
416019SN/A// forward declarations
426308SN/A#if FULL_SYSTEM
436308SN/Aclass Processor;
446309SN/Aclass AlphaITB;
456309SN/Aclass AlphaDTB;
466309SN/Aclass PhysicalMemory;
476309SN/A
486309SN/Aclass RemoteGDB;
497134Sgblack@eecs.umich.educlass GDBListener;
507296Sgblack@eecs.umich.edu
516309SN/A#else
526309SN/A
537296Sgblack@eecs.umich.educlass Process;
547134Sgblack@eecs.umich.edu
556309SN/A#endif // FULL_SYSTEM
566309SN/A
576309SN/Aclass MemInterface;
587342Sgblack@eecs.umich.educlass Checkpoint;
597174Sgblack@eecs.umich.edu
607639Sgblack@eecs.umich.edunamespace Trace {
617639Sgblack@eecs.umich.edu    class InstRecord;
627644Sali.saidi@arm.com}
637639Sgblack@eecs.umich.edu
647639Sgblack@eecs.umich.educlass SimpleCPU : public BaseCPU
657639Sgblack@eecs.umich.edu{
667639Sgblack@eecs.umich.edu  protected:
677639Sgblack@eecs.umich.edu    typedef TheISA::MachInst MachInst;
687639Sgblack@eecs.umich.edu  public:
697639Sgblack@eecs.umich.edu    // main simulation loop (one cycle)
707639Sgblack@eecs.umich.edu    void tick();
717644Sali.saidi@arm.com
727639Sgblack@eecs.umich.edu  private:
737639Sgblack@eecs.umich.edu    struct TickEvent : public Event
747639Sgblack@eecs.umich.edu    {
757639Sgblack@eecs.umich.edu        SimpleCPU *cpu;
767639Sgblack@eecs.umich.edu        int width;
777639Sgblack@eecs.umich.edu
787639Sgblack@eecs.umich.edu        TickEvent(SimpleCPU *c, int w);
797639Sgblack@eecs.umich.edu        void process();
807639Sgblack@eecs.umich.edu        const char *description();
817639Sgblack@eecs.umich.edu    };
827644Sali.saidi@arm.com
837639Sgblack@eecs.umich.edu    TickEvent tickEvent;
847639Sgblack@eecs.umich.edu
857639Sgblack@eecs.umich.edu    /// Schedule tick event, regardless of its current state.
867639Sgblack@eecs.umich.edu    void scheduleTickEvent(int numCycles)
877639Sgblack@eecs.umich.edu    {
887174Sgblack@eecs.umich.edu        if (tickEvent.squashed())
896754SN/A            tickEvent.reschedule(curTick + cycles(numCycles));
907296Sgblack@eecs.umich.edu        else if (!tickEvent.scheduled())
917400SAli.Saidi@ARM.com            tickEvent.schedule(curTick + cycles(numCycles));
927134Sgblack@eecs.umich.edu    }
937400SAli.Saidi@ARM.com
947134Sgblack@eecs.umich.edu    /// Unschedule tick event, regardless of its current state.
957134Sgblack@eecs.umich.edu    void unscheduleTickEvent()
967797Sgblack@eecs.umich.edu    {
977858SMatt.Horsnell@arm.com        if (tickEvent.scheduled())
987858SMatt.Horsnell@arm.com            tickEvent.squash();
996754SN/A    }
1006754SN/A
1016754SN/A  private:
1026754SN/A    Trace::InstRecord *traceData;
1036754SN/A
1047134Sgblack@eecs.umich.edu  public:
1057422Sgblack@eecs.umich.edu    //
1067648SAli.Saidi@ARM.com    enum Status {
1076754SN/A        Running,
1087296Sgblack@eecs.umich.edu        Idle,
1096309SN/A        IcacheMissStall,
1106309SN/A        IcacheMissComplete,
1117296Sgblack@eecs.umich.edu        DcacheMissStall,
1127303Sgblack@eecs.umich.edu        DcacheMissSwitch,
1137134Sgblack@eecs.umich.edu        SwitchedOut
1146309SN/A    };
1156309SN/A
1166309SN/A  private:
1177296Sgblack@eecs.umich.edu    Status _status;
1187174Sgblack@eecs.umich.edu
1197174Sgblack@eecs.umich.edu  public:
1207296Sgblack@eecs.umich.edu    void post_interrupt(int int_num, int index);
1217303Sgblack@eecs.umich.edu
1227644Sali.saidi@arm.com    void zero_fill_64(Addr addr) {
1237644Sali.saidi@arm.com      static int warned = 0;
1247174Sgblack@eecs.umich.edu      if (!warned) {
1257174Sgblack@eecs.umich.edu        warn ("WH64 is not implemented");
1267174Sgblack@eecs.umich.edu        warned = 1;
1277639Sgblack@eecs.umich.edu      }
1287639Sgblack@eecs.umich.edu    };
1297639Sgblack@eecs.umich.edu
1307639Sgblack@eecs.umich.edu  public:
1317639Sgblack@eecs.umich.edu    struct Params : public BaseCPU::Params
1327644Sali.saidi@arm.com    {
1337639Sgblack@eecs.umich.edu        MemInterface *icache_interface;
1347639Sgblack@eecs.umich.edu        MemInterface *dcache_interface;
1357639Sgblack@eecs.umich.edu        int width;
1367639Sgblack@eecs.umich.edu#if FULL_SYSTEM
1377639Sgblack@eecs.umich.edu        AlphaITB *itb;
1387639Sgblack@eecs.umich.edu        AlphaDTB *dtb;
1397639Sgblack@eecs.umich.edu        FunctionalMemory *mem;
1407639Sgblack@eecs.umich.edu#else
1417639Sgblack@eecs.umich.edu        Process *process;
1427639Sgblack@eecs.umich.edu#endif
1437639Sgblack@eecs.umich.edu    };
1447644Sali.saidi@arm.com    SimpleCPU(Params *params);
1457639Sgblack@eecs.umich.edu    virtual ~SimpleCPU();
1467639Sgblack@eecs.umich.edu
1477639Sgblack@eecs.umich.edu  public:
1487639Sgblack@eecs.umich.edu    // execution context
1497639Sgblack@eecs.umich.edu    ExecContext *xc;
1507639Sgblack@eecs.umich.edu
1517174Sgblack@eecs.umich.edu    void switchOut(Sampler *s);
1527174Sgblack@eecs.umich.edu    void takeOverFrom(BaseCPU *oldCPU);
1537639Sgblack@eecs.umich.edu
1547639Sgblack@eecs.umich.edu#if FULL_SYSTEM
1557639Sgblack@eecs.umich.edu    Addr dbg_vtophys(Addr addr);
1567639Sgblack@eecs.umich.edu
1577174Sgblack@eecs.umich.edu    bool interval_stats;
1587174Sgblack@eecs.umich.edu#endif
1597174Sgblack@eecs.umich.edu
1607174Sgblack@eecs.umich.edu    // L1 instruction cache
1617174Sgblack@eecs.umich.edu    MemInterface *icacheInterface;
1627174Sgblack@eecs.umich.edu
1637174Sgblack@eecs.umich.edu    // L1 data cache
1647174Sgblack@eecs.umich.edu    MemInterface *dcacheInterface;
1657174Sgblack@eecs.umich.edu
1667174Sgblack@eecs.umich.edu    // current instruction
1677174Sgblack@eecs.umich.edu    MachInst inst;
1686309SN/A
1696308SN/A    // Refcounted pointer to the one memory request.
1707639Sgblack@eecs.umich.edu    MemReqPtr memReq;
1717639Sgblack@eecs.umich.edu
1727639Sgblack@eecs.umich.edu    // Pointer to the sampler that is telling us to switchover.
1737639Sgblack@eecs.umich.edu    // Used to signal the completion of the pipe drain and schedule
1747639Sgblack@eecs.umich.edu    // the next switchover
1757639Sgblack@eecs.umich.edu    Sampler *sampler;
1767639Sgblack@eecs.umich.edu
1777639Sgblack@eecs.umich.edu    StaticInstPtr curStaticInst;
1787639Sgblack@eecs.umich.edu
1797639Sgblack@eecs.umich.edu    class CacheCompletionEvent : public Event
1807639Sgblack@eecs.umich.edu    {
1817639Sgblack@eecs.umich.edu      private:
1827639Sgblack@eecs.umich.edu        SimpleCPU *cpu;
1837639Sgblack@eecs.umich.edu
1847639Sgblack@eecs.umich.edu      public:
1857639Sgblack@eecs.umich.edu        CacheCompletionEvent(SimpleCPU *_cpu);
1867639Sgblack@eecs.umich.edu
1877639Sgblack@eecs.umich.edu        virtual void process();
1887639Sgblack@eecs.umich.edu        virtual const char *description();
1897639Sgblack@eecs.umich.edu    };
1907639Sgblack@eecs.umich.edu
1917639Sgblack@eecs.umich.edu    CacheCompletionEvent cacheCompletionEvent;
1927639Sgblack@eecs.umich.edu
1937639Sgblack@eecs.umich.edu    Status status() const { return _status; }
1947639Sgblack@eecs.umich.edu
1957639Sgblack@eecs.umich.edu    virtual void activateContext(int thread_num, int delay);
1967639Sgblack@eecs.umich.edu    virtual void suspendContext(int thread_num);
1977639Sgblack@eecs.umich.edu    virtual void deallocateContext(int thread_num);
1987639Sgblack@eecs.umich.edu    virtual void haltContext(int thread_num);
1997639Sgblack@eecs.umich.edu
2007639Sgblack@eecs.umich.edu    // statistics
2017639Sgblack@eecs.umich.edu    virtual void regStats();
2027639Sgblack@eecs.umich.edu    virtual void resetStats();
2037639Sgblack@eecs.umich.edu
2047639Sgblack@eecs.umich.edu    // number of simulated instructions
2057639Sgblack@eecs.umich.edu    Counter numInst;
2067639Sgblack@eecs.umich.edu    Counter startNumInst;
2077639Sgblack@eecs.umich.edu    Stats::Scalar<> numInsts;
2087639Sgblack@eecs.umich.edu
2097639Sgblack@eecs.umich.edu    virtual Counter totalInstructions() const
2107639Sgblack@eecs.umich.edu    {
2117639Sgblack@eecs.umich.edu        return numInst - startNumInst;
2127639Sgblack@eecs.umich.edu    }
2137639Sgblack@eecs.umich.edu
2147639Sgblack@eecs.umich.edu    // number of simulated memory references
2157639Sgblack@eecs.umich.edu    Stats::Scalar<> numMemRefs;
2167639Sgblack@eecs.umich.edu
2177639Sgblack@eecs.umich.edu    // number of simulated loads
2187639Sgblack@eecs.umich.edu    Counter numLoad;
2197639Sgblack@eecs.umich.edu    Counter startNumLoad;
2207639Sgblack@eecs.umich.edu
2217639Sgblack@eecs.umich.edu    // number of idle cycles
2227639Sgblack@eecs.umich.edu    Stats::Average<> notIdleFraction;
2237639Sgblack@eecs.umich.edu    Stats::Formula idleFraction;
2247639Sgblack@eecs.umich.edu
2257639Sgblack@eecs.umich.edu    // number of cycles stalled for I-cache misses
2267639Sgblack@eecs.umich.edu    Stats::Scalar<> icacheStallCycles;
2277639Sgblack@eecs.umich.edu    Counter lastIcacheStall;
2287644Sali.saidi@arm.com
2297639Sgblack@eecs.umich.edu    // number of cycles stalled for D-cache misses
2307639Sgblack@eecs.umich.edu    Stats::Scalar<> dcacheStallCycles;
2317639Sgblack@eecs.umich.edu    Counter lastDcacheStall;
2327639Sgblack@eecs.umich.edu
2337639Sgblack@eecs.umich.edu    void processCacheCompletion();
2347639Sgblack@eecs.umich.edu
2357639Sgblack@eecs.umich.edu    virtual void serialize(std::ostream &os);
2367639Sgblack@eecs.umich.edu    virtual void unserialize(Checkpoint *cp, const std::string &section);
2377644Sali.saidi@arm.com
2387639Sgblack@eecs.umich.edu    template <class T>
2397639Sgblack@eecs.umich.edu    Fault * read(Addr addr, T &data, unsigned flags);
2407639Sgblack@eecs.umich.edu
2417639Sgblack@eecs.umich.edu    template <class T>
2427639Sgblack@eecs.umich.edu    Fault * write(T data, Addr addr, unsigned flags, uint64_t *res);
2437639Sgblack@eecs.umich.edu
2447639Sgblack@eecs.umich.edu    // These functions are only used in CPU models that split
2457639Sgblack@eecs.umich.edu    // effective address computation from the actual memory access.
2467639Sgblack@eecs.umich.edu    void setEA(Addr EA) { panic("SimpleCPU::setEA() not implemented\n"); }
2477639Sgblack@eecs.umich.edu    Addr getEA() 	{ panic("SimpleCPU::getEA() not implemented\n"); }
2487639Sgblack@eecs.umich.edu
2497639Sgblack@eecs.umich.edu    void prefetch(Addr addr, unsigned flags)
2507639Sgblack@eecs.umich.edu    {
2517639Sgblack@eecs.umich.edu        // need to do this...
2527639Sgblack@eecs.umich.edu    }
2537639Sgblack@eecs.umich.edu
2547639Sgblack@eecs.umich.edu    void writeHint(Addr addr, int size, unsigned flags)
2557639Sgblack@eecs.umich.edu    {
2567639Sgblack@eecs.umich.edu        // need to do this...
2577639Sgblack@eecs.umich.edu    }
2587639Sgblack@eecs.umich.edu
2597639Sgblack@eecs.umich.edu    Fault * copySrcTranslate(Addr src);
2607639Sgblack@eecs.umich.edu
2617639Sgblack@eecs.umich.edu    Fault * copy(Addr dest);
2627639Sgblack@eecs.umich.edu
2637639Sgblack@eecs.umich.edu    // The register accessor methods provide the index of the
2647639Sgblack@eecs.umich.edu    // instruction's operand (e.g., 0 or 1), not the architectural
2657639Sgblack@eecs.umich.edu    // register index, to simplify the implementation of register
2667639Sgblack@eecs.umich.edu    // renaming.  We find the architectural register index by indexing
2677639Sgblack@eecs.umich.edu    // into the instruction's own operand index table.  Note that a
2687639Sgblack@eecs.umich.edu    // raw pointer to the StaticInst is provided instead of a
2697639Sgblack@eecs.umich.edu    // ref-counted StaticInstPtr to redice overhead.  This is fine as
2707639Sgblack@eecs.umich.edu    // long as these methods don't copy the pointer into any long-term
2717639Sgblack@eecs.umich.edu    // storage (which is pretty hard to imagine they would have reason
2727639Sgblack@eecs.umich.edu    // to do).
2737639Sgblack@eecs.umich.edu
2747639Sgblack@eecs.umich.edu    uint64_t readIntReg(const StaticInst *si, int idx)
2757639Sgblack@eecs.umich.edu    {
2767639Sgblack@eecs.umich.edu        return xc->readIntReg(si->srcRegIdx(idx));
2777639Sgblack@eecs.umich.edu    }
2787639Sgblack@eecs.umich.edu
2797639Sgblack@eecs.umich.edu    float readFloatRegSingle(const StaticInst *si, int idx)
2807639Sgblack@eecs.umich.edu    {
2817639Sgblack@eecs.umich.edu        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
2827639Sgblack@eecs.umich.edu        return xc->readFloatRegSingle(reg_idx);
2837639Sgblack@eecs.umich.edu    }
2847639Sgblack@eecs.umich.edu
2857639Sgblack@eecs.umich.edu    double readFloatRegDouble(const StaticInst *si, int idx)
2867639Sgblack@eecs.umich.edu    {
2877639Sgblack@eecs.umich.edu        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
2887639Sgblack@eecs.umich.edu        return xc->readFloatRegDouble(reg_idx);
2897639Sgblack@eecs.umich.edu    }
2907639Sgblack@eecs.umich.edu
2917639Sgblack@eecs.umich.edu    uint64_t readFloatRegInt(const StaticInst *si, int idx)
2927639Sgblack@eecs.umich.edu    {
2937639Sgblack@eecs.umich.edu        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
2947639Sgblack@eecs.umich.edu        return xc->readFloatRegInt(reg_idx);
2957639Sgblack@eecs.umich.edu    }
2967639Sgblack@eecs.umich.edu
2977639Sgblack@eecs.umich.edu    void setIntReg(const StaticInst *si, int idx, uint64_t val)
2987639Sgblack@eecs.umich.edu    {
2997639Sgblack@eecs.umich.edu        xc->setIntReg(si->destRegIdx(idx), val);
3007639Sgblack@eecs.umich.edu    }
3017639Sgblack@eecs.umich.edu
3027639Sgblack@eecs.umich.edu    void setFloatRegSingle(const StaticInst *si, int idx, float val)
3037639Sgblack@eecs.umich.edu    {
3047639Sgblack@eecs.umich.edu        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
3057639Sgblack@eecs.umich.edu        xc->setFloatRegSingle(reg_idx, val);
3067639Sgblack@eecs.umich.edu    }
3077639Sgblack@eecs.umich.edu
3087639Sgblack@eecs.umich.edu    void setFloatRegDouble(const StaticInst *si, int idx, double val)
3097639Sgblack@eecs.umich.edu    {
3107639Sgblack@eecs.umich.edu        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
3117639Sgblack@eecs.umich.edu        xc->setFloatRegDouble(reg_idx, val);
3127639Sgblack@eecs.umich.edu    }
3137639Sgblack@eecs.umich.edu
3147639Sgblack@eecs.umich.edu    void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
3157639Sgblack@eecs.umich.edu    {
3167639Sgblack@eecs.umich.edu        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
3177639Sgblack@eecs.umich.edu        xc->setFloatRegInt(reg_idx, val);
3187639Sgblack@eecs.umich.edu    }
3197639Sgblack@eecs.umich.edu
3207639Sgblack@eecs.umich.edu    uint64_t readPC() { return xc->readPC(); }
3217639Sgblack@eecs.umich.edu    void setNextPC(uint64_t val) { xc->setNextPC(val); }
3227639Sgblack@eecs.umich.edu
3237639Sgblack@eecs.umich.edu    uint64_t readUniq() { return xc->readUniq(); }
3247639Sgblack@eecs.umich.edu    void setUniq(uint64_t val) { xc->setUniq(val); }
3257639Sgblack@eecs.umich.edu
3267639Sgblack@eecs.umich.edu    uint64_t readFpcr() { return xc->readFpcr(); }
3277639Sgblack@eecs.umich.edu    void setFpcr(uint64_t val) { xc->setFpcr(val); }
3287639Sgblack@eecs.umich.edu
3297639Sgblack@eecs.umich.edu#if FULL_SYSTEM
3307639Sgblack@eecs.umich.edu    uint64_t readIpr(int idx, Fault * &fault) { return xc->readIpr(idx, fault); }
3317639Sgblack@eecs.umich.edu    Fault * setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); }
3327639Sgblack@eecs.umich.edu    Fault * hwrei() { return xc->hwrei(); }
3337639Sgblack@eecs.umich.edu    int readIntrFlag() { return xc->readIntrFlag(); }
3347639Sgblack@eecs.umich.edu    void setIntrFlag(int val) { xc->setIntrFlag(val); }
3357639Sgblack@eecs.umich.edu    bool inPalMode() { return xc->inPalMode(); }
3367639Sgblack@eecs.umich.edu    void ev5_trap(Fault * fault) { xc->ev5_trap(fault); }
3377639Sgblack@eecs.umich.edu    bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
3387639Sgblack@eecs.umich.edu#else
3397639Sgblack@eecs.umich.edu    void syscall() { xc->syscall(); }
3407639Sgblack@eecs.umich.edu#endif
3417639Sgblack@eecs.umich.edu
3427639Sgblack@eecs.umich.edu    bool misspeculating() { return xc->misspeculating(); }
3437639Sgblack@eecs.umich.edu    ExecContext *xcBase() { return xc; }
3447639Sgblack@eecs.umich.edu};
3457639Sgblack@eecs.umich.edu
3467639Sgblack@eecs.umich.edu#endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
3477639Sgblack@eecs.umich.edu