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