base.hh revision 5222:bb733a878f85
1/*
2 * Copyright (c) 2002-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Steve Reinhardt
29 *          Nathan Binkert
30 */
31
32#ifndef __CPU_BASE_HH__
33#define __CPU_BASE_HH__
34
35#include <vector>
36
37#include "arch/isa_traits.hh"
38#include "base/statistics.hh"
39#include "config/full_system.hh"
40#include "sim/eventq.hh"
41#include "sim/insttracer.hh"
42#include "mem/mem_object.hh"
43
44#if FULL_SYSTEM
45#include "arch/interrupts.hh"
46#endif
47
48class BranchPred;
49class CheckerCPU;
50class ThreadContext;
51class System;
52class Port;
53
54namespace TheISA
55{
56    class Predecoder;
57}
58
59class CPUProgressEvent : public Event
60{
61  protected:
62    Tick interval;
63    Counter lastNumInst;
64    BaseCPU *cpu;
65
66  public:
67    CPUProgressEvent(EventQueue *q, Tick ival, BaseCPU *_cpu);
68
69    void process();
70
71    virtual const char *description();
72};
73
74class BaseCPU : public MemObject
75{
76  protected:
77    // CPU's clock period in terms of the number of ticks of curTime.
78    Tick clock;
79    // @todo remove me after debugging with legion done
80    Tick instCnt;
81
82  public:
83//    Tick currentTick;
84    inline Tick frequency() const { return Clock::Frequency / clock; }
85    inline Tick ticks(int numCycles) const { return clock * numCycles; }
86    inline Tick curCycle() const { return curTick / clock; }
87    inline Tick tickToCycles(Tick val) const { return val / clock; }
88    // @todo remove me after debugging with legion done
89    Tick instCount() { return instCnt; }
90
91    /** The next cycle the CPU should be scheduled, given a cache
92     * access or quiesce event returning on this cycle.  This function
93     * may return curTick if the CPU should run on the current cycle.
94     */
95    Tick nextCycle();
96
97    /** The next cycle the CPU should be scheduled, given a cache
98     * access or quiesce event returning on the given Tick.  This
99     * function may return curTick if the CPU should run on the
100     * current cycle.
101     * @param begin_tick The tick that the event is completing on.
102     */
103    Tick nextCycle(Tick begin_tick);
104
105#if FULL_SYSTEM
106  protected:
107//    uint64_t interrupts[TheISA::NumInterruptLevels];
108//    uint64_t intstatus;
109    TheISA::Interrupts interrupts;
110
111  public:
112    virtual void post_interrupt(int int_num, int index);
113    virtual void clear_interrupt(int int_num, int index);
114    virtual void clear_interrupts();
115    virtual uint64_t get_interrupts(int int_num);
116
117    bool check_interrupts(ThreadContext * tc) const
118    { return interrupts.check_interrupts(tc); }
119
120    class ProfileEvent : public Event
121    {
122      private:
123        BaseCPU *cpu;
124        int interval;
125
126      public:
127        ProfileEvent(BaseCPU *cpu, int interval);
128        void process();
129    };
130    ProfileEvent *profileEvent;
131#endif
132
133  protected:
134    std::vector<ThreadContext *> threadContexts;
135    std::vector<TheISA::Predecoder *> predecoders;
136
137    Trace::InstTracer * tracer;
138
139  public:
140
141    /// Provide access to the tracer pointer
142    Trace::InstTracer * getTracer() { return tracer; }
143
144    /// Notify the CPU that the indicated context is now active.  The
145    /// delay parameter indicates the number of ticks to wait before
146    /// executing (typically 0 or 1).
147    virtual void activateContext(int thread_num, int delay) {}
148
149    /// Notify the CPU that the indicated context is now suspended.
150    virtual void suspendContext(int thread_num) {}
151
152    /// Notify the CPU that the indicated context is now deallocated.
153    virtual void deallocateContext(int thread_num) {}
154
155    /// Notify the CPU that the indicated context is now halted.
156    virtual void haltContext(int thread_num) {}
157
158   /// Given a Thread Context pointer return the thread num
159   int findContext(ThreadContext *tc);
160
161   /// Given a thread num get tho thread context for it
162   ThreadContext *getContext(int tn) { return threadContexts[tn]; }
163
164  public:
165    struct Params
166    {
167        std::string name;
168        int numberOfThreads;
169        bool deferRegistration;
170        Counter max_insts_any_thread;
171        Counter max_insts_all_threads;
172        Counter max_loads_any_thread;
173        Counter max_loads_all_threads;
174        Tick clock;
175        bool functionTrace;
176        Tick functionTraceStart;
177        System *system;
178        int cpu_id;
179        Trace::InstTracer * tracer;
180
181        Tick phase;
182#if FULL_SYSTEM
183        Tick profile;
184
185        bool do_statistics_insts;
186        bool do_checkpoint_insts;
187        bool do_quiesce;
188#endif
189        Tick progress_interval;
190        BaseCPU *checker;
191
192#if THE_ISA == MIPS_ISA
193      /* Note: It looks like it will be better to allow simulator users
194         to specify the values of individual variables instead of requiring
195         users to define the values of entire registers
196         Especially since a lot of these variables can be created from other
197         user parameters  (cache descriptions)
198                                               -jpp
199      */
200      // MIPS CP0 State - First individual variables
201      // Page numbers refer to revision 2.50 (July 2005) of the MIPS32 ARM, Volume III (PRA)
202      unsigned CP0_IntCtl_IPTI; // Page 93, IP Timer Interrupt
203      unsigned CP0_IntCtl_IPPCI; // Page 94, IP Performance Counter Interrupt
204      unsigned CP0_SrsCtl_HSS; // Page 95, Highest Implemented Shadow Set
205      unsigned CP0_PRId_CompanyOptions; // Page 105, Manufacture options
206      unsigned CP0_PRId_CompanyID; // Page 105, Company ID - (0-255, 1=>MIPS)
207      unsigned CP0_PRId_ProcessorID; // Page 105
208      unsigned CP0_PRId_Revision; // Page 105
209      unsigned CP0_EBase_CPUNum; // Page 106, CPU Number in a multiprocessor system
210      unsigned CP0_Config_BE; // Page 108, Big/Little Endian mode
211      unsigned CP0_Config_AT; //Page 109
212      unsigned CP0_Config_AR; //Page 109
213      unsigned CP0_Config_MT; //Page 109
214      unsigned CP0_Config_VI; //Page 109
215      unsigned CP0_Config1_M; // Page 110
216      unsigned CP0_Config1_MMU; // Page 110
217      unsigned CP0_Config1_IS; // Page 110
218      unsigned CP0_Config1_IL; // Page 111
219      unsigned CP0_Config1_IA; // Page 111
220      unsigned CP0_Config1_DS; // Page 111
221      unsigned CP0_Config1_DL; // Page 112
222      unsigned CP0_Config1_DA; // Page 112
223      bool CP0_Config1_C2; // Page 112
224      bool CP0_Config1_MD;// Page 112 - Technically not used in MIPS32
225      bool CP0_Config1_PC;// Page 112
226      bool CP0_Config1_WR;// Page 113
227      bool CP0_Config1_CA;// Page 113
228      bool CP0_Config1_EP;// Page 113
229      bool CP0_Config1_FP;// Page 113
230      bool CP0_Config2_M; // Page 114
231      unsigned CP0_Config2_TU;// Page 114
232      unsigned CP0_Config2_TS;// Page 114
233      unsigned CP0_Config2_TL;// Page 115
234      unsigned CP0_Config2_TA;// Page 115
235      unsigned CP0_Config2_SU;// Page 115
236      unsigned CP0_Config2_SS;// Page 115
237      unsigned CP0_Config2_SL;// Page 116
238      unsigned CP0_Config2_SA;// Page 116
239      bool CP0_Config3_M; //// Page 117
240      bool CP0_Config3_DSPP;// Page 117
241      bool CP0_Config3_LPA;// Page 117
242      bool CP0_Config3_VEIC;// Page 118
243      bool CP0_Config3_VInt; // Page 118
244      bool CP0_Config3_SP;// Page 118
245      bool CP0_Config3_MT;// Page 119
246      bool CP0_Config3_SM;// Page 119
247      bool CP0_Config3_TL;// Page 119
248
249      bool CP0_WatchHi_M; // Page 124
250      bool CP0_PerfCtr_M; // Page 130
251      bool CP0_PerfCtr_W; // Page 130
252
253
254      // Then, whole registers
255      unsigned CP0_PRId;
256      unsigned CP0_Config;
257      unsigned CP0_Config1;
258      unsigned CP0_Config2;
259      unsigned CP0_Config3;
260
261#endif
262
263        Params();
264    };
265
266    const Params *params;
267
268    BaseCPU(Params *params);
269    virtual ~BaseCPU();
270
271    virtual void init();
272    virtual void startup();
273    virtual void regStats();
274
275    virtual void activateWhenReady(int tid) {};
276
277    void registerThreadContexts();
278
279    /// Prepare for another CPU to take over execution.  When it is
280    /// is ready (drained pipe) it signals the sampler.
281    virtual void switchOut();
282
283    /// Take over execution from the given CPU.  Used for warm-up and
284    /// sampling.
285    virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
286
287    /**
288     *  Number of threads we're actually simulating (<= SMT_MAX_THREADS).
289     * This is a constant for the duration of the simulation.
290     */
291    int number_of_threads;
292
293    /**
294     * Vector of per-thread instruction-based event queues.  Used for
295     * scheduling events based on number of instructions committed by
296     * a particular thread.
297     */
298    EventQueue **comInstEventQueue;
299
300    /**
301     * Vector of per-thread load-based event queues.  Used for
302     * scheduling events based on number of loads committed by
303     *a particular thread.
304     */
305    EventQueue **comLoadEventQueue;
306
307    System *system;
308
309    Tick phase;
310
311#if FULL_SYSTEM
312    /**
313     * Serialize this object to the given output stream.
314     * @param os The stream to serialize to.
315     */
316    virtual void serialize(std::ostream &os);
317
318    /**
319     * Reconstruct the state of this object from a checkpoint.
320     * @param cp The checkpoint use.
321     * @param section The section name of this object
322     */
323    virtual void unserialize(Checkpoint *cp, const std::string &section);
324
325#endif
326
327    /**
328     * Return pointer to CPU's branch predictor (NULL if none).
329     * @return Branch predictor pointer.
330     */
331    virtual BranchPred *getBranchPred() { return NULL; };
332
333    virtual Counter totalInstructions() const { return 0; }
334
335    // Function tracing
336  private:
337    bool functionTracingEnabled;
338    std::ostream *functionTraceStream;
339    Addr currentFunctionStart;
340    Addr currentFunctionEnd;
341    Tick functionEntryTick;
342    void enableFunctionTrace();
343    void traceFunctionsInternal(Addr pc);
344
345  protected:
346    void traceFunctions(Addr pc)
347    {
348        if (functionTracingEnabled)
349            traceFunctionsInternal(pc);
350    }
351
352  private:
353    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list
354
355  public:
356    static int numSimulatedCPUs() { return cpuList.size(); }
357    static Counter numSimulatedInstructions()
358    {
359        Counter total = 0;
360
361        int size = cpuList.size();
362        for (int i = 0; i < size; ++i)
363            total += cpuList[i]->totalInstructions();
364
365        return total;
366    }
367
368  public:
369    // Number of CPU cycles simulated
370    Stats::Scalar<> numCycles;
371};
372
373#endif // __CPU_BASE_HH__
374