base.hh revision 6816:6f8efbef2300
12330SN/A/*
22330SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32330SN/A * All rights reserved.
42330SN/A *
52330SN/A * Redistribution and use in source and binary forms, with or without
62330SN/A * modification, are permitted provided that the following conditions are
72330SN/A * met: redistributions of source code must retain the above copyright
82330SN/A * notice, this list of conditions and the following disclaimer;
92330SN/A * redistributions in binary form must reproduce the above copyright
102330SN/A * notice, this list of conditions and the following disclaimer in the
112330SN/A * documentation and/or other materials provided with the distribution;
122330SN/A * neither the name of the copyright holders nor the names of its
132330SN/A * contributors may be used to endorse or promote products derived from
142330SN/A * this software without specific prior written permission.
152330SN/A *
162330SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172330SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182330SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192330SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202330SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212330SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222330SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232330SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242330SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252330SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262330SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272689Sktlim@umich.edu *
282689Sktlim@umich.edu * Authors: Steve Reinhardt
292330SN/A *          Nathan Binkert
302292SN/A */
312292SN/A
322292SN/A#ifndef __CPU_BASE_HH__
332292SN/A#define __CPU_BASE_HH__
342980Sgblack@eecs.umich.edu
356658Snate@binkert.org#include <vector>
368229Snate@binkert.org
372362SN/A#include "arch/isa_traits.hh"
382680Sktlim@umich.edu#include "arch/microcode_rom.hh"
392683Sktlim@umich.edu#include "base/statistics.hh"
402683Sktlim@umich.edu#include "config/full_system.hh"
412678Sktlim@umich.edu#include "config/the_isa.hh"
422292SN/A#include "sim/eventq.hh"
432292SN/A#include "sim/insttracer.hh"
442292SN/A#include "mem/mem_object.hh"
453548Sgblack@eecs.umich.edu
463548Sgblack@eecs.umich.edu#if FULL_SYSTEM
473548Sgblack@eecs.umich.edu#include "arch/interrupts.hh"
483548Sgblack@eecs.umich.edu#endif
492330SN/A
502292SN/Aclass BaseCPUParams;
512862Sktlim@umich.educlass BranchPred;
523486Sktlim@umich.educlass CheckerCPU;
533402Sktlim@umich.educlass ThreadContext;
542862Sktlim@umich.educlass System;
552330SN/Aclass Port;
562330SN/A
572330SN/Anamespace TheISA
582330SN/A{
592330SN/A    class Predecoder;
602330SN/A}
612292SN/A
622683Sktlim@umich.educlass CPUProgressEvent : public Event
632683Sktlim@umich.edu{
646331Sgblack@eecs.umich.edu  protected:
652683Sktlim@umich.edu    Tick _interval;
663486Sktlim@umich.edu    Counter lastNumInst;
673486Sktlim@umich.edu    BaseCPU *cpu;
682862Sktlim@umich.edu    bool _repeatEvent;
692862Sktlim@umich.edu
702862Sktlim@umich.edu  public:
712862Sktlim@umich.edu    CPUProgressEvent(BaseCPU *_cpu, Tick ival = 0);
725712Shsul@eecs.umich.edu
732683Sktlim@umich.edu    void process();
745714Shsul@eecs.umich.edu
755714Shsul@eecs.umich.edu    void interval(Tick ival) { _interval = ival; }
765714Shsul@eecs.umich.edu    Tick interval() { return _interval; }
775714Shsul@eecs.umich.edu
786221Snate@binkert.org    void repeatEvent(bool repeat) { _repeatEvent = repeat; }
792683Sktlim@umich.edu
806221Snate@binkert.org    virtual const char *description() const;
812683Sktlim@umich.edu};
822683Sktlim@umich.edu
832683Sktlim@umich.educlass BaseCPU : public MemObject
842683Sktlim@umich.edu{
852683Sktlim@umich.edu  protected:
868754Sgblack@eecs.umich.edu    // CPU's clock period in terms of the number of ticks of curTime.
878754Sgblack@eecs.umich.edu    Tick clock;
888761Sgblack@eecs.umich.edu    // @todo remove me after debugging with legion done
898761Sgblack@eecs.umich.edu    Tick instCnt;
905497Ssaidi@eecs.umich.edu    // every cpu has an id, put it in the base cpu
913675Sktlim@umich.edu    // Set at initialization, only time a cpuId might change is during a
922683Sktlim@umich.edu    // takeover (which should be done from within the BaseCPU anyway,
932683Sktlim@umich.edu    // therefore no setCpuId() method is provided
942683Sktlim@umich.edu    int _cpuId;
952683Sktlim@umich.edu
962683Sktlim@umich.edu  public:
972683Sktlim@umich.edu    /** Reads this CPU's ID. */
982683Sktlim@umich.edu    int cpuId() { return _cpuId; }
992683Sktlim@umich.edu
1003548Sgblack@eecs.umich.edu//    Tick currentTick;
1018777Sgblack@eecs.umich.edu    inline Tick frequency() const { return Clock::Frequency / clock; }
1022683Sktlim@umich.edu    inline Tick ticks(int numCycles) const { return clock * numCycles; }
1032683Sktlim@umich.edu    inline Tick curCycle() const { return curTick / clock; }
1043402Sktlim@umich.edu    inline Tick tickToCycles(Tick val) const { return val / clock; }
1052683Sktlim@umich.edu    // @todo remove me after debugging with legion done
1062683Sktlim@umich.edu    Tick instCount() { return instCnt; }
1072292SN/A
1088761Sgblack@eecs.umich.edu    /** The next cycle the CPU should be scheduled, given a cache
1098761Sgblack@eecs.umich.edu     * access or quiesce event returning on this cycle.  This function
1108754Sgblack@eecs.umich.edu     * may return curTick if the CPU should run on the current cycle.
1118754Sgblack@eecs.umich.edu     */
1128754Sgblack@eecs.umich.edu    Tick nextCycle();
1138754Sgblack@eecs.umich.edu
1142683Sktlim@umich.edu    /** The next cycle the CPU should be scheduled, given a cache
1152683Sktlim@umich.edu     * access or quiesce event returning on the given Tick.  This
1162683Sktlim@umich.edu     * function may return curTick if the CPU should run on the
1172683Sktlim@umich.edu     * current cycle.
1182683Sktlim@umich.edu     * @param begin_tick The tick that the event is completing on.
1192683Sktlim@umich.edu     */
1202683Sktlim@umich.edu    Tick nextCycle(Tick begin_tick);
1212683Sktlim@umich.edu
1222683Sktlim@umich.edu    TheISA::MicrocodeRom microcodeRom;
1232683Sktlim@umich.edu
1242683Sktlim@umich.edu#if FULL_SYSTEM
1252683Sktlim@umich.edu  protected:
1262683Sktlim@umich.edu    TheISA::Interrupts *interrupts;
1272683Sktlim@umich.edu
1282683Sktlim@umich.edu  public:
1292683Sktlim@umich.edu    TheISA::Interrupts *
1303673Srdreslin@umich.edu    getInterruptController()
1313675Sktlim@umich.edu    {
1323675Sktlim@umich.edu        return interrupts;
1333675Sktlim@umich.edu    }
1343486Sktlim@umich.edu
1352683Sktlim@umich.edu    virtual void wakeup() = 0;
1362683Sktlim@umich.edu
1372683Sktlim@umich.edu    void
1385999Snate@binkert.org    postInterrupt(int int_num, int index)
1392683Sktlim@umich.edu    {
1405999Snate@binkert.org        interrupts->post(int_num, index);
1412683Sktlim@umich.edu        wakeup();
1422683Sktlim@umich.edu    }
1432683Sktlim@umich.edu
1442683Sktlim@umich.edu    void
1452683Sktlim@umich.edu    clearInterrupt(int int_num, int index)
1462683Sktlim@umich.edu    {
1472683Sktlim@umich.edu        interrupts->clear(int_num, index);
1482683Sktlim@umich.edu    }
1492683Sktlim@umich.edu
1502683Sktlim@umich.edu    void
1512683Sktlim@umich.edu    clearInterrupts()
1522683Sktlim@umich.edu    {
1533402Sktlim@umich.edu        interrupts->clearAll();
1543402Sktlim@umich.edu    }
1553402Sktlim@umich.edu
1565714Shsul@eecs.umich.edu    bool
1575714Shsul@eecs.umich.edu    checkInterrupts(ThreadContext *tc) const
1585714Shsul@eecs.umich.edu    {
1592292SN/A        return interrupts->checkInterrupts(tc);
1606221Snate@binkert.org    }
1612292SN/A
1622690Sktlim@umich.edu    class ProfileEvent : public Event
1632683Sktlim@umich.edu    {
1642683Sktlim@umich.edu      private:
1652292SN/A        BaseCPU *cpu;
1662683Sktlim@umich.edu        Tick interval;
1672683Sktlim@umich.edu
1682292SN/A      public:
1692683Sktlim@umich.edu        ProfileEvent(BaseCPU *cpu, Tick interval);
1702292SN/A        void process();
1712292SN/A    };
1722292SN/A    ProfileEvent *profileEvent;
1732292SN/A#endif
1742292SN/A
1753548Sgblack@eecs.umich.edu  protected:
1768777Sgblack@eecs.umich.edu    std::vector<ThreadContext *> threadContexts;
1772683Sktlim@umich.edu    std::vector<TheISA::Predecoder *> predecoders;
1782292SN/A
1792330SN/A    Trace::InstTracer * tracer;
1808764Sgblack@eecs.umich.edu
1818764Sgblack@eecs.umich.edu  public:
1828761Sgblack@eecs.umich.edu
1838761Sgblack@eecs.umich.edu    /// Provide access to the tracer pointer
1848761Sgblack@eecs.umich.edu    Trace::InstTracer * getTracer() { return tracer; }
1858761Sgblack@eecs.umich.edu
1868754Sgblack@eecs.umich.edu    /// Notify the CPU that the indicated context is now active.  The
1878754Sgblack@eecs.umich.edu    /// delay parameter indicates the number of ticks to wait before
1888754Sgblack@eecs.umich.edu    /// executing (typically 0 or 1).
1898754Sgblack@eecs.umich.edu    virtual void activateContext(int thread_num, int delay) {}
1902690Sktlim@umich.edu
1912292SN/A    /// Notify the CPU that the indicated context is now suspended.
1922292SN/A    virtual void suspendContext(int thread_num) {}
1932292SN/A
1942292SN/A    /// Notify the CPU that the indicated context is now deallocated.
1952292SN/A    virtual void deallocateContext(int thread_num) {}
1962292SN/A
1972292SN/A    /// Notify the CPU that the indicated context is now halted.
1982292SN/A    virtual void haltContext(int thread_num) {}
1992292SN/A
2002292SN/A   /// Given a Thread Context pointer return the thread num
2012292SN/A   int findContext(ThreadContext *tc);
2022292SN/A
2032292SN/A   /// Given a thread num get tho thread context for it
204   ThreadContext *getContext(int tn) { return threadContexts[tn]; }
205
206  public:
207    typedef BaseCPUParams Params;
208    const Params *params() const
209    { return reinterpret_cast<const Params *>(_params); }
210    BaseCPU(Params *params);
211    virtual ~BaseCPU();
212
213    virtual void init();
214    virtual void startup();
215    virtual void regStats();
216
217    virtual void activateWhenReady(ThreadID tid) {};
218
219    void registerThreadContexts();
220
221    /// Prepare for another CPU to take over execution.  When it is
222    /// is ready (drained pipe) it signals the sampler.
223    virtual void switchOut();
224
225    /// Take over execution from the given CPU.  Used for warm-up and
226    /// sampling.
227    virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
228
229    /**
230     *  Number of threads we're actually simulating (<= SMT_MAX_THREADS).
231     * This is a constant for the duration of the simulation.
232     */
233    ThreadID numThreads;
234
235    TheISA::CoreSpecific coreParams; //ISA-Specific Params That Set Up State in Core
236
237    /**
238     * Vector of per-thread instruction-based event queues.  Used for
239     * scheduling events based on number of instructions committed by
240     * a particular thread.
241     */
242    EventQueue **comInstEventQueue;
243
244    /**
245     * Vector of per-thread load-based event queues.  Used for
246     * scheduling events based on number of loads committed by
247     *a particular thread.
248     */
249    EventQueue **comLoadEventQueue;
250
251    System *system;
252
253    Tick phase;
254
255#if FULL_SYSTEM
256    /**
257     * Serialize this object to the given output stream.
258     * @param os The stream to serialize to.
259     */
260    virtual void serialize(std::ostream &os);
261
262    /**
263     * Reconstruct the state of this object from a checkpoint.
264     * @param cp The checkpoint use.
265     * @param section The section name of this object
266     */
267    virtual void unserialize(Checkpoint *cp, const std::string &section);
268
269#endif
270
271    /**
272     * Return pointer to CPU's branch predictor (NULL if none).
273     * @return Branch predictor pointer.
274     */
275    virtual BranchPred *getBranchPred() { return NULL; };
276
277    virtual Counter totalInstructions() const = 0;
278
279    // Function tracing
280  private:
281    bool functionTracingEnabled;
282    std::ostream *functionTraceStream;
283    Addr currentFunctionStart;
284    Addr currentFunctionEnd;
285    Tick functionEntryTick;
286    void enableFunctionTrace();
287    void traceFunctionsInternal(Addr pc);
288
289  protected:
290    void traceFunctions(Addr pc)
291    {
292        if (functionTracingEnabled)
293            traceFunctionsInternal(pc);
294    }
295
296  private:
297    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list
298
299  public:
300    static int numSimulatedCPUs() { return cpuList.size(); }
301    static Counter numSimulatedInstructions()
302    {
303        Counter total = 0;
304
305        int size = cpuList.size();
306        for (int i = 0; i < size; ++i)
307            total += cpuList[i]->totalInstructions();
308
309        return total;
310    }
311
312  public:
313    // Number of CPU cycles simulated
314    Stats::Scalar numCycles;
315};
316
317#endif // __CPU_BASE_HH__
318