base.hh revision 707
113627Sjavier.bueno@metempsy.com/*
213627Sjavier.bueno@metempsy.com * Copyright (c) 2003 The Regents of The University of Michigan
313627Sjavier.bueno@metempsy.com * All rights reserved.
413627Sjavier.bueno@metempsy.com *
513627Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without
613627Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are
713627Sjavier.bueno@metempsy.com * met: redistributions of source code must retain the above copyright
813627Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer;
913627Sjavier.bueno@metempsy.com * redistributions in binary form must reproduce the above copyright
1013627Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer in the
1113627Sjavier.bueno@metempsy.com * documentation and/or other materials provided with the distribution;
1213627Sjavier.bueno@metempsy.com * neither the name of the copyright holders nor the names of its
1313627Sjavier.bueno@metempsy.com * contributors may be used to endorse or promote products derived from
1413627Sjavier.bueno@metempsy.com * this software without specific prior written permission.
1513627Sjavier.bueno@metempsy.com *
1613627Sjavier.bueno@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713627Sjavier.bueno@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813627Sjavier.bueno@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913627Sjavier.bueno@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013627Sjavier.bueno@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113627Sjavier.bueno@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213627Sjavier.bueno@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313627Sjavier.bueno@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413627Sjavier.bueno@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513627Sjavier.bueno@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613627Sjavier.bueno@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713627Sjavier.bueno@metempsy.com */
2813627Sjavier.bueno@metempsy.com
2913627Sjavier.bueno@metempsy.com#ifndef __BASE_CPU_HH__
3013627Sjavier.bueno@metempsy.com#define __BASE_CPU_HH__
3113627Sjavier.bueno@metempsy.com
3213627Sjavier.bueno@metempsy.com#include <vector>
3313627Sjavier.bueno@metempsy.com
3413627Sjavier.bueno@metempsy.com#include "base/statistics.hh"
3513627Sjavier.bueno@metempsy.com#include "sim/eventq.hh"
3613627Sjavier.bueno@metempsy.com#include "sim/sim_object.hh"
3713627Sjavier.bueno@metempsy.com#include "targetarch/isa_traits.hh"
3813627Sjavier.bueno@metempsy.com
3913627Sjavier.bueno@metempsy.com#ifdef FULL_SYSTEM
4013627Sjavier.bueno@metempsy.comclass System;
4113627Sjavier.bueno@metempsy.com#endif
4213627Sjavier.bueno@metempsy.com
4313627Sjavier.bueno@metempsy.comclass BranchPred;
4413627Sjavier.bueno@metempsy.comclass ExecContext;
4513627Sjavier.bueno@metempsy.com
4613627Sjavier.bueno@metempsy.comclass BaseCPU : public SimObject
4713627Sjavier.bueno@metempsy.com{
4813627Sjavier.bueno@metempsy.com#ifdef FULL_SYSTEM
4913627Sjavier.bueno@metempsy.com  protected:
5013627Sjavier.bueno@metempsy.com    Tick frequency;
5113627Sjavier.bueno@metempsy.com    uint8_t interrupts[NumInterruptLevels];
5213627Sjavier.bueno@metempsy.com    uint64_t intstatus;
5313627Sjavier.bueno@metempsy.com
5413627Sjavier.bueno@metempsy.com  public:
5513627Sjavier.bueno@metempsy.com    virtual void post_interrupt(int int_num, int index);
5613627Sjavier.bueno@metempsy.com    virtual void clear_interrupt(int int_num, int index);
5713627Sjavier.bueno@metempsy.com    virtual void clear_interrupts();
5813627Sjavier.bueno@metempsy.com
5913627Sjavier.bueno@metempsy.com    bool check_interrupt(int int_num) const {
6013627Sjavier.bueno@metempsy.com        if (int_num > NumInterruptLevels)
6113627Sjavier.bueno@metempsy.com            panic("int_num out of bounds\n");
6213627Sjavier.bueno@metempsy.com
6313627Sjavier.bueno@metempsy.com        return interrupts[int_num] != 0;
6413627Sjavier.bueno@metempsy.com    }
6513627Sjavier.bueno@metempsy.com
6613627Sjavier.bueno@metempsy.com    bool check_interrupts() const { return intstatus != 0; }
6713627Sjavier.bueno@metempsy.com    uint64_t intr_status() const { return intstatus; }
6813627Sjavier.bueno@metempsy.com
6913627Sjavier.bueno@metempsy.com    Tick getFreq() const { return frequency; }
7013627Sjavier.bueno@metempsy.com#endif
7113627Sjavier.bueno@metempsy.com
7213627Sjavier.bueno@metempsy.com  protected:
7313627Sjavier.bueno@metempsy.com    std::vector<ExecContext *> execContexts;
7413627Sjavier.bueno@metempsy.com
7513627Sjavier.bueno@metempsy.com  public:
7613627Sjavier.bueno@metempsy.com
7713627Sjavier.bueno@metempsy.com    /// Notify the CPU that the indicated context is now active.  The
7813627Sjavier.bueno@metempsy.com    /// delay parameter indicates the number of ticks to wait before
7913627Sjavier.bueno@metempsy.com    /// executing (typically 0 or 1).
8013627Sjavier.bueno@metempsy.com    virtual void activateContext(int thread_num, int delay) {}
8113627Sjavier.bueno@metempsy.com
8213627Sjavier.bueno@metempsy.com    /// Notify the CPU that the indicated context is now suspended.
8313627Sjavier.bueno@metempsy.com    virtual void suspendContext(int thread_num) {}
8413627Sjavier.bueno@metempsy.com
8513627Sjavier.bueno@metempsy.com    /// Notify the CPU that the indicated context is now deallocated.
8613627Sjavier.bueno@metempsy.com    virtual void deallocateContext(int thread_num) {}
8713627Sjavier.bueno@metempsy.com
8813627Sjavier.bueno@metempsy.com    /// Notify the CPU that the indicated context is now halted.
8913627Sjavier.bueno@metempsy.com    virtual void haltContext(int thread_num) {}
9013627Sjavier.bueno@metempsy.com
9113627Sjavier.bueno@metempsy.com  public:
9213627Sjavier.bueno@metempsy.com
9313627Sjavier.bueno@metempsy.com#ifdef FULL_SYSTEM
9413627Sjavier.bueno@metempsy.com    BaseCPU(const std::string &_name, int _number_of_threads,
9513627Sjavier.bueno@metempsy.com            Counter max_insts_any_thread, Counter max_insts_all_threads,
9613627Sjavier.bueno@metempsy.com            Counter max_loads_any_thread, Counter max_loads_all_threads,
9713627Sjavier.bueno@metempsy.com            System *_system, Tick freq);
9813627Sjavier.bueno@metempsy.com#else
9913627Sjavier.bueno@metempsy.com    BaseCPU(const std::string &_name, int _number_of_threads,
10013627Sjavier.bueno@metempsy.com            Counter max_insts_any_thread = 0,
10113627Sjavier.bueno@metempsy.com            Counter max_insts_all_threads = 0,
10213627Sjavier.bueno@metempsy.com            Counter max_loads_any_thread = 0,
10313627Sjavier.bueno@metempsy.com            Counter max_loads_all_threads = 0);
10413627Sjavier.bueno@metempsy.com#endif
10513627Sjavier.bueno@metempsy.com
10613627Sjavier.bueno@metempsy.com    virtual ~BaseCPU() {}
10713627Sjavier.bueno@metempsy.com
10813627Sjavier.bueno@metempsy.com    virtual void regStats();
10913627Sjavier.bueno@metempsy.com
11013627Sjavier.bueno@metempsy.com    void registerExecContexts();
11113627Sjavier.bueno@metempsy.com
11213627Sjavier.bueno@metempsy.com    /// Prepare for another CPU to take over execution.  Called by
11313627Sjavier.bueno@metempsy.com    /// takeOverFrom() on its argument.
11413627Sjavier.bueno@metempsy.com    virtual void switchOut();
11513627Sjavier.bueno@metempsy.com
11613627Sjavier.bueno@metempsy.com    /// Take over execution from the given CPU.  Used for warm-up and
11713627Sjavier.bueno@metempsy.com    /// sampling.
11813627Sjavier.bueno@metempsy.com    virtual void takeOverFrom(BaseCPU *);
11913627Sjavier.bueno@metempsy.com
12013627Sjavier.bueno@metempsy.com    /**
12113627Sjavier.bueno@metempsy.com     *  Number of threads we're actually simulating (<= SMT_MAX_THREADS).
12213627Sjavier.bueno@metempsy.com     * This is a constant for the duration of the simulation.
12313627Sjavier.bueno@metempsy.com     */
12413627Sjavier.bueno@metempsy.com    int number_of_threads;
12513627Sjavier.bueno@metempsy.com
12613627Sjavier.bueno@metempsy.com    /**
12713627Sjavier.bueno@metempsy.com     * Vector of per-thread instruction-based event queues.  Used for
12813627Sjavier.bueno@metempsy.com     * scheduling events based on number of instructions committed by
12913627Sjavier.bueno@metempsy.com     * a particular thread.
13013627Sjavier.bueno@metempsy.com     */
13113627Sjavier.bueno@metempsy.com    EventQueue **comInstEventQueue;
13213627Sjavier.bueno@metempsy.com
13313627Sjavier.bueno@metempsy.com    /**
13413627Sjavier.bueno@metempsy.com     * Vector of per-thread load-based event queues.  Used for
13513627Sjavier.bueno@metempsy.com     * scheduling events based on number of loads committed by
13613627Sjavier.bueno@metempsy.com     *a particular thread.
13713627Sjavier.bueno@metempsy.com     */
13813627Sjavier.bueno@metempsy.com    EventQueue **comLoadEventQueue;
13913627Sjavier.bueno@metempsy.com
14013627Sjavier.bueno@metempsy.com#ifdef FULL_SYSTEM
14113627Sjavier.bueno@metempsy.com    System *system;
14213627Sjavier.bueno@metempsy.com#endif
14313627Sjavier.bueno@metempsy.com
14413627Sjavier.bueno@metempsy.com    /**
14513627Sjavier.bueno@metempsy.com     * Return pointer to CPU's branch predictor (NULL if none).
14613627Sjavier.bueno@metempsy.com     * @return Branch predictor pointer.
14713627Sjavier.bueno@metempsy.com     */
14813627Sjavier.bueno@metempsy.com    virtual BranchPred *getBranchPred() { return NULL; };
14913627Sjavier.bueno@metempsy.com
15013627Sjavier.bueno@metempsy.com    virtual Counter totalInstructions() const { return 0; }
15113627Sjavier.bueno@metempsy.com
15213627Sjavier.bueno@metempsy.com  private:
15313627Sjavier.bueno@metempsy.com    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list
15413627Sjavier.bueno@metempsy.com
15513627Sjavier.bueno@metempsy.com  public:
15613627Sjavier.bueno@metempsy.com    static int numSimulatedCPUs() { return cpuList.size(); }
15713627Sjavier.bueno@metempsy.com    static Counter numSimulatedInstructions()
15813627Sjavier.bueno@metempsy.com    {
15913627Sjavier.bueno@metempsy.com        Counter total = 0;
16013627Sjavier.bueno@metempsy.com
16113627Sjavier.bueno@metempsy.com        int size = cpuList.size();
16213627Sjavier.bueno@metempsy.com        for (int i = 0; i < size; ++i)
16313627Sjavier.bueno@metempsy.com            total += cpuList[i]->totalInstructions();
16413627Sjavier.bueno@metempsy.com
16513627Sjavier.bueno@metempsy.com        return total;
16613627Sjavier.bueno@metempsy.com    }
16713627Sjavier.bueno@metempsy.com
16813627Sjavier.bueno@metempsy.com  public:
16913627Sjavier.bueno@metempsy.com    // Number of CPU cycles simulated
17013627Sjavier.bueno@metempsy.com    Statistics::Scalar<> numCycles;
17113627Sjavier.bueno@metempsy.com};
17213627Sjavier.bueno@metempsy.com
17313627Sjavier.bueno@metempsy.com#endif // __BASE_CPU_HH__
17413627Sjavier.bueno@metempsy.com