base.hh revision 2103
13006SN/A/*
23006SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
34398SN/A * All rights reserved.
411390Ssteve.reinhardt@amd.com *
511390Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without
68540SN/A * modification, are permitted provided that the following conditions are
711606Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
811606Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
911606Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1011606Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1111606Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1211390Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its
1311390Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from
1410036SAli.Saidi@ARM.com * this software without specific prior written permission.
1510036SAli.Saidi@ARM.com *
1611530Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711390Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811390Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911390Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011390Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111390Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2210488Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2310488Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411390Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511390Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611390Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2710488Snilay@cs.wisc.edu */
2810488Snilay@cs.wisc.edu
2911390Ssteve.reinhardt@amd.com#ifndef __CPU_BASE_HH__
3011390Ssteve.reinhardt@amd.com#define __CPU_BASE_HH__
3111390Ssteve.reinhardt@amd.com
3211390Ssteve.reinhardt@amd.com#include <vector>
3311390Ssteve.reinhardt@amd.com
3411390Ssteve.reinhardt@amd.com#include "base/statistics.hh"
3511390Ssteve.reinhardt@amd.com#include "config/full_system.hh"
3611390Ssteve.reinhardt@amd.com#include "cpu/sampler/sampler.hh"
3711390Ssteve.reinhardt@amd.com#include "sim/eventq.hh"
3811390Ssteve.reinhardt@amd.com#include "sim/sim_object.hh"
3911530Sandreas.sandberg@arm.com#include "targetarch/isa_traits.hh"
4010036SAli.Saidi@ARM.com
418540SN/A#if FULL_SYSTEM
428540SN/Aclass System;
438540SN/A#endif
448540SN/A
458540SN/Aclass BranchPred;
468540SN/Aclass ExecContext;
475510SN/A
485510SN/Aclass BaseCPU : public SimObject
498540SN/A{
508540SN/A  protected:
518540SN/A    // CPU's clock period in terms of the number of ticks of curTime.
528540SN/A    Tick clock;
538540SN/A
548540SN/A  public:
558540SN/A    inline Tick frequency() const { return Clock::Frequency / clock; }
565510SN/A    inline Tick cycles(int numCycles) const { return clock * numCycles; }
575510SN/A    inline Tick curCycle() const { return curTick / clock; }
588540SN/A
5910488Snilay@cs.wisc.edu#if FULL_SYSTEM
6011530Sandreas.sandberg@arm.com  protected:
6111390Ssteve.reinhardt@amd.com    uint64_t interrupts[NumInterruptLevels];
628540SN/A    uint64_t intstatus;
637935SN/A
6411390Ssteve.reinhardt@amd.com  public:
6511390Ssteve.reinhardt@amd.com    virtual void post_interrupt(int int_num, int index);
6611390Ssteve.reinhardt@amd.com    virtual void clear_interrupt(int int_num, int index);
678540SN/A    virtual void clear_interrupts();
6811390Ssteve.reinhardt@amd.com    bool checkInterrupts;
6911390Ssteve.reinhardt@amd.com
7011390Ssteve.reinhardt@amd.com    bool check_interrupt(int int_num) const {
717935SN/A        if (int_num > NumInterruptLevels)
7211390Ssteve.reinhardt@amd.com            panic("int_num out of bounds\n");
7311390Ssteve.reinhardt@amd.com
747935SN/A        return interrupts[int_num] != 0;
757935SN/A    }
7611390Ssteve.reinhardt@amd.com
7711390Ssteve.reinhardt@amd.com    bool check_interrupts() const { return intstatus != 0; }
7810488Snilay@cs.wisc.edu    uint64_t intr_status() const { return intstatus; }
797935SN/A
8011390Ssteve.reinhardt@amd.com    class ProfileEvent : public Event
818540SN/A    {
828540SN/A      private:
8311390Ssteve.reinhardt@amd.com        BaseCPU *cpu;
8411390Ssteve.reinhardt@amd.com        int interval;
8511390Ssteve.reinhardt@amd.com
8611390Ssteve.reinhardt@amd.com      public:
8711390Ssteve.reinhardt@amd.com        ProfileEvent(BaseCPU *cpu, int interval);
8811390Ssteve.reinhardt@amd.com        void process();
8911390Ssteve.reinhardt@amd.com    };
9011390Ssteve.reinhardt@amd.com    ProfileEvent *profileEvent;
9111390Ssteve.reinhardt@amd.com#endif
9211390Ssteve.reinhardt@amd.com
9311390Ssteve.reinhardt@amd.com  protected:
9411390Ssteve.reinhardt@amd.com    std::vector<ExecContext *> execContexts;
9511390Ssteve.reinhardt@amd.com
9611390Ssteve.reinhardt@amd.com  public:
9711390Ssteve.reinhardt@amd.com
9811390Ssteve.reinhardt@amd.com    /// Notify the CPU that the indicated context is now active.  The
9911390Ssteve.reinhardt@amd.com    /// delay parameter indicates the number of ticks to wait before
10011390Ssteve.reinhardt@amd.com    /// executing (typically 0 or 1).
10111390Ssteve.reinhardt@amd.com    virtual void activateContext(int thread_num, int delay) {}
10211390Ssteve.reinhardt@amd.com
10311390Ssteve.reinhardt@amd.com    /// Notify the CPU that the indicated context is now suspended.
10411390Ssteve.reinhardt@amd.com    virtual void suspendContext(int thread_num) {}
10511390Ssteve.reinhardt@amd.com
10611390Ssteve.reinhardt@amd.com    /// Notify the CPU that the indicated context is now deallocated.
10711390Ssteve.reinhardt@amd.com    virtual void deallocateContext(int thread_num) {}
10811390Ssteve.reinhardt@amd.com
10911390Ssteve.reinhardt@amd.com    /// Notify the CPU that the indicated context is now halted.
11011390Ssteve.reinhardt@amd.com    virtual void haltContext(int thread_num) {}
11111390Ssteve.reinhardt@amd.com
11211390Ssteve.reinhardt@amd.com  public:
11311390Ssteve.reinhardt@amd.com    struct Params
11411390Ssteve.reinhardt@amd.com    {
11511390Ssteve.reinhardt@amd.com        std::string name;
11610220Sandreas.hansson@arm.com        int numberOfThreads;
11710220Sandreas.hansson@arm.com        bool deferRegistration;
11811390Ssteve.reinhardt@amd.com        Counter max_insts_any_thread;
11911606Sandreas.sandberg@arm.com        Counter max_insts_all_threads;
12011606Sandreas.sandberg@arm.com        Counter max_loads_any_thread;
12111606Sandreas.sandberg@arm.com        Counter max_loads_all_threads;
12211606Sandreas.sandberg@arm.com        Tick clock;
12311606Sandreas.sandberg@arm.com        bool functionTrace;
12411606Sandreas.sandberg@arm.com        Tick functionTraceStart;
12511530Sandreas.sandberg@arm.com#if FULL_SYSTEM
12611390Ssteve.reinhardt@amd.com        System *system;
12711390Ssteve.reinhardt@amd.com        int cpu_id;
12811268Satgutier@umich.edu        Tick profile;
12911268Satgutier@umich.edu#endif
13011390Ssteve.reinhardt@amd.com
13111390Ssteve.reinhardt@amd.com        Params();
13211390Ssteve.reinhardt@amd.com    };
13311390Ssteve.reinhardt@amd.com
13411390Ssteve.reinhardt@amd.com    const Params *params;
13511390Ssteve.reinhardt@amd.com
13611268Satgutier@umich.edu    BaseCPU(Params *params);
13711570SCurtis.Dunham@arm.com    virtual ~BaseCPU();
13811390Ssteve.reinhardt@amd.com
13911606Sandreas.sandberg@arm.com    virtual void init();
14011606Sandreas.sandberg@arm.com    virtual void startup();
14111268Satgutier@umich.edu    virtual void regStats();
14211606Sandreas.sandberg@arm.com
14311606Sandreas.sandberg@arm.com    virtual void activateWhenReady(int tid) {};
14411268Satgutier@umich.edu
14511268Satgutier@umich.edu    void registerExecContexts();
14611606Sandreas.sandberg@arm.com
14711390Ssteve.reinhardt@amd.com    /// Prepare for another CPU to take over execution.  When it is
1483006SN/A    /// is ready (drained pipe) it signals the sampler.
1493006SN/A    virtual void switchOut(Sampler *);
150
151    /// Take over execution from the given CPU.  Used for warm-up and
152    /// sampling.
153    virtual void takeOverFrom(BaseCPU *);
154
155    /**
156     *  Number of threads we're actually simulating (<= SMT_MAX_THREADS).
157     * This is a constant for the duration of the simulation.
158     */
159    int number_of_threads;
160
161    /**
162     * Vector of per-thread instruction-based event queues.  Used for
163     * scheduling events based on number of instructions committed by
164     * a particular thread.
165     */
166    EventQueue **comInstEventQueue;
167
168    /**
169     * Vector of per-thread load-based event queues.  Used for
170     * scheduling events based on number of loads committed by
171     *a particular thread.
172     */
173    EventQueue **comLoadEventQueue;
174
175#if FULL_SYSTEM
176    System *system;
177
178    /**
179     * Serialize this object to the given output stream.
180     * @param os The stream to serialize to.
181     */
182    virtual void serialize(std::ostream &os);
183
184    /**
185     * Reconstruct the state of this object from a checkpoint.
186     * @param cp The checkpoint use.
187     * @param section The section name of this object
188     */
189    virtual void unserialize(Checkpoint *cp, const std::string &section);
190
191#endif
192
193    /**
194     * Return pointer to CPU's branch predictor (NULL if none).
195     * @return Branch predictor pointer.
196     */
197    virtual BranchPred *getBranchPred() { return NULL; };
198
199    virtual Counter totalInstructions() const { return 0; }
200
201    // Function tracing
202  private:
203    bool functionTracingEnabled;
204    std::ostream *functionTraceStream;
205    Addr currentFunctionStart;
206    Addr currentFunctionEnd;
207    Tick functionEntryTick;
208    void enableFunctionTrace();
209    void traceFunctionsInternal(Addr pc);
210
211  protected:
212    void traceFunctions(Addr pc)
213    {
214        if (functionTracingEnabled)
215            traceFunctionsInternal(pc);
216    }
217
218  private:
219    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list
220
221  public:
222    static int numSimulatedCPUs() { return cpuList.size(); }
223    static Counter numSimulatedInstructions()
224    {
225        Counter total = 0;
226
227        int size = cpuList.size();
228        for (int i = 0; i < size; ++i)
229            total += cpuList[i]->totalInstructions();
230
231        return total;
232    }
233
234  public:
235    // Number of CPU cycles simulated
236    Stats::Scalar<> numCycles;
237};
238
239#endif // __CPU_BASE_HH__
240