cpu.hh revision 1684
110037SARM gem5 Developers//Todo: Add in a lot of the functions that are ISA specific.  Also define
210037SARM gem5 Developers//the functions that currently exist within the base cpu class.  Define
312531Sandreas.sandberg@arm.com//everything for the simobject stuff so it can be serialized and
410037SARM gem5 Developers//instantiated, add in debugging statements everywhere.  Have CPU schedule
510037SARM gem5 Developers//itself properly.  Constructor.  Derived alpha class.  Threads!
610037SARM gem5 Developers// Avoid running stages and advancing queues if idle/stalled.
710037SARM gem5 Developers
810037SARM gem5 Developers#ifndef __CPU_BETA_CPU_FULL_CPU_HH__
910037SARM gem5 Developers#define __CPU_BETA_CPU_FULL_CPU_HH__
1010037SARM gem5 Developers
1110037SARM gem5 Developers#include <iostream>
1210037SARM gem5 Developers#include <list>
1310037SARM gem5 Developers#include <vector>
1410037SARM gem5 Developers
1510037SARM gem5 Developers#include "base/statistics.hh"
1610037SARM gem5 Developers#include "base/timebuf.hh"
1710037SARM gem5 Developers#include "cpu/base_cpu.hh"
1810037SARM gem5 Developers#include "cpu/beta_cpu/comm.hh"
1910037SARM gem5 Developers#include "cpu/beta_cpu/cpu_policy.hh"
2010037SARM gem5 Developers#include "cpu/exec_context.hh"
2110037SARM gem5 Developers#include "sim/process.hh"
2210037SARM gem5 Developers
2310037SARM gem5 Developers#ifdef FULL_SYSTEM
2410037SARM gem5 Developers#include "arch/alpha/ev5.hh"
2510037SARM gem5 Developersusing namespace EV5;
2610037SARM gem5 Developers#endif
2710037SARM gem5 Developers
2810037SARM gem5 Developersclass FunctionalMemory;
2910037SARM gem5 Developersclass Process;
3010037SARM gem5 Developers
3110037SARM gem5 Developersclass BaseFullCPU : public BaseCPU
3210037SARM gem5 Developers{
3310037SARM gem5 Developers    //Stuff that's pretty ISA independent will go here.
3410037SARM gem5 Developers  public:
3510037SARM gem5 Developers    typedef BaseCPU::Params Params;
3610037SARM gem5 Developers
3710037SARM gem5 Developers#ifdef FULL_SYSTEM
3810037SARM gem5 Developers    BaseFullCPU(Params &params);
3910037SARM gem5 Developers#else
4010037SARM gem5 Developers    BaseFullCPU(Params &params);
4110037SARM gem5 Developers#endif // FULL_SYSTEM
4210474Sandreas.hansson@arm.com
4310037SARM gem5 Developers  private:
4410037SARM gem5 Developers    int cpu_id;
4512538Sgiacomo.travaglini@arm.com};
4610037SARM gem5 Developers
4710037SARM gem5 Developerstemplate <class Impl>
4812538Sgiacomo.travaglini@arm.comclass FullBetaCPU : public BaseFullCPU
4912538Sgiacomo.travaglini@arm.com{
5010037SARM gem5 Developers  public:
5110037SARM gem5 Developers    //Put typedefs from the Impl here.
5211576SDylan.Johnson@ARM.com    typedef typename Impl::ISA ISA;
5311576SDylan.Johnson@ARM.com    typedef typename Impl::CPUPol CPUPolicy;
5413362Sgiacomo.travaglini@arm.com    typedef typename Impl::Params Params;
5513362Sgiacomo.travaglini@arm.com    typedef typename Impl::DynInstPtr DynInstPtr;
5611576SDylan.Johnson@ARM.com
5713362Sgiacomo.travaglini@arm.com  public:
5813362Sgiacomo.travaglini@arm.com    enum Status {
5913362Sgiacomo.travaglini@arm.com        Running,
6013362Sgiacomo.travaglini@arm.com        Idle,
6113362Sgiacomo.travaglini@arm.com        Halted,
6213362Sgiacomo.travaglini@arm.com        Blocked // ?
6313362Sgiacomo.travaglini@arm.com    };
6413362Sgiacomo.travaglini@arm.com
6513362Sgiacomo.travaglini@arm.com    Status _status;
6613362Sgiacomo.travaglini@arm.com
6713362Sgiacomo.travaglini@arm.com  private:
6811576SDylan.Johnson@ARM.com    class TickEvent : public Event
6911576SDylan.Johnson@ARM.com    {
7011576SDylan.Johnson@ARM.com      private:
7111576SDylan.Johnson@ARM.com        FullBetaCPU<Impl> *cpu;
7211576SDylan.Johnson@ARM.com
7312538Sgiacomo.travaglini@arm.com      public:
7411576SDylan.Johnson@ARM.com        TickEvent(FullBetaCPU<Impl> *c);
7511576SDylan.Johnson@ARM.com        void process();
7612538Sgiacomo.travaglini@arm.com        const char *description();
7712538Sgiacomo.travaglini@arm.com    };
7811576SDylan.Johnson@ARM.com
7911576SDylan.Johnson@ARM.com    TickEvent tickEvent;
8010037SARM gem5 Developers
8110037SARM gem5 Developers    /// Schedule tick event, regardless of its current state.
8210037SARM gem5 Developers    void scheduleTickEvent(int delay)
8310037SARM gem5 Developers    {
8410037SARM gem5 Developers        if (tickEvent.squashed())
8510037SARM gem5 Developers            tickEvent.reschedule(curTick + delay);
8610037SARM gem5 Developers        else if (!tickEvent.scheduled())
8710037SARM gem5 Developers            tickEvent.schedule(curTick + delay);
8810474Sandreas.hansson@arm.com    }
8910037SARM gem5 Developers
9010037SARM gem5 Developers    /// Unschedule tick event, regardless of its current state.
9110037SARM gem5 Developers    void unscheduleTickEvent()
9212538Sgiacomo.travaglini@arm.com    {
9310037SARM gem5 Developers        if (tickEvent.scheduled())
9412538Sgiacomo.travaglini@arm.com            tickEvent.squash();
9512538Sgiacomo.travaglini@arm.com    }
9610037SARM gem5 Developers
9710037SARM gem5 Developers  public:
9810037SARM gem5 Developers    FullBetaCPU(Params &params);
9910037SARM gem5 Developers    ~FullBetaCPU();
10010037SARM gem5 Developers
10110037SARM gem5 Developers    void fullCPURegStats();
10210037SARM gem5 Developers
10310037SARM gem5 Developers    void tick();
10410037SARM gem5 Developers
10510037SARM gem5 Developers    void init();
10610037SARM gem5 Developers
10710037SARM gem5 Developers    void activateContext(int thread_num, int delay);
10810037SARM gem5 Developers    void suspendContext(int thread_num);
10910037SARM gem5 Developers    void deallocateContext(int thread_num);
11010037SARM gem5 Developers    void haltContext(int thread_num);
11110037SARM gem5 Developers
11210037SARM gem5 Developers    void switchOut();
11310037SARM gem5 Developers    void takeOverFrom(BaseCPU *oldCPU);
11410037SARM gem5 Developers
11510537Sandreas.hansson@arm.com    /** Get the current instruction sequence number, and increment it. */
11610537Sandreas.hansson@arm.com    InstSeqNum getAndIncrementInstSeq();
11710037SARM gem5 Developers
11810037SARM gem5 Developers#ifdef FULL_SYSTEM
11910037SARM gem5 Developers    /** Check if this address is a valid instruction address. */
12010037SARM gem5 Developers    bool validInstAddr(Addr addr) { return true; }
12110037SARM gem5 Developers
12210037SARM gem5 Developers    /** Check if this address is a valid data address. */
12310037SARM gem5 Developers    bool validDataAddr(Addr addr) { return true; }
12410037SARM gem5 Developers
12510037SARM gem5 Developers    /** Get instruction asid. */
12610037SARM gem5 Developers    int getInstAsid()
12710037SARM gem5 Developers    { return ITB_ASN_ASN(regFile.getIpr()[ISA::IPR_ITB_ASN]); }
12810037SARM gem5 Developers
12910037SARM gem5 Developers    /** Get data asid. */
13010037SARM gem5 Developers    int getDataAsid()
13110037SARM gem5 Developers    { return DTB_ASN_ASN(regFile.getIpr()[ISA::IPR_DTB_ASN]); }
13210037SARM gem5 Developers#else
13310037SARM gem5 Developers    bool validInstAddr(Addr addr)
13410037SARM gem5 Developers    { return thread[0]->validInstAddr(addr); }
13510037SARM gem5 Developers
13610037SARM gem5 Developers    bool validDataAddr(Addr addr)
13710037SARM gem5 Developers    { return thread[0]->validDataAddr(addr); }
13810037SARM gem5 Developers
13910037SARM gem5 Developers    int getInstAsid() { return thread[0]->asid; }
14010037SARM gem5 Developers    int getDataAsid() { return thread[0]->asid; }
14110037SARM gem5 Developers
14210037SARM gem5 Developers#endif
14310037SARM gem5 Developers
14410474Sandreas.hansson@arm.com    //
14510037SARM gem5 Developers    // New accessors for new decoder.
14610037SARM gem5 Developers    //
14710037SARM gem5 Developers    uint64_t readIntReg(int reg_idx);
14810037SARM gem5 Developers
14910037SARM gem5 Developers    float readFloatRegSingle(int reg_idx);
15010037SARM gem5 Developers
15110037SARM gem5 Developers    double readFloatRegDouble(int reg_idx);
15212259Sgiacomo.travaglini@arm.com
15312488Sgiacomo.travaglini@arm.com    uint64_t readFloatRegInt(int reg_idx);
15410037SARM gem5 Developers
15510037SARM gem5 Developers    void setIntReg(int reg_idx, uint64_t val);
15610037SARM gem5 Developers
15710037SARM gem5 Developers    void setFloatRegSingle(int reg_idx, float val);
15812259Sgiacomo.travaglini@arm.com
15912261Sgiacomo.travaglini@arm.com    void setFloatRegDouble(int reg_idx, double val);
16010037SARM gem5 Developers
16110037SARM gem5 Developers    void setFloatRegInt(int reg_idx, uint64_t val);
16210037SARM gem5 Developers
16310037SARM gem5 Developers    uint64_t readPC();
16410037SARM gem5 Developers
16510037SARM gem5 Developers    void setNextPC(uint64_t val);
16610037SARM gem5 Developers
16710037SARM gem5 Developers    void setPC(Addr new_PC);
16810037SARM gem5 Developers
16910037SARM gem5 Developers    /** Function to add instruction onto the head of the list of the
17010037SARM gem5 Developers     *  instructions.  Used when new instructions are fetched.
17110037SARM gem5 Developers     */
17210037SARM gem5 Developers    void addInst(DynInstPtr &inst);
17310037SARM gem5 Developers
17410037SARM gem5 Developers    /** Function to tell the CPU that an instruction has completed. */
17512299Sandreas.sandberg@arm.com    void instDone();
17612299Sandreas.sandberg@arm.com
17712299Sandreas.sandberg@arm.com    /** Remove all instructions in back of the given instruction, but leave
17812299Sandreas.sandberg@arm.com     *  that instruction in the list.  This is useful in a squash, when there
17912299Sandreas.sandberg@arm.com     *  are instructions in this list that don't exist in structures such as
18012299Sandreas.sandberg@arm.com     *  the ROB.  The instruction doesn't have to be the last instruction in
18112299Sandreas.sandberg@arm.com     *  the list, but will be once this function completes.
18212538Sgiacomo.travaglini@arm.com     *  @todo: Remove only up until that inst?  Squashed inst is most likely
18312299Sandreas.sandberg@arm.com     *  valid.
18412538Sgiacomo.travaglini@arm.com     */
18512538Sgiacomo.travaglini@arm.com    void removeBackInst(DynInstPtr &inst);
18612299Sandreas.sandberg@arm.com
18712531Sandreas.sandberg@arm.com    /** Remove an instruction from the front of the list.  It is expected
18812531Sandreas.sandberg@arm.com     *  that there are no instructions in front of it (that is, none are older
18912531Sandreas.sandberg@arm.com     *  than the instruction being removed).  Used when retiring instructions.
19012539Sgiacomo.travaglini@arm.com     *  @todo: Remove the argument to this function, and just have it remove
19112531Sandreas.sandberg@arm.com     *  last instruction once it's verified that commit has the same ordering
19212531Sandreas.sandberg@arm.com     *  as the instruction list.
19312531Sandreas.sandberg@arm.com     */
19412531Sandreas.sandberg@arm.com    void removeFrontInst(DynInstPtr &inst);
19512531Sandreas.sandberg@arm.com
19612531Sandreas.sandberg@arm.com    /** Remove all instructions that are not currently in the ROB. */
19712531Sandreas.sandberg@arm.com    void removeInstsNotInROB();
19812531Sandreas.sandberg@arm.com
19912531Sandreas.sandberg@arm.com    /** Remove all instructions younger than the given sequence number. */
20012531Sandreas.sandberg@arm.com    void removeInstsUntil(const InstSeqNum &seq_num);
20112538Sgiacomo.travaglini@arm.com
20212531Sandreas.sandberg@arm.com    /** Remove all instructions from the list. */
20312538Sgiacomo.travaglini@arm.com    void removeAllInsts();
20412543Sgiacomo.travaglini@arm.com
20512531Sandreas.sandberg@arm.com    void dumpInsts();
20610037SARM gem5 Developers
207    /** Basically a wrapper function so that instructions executed at
208     *  commit can tell the instruction queue that they have completed.
209     *  Eventually this hack should be removed.
210     */
211    void wakeDependents(DynInstPtr &inst);
212
213  public:
214    /** List of all the instructions in flight. */
215    list<DynInstPtr> instList;
216
217    //not sure these should be private.
218  protected:
219    /** The fetch stage. */
220    typename CPUPolicy::Fetch fetch;
221
222    /** The fetch stage's status. */
223    typename CPUPolicy::Fetch::Status fetchStatus;
224
225    /** The decode stage. */
226    typename CPUPolicy::Decode decode;
227
228    /** The decode stage's status. */
229    typename CPUPolicy::Decode::Status decodeStatus;
230
231    /** The dispatch stage. */
232    typename CPUPolicy::Rename rename;
233
234    /** The dispatch stage's status. */
235    typename CPUPolicy::Rename::Status renameStatus;
236
237    /** The issue/execute/writeback stages. */
238    typename CPUPolicy::IEW iew;
239
240    /** The issue/execute/writeback stage's status. */
241    typename CPUPolicy::IEW::Status iewStatus;
242
243    /** The commit stage. */
244    typename CPUPolicy::Commit commit;
245
246    /** The fetch stage's status. */
247    typename CPUPolicy::Commit::Status commitStatus;
248
249    //Might want to just pass these objects in to the constructors of the
250    //appropriate stage.  regFile is in iew, freeList in dispatch, renameMap
251    //in dispatch, and the rob in commit.
252    /** The register file. */
253    typename CPUPolicy::RegFile regFile;
254
255    /** The free list. */
256    typename CPUPolicy::FreeList freeList;
257
258    /** The rename map. */
259    typename CPUPolicy::RenameMap renameMap;
260
261    /** The re-order buffer. */
262    typename CPUPolicy::ROB rob;
263
264  public:
265    /** Typedefs from the Impl to get the structs that each of the
266     *  time buffers should use.
267     */
268    typedef typename CPUPolicy::TimeStruct TimeStruct;
269
270    typedef typename CPUPolicy::FetchStruct FetchStruct;
271
272    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
273
274    typedef typename CPUPolicy::RenameStruct RenameStruct;
275
276    typedef typename CPUPolicy::IEWStruct IEWStruct;
277
278    /** The main time buffer to do backwards communication. */
279    TimeBuffer<TimeStruct> timeBuffer;
280
281    /** The fetch stage's instruction queue. */
282    TimeBuffer<FetchStruct> fetchQueue;
283
284    /** The decode stage's instruction queue. */
285    TimeBuffer<DecodeStruct> decodeQueue;
286
287    /** The rename stage's instruction queue. */
288    TimeBuffer<RenameStruct> renameQueue;
289
290    /** The IEW stage's instruction queue. */
291    TimeBuffer<IEWStruct> iewQueue;
292
293  public:
294    /** The temporary exec context to support older accessors. */
295    ExecContext *xc;
296
297    /** Temporary function to get pointer to exec context. */
298    ExecContext *xcBase()
299    {
300#ifdef FULL_SYSTEM
301        return system->execContexts[0];
302#else
303        return thread[0];
304#endif
305    }
306
307    InstSeqNum globalSeqNum;
308
309#ifdef FULL_SYSTEM
310    System *system;
311
312    MemoryController *memCtrl;
313    PhysicalMemory *physmem;
314
315    AlphaITB *itb;
316    AlphaDTB *dtb;
317
318//    SWContext *swCtx;
319#else
320    std::vector<ExecContext *> thread;
321#endif
322
323    FunctionalMemory *mem;
324
325    MemInterface *icacheInterface;
326    MemInterface *dcacheInterface;
327
328    bool deferRegistration;
329
330    Counter numInsts;
331
332    Counter funcExeInst;
333};
334
335#endif
336