base.hh revision 5712
11060SN/A/*
22702SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
31060SN/A * All rights reserved.
41060SN/A *
51060SN/A * Redistribution and use in source and binary forms, with or without
61060SN/A * modification, are permitted provided that the following conditions are
71060SN/A * met: redistributions of source code must retain the above copyright
81060SN/A * notice, this list of conditions and the following disclaimer;
91060SN/A * redistributions in binary form must reproduce the above copyright
101060SN/A * notice, this list of conditions and the following disclaimer in the
111060SN/A * documentation and/or other materials provided with the distribution;
121060SN/A * neither the name of the copyright holders nor the names of its
131060SN/A * contributors may be used to endorse or promote products derived from
141060SN/A * this software without specific prior written permission.
151060SN/A *
161060SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665SN/A *
282665SN/A * Authors: Steve Reinhardt
291060SN/A *          Nathan Binkert
301060SN/A */
311060SN/A
322292SN/A#ifndef __CPU_BASE_HH__
331060SN/A#define __CPU_BASE_HH__
341060SN/A
351060SN/A#include <vector>
361060SN/A
371061SN/A#include "arch/isa_traits.hh"
386658Snate@binkert.org#include "arch/microcode_rom.hh"
396658Snate@binkert.org#include "base/statistics.hh"
401060SN/A#include "config/full_system.hh"
412669SN/A#include "sim/eventq.hh"
426658Snate@binkert.org#include "sim/insttracer.hh"
431060SN/A#include "mem/mem_object.hh"
441060SN/A
451060SN/A#if FULL_SYSTEM
461060SN/A#include "arch/interrupts.hh"
471060SN/A#endif
481060SN/A
491060SN/Aclass BaseCPUParams;
501060SN/Aclass BranchPred;
512292SN/Aclass CheckerCPU;
522292SN/Aclass ThreadContext;
531060SN/Aclass System;
542292SN/Aclass Port;
551060SN/A
561060SN/Anamespace TheISA
572292SN/A{
582292SN/A    class Predecoder;
592292SN/A}
601060SN/A
611060SN/Aclass CPUProgressEvent : public Event
621060SN/A{
631061SN/A  protected:
644636Sgblack@eecs.umich.edu    Tick interval;
653801Sgblack@eecs.umich.edu    Counter lastNumInst;
664636Sgblack@eecs.umich.edu    BaseCPU *cpu;
673794Sgblack@eecs.umich.edu
684636Sgblack@eecs.umich.edu  public:
693794Sgblack@eecs.umich.edu    CPUProgressEvent(BaseCPU *_cpu, Tick ival);
704636Sgblack@eecs.umich.edu
711060SN/A    void process();
721464SN/A
731061SN/A    virtual const char *description() const;
744636Sgblack@eecs.umich.edu};
754654Sgblack@eecs.umich.edu
764636Sgblack@eecs.umich.educlass BaseCPU : public MemObject
771464SN/A{
784636Sgblack@eecs.umich.edu  protected:
794636Sgblack@eecs.umich.edu    // CPU's clock period in terms of the number of ticks of curTime.
804636Sgblack@eecs.umich.edu    Tick clock;
814636Sgblack@eecs.umich.edu    // @todo remove me after debugging with legion done
824636Sgblack@eecs.umich.edu    Tick instCnt;
834636Sgblack@eecs.umich.edu    // every cpu has an id, put it in the base cpu
844636Sgblack@eecs.umich.edu    // Set at initialization, only time a cpuId might change is during a
854636Sgblack@eecs.umich.edu    // takeover (which should be done from within the BaseCPU anyway,
864636Sgblack@eecs.umich.edu    // therefore no setCpuId() method is provided
874636Sgblack@eecs.umich.edu    int _cpuId;
881464SN/A
893794Sgblack@eecs.umich.edu  public:
904636Sgblack@eecs.umich.edu    /** Reads this CPU's ID. */
914636Sgblack@eecs.umich.edu    int cpuId() { return _cpuId; }
924636Sgblack@eecs.umich.edu
934636Sgblack@eecs.umich.edu//    Tick currentTick;
944636Sgblack@eecs.umich.edu    inline Tick frequency() const { return Clock::Frequency / clock; }
954636Sgblack@eecs.umich.edu    inline Tick ticks(int numCycles) const { return clock * numCycles; }
964636Sgblack@eecs.umich.edu    inline Tick curCycle() const { return curTick / clock; }
974636Sgblack@eecs.umich.edu    inline Tick tickToCycles(Tick val) const { return val / clock; }
984636Sgblack@eecs.umich.edu    // @todo remove me after debugging with legion done
994636Sgblack@eecs.umich.edu    Tick instCount() { return instCnt; }
1004636Sgblack@eecs.umich.edu
1014636Sgblack@eecs.umich.edu    /** The next cycle the CPU should be scheduled, given a cache
1024636Sgblack@eecs.umich.edu     * access or quiesce event returning on this cycle.  This function
1034654Sgblack@eecs.umich.edu     * may return curTick if the CPU should run on the current cycle.
1044636Sgblack@eecs.umich.edu     */
1054636Sgblack@eecs.umich.edu    Tick nextCycle();
1064636Sgblack@eecs.umich.edu
1074636Sgblack@eecs.umich.edu    /** The next cycle the CPU should be scheduled, given a cache
1084654Sgblack@eecs.umich.edu     * access or quiesce event returning on the given Tick.  This
1094636Sgblack@eecs.umich.edu     * function may return curTick if the CPU should run on the
1104636Sgblack@eecs.umich.edu     * current cycle.
1114636Sgblack@eecs.umich.edu     * @param begin_tick The tick that the event is completing on.
1124636Sgblack@eecs.umich.edu     */
1134636Sgblack@eecs.umich.edu    Tick nextCycle(Tick begin_tick);
1144636Sgblack@eecs.umich.edu
1154636Sgblack@eecs.umich.edu    TheISA::MicrocodeRom microcodeRom;
1164636Sgblack@eecs.umich.edu
1174636Sgblack@eecs.umich.edu#if FULL_SYSTEM
1184636Sgblack@eecs.umich.edu  protected:
1194636Sgblack@eecs.umich.edu    TheISA::Interrupts *interrupts;
1204636Sgblack@eecs.umich.edu
1214636Sgblack@eecs.umich.edu  public:
1224636Sgblack@eecs.umich.edu    TheISA::Interrupts *
1234636Sgblack@eecs.umich.edu    getInterruptController()
1243794Sgblack@eecs.umich.edu    {
1251464SN/A        return interrupts;
1261464SN/A    }
1271464SN/A
1281464SN/A    virtual void postInterrupt(int int_num, int index);
1291464SN/A    virtual void clearInterrupt(int int_num, int index);
1302107SN/A    virtual void clearInterrupts();
1311464SN/A
1321464SN/A    bool
1332292SN/A    checkInterrupts(ThreadContext *tc) const
1341464SN/A    {
1351464SN/A        return interrupts->checkInterrupts(tc);
1361464SN/A    }
1371464SN/A
1381464SN/A    class ProfileEvent : public Event
1391464SN/A    {
1401464SN/A      private:
1412678SN/A        BaseCPU *cpu;
1422669SN/A        Tick interval;
1434032Sktlim@umich.edu
1442669SN/A      public:
1451060SN/A        ProfileEvent(BaseCPU *cpu, Tick interval);
1464032Sktlim@umich.edu        void process();
1474032Sktlim@umich.edu    };
1481060SN/A    ProfileEvent *profileEvent;
1491060SN/A#endif
1502702SN/A
1513326Sktlim@umich.edu  protected:
1522702SN/A    std::vector<ThreadContext *> threadContexts;
1532731SN/A    std::vector<TheISA::Predecoder *> predecoders;
1542731SN/A
1551464SN/A    Trace::InstTracer * tracer;
1562292SN/A
1577597Sminkyu.jeong@arm.com  public:
1582731SN/A
1592292SN/A    /// Provide access to the tracer pointer
1602292SN/A    Trace::InstTracer * getTracer() { return tracer; }
1612292SN/A
1621060SN/A    /// Notify the CPU that the indicated context is now active.  The
1631060SN/A    /// delay parameter indicates the number of ticks to wait before
1641464SN/A    /// executing (typically 0 or 1).
1651060SN/A    virtual void activateContext(int thread_num, int delay) {}
1661060SN/A
1671060SN/A    /// Notify the CPU that the indicated context is now suspended.
1682698SN/A    virtual void suspendContext(int thread_num) {}
1692292SN/A
1701060SN/A    /// Notify the CPU that the indicated context is now deallocated.
1715737Scws3k@cs.virginia.edu    virtual void deallocateContext(int thread_num) {}
1725737Scws3k@cs.virginia.edu
1731060SN/A    /// Notify the CPU that the indicated context is now halted.
1745737Scws3k@cs.virginia.edu    virtual void haltContext(int thread_num) {}
1755375Svilas.sridharan@gmail.com
1762292SN/A   /// Given a Thread Context pointer return the thread num
1772292SN/A   int findContext(ThreadContext *tc);
1782292SN/A
1795737Scws3k@cs.virginia.edu   /// Given a thread num get tho thread context for it
1802292SN/A   ThreadContext *getContext(int tn) { return threadContexts[tn]; }
1812292SN/A
1825737Scws3k@cs.virginia.edu  public:
1835737Scws3k@cs.virginia.edu    typedef BaseCPUParams Params;
1845737Scws3k@cs.virginia.edu    const Params *params() const
1855737Scws3k@cs.virginia.edu    { return reinterpret_cast<const Params *>(_params); }
1862292SN/A    BaseCPU(Params *params);
1872292SN/A    virtual ~BaseCPU();
1882292SN/A
1892292SN/A    virtual void init();
1901060SN/A    virtual void startup();
1911060SN/A    virtual void regStats();
1921061SN/A
1931060SN/A    virtual void activateWhenReady(int tid) {};
1941060SN/A
1952678SN/A    void registerThreadContexts();
1962678SN/A
1972292SN/A    /// Prepare for another CPU to take over execution.  When it is
1982292SN/A    /// is ready (drained pipe) it signals the sampler.
1992292SN/A    virtual void switchOut();
2002292SN/A
2012292SN/A    /// Take over execution from the given CPU.  Used for warm-up and
2022292SN/A    /// sampling.
2032348SN/A    virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
2042348SN/A
2055737Scws3k@cs.virginia.edu    /**
2065737Scws3k@cs.virginia.edu     *  Number of threads we're actually simulating (<= SMT_MAX_THREADS).
2072292SN/A     * This is a constant for the duration of the simulation.
2085737Scws3k@cs.virginia.edu     */
2095737Scws3k@cs.virginia.edu    int number_of_threads;
2105737Scws3k@cs.virginia.edu
2115737Scws3k@cs.virginia.edu    TheISA::CoreSpecific coreParams; //ISA-Specific Params That Set Up State in Core
2122292SN/A
2132292SN/A    /**
2142292SN/A     * Vector of per-thread instruction-based event queues.  Used for
2151060SN/A     * scheduling events based on number of instructions committed by
2161464SN/A     * a particular thread.
2172292SN/A     */
2182292SN/A    EventQueue **comInstEventQueue;
2192292SN/A
2202292SN/A    /**
2212292SN/A     * Vector of per-thread load-based event queues.  Used for
2222292SN/A     * scheduling events based on number of loads committed by
2232292SN/A     *a particular thread.
2242292SN/A     */
2252292SN/A    EventQueue **comLoadEventQueue;
2262292SN/A
2272292SN/A    System *system;
2282292SN/A
2292292SN/A    Tick phase;
2302292SN/A
2312292SN/A#if FULL_SYSTEM
2322292SN/A    /**
2331061SN/A     * Serialize this object to the given output stream.
2341060SN/A     * @param os The stream to serialize to.
2351060SN/A     */
2361060SN/A    virtual void serialize(std::ostream &os);
2371060SN/A
2381060SN/A    /**
2391060SN/A     * Reconstruct the state of this object from a checkpoint.
2402669SN/A     * @param cp The checkpoint use.
2411060SN/A     * @param section The section name of this object
2422292SN/A     */
2431060SN/A    virtual void unserialize(Checkpoint *cp, const std::string &section);
2441060SN/A
2451060SN/A#endif
2462090SN/A
2471060SN/A    /**
2481060SN/A     * Return pointer to CPU's branch predictor (NULL if none).
2492292SN/A     * @return Branch predictor pointer.
2501060SN/A     */
2513172Sstever@eecs.umich.edu    virtual BranchPred *getBranchPred() { return NULL; };
2521060SN/A
2531060SN/A    virtual Counter totalInstructions() const { return 0; }
2541060SN/A
2551060SN/A    // Function tracing
2561060SN/A  private:
2571060SN/A    bool functionTracingEnabled;
2581060SN/A    std::ostream *functionTraceStream;
2591060SN/A    Addr currentFunctionStart;
2601060SN/A    Addr currentFunctionEnd;
2611060SN/A    Tick functionEntryTick;
2621060SN/A    void enableFunctionTrace();
2631060SN/A    void traceFunctionsInternal(Addr pc);
2641060SN/A
2651060SN/A  protected:
2661060SN/A    void traceFunctions(Addr pc)
2671060SN/A    {
2682669SN/A        if (functionTracingEnabled)
2691060SN/A            traceFunctionsInternal(pc);
2701060SN/A    }
2711061SN/A
2721060SN/A  private:
2731060SN/A    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list
2741060SN/A
2752702SN/A  public:
2761060SN/A    static int numSimulatedCPUs() { return cpuList.size(); }
2771060SN/A    static Counter numSimulatedInstructions()
2781060SN/A    {
2791060SN/A        Counter total = 0;
2801060SN/A
2811061SN/A        int size = cpuList.size();
2822132SN/A        for (int i = 0; i < size; ++i)
2831060SN/A            total += cpuList[i]->totalInstructions();
2841060SN/A
2852702SN/A        return total;
2862669SN/A    }
2871060SN/A
2881060SN/A  public:
2891060SN/A    // Number of CPU cycles simulated
2901060SN/A    Stats::Scalar<> numCycles;
2911060SN/A};
2921061SN/A
2932132SN/A#endif // __CPU_BASE_HH__
2941060SN/A