cpu.hh revision 2632
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.
271689SN/A */
281689SN/A
291060SN/A//Todo: Add in a lot of the functions that are ISA specific.  Also define
301060SN/A//the functions that currently exist within the base cpu class.  Define
311060SN/A//everything for the simobject stuff so it can be serialized and
321060SN/A//instantiated, add in debugging statements everywhere.  Have CPU schedule
331689SN/A//itself properly.  Threads!
341060SN/A// Avoid running stages and advancing queues if idle/stalled.
351060SN/A
361755SN/A#ifndef __CPU_O3_CPU_FULL_CPU_HH__
371755SN/A#define __CPU_O3_CPU_FULL_CPU_HH__
381060SN/A
391060SN/A#include <iostream>
401060SN/A#include <list>
411681SN/A#include <vector>
421060SN/A
431060SN/A#include "base/statistics.hh"
441060SN/A#include "base/timebuf.hh"
451858SN/A#include "config/full_system.hh"
461717SN/A#include "cpu/base.hh"
472190SN/A#include "cpu/cpu_exec_context.hh"
481717SN/A#include "cpu/o3/comm.hh"
491717SN/A#include "cpu/o3/cpu_policy.hh"
501060SN/A#include "sim/process.hh"
511060SN/A
522190SN/Aclass ExecContext;
531060SN/Aclass FunctionalMemory;
541060SN/Aclass Process;
551060SN/A
561060SN/Aclass BaseFullCPU : public BaseCPU
571060SN/A{
581060SN/A    //Stuff that's pretty ISA independent will go here.
591060SN/A  public:
601464SN/A    typedef BaseCPU::Params Params;
611061SN/A
621858SN/A#if FULL_SYSTEM
631061SN/A    BaseFullCPU(Params &params);
641061SN/A#else
651061SN/A    BaseFullCPU(Params &params);
661060SN/A#endif // FULL_SYSTEM
671681SN/A
681685SN/A  protected:
691681SN/A    int cpu_id;
701060SN/A};
711060SN/A
721060SN/Atemplate <class Impl>
731755SN/Aclass FullO3CPU : public BaseFullCPU
741060SN/A{
751060SN/A  public:
761060SN/A    //Put typedefs from the Impl here.
771060SN/A    typedef typename Impl::CPUPol CPUPolicy;
781060SN/A    typedef typename Impl::Params Params;
791061SN/A    typedef typename Impl::DynInstPtr DynInstPtr;
801060SN/A
811060SN/A  public:
821060SN/A    enum Status {
831060SN/A        Running,
841060SN/A        Idle,
851060SN/A        Halted,
861060SN/A        Blocked // ?
871060SN/A    };
881060SN/A
891060SN/A    Status _status;
901060SN/A
911060SN/A  private:
921060SN/A    class TickEvent : public Event
931060SN/A    {
941060SN/A      private:
951755SN/A        FullO3CPU<Impl> *cpu;
961060SN/A
971060SN/A      public:
981755SN/A        TickEvent(FullO3CPU<Impl> *c);
991060SN/A        void process();
1001060SN/A        const char *description();
1011060SN/A    };
1021060SN/A
1031060SN/A    TickEvent tickEvent;
1041060SN/A
1051060SN/A    /// Schedule tick event, regardless of its current state.
1061060SN/A    void scheduleTickEvent(int delay)
1071060SN/A    {
1081060SN/A        if (tickEvent.squashed())
1091060SN/A            tickEvent.reschedule(curTick + delay);
1101060SN/A        else if (!tickEvent.scheduled())
1111060SN/A            tickEvent.schedule(curTick + delay);
1121060SN/A    }
1131060SN/A
1141060SN/A    /// Unschedule tick event, regardless of its current state.
1151060SN/A    void unscheduleTickEvent()
1161060SN/A    {
1171060SN/A        if (tickEvent.scheduled())
1181060SN/A            tickEvent.squash();
1191060SN/A    }
1201060SN/A
1211060SN/A  public:
1221755SN/A    FullO3CPU(Params &params);
1231755SN/A    ~FullO3CPU();
1241060SN/A
1251684SN/A    void fullCPURegStats();
1261684SN/A
1271684SN/A    void tick();
1281684SN/A
1291060SN/A    void init();
1301060SN/A
1311060SN/A    void activateContext(int thread_num, int delay);
1321060SN/A    void suspendContext(int thread_num);
1331060SN/A    void deallocateContext(int thread_num);
1341060SN/A    void haltContext(int thread_num);
1351060SN/A
1361060SN/A    void switchOut();
1371060SN/A    void takeOverFrom(BaseCPU *oldCPU);
1381060SN/A
1391060SN/A    /** Get the current instruction sequence number, and increment it. */
1401060SN/A    InstSeqNum getAndIncrementInstSeq();
1411060SN/A
1421858SN/A#if FULL_SYSTEM
1431060SN/A    /** Check if this address is a valid instruction address. */
1441060SN/A    bool validInstAddr(Addr addr) { return true; }
1451060SN/A
1461060SN/A    /** Check if this address is a valid data address. */
1471060SN/A    bool validDataAddr(Addr addr) { return true; }
1481060SN/A
1491060SN/A    /** Get instruction asid. */
1501681SN/A    int getInstAsid()
1512245SN/A    { return regFile.miscRegs.getInstAsid(); }
1521060SN/A
1531060SN/A    /** Get data asid. */
1541681SN/A    int getDataAsid()
1552245SN/A    { return regFile.miscRegs.getDataAsid(); }
1561060SN/A#else
1571060SN/A    bool validInstAddr(Addr addr)
1581681SN/A    { return thread[0]->validInstAddr(addr); }
1591060SN/A
1601060SN/A    bool validDataAddr(Addr addr)
1611681SN/A    { return thread[0]->validDataAddr(addr); }
1621060SN/A
1632190SN/A    int getInstAsid() { return thread[0]->getInstAsid(); }
1642190SN/A    int getDataAsid() { return thread[0]->getDataAsid(); }
1651060SN/A
1661060SN/A#endif
1671060SN/A
1681060SN/A    //
1691060SN/A    // New accessors for new decoder.
1701060SN/A    //
1711060SN/A    uint64_t readIntReg(int reg_idx);
1721060SN/A
1732455SN/A    FloatReg readFloatReg(int reg_idx);
1741060SN/A
1752455SN/A    FloatReg readFloatReg(int reg_idx, int width);
1761060SN/A
1772455SN/A    FloatRegBits readFloatRegBits(int reg_idx);
1782455SN/A
1792455SN/A    FloatRegBits readFloatRegBits(int reg_idx, int width);
1801060SN/A
1811060SN/A    void setIntReg(int reg_idx, uint64_t val);
1821060SN/A
1832455SN/A    void setFloatReg(int reg_idx, FloatReg val, int width);
1841060SN/A
1852455SN/A    void setFloatReg(int reg_idx, FloatReg val, int width);
1861060SN/A
1872455SN/A    void setFloatRegBits(int reg_idx, FloatRegBits val);
1882455SN/A
1892455SN/A    void setFloatRegBits(int reg_idx, FloatRegBits val);
1901060SN/A
1911060SN/A    uint64_t readPC();
1921060SN/A
1931060SN/A    void setNextPC(uint64_t val);
1941060SN/A
1951060SN/A    void setPC(Addr new_PC);
1961060SN/A
1971060SN/A    /** Function to add instruction onto the head of the list of the
1981060SN/A     *  instructions.  Used when new instructions are fetched.
1991060SN/A     */
2001061SN/A    void addInst(DynInstPtr &inst);
2011060SN/A
2021060SN/A    /** Function to tell the CPU that an instruction has completed. */
2031060SN/A    void instDone();
2041060SN/A
2051060SN/A    /** Remove all instructions in back of the given instruction, but leave
2061060SN/A     *  that instruction in the list.  This is useful in a squash, when there
2071060SN/A     *  are instructions in this list that don't exist in structures such as
2081060SN/A     *  the ROB.  The instruction doesn't have to be the last instruction in
2091060SN/A     *  the list, but will be once this function completes.
2101060SN/A     *  @todo: Remove only up until that inst?  Squashed inst is most likely
2111060SN/A     *  valid.
2121060SN/A     */
2131061SN/A    void removeBackInst(DynInstPtr &inst);
2141060SN/A
2151060SN/A    /** Remove an instruction from the front of the list.  It is expected
2161060SN/A     *  that there are no instructions in front of it (that is, none are older
2171060SN/A     *  than the instruction being removed).  Used when retiring instructions.
2181060SN/A     *  @todo: Remove the argument to this function, and just have it remove
2191060SN/A     *  last instruction once it's verified that commit has the same ordering
2201060SN/A     *  as the instruction list.
2211060SN/A     */
2221061SN/A    void removeFrontInst(DynInstPtr &inst);
2231060SN/A
2241060SN/A    /** Remove all instructions that are not currently in the ROB. */
2251060SN/A    void removeInstsNotInROB();
2261060SN/A
2271062SN/A    /** Remove all instructions younger than the given sequence number. */
2281062SN/A    void removeInstsUntil(const InstSeqNum &seq_num);
2291062SN/A
2301060SN/A    /** Remove all instructions from the list. */
2311060SN/A    void removeAllInsts();
2321060SN/A
2331060SN/A    void dumpInsts();
2341060SN/A
2351060SN/A    /** Basically a wrapper function so that instructions executed at
2361060SN/A     *  commit can tell the instruction queue that they have completed.
2371060SN/A     *  Eventually this hack should be removed.
2381060SN/A     */
2391061SN/A    void wakeDependents(DynInstPtr &inst);
2401060SN/A
2411060SN/A  public:
2421060SN/A    /** List of all the instructions in flight. */
2431061SN/A    list<DynInstPtr> instList;
2441060SN/A
2451060SN/A    //not sure these should be private.
2461060SN/A  protected:
2471060SN/A    /** The fetch stage. */
2481060SN/A    typename CPUPolicy::Fetch fetch;
2491060SN/A
2501060SN/A    /** The fetch stage's status. */
2511060SN/A    typename CPUPolicy::Fetch::Status fetchStatus;
2521060SN/A
2531060SN/A    /** The decode stage. */
2541060SN/A    typename CPUPolicy::Decode decode;
2551060SN/A
2561060SN/A    /** The decode stage's status. */
2571060SN/A    typename CPUPolicy::Decode::Status decodeStatus;
2581060SN/A
2591060SN/A    /** The dispatch stage. */
2601060SN/A    typename CPUPolicy::Rename rename;
2611060SN/A
2621060SN/A    /** The dispatch stage's status. */
2631060SN/A    typename CPUPolicy::Rename::Status renameStatus;
2641060SN/A
2651060SN/A    /** The issue/execute/writeback stages. */
2661060SN/A    typename CPUPolicy::IEW iew;
2671060SN/A
2681060SN/A    /** The issue/execute/writeback stage's status. */
2691060SN/A    typename CPUPolicy::IEW::Status iewStatus;
2701060SN/A
2711060SN/A    /** The commit stage. */
2721060SN/A    typename CPUPolicy::Commit commit;
2731060SN/A
2741060SN/A    /** The fetch stage's status. */
2751060SN/A    typename CPUPolicy::Commit::Status commitStatus;
2761060SN/A
2771060SN/A    //Might want to just pass these objects in to the constructors of the
2781060SN/A    //appropriate stage.  regFile is in iew, freeList in dispatch, renameMap
2791060SN/A    //in dispatch, and the rob in commit.
2801060SN/A    /** The register file. */
2811060SN/A    typename CPUPolicy::RegFile regFile;
2821060SN/A
2831060SN/A    /** The free list. */
2841060SN/A    typename CPUPolicy::FreeList freeList;
2851060SN/A
2861060SN/A    /** The rename map. */
2871060SN/A    typename CPUPolicy::RenameMap renameMap;
2881060SN/A
2891060SN/A    /** The re-order buffer. */
2901060SN/A    typename CPUPolicy::ROB rob;
2911060SN/A
2921060SN/A  public:
2931060SN/A    /** Typedefs from the Impl to get the structs that each of the
2941060SN/A     *  time buffers should use.
2951060SN/A     */
2961061SN/A    typedef typename CPUPolicy::TimeStruct TimeStruct;
2971060SN/A
2981061SN/A    typedef typename CPUPolicy::FetchStruct FetchStruct;
2991060SN/A
3001061SN/A    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
3011060SN/A
3021061SN/A    typedef typename CPUPolicy::RenameStruct RenameStruct;
3031060SN/A
3041061SN/A    typedef typename CPUPolicy::IEWStruct IEWStruct;
3051060SN/A
3061060SN/A    /** The main time buffer to do backwards communication. */
3071060SN/A    TimeBuffer<TimeStruct> timeBuffer;
3081060SN/A
3091060SN/A    /** The fetch stage's instruction queue. */
3101060SN/A    TimeBuffer<FetchStruct> fetchQueue;
3111060SN/A
3121060SN/A    /** The decode stage's instruction queue. */
3131060SN/A    TimeBuffer<DecodeStruct> decodeQueue;
3141060SN/A
3151060SN/A    /** The rename stage's instruction queue. */
3161060SN/A    TimeBuffer<RenameStruct> renameQueue;
3171060SN/A
3181060SN/A    /** The IEW stage's instruction queue. */
3191060SN/A    TimeBuffer<IEWStruct> iewQueue;
3201060SN/A
3211060SN/A  public:
3221060SN/A    /** The temporary exec context to support older accessors. */
3232190SN/A    CPUExecContext *cpuXC;
3241060SN/A
3251060SN/A    /** Temporary function to get pointer to exec context. */
3261681SN/A    ExecContext *xcBase()
3271681SN/A    {
3282190SN/A        return thread[0]->getProxy();
3292190SN/A    }
3302190SN/A
3312190SN/A    CPUExecContext *cpuXCBase()
3322190SN/A    {
3331681SN/A        return thread[0];
3341681SN/A    }
3351060SN/A
3361060SN/A    InstSeqNum globalSeqNum;
3371060SN/A
3381858SN/A#if FULL_SYSTEM
3391060SN/A    System *system;
3401060SN/A
3411060SN/A    MemoryController *memCtrl;
3421060SN/A    PhysicalMemory *physmem;
3431060SN/A
3441060SN/A    AlphaITB *itb;
3451060SN/A    AlphaDTB *dtb;
3461060SN/A
3471060SN/A//    SWContext *swCtx;
3481060SN/A#endif
3492190SN/A    std::vector<CPUExecContext *> thread;
3501060SN/A
3511060SN/A    FunctionalMemory *mem;
3521060SN/A
3531060SN/A    MemInterface *icacheInterface;
3541060SN/A    MemInterface *dcacheInterface;
3551060SN/A
3561060SN/A    bool deferRegistration;
3571060SN/A
3581060SN/A    Counter numInsts;
3591060SN/A
3601060SN/A    Counter funcExeInst;
3611060SN/A};
3621060SN/A
3631060SN/A#endif
364