cpu.hh revision 1858
11689SN/A/*
22329SN/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
292756Sksewell@umich.edu//Todo: Add in a lot of the functions that are ISA specific.  Also define
301689SN/A//the functions that currently exist within the base cpu class.  Define
311689SN/A//everything for the simobject stuff so it can be serialized and
322292SN/A//instantiated, add in debugging statements everywhere.  Have CPU schedule
332292SN/A//itself properly.  Threads!
341060SN/A// Avoid running stages and advancing queues if idle/stalled.
352669Sktlim@umich.edu
364182Sgblack@eecs.umich.edu#ifndef __CPU_O3_CPU_FULL_CPU_HH__
371461SN/A#define __CPU_O3_CPU_FULL_CPU_HH__
381060SN/A
391060SN/A#include <iostream>
403348Sbinkertn@umich.edu#include <list>
412669Sktlim@umich.edu#include <vector>
421461SN/A
431060SN/A#include "base/statistics.hh"
441060SN/A#include "base/timebuf.hh"
452329SN/A#include "config/full_system.hh"
462329SN/A#include "cpu/base.hh"
472329SN/A#include "cpu/o3/comm.hh"
482329SN/A#include "cpu/o3/cpu_policy.hh"
492348SN/A#include "cpu/exec_context.hh"
502329SN/A#include "sim/process.hh"
511060SN/A
521060SN/A#if FULL_SYSTEM
532292SN/A#include "arch/alpha/ev5.hh"
541060SN/Ausing namespace EV5;
551060SN/A#endif
561060SN/A
571061SN/Aclass FunctionalMemory;
581060SN/Aclass Process;
591061SN/A
602733Sktlim@umich.educlass BaseFullCPU : public BaseCPU
611060SN/A{
621060SN/A    //Stuff that's pretty ISA independent will go here.
632292SN/A  public:
641061SN/A    typedef BaseCPU::Params Params;
651061SN/A
661061SN/A#if FULL_SYSTEM
671060SN/A    BaseFullCPU(Params &params);
681060SN/A#else
692107SN/A    BaseFullCPU(Params &params);
702292SN/A#endif // FULL_SYSTEM
712632Sstever@eecs.umich.edu
722698Sktlim@umich.edu  protected:
732698Sktlim@umich.edu    int cpu_id;
742698Sktlim@umich.edu};
752669Sktlim@umich.edu
762669Sktlim@umich.edutemplate <class Impl>
772669Sktlim@umich.educlass FullO3CPU : public BaseFullCPU
782698Sktlim@umich.edu{
792669Sktlim@umich.edu  public:
802669Sktlim@umich.edu    //Put typedefs from the Impl here.
812669Sktlim@umich.edu    typedef typename Impl::ISA ISA;
822698Sktlim@umich.edu    typedef typename Impl::CPUPol CPUPolicy;
832669Sktlim@umich.edu    typedef typename Impl::Params Params;
842669Sktlim@umich.edu    typedef typename Impl::DynInstPtr DynInstPtr;
852669Sktlim@umich.edu
862669Sktlim@umich.edu  public:
873647Srdreslin@umich.edu    enum Status {
883647Srdreslin@umich.edu        Running,
892669Sktlim@umich.edu        Idle,
902698Sktlim@umich.edu        Halted,
912669Sktlim@umich.edu        Blocked // ?
922669Sktlim@umich.edu    };
932698Sktlim@umich.edu
942669Sktlim@umich.edu    Status _status;
952669Sktlim@umich.edu
962698Sktlim@umich.edu  private:
972669Sktlim@umich.edu    class TickEvent : public Event
982669Sktlim@umich.edu    {
992698Sktlim@umich.edu      private:
1002669Sktlim@umich.edu        FullO3CPU<Impl> *cpu;
1012669Sktlim@umich.edu
1023846Shsul@eecs.umich.edu      public:
1032669Sktlim@umich.edu        TickEvent(FullO3CPU<Impl> *c);
1042698Sktlim@umich.edu        void process();
1052698Sktlim@umich.edu        const char *description();
1062669Sktlim@umich.edu    };
1072669Sktlim@umich.edu
1082698Sktlim@umich.edu    TickEvent tickEvent;
1092669Sktlim@umich.edu
1102669Sktlim@umich.edu    /// Schedule tick event, regardless of its current state.
1111060SN/A    void scheduleTickEvent(int delay)
1122935Sksewell@umich.edu    {
1131060SN/A        if (tickEvent.squashed())
1142329SN/A            tickEvent.reschedule(curTick + delay);
1152329SN/A        else if (!tickEvent.scheduled())
1162292SN/A            tickEvent.schedule(curTick + delay);
1172292SN/A    }
1182292SN/A
1192292SN/A    /// Unschedule tick event, regardless of its current state.
1202292SN/A    void unscheduleTickEvent()
1212292SN/A    {
1222292SN/A        if (tickEvent.scheduled())
1232292SN/A            tickEvent.squash();
1241060SN/A    }
1251060SN/A
1261060SN/A  public:
1271060SN/A    FullO3CPU(Params &params);
1282292SN/A    ~FullO3CPU();
1292292SN/A
1302292SN/A    void fullCPURegStats();
1312307SN/A
1322669Sktlim@umich.edu    void tick();
1332696Sktlim@umich.edu
1342669Sktlim@umich.edu    void init();
1351060SN/A
1361060SN/A    void activateContext(int thread_num, int delay);
1372292SN/A    void suspendContext(int thread_num);
1382292SN/A    void deallocateContext(int thread_num);
1392292SN/A    void haltContext(int thread_num);
1402292SN/A
1412292SN/A    void switchOut();
1422292SN/A    void takeOverFrom(BaseCPU *oldCPU);
1432292SN/A
1442292SN/A    /** Get the current instruction sequence number, and increment it. */
1451060SN/A    InstSeqNum getAndIncrementInstSeq();
1462292SN/A
1472292SN/A#if FULL_SYSTEM
1482292SN/A    /** Check if this address is a valid instruction address. */
1492292SN/A    bool validInstAddr(Addr addr) { return true; }
1502292SN/A
1512292SN/A    /** Check if this address is a valid data address. */
1522292SN/A    bool validDataAddr(Addr addr) { return true; }
1532292SN/A
1542292SN/A    /** Get instruction asid. */
1552292SN/A    int getInstAsid()
1562292SN/A    { return ITB_ASN_ASN(regFile.getIpr()[ISA::IPR_ITB_ASN]); }
1572292SN/A
1581060SN/A    /** Get data asid. */
1591060SN/A    int getDataAsid()
1602292SN/A    { return DTB_ASN_ASN(regFile.getIpr()[ISA::IPR_DTB_ASN]); }
1612292SN/A#else
1621684SN/A    bool validInstAddr(Addr addr)
1632292SN/A    { return thread[0]->validInstAddr(addr); }
1642292SN/A
1651684SN/A    bool validDataAddr(Addr addr)
1662292SN/A    { return thread[0]->validDataAddr(addr); }
1671062SN/A
1681062SN/A    int getInstAsid() { return thread[0]->asid; }
1692871Sktlim@umich.edu    int getDataAsid() { return thread[0]->asid; }
1702871Sktlim@umich.edu
1712871Sktlim@umich.edu#endif
1722292SN/A
1732733Sktlim@umich.edu    //
1741060SN/A    // New accessors for new decoder.
1752292SN/A    //
1761060SN/A    uint64_t readIntReg(int reg_idx);
1771060SN/A
1782292SN/A    float readFloatRegSingle(int reg_idx);
1792292SN/A
1802292SN/A    double readFloatRegDouble(int reg_idx);
1812292SN/A
1821060SN/A    uint64_t readFloatRegInt(int reg_idx);
1831060SN/A
1842292SN/A    void setIntReg(int reg_idx, uint64_t val);
1852292SN/A
1862292SN/A    void setFloatRegSingle(int reg_idx, float val);
1872292SN/A
1882669Sktlim@umich.edu    void setFloatRegDouble(int reg_idx, double val);
1892292SN/A
1902843Sktlim@umich.edu    void setFloatRegInt(int reg_idx, uint64_t val);
1912863Sktlim@umich.edu
1922843Sktlim@umich.edu    uint64_t readPC();
1932843Sktlim@umich.edu
1942843Sktlim@umich.edu    void setNextPC(uint64_t val);
1952843Sktlim@umich.edu
1962843Sktlim@umich.edu    void setPC(Addr new_PC);
1972307SN/A
1982307SN/A    /** Function to add instruction onto the head of the list of the
1992348SN/A     *  instructions.  Used when new instructions are fetched.
2002307SN/A     */
2012307SN/A    void addInst(DynInstPtr &inst);
2022348SN/A
2032307SN/A    /** Function to tell the CPU that an instruction has completed. */
2042307SN/A    void instDone();
2052348SN/A
2062292SN/A    /** Remove all instructions in back of the given instruction, but leave
2071060SN/A     *  that instruction in the list.  This is useful in a squash, when there
2081061SN/A     *  are instructions in this list that don't exist in structures such as
2092329SN/A     *  the ROB.  The instruction doesn't have to be the last instruction in
2102329SN/A     *  the list, but will be once this function completes.
2112292SN/A     *  @todo: Remove only up until that inst?  Squashed inst is most likely
2122292SN/A     *  valid.
2132292SN/A     */
2142329SN/A    void removeBackInst(DynInstPtr &inst);
2152329SN/A
2162292SN/A    /** Remove an instruction from the front of the list.  It is expected
2172292SN/A     *  that there are no instructions in front of it (that is, none are older
2182292SN/A     *  than the instruction being removed).  Used when retiring instructions.
2191061SN/A     *  @todo: Remove the argument to this function, and just have it remove
2201061SN/A     *  last instruction once it's verified that commit has the same ordering
2211061SN/A     *  as the instruction list.
2221763SN/A     */
2231061SN/A    void removeFrontInst(DynInstPtr &inst);
2241061SN/A
2252935Sksewell@umich.edu    /** Remove all instructions that are not currently in the ROB. */
2261061SN/A    void removeInstsNotInROB();
2271061SN/A
2282935Sksewell@umich.edu    /** Remove all instructions younger than the given sequence number. */
2291062SN/A    void removeInstsUntil(const InstSeqNum &seq_num);
2301062SN/A
2311062SN/A    /** Remove all instructions from the list. */
2321062SN/A    void removeAllInsts();
2331062SN/A
2341763SN/A    void dumpInsts();
2352292SN/A
2362292SN/A    /** Basically a wrapper function so that instructions executed at
2372292SN/A     *  commit can tell the instruction queue that they have completed.
2381062SN/A     *  Eventually this hack should be removed.
2391062SN/A     */
2402292SN/A    void wakeDependents(DynInstPtr &inst);
2411062SN/A
2422292SN/A  public:
2433795Sgblack@eecs.umich.edu    /** List of all the instructions in flight. */
2441684SN/A    list<DynInstPtr> instList;
2452292SN/A
2462292SN/A    //not sure these should be private.
2472292SN/A  protected:
2483795Sgblack@eecs.umich.edu    /** The fetch stage. */
2493795Sgblack@eecs.umich.edu    typename CPUPolicy::Fetch fetch;
2502292SN/A
2512292SN/A    /** The fetch stage's status. */
2522292SN/A    typename CPUPolicy::Fetch::Status fetchStatus;
2532292SN/A
2542292SN/A    /** The decode stage. */
2552292SN/A    typename CPUPolicy::Decode decode;
2562292SN/A
2571684SN/A    /** The decode stage's status. */
2581684SN/A    typename CPUPolicy::Decode::Status decodeStatus;
2592292SN/A
2602292SN/A    /** The dispatch stage. */
2612292SN/A    typename CPUPolicy::Rename rename;
2622292SN/A
2633795Sgblack@eecs.umich.edu    /** The dispatch stage's status. */
2643795Sgblack@eecs.umich.edu    typename CPUPolicy::Rename::Status renameStatus;
2652935Sksewell@umich.edu
2661684SN/A    /** The issue/execute/writeback stages. */
2672292SN/A    typename CPUPolicy::IEW iew;
2682292SN/A
2692292SN/A    /** The issue/execute/writeback stage's status. */
2701684SN/A    typename CPUPolicy::IEW::Status iewStatus;
2711684SN/A
2722292SN/A    /** The commit stage. */
2732292SN/A    typename CPUPolicy::Commit commit;
2742292SN/A
2752292SN/A    /** The fetch stage's status. */
2761684SN/A    typename CPUPolicy::Commit::Status commitStatus;
2772292SN/A
2782292SN/A    //Might want to just pass these objects in to the constructors of the
2792292SN/A    //appropriate stage.  regFile is in iew, freeList in dispatch, renameMap
2802292SN/A    //in dispatch, and the rob in commit.
2812292SN/A    /** The register file. */
2822292SN/A    typename CPUPolicy::RegFile regFile;
2832292SN/A
2842292SN/A    /** The free list. */
2851062SN/A    typename CPUPolicy::FreeList freeList;
2861062SN/A
2872107SN/A    /** The rename map. */
2881062SN/A    typename CPUPolicy::RenameMap renameMap;
2891062SN/A
2901061SN/A    /** The re-order buffer. */
2911060SN/A    typename CPUPolicy::ROB rob;
2922698Sktlim@umich.edu
2932696Sktlim@umich.edu  public:
2942696Sktlim@umich.edu    /** Typedefs from the Impl to get the structs that each of the
2952292SN/A     *  time buffers should use.
2962292SN/A     */
2972292SN/A    typedef typename CPUPolicy::TimeStruct TimeStruct;
2982292SN/A
2992292SN/A    typedef typename CPUPolicy::FetchStruct FetchStruct;
3002292SN/A
3012292SN/A    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
3022292SN/A
3032292SN/A    typedef typename CPUPolicy::RenameStruct RenameStruct;
3042292SN/A
3052292SN/A    typedef typename CPUPolicy::IEWStruct IEWStruct;
3062292SN/A
3072292SN/A    /** The main time buffer to do backwards communication. */
3082292SN/A    TimeBuffer<TimeStruct> timeBuffer;
3092292SN/A
3102292SN/A    /** The fetch stage's instruction queue. */
3112733Sktlim@umich.edu    TimeBuffer<FetchStruct> fetchQueue;
3122733Sktlim@umich.edu
3131060SN/A    /** The decode stage's instruction queue. */
3141060SN/A    TimeBuffer<DecodeStruct> decodeQueue;
3151060SN/A
3161060SN/A    /** The rename stage's instruction queue. */
3171060SN/A    TimeBuffer<RenameStruct> renameQueue;
3181060SN/A
3191060SN/A    /** The IEW stage's instruction queue. */
3201060SN/A    TimeBuffer<IEWStruct> iewQueue;
3211060SN/A
3221060SN/A  public:
3231060SN/A    /** The temporary exec context to support older accessors. */
3241060SN/A    ExecContext *xc;
3251060SN/A
3261060SN/A    /** Temporary function to get pointer to exec context. */
3271060SN/A    ExecContext *xcBase()
3281060SN/A    {
3291060SN/A#if FULL_SYSTEM
3301060SN/A        return system->execContexts[0];
3311060SN/A#else
3321060SN/A        return thread[0];
3331060SN/A#endif
3341060SN/A    }
3351060SN/A
3361060SN/A    InstSeqNum globalSeqNum;
3372669Sktlim@umich.edu
3381060SN/A#if FULL_SYSTEM
3391061SN/A    System *system;
3401061SN/A
3411061SN/A    MemoryController *memCtrl;
3424182Sgblack@eecs.umich.edu    PhysicalMemory *physmem;
3434182Sgblack@eecs.umich.edu
3444182Sgblack@eecs.umich.edu    AlphaITB *itb;
3452348SN/A    AlphaDTB *dtb;
3462292SN/A
3472292SN/A//    SWContext *swCtx;
3482348SN/A#else
3492292SN/A    std::vector<ExecContext *> thread;
3502292SN/A#endif
3512756Sksewell@umich.edu
3522756Sksewell@umich.edu    FunctionalMemory *mem;
3532756Sksewell@umich.edu
3542756Sksewell@umich.edu    MemInterface *icacheInterface;
3552756Sksewell@umich.edu    MemInterface *dcacheInterface;
3562756Sksewell@umich.edu
3572756Sksewell@umich.edu    bool deferRegistration;
3582678Sktlim@umich.edu
3592678Sktlim@umich.edu    Counter numInsts;
3602292SN/A
3612292SN/A    Counter funcExeInst;
3622292SN/A};
3632292SN/A
3642292SN/A#endif
3652292SN/A