cpu.hh revision 2665
11689SN/A/*
21689SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
31689SN/A * All rights reserved.
41689SN/A *
51689SN/A * Redistribution and use in source and binary forms, with or without
61689SN/A * modification, are permitted provided that the following conditions are
71689SN/A * met: redistributions of source code must retain the above copyright
81689SN/A * notice, this list of conditions and the following disclaimer;
91689SN/A * redistributions in binary form must reproduce the above copyright
101689SN/A * notice, this list of conditions and the following disclaimer in the
111689SN/A * documentation and/or other materials provided with the distribution;
121689SN/A * neither the name of the copyright holders nor the names of its
131689SN/A * contributors may be used to endorse or promote products derived from
141689SN/A * this software without specific prior written permission.
151689SN/A *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim
291689SN/A */
301689SN/A
311060SN/A//Todo: Add in a lot of the functions that are ISA specific.  Also define
321060SN/A//the functions that currently exist within the base cpu class.  Define
331060SN/A//everything for the simobject stuff so it can be serialized and
341060SN/A//instantiated, add in debugging statements everywhere.  Have CPU schedule
351689SN/A//itself properly.  Threads!
361060SN/A// Avoid running stages and advancing queues if idle/stalled.
371060SN/A
381755SN/A#ifndef __CPU_O3_CPU_FULL_CPU_HH__
391755SN/A#define __CPU_O3_CPU_FULL_CPU_HH__
401060SN/A
411060SN/A#include <iostream>
421060SN/A#include <list>
431681SN/A#include <vector>
441060SN/A
451060SN/A#include "base/statistics.hh"
461060SN/A#include "base/timebuf.hh"
471858SN/A#include "config/full_system.hh"
481717SN/A#include "cpu/base.hh"
492190SN/A#include "cpu/cpu_exec_context.hh"
501717SN/A#include "cpu/o3/comm.hh"
511717SN/A#include "cpu/o3/cpu_policy.hh"
521060SN/A#include "sim/process.hh"
531060SN/A
542190SN/Aclass ExecContext;
551060SN/Aclass FunctionalMemory;
561060SN/Aclass Process;
571060SN/A
581060SN/Aclass BaseFullCPU : public BaseCPU
591060SN/A{
601060SN/A    //Stuff that's pretty ISA independent will go here.
611060SN/A  public:
621464SN/A    typedef BaseCPU::Params Params;
631061SN/A
641858SN/A#if FULL_SYSTEM
651061SN/A    BaseFullCPU(Params &params);
661061SN/A#else
671061SN/A    BaseFullCPU(Params &params);
681060SN/A#endif // FULL_SYSTEM
691681SN/A
701685SN/A  protected:
711681SN/A    int cpu_id;
721060SN/A};
731060SN/A
741060SN/Atemplate <class Impl>
751755SN/Aclass FullO3CPU : public BaseFullCPU
761060SN/A{
771060SN/A  public:
781060SN/A    //Put typedefs from the Impl here.
791060SN/A    typedef typename Impl::CPUPol CPUPolicy;
801060SN/A    typedef typename Impl::Params Params;
811061SN/A    typedef typename Impl::DynInstPtr DynInstPtr;
821060SN/A
831060SN/A  public:
841060SN/A    enum Status {
851060SN/A        Running,
861060SN/A        Idle,
871060SN/A        Halted,
881060SN/A        Blocked // ?
891060SN/A    };
901060SN/A
911060SN/A    Status _status;
921060SN/A
931060SN/A  private:
941060SN/A    class TickEvent : public Event
951060SN/A    {
961060SN/A      private:
971755SN/A        FullO3CPU<Impl> *cpu;
981060SN/A
991060SN/A      public:
1001755SN/A        TickEvent(FullO3CPU<Impl> *c);
1011060SN/A        void process();
1021060SN/A        const char *description();
1031060SN/A    };
1041060SN/A
1051060SN/A    TickEvent tickEvent;
1061060SN/A
1071060SN/A    /// Schedule tick event, regardless of its current state.
1081060SN/A    void scheduleTickEvent(int delay)
1091060SN/A    {
1101060SN/A        if (tickEvent.squashed())
1111060SN/A            tickEvent.reschedule(curTick + delay);
1121060SN/A        else if (!tickEvent.scheduled())
1131060SN/A            tickEvent.schedule(curTick + delay);
1141060SN/A    }
1151060SN/A
1161060SN/A    /// Unschedule tick event, regardless of its current state.
1171060SN/A    void unscheduleTickEvent()
1181060SN/A    {
1191060SN/A        if (tickEvent.scheduled())
1201060SN/A            tickEvent.squash();
1211060SN/A    }
1221060SN/A
1231060SN/A  public:
1241755SN/A    FullO3CPU(Params &params);
1251755SN/A    ~FullO3CPU();
1261060SN/A
1271684SN/A    void fullCPURegStats();
1281684SN/A
1291684SN/A    void tick();
1301684SN/A
1311060SN/A    void init();
1321060SN/A
1331060SN/A    void activateContext(int thread_num, int delay);
1341060SN/A    void suspendContext(int thread_num);
1351060SN/A    void deallocateContext(int thread_num);
1361060SN/A    void haltContext(int thread_num);
1371060SN/A
1381060SN/A    void switchOut();
1391060SN/A    void takeOverFrom(BaseCPU *oldCPU);
1401060SN/A
1411060SN/A    /** Get the current instruction sequence number, and increment it. */
1421060SN/A    InstSeqNum getAndIncrementInstSeq();
1431060SN/A
1441858SN/A#if FULL_SYSTEM
1451060SN/A    /** Check if this address is a valid instruction address. */
1461060SN/A    bool validInstAddr(Addr addr) { return true; }
1471060SN/A
1481060SN/A    /** Check if this address is a valid data address. */
1491060SN/A    bool validDataAddr(Addr addr) { return true; }
1501060SN/A
1511060SN/A    /** Get instruction asid. */
1521681SN/A    int getInstAsid()
1532245SN/A    { return regFile.miscRegs.getInstAsid(); }
1541060SN/A
1551060SN/A    /** Get data asid. */
1561681SN/A    int getDataAsid()
1572245SN/A    { return regFile.miscRegs.getDataAsid(); }
1581060SN/A#else
1591060SN/A    bool validInstAddr(Addr addr)
1601681SN/A    { return thread[0]->validInstAddr(addr); }
1611060SN/A
1621060SN/A    bool validDataAddr(Addr addr)
1631681SN/A    { return thread[0]->validDataAddr(addr); }
1641060SN/A
1652190SN/A    int getInstAsid() { return thread[0]->getInstAsid(); }
1662190SN/A    int getDataAsid() { return thread[0]->getDataAsid(); }
1671060SN/A
1681060SN/A#endif
1691060SN/A
1701060SN/A    //
1711060SN/A    // New accessors for new decoder.
1721060SN/A    //
1731060SN/A    uint64_t readIntReg(int reg_idx);
1741060SN/A
1752455SN/A    FloatReg readFloatReg(int reg_idx);
1761060SN/A
1772455SN/A    FloatReg readFloatReg(int reg_idx, int width);
1781060SN/A
1792455SN/A    FloatRegBits readFloatRegBits(int reg_idx);
1802455SN/A
1812455SN/A    FloatRegBits readFloatRegBits(int reg_idx, int width);
1821060SN/A
1831060SN/A    void setIntReg(int reg_idx, uint64_t val);
1841060SN/A
1852455SN/A    void setFloatReg(int reg_idx, FloatReg val, int width);
1861060SN/A
1872455SN/A    void setFloatReg(int reg_idx, FloatReg val, int width);
1881060SN/A
1892455SN/A    void setFloatRegBits(int reg_idx, FloatRegBits val);
1902455SN/A
1912455SN/A    void setFloatRegBits(int reg_idx, FloatRegBits val);
1921060SN/A
1931060SN/A    uint64_t readPC();
1941060SN/A
1951060SN/A    void setNextPC(uint64_t val);
1961060SN/A
1971060SN/A    void setPC(Addr new_PC);
1981060SN/A
1991060SN/A    /** Function to add instruction onto the head of the list of the
2001060SN/A     *  instructions.  Used when new instructions are fetched.
2011060SN/A     */
2021061SN/A    void addInst(DynInstPtr &inst);
2031060SN/A
2041060SN/A    /** Function to tell the CPU that an instruction has completed. */
2051060SN/A    void instDone();
2061060SN/A
2071060SN/A    /** Remove all instructions in back of the given instruction, but leave
2081060SN/A     *  that instruction in the list.  This is useful in a squash, when there
2091060SN/A     *  are instructions in this list that don't exist in structures such as
2101060SN/A     *  the ROB.  The instruction doesn't have to be the last instruction in
2111060SN/A     *  the list, but will be once this function completes.
2121060SN/A     *  @todo: Remove only up until that inst?  Squashed inst is most likely
2131060SN/A     *  valid.
2141060SN/A     */
2151061SN/A    void removeBackInst(DynInstPtr &inst);
2161060SN/A
2171060SN/A    /** Remove an instruction from the front of the list.  It is expected
2181060SN/A     *  that there are no instructions in front of it (that is, none are older
2191060SN/A     *  than the instruction being removed).  Used when retiring instructions.
2201060SN/A     *  @todo: Remove the argument to this function, and just have it remove
2211060SN/A     *  last instruction once it's verified that commit has the same ordering
2221060SN/A     *  as the instruction list.
2231060SN/A     */
2241061SN/A    void removeFrontInst(DynInstPtr &inst);
2251060SN/A
2261060SN/A    /** Remove all instructions that are not currently in the ROB. */
2271060SN/A    void removeInstsNotInROB();
2281060SN/A
2291062SN/A    /** Remove all instructions younger than the given sequence number. */
2301062SN/A    void removeInstsUntil(const InstSeqNum &seq_num);
2311062SN/A
2321060SN/A    /** Remove all instructions from the list. */
2331060SN/A    void removeAllInsts();
2341060SN/A
2351060SN/A    void dumpInsts();
2361060SN/A
2371060SN/A    /** Basically a wrapper function so that instructions executed at
2381060SN/A     *  commit can tell the instruction queue that they have completed.
2391060SN/A     *  Eventually this hack should be removed.
2401060SN/A     */
2411061SN/A    void wakeDependents(DynInstPtr &inst);
2421060SN/A
2431060SN/A  public:
2441060SN/A    /** List of all the instructions in flight. */
2451061SN/A    list<DynInstPtr> instList;
2461060SN/A
2471060SN/A    //not sure these should be private.
2481060SN/A  protected:
2491060SN/A    /** The fetch stage. */
2501060SN/A    typename CPUPolicy::Fetch fetch;
2511060SN/A
2521060SN/A    /** The fetch stage's status. */
2531060SN/A    typename CPUPolicy::Fetch::Status fetchStatus;
2541060SN/A
2551060SN/A    /** The decode stage. */
2561060SN/A    typename CPUPolicy::Decode decode;
2571060SN/A
2581060SN/A    /** The decode stage's status. */
2591060SN/A    typename CPUPolicy::Decode::Status decodeStatus;
2601060SN/A
2611060SN/A    /** The dispatch stage. */
2621060SN/A    typename CPUPolicy::Rename rename;
2631060SN/A
2641060SN/A    /** The dispatch stage's status. */
2651060SN/A    typename CPUPolicy::Rename::Status renameStatus;
2661060SN/A
2671060SN/A    /** The issue/execute/writeback stages. */
2681060SN/A    typename CPUPolicy::IEW iew;
2691060SN/A
2701060SN/A    /** The issue/execute/writeback stage's status. */
2711060SN/A    typename CPUPolicy::IEW::Status iewStatus;
2721060SN/A
2731060SN/A    /** The commit stage. */
2741060SN/A    typename CPUPolicy::Commit commit;
2751060SN/A
2761060SN/A    /** The fetch stage's status. */
2771060SN/A    typename CPUPolicy::Commit::Status commitStatus;
2781060SN/A
2791060SN/A    //Might want to just pass these objects in to the constructors of the
2801060SN/A    //appropriate stage.  regFile is in iew, freeList in dispatch, renameMap
2811060SN/A    //in dispatch, and the rob in commit.
2821060SN/A    /** The register file. */
2831060SN/A    typename CPUPolicy::RegFile regFile;
2841060SN/A
2851060SN/A    /** The free list. */
2861060SN/A    typename CPUPolicy::FreeList freeList;
2871060SN/A
2881060SN/A    /** The rename map. */
2891060SN/A    typename CPUPolicy::RenameMap renameMap;
2901060SN/A
2911060SN/A    /** The re-order buffer. */
2921060SN/A    typename CPUPolicy::ROB rob;
2931060SN/A
2941060SN/A  public:
2951060SN/A    /** Typedefs from the Impl to get the structs that each of the
2961060SN/A     *  time buffers should use.
2971060SN/A     */
2981061SN/A    typedef typename CPUPolicy::TimeStruct TimeStruct;
2991060SN/A
3001061SN/A    typedef typename CPUPolicy::FetchStruct FetchStruct;
3011060SN/A
3021061SN/A    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
3031060SN/A
3041061SN/A    typedef typename CPUPolicy::RenameStruct RenameStruct;
3051060SN/A
3061061SN/A    typedef typename CPUPolicy::IEWStruct IEWStruct;
3071060SN/A
3081060SN/A    /** The main time buffer to do backwards communication. */
3091060SN/A    TimeBuffer<TimeStruct> timeBuffer;
3101060SN/A
3111060SN/A    /** The fetch stage's instruction queue. */
3121060SN/A    TimeBuffer<FetchStruct> fetchQueue;
3131060SN/A
3141060SN/A    /** The decode stage's instruction queue. */
3151060SN/A    TimeBuffer<DecodeStruct> decodeQueue;
3161060SN/A
3171060SN/A    /** The rename stage's instruction queue. */
3181060SN/A    TimeBuffer<RenameStruct> renameQueue;
3191060SN/A
3201060SN/A    /** The IEW stage's instruction queue. */
3211060SN/A    TimeBuffer<IEWStruct> iewQueue;
3221060SN/A
3231060SN/A  public:
3241060SN/A    /** The temporary exec context to support older accessors. */
3252190SN/A    CPUExecContext *cpuXC;
3261060SN/A
3271060SN/A    /** Temporary function to get pointer to exec context. */
3281681SN/A    ExecContext *xcBase()
3291681SN/A    {
3302190SN/A        return thread[0]->getProxy();
3312190SN/A    }
3322190SN/A
3332190SN/A    CPUExecContext *cpuXCBase()
3342190SN/A    {
3351681SN/A        return thread[0];
3361681SN/A    }
3371060SN/A
3381060SN/A    InstSeqNum globalSeqNum;
3391060SN/A
3401858SN/A#if FULL_SYSTEM
3411060SN/A    System *system;
3421060SN/A
3431060SN/A    MemoryController *memCtrl;
3441060SN/A    PhysicalMemory *physmem;
3451060SN/A
3461060SN/A    AlphaITB *itb;
3471060SN/A    AlphaDTB *dtb;
3481060SN/A
3491060SN/A//    SWContext *swCtx;
3501060SN/A#endif
3512190SN/A    std::vector<CPUExecContext *> thread;
3521060SN/A
3531060SN/A    FunctionalMemory *mem;
3541060SN/A
3551060SN/A    MemInterface *icacheInterface;
3561060SN/A    MemInterface *dcacheInterface;
3571060SN/A
3581060SN/A    bool deferRegistration;
3591060SN/A
3601060SN/A    Counter numInsts;
3611060SN/A
3621060SN/A    Counter funcExeInst;
3631060SN/A};
3641060SN/A
3651060SN/A#endif
366