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 §ion); 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