cpu.hh revision 2190
110396Sakash.bagdia@arm.com/* 210396Sakash.bagdia@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 310396Sakash.bagdia@arm.com * All rights reserved. 410396Sakash.bagdia@arm.com * 510396Sakash.bagdia@arm.com * Redistribution and use in source and binary forms, with or without 610396Sakash.bagdia@arm.com * modification, are permitted provided that the following conditions are 710396Sakash.bagdia@arm.com * met: redistributions of source code must retain the above copyright 810396Sakash.bagdia@arm.com * notice, this list of conditions and the following disclaimer; 910396Sakash.bagdia@arm.com * redistributions in binary form must reproduce the above copyright 1010396Sakash.bagdia@arm.com * notice, this list of conditions and the following disclaimer in the 1110396Sakash.bagdia@arm.com * documentation and/or other materials provided with the distribution; 1210396Sakash.bagdia@arm.com * neither the name of the copyright holders nor the names of its 1310396Sakash.bagdia@arm.com * contributors may be used to endorse or promote products derived from 1410396Sakash.bagdia@arm.com * this software without specific prior written permission. 1510396Sakash.bagdia@arm.com * 1610396Sakash.bagdia@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710396Sakash.bagdia@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810396Sakash.bagdia@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910396Sakash.bagdia@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010396Sakash.bagdia@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110396Sakash.bagdia@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210396Sakash.bagdia@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310396Sakash.bagdia@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410396Sakash.bagdia@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510396Sakash.bagdia@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610396Sakash.bagdia@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710396Sakash.bagdia@arm.com */ 2810396Sakash.bagdia@arm.com 2910396Sakash.bagdia@arm.com//Todo: Add in a lot of the functions that are ISA specific. Also define 3010396Sakash.bagdia@arm.com//the functions that currently exist within the base cpu class. Define 3110396Sakash.bagdia@arm.com//everything for the simobject stuff so it can be serialized and 3210396Sakash.bagdia@arm.com//instantiated, add in debugging statements everywhere. Have CPU schedule 3310396Sakash.bagdia@arm.com//itself properly. Threads! 3410396Sakash.bagdia@arm.com// Avoid running stages and advancing queues if idle/stalled. 3510396Sakash.bagdia@arm.com 3610396Sakash.bagdia@arm.com#ifndef __CPU_O3_CPU_FULL_CPU_HH__ 3710396Sakash.bagdia@arm.com#define __CPU_O3_CPU_FULL_CPU_HH__ 3810396Sakash.bagdia@arm.com 3910396Sakash.bagdia@arm.com#include <iostream> 4010396Sakash.bagdia@arm.com#include <list> 4110396Sakash.bagdia@arm.com#include <vector> 4210396Sakash.bagdia@arm.com 4310396Sakash.bagdia@arm.com#include "base/statistics.hh" 4410396Sakash.bagdia@arm.com#include "base/timebuf.hh" 4510396Sakash.bagdia@arm.com#include "config/full_system.hh" 4610396Sakash.bagdia@arm.com#include "cpu/base.hh" 4710396Sakash.bagdia@arm.com#include "cpu/cpu_exec_context.hh" 4810396Sakash.bagdia@arm.com#include "cpu/o3/comm.hh" 4910396Sakash.bagdia@arm.com#include "cpu/o3/cpu_policy.hh" 5010396Sakash.bagdia@arm.com#include "sim/process.hh" 5110396Sakash.bagdia@arm.com 5210396Sakash.bagdia@arm.com#if FULL_SYSTEM 5310396Sakash.bagdia@arm.com#include "arch/alpha/ev5.hh" 5410396Sakash.bagdia@arm.comusing namespace EV5; 5510396Sakash.bagdia@arm.com#endif 5610396Sakash.bagdia@arm.com 5710396Sakash.bagdia@arm.comclass ExecContext; 5810396Sakash.bagdia@arm.comclass FunctionalMemory; 5910396Sakash.bagdia@arm.comclass Process; 6010396Sakash.bagdia@arm.com 6110396Sakash.bagdia@arm.comclass BaseFullCPU : public BaseCPU 6210396Sakash.bagdia@arm.com{ 6310396Sakash.bagdia@arm.com //Stuff that's pretty ISA independent will go here. 6410396Sakash.bagdia@arm.com public: 6510396Sakash.bagdia@arm.com typedef BaseCPU::Params Params; 6610396Sakash.bagdia@arm.com 6710396Sakash.bagdia@arm.com#if FULL_SYSTEM 6810396Sakash.bagdia@arm.com BaseFullCPU(Params ¶ms); 6910396Sakash.bagdia@arm.com#else 7010396Sakash.bagdia@arm.com BaseFullCPU(Params ¶ms); 7110396Sakash.bagdia@arm.com#endif // FULL_SYSTEM 7210396Sakash.bagdia@arm.com 7310396Sakash.bagdia@arm.com protected: 7410396Sakash.bagdia@arm.com int cpu_id; 7510396Sakash.bagdia@arm.com}; 7610396Sakash.bagdia@arm.com 7710396Sakash.bagdia@arm.comtemplate <class Impl> 7810396Sakash.bagdia@arm.comclass FullO3CPU : public BaseFullCPU 7910396Sakash.bagdia@arm.com{ 8010396Sakash.bagdia@arm.com public: 8110396Sakash.bagdia@arm.com //Put typedefs from the Impl here. 8210396Sakash.bagdia@arm.com typedef typename Impl::CPUPol CPUPolicy; 8310396Sakash.bagdia@arm.com typedef typename Impl::Params Params; 8410396Sakash.bagdia@arm.com typedef typename Impl::DynInstPtr DynInstPtr; 8510396Sakash.bagdia@arm.com 8610396Sakash.bagdia@arm.com public: 8710396Sakash.bagdia@arm.com enum Status { 8810396Sakash.bagdia@arm.com Running, 8910396Sakash.bagdia@arm.com Idle, 9010396Sakash.bagdia@arm.com Halted, 9110396Sakash.bagdia@arm.com Blocked // ? 9210396Sakash.bagdia@arm.com }; 9310396Sakash.bagdia@arm.com 9410396Sakash.bagdia@arm.com Status _status; 9510396Sakash.bagdia@arm.com 9610396Sakash.bagdia@arm.com private: 9710396Sakash.bagdia@arm.com class TickEvent : public Event 9810396Sakash.bagdia@arm.com { 9910396Sakash.bagdia@arm.com private: 10010396Sakash.bagdia@arm.com FullO3CPU<Impl> *cpu; 10110396Sakash.bagdia@arm.com 10210396Sakash.bagdia@arm.com public: 10310396Sakash.bagdia@arm.com TickEvent(FullO3CPU<Impl> *c); 10410396Sakash.bagdia@arm.com void process(); 10510396Sakash.bagdia@arm.com const char *description(); 10610396Sakash.bagdia@arm.com }; 10710396Sakash.bagdia@arm.com 10810396Sakash.bagdia@arm.com TickEvent tickEvent; 10910396Sakash.bagdia@arm.com 11010396Sakash.bagdia@arm.com /// Schedule tick event, regardless of its current state. 11110396Sakash.bagdia@arm.com void scheduleTickEvent(int delay) 11210396Sakash.bagdia@arm.com { 11310396Sakash.bagdia@arm.com if (tickEvent.squashed()) 11410396Sakash.bagdia@arm.com tickEvent.reschedule(curTick + delay); 11510396Sakash.bagdia@arm.com else if (!tickEvent.scheduled()) 11610396Sakash.bagdia@arm.com tickEvent.schedule(curTick + delay); 11710396Sakash.bagdia@arm.com } 11810396Sakash.bagdia@arm.com 11910396Sakash.bagdia@arm.com /// Unschedule tick event, regardless of its current state. 12010396Sakash.bagdia@arm.com void unscheduleTickEvent() 12110396Sakash.bagdia@arm.com { 12210396Sakash.bagdia@arm.com if (tickEvent.scheduled()) 12310396Sakash.bagdia@arm.com tickEvent.squash(); 12410396Sakash.bagdia@arm.com } 12510396Sakash.bagdia@arm.com 12610396Sakash.bagdia@arm.com public: 12710396Sakash.bagdia@arm.com FullO3CPU(Params ¶ms); 12810396Sakash.bagdia@arm.com ~FullO3CPU(); 12910396Sakash.bagdia@arm.com 13010396Sakash.bagdia@arm.com void fullCPURegStats(); 13110396Sakash.bagdia@arm.com 13210396Sakash.bagdia@arm.com void tick(); 13310396Sakash.bagdia@arm.com 13410396Sakash.bagdia@arm.com void init(); 13510396Sakash.bagdia@arm.com 13610396Sakash.bagdia@arm.com void activateContext(int thread_num, int delay); 13710396Sakash.bagdia@arm.com void suspendContext(int thread_num); 13810396Sakash.bagdia@arm.com void deallocateContext(int thread_num); 13910396Sakash.bagdia@arm.com void haltContext(int thread_num); 14010396Sakash.bagdia@arm.com 14110396Sakash.bagdia@arm.com void switchOut(); 14210396Sakash.bagdia@arm.com void takeOverFrom(BaseCPU *oldCPU); 14310396Sakash.bagdia@arm.com 14410396Sakash.bagdia@arm.com /** Get the current instruction sequence number, and increment it. */ 14510396Sakash.bagdia@arm.com InstSeqNum getAndIncrementInstSeq(); 14610396Sakash.bagdia@arm.com 14710396Sakash.bagdia@arm.com#if FULL_SYSTEM 14810396Sakash.bagdia@arm.com /** Check if this address is a valid instruction address. */ 14910396Sakash.bagdia@arm.com bool validInstAddr(Addr addr) { return true; } 15010396Sakash.bagdia@arm.com 15110396Sakash.bagdia@arm.com /** Check if this address is a valid data address. */ 15210396Sakash.bagdia@arm.com bool validDataAddr(Addr addr) { return true; } 15310396Sakash.bagdia@arm.com 15410396Sakash.bagdia@arm.com /** Get instruction asid. */ 15510396Sakash.bagdia@arm.com int getInstAsid() 15610396Sakash.bagdia@arm.com { return ITB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_ITB_ASN)); } 15710396Sakash.bagdia@arm.com 15810396Sakash.bagdia@arm.com /** Get data asid. */ 15910396Sakash.bagdia@arm.com int getDataAsid() 16010396Sakash.bagdia@arm.com { return DTB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_DTB_ASN)); } 16110396Sakash.bagdia@arm.com#else 16210396Sakash.bagdia@arm.com bool validInstAddr(Addr addr) 16310396Sakash.bagdia@arm.com { return thread[0]->validInstAddr(addr); } 16410396Sakash.bagdia@arm.com 16510396Sakash.bagdia@arm.com bool validDataAddr(Addr addr) 16610396Sakash.bagdia@arm.com { return thread[0]->validDataAddr(addr); } 16710396Sakash.bagdia@arm.com 16810396Sakash.bagdia@arm.com int getInstAsid() { return thread[0]->getInstAsid(); } 16910396Sakash.bagdia@arm.com int getDataAsid() { return thread[0]->getDataAsid(); } 17010396Sakash.bagdia@arm.com 17110396Sakash.bagdia@arm.com#endif 17210396Sakash.bagdia@arm.com 17310396Sakash.bagdia@arm.com // 17410396Sakash.bagdia@arm.com // New accessors for new decoder. 17510396Sakash.bagdia@arm.com // 17610396Sakash.bagdia@arm.com uint64_t readIntReg(int reg_idx); 17710396Sakash.bagdia@arm.com 17810396Sakash.bagdia@arm.com float readFloatRegSingle(int reg_idx); 17910396Sakash.bagdia@arm.com 18010396Sakash.bagdia@arm.com double readFloatRegDouble(int reg_idx); 18110396Sakash.bagdia@arm.com 18210396Sakash.bagdia@arm.com uint64_t readFloatRegInt(int reg_idx); 18310396Sakash.bagdia@arm.com 18410396Sakash.bagdia@arm.com void setIntReg(int reg_idx, uint64_t val); 18510396Sakash.bagdia@arm.com 18610396Sakash.bagdia@arm.com void setFloatRegSingle(int reg_idx, float val); 18710396Sakash.bagdia@arm.com 18810396Sakash.bagdia@arm.com void setFloatRegDouble(int reg_idx, double val); 18910396Sakash.bagdia@arm.com 19010396Sakash.bagdia@arm.com void setFloatRegInt(int reg_idx, uint64_t val); 19110396Sakash.bagdia@arm.com 19210396Sakash.bagdia@arm.com uint64_t readPC(); 19310396Sakash.bagdia@arm.com 19410396Sakash.bagdia@arm.com void setNextPC(uint64_t val); 19510396Sakash.bagdia@arm.com 19610396Sakash.bagdia@arm.com void setPC(Addr new_PC); 19710396Sakash.bagdia@arm.com 19810396Sakash.bagdia@arm.com /** Function to add instruction onto the head of the list of the 19910396Sakash.bagdia@arm.com * instructions. Used when new instructions are fetched. 20010396Sakash.bagdia@arm.com */ 20110396Sakash.bagdia@arm.com void addInst(DynInstPtr &inst); 20210396Sakash.bagdia@arm.com 20310396Sakash.bagdia@arm.com /** Function to tell the CPU that an instruction has completed. */ 20410396Sakash.bagdia@arm.com void instDone(); 20510396Sakash.bagdia@arm.com 20610396Sakash.bagdia@arm.com /** Remove all instructions in back of the given instruction, but leave 20710396Sakash.bagdia@arm.com * that instruction in the list. This is useful in a squash, when there 20810396Sakash.bagdia@arm.com * are instructions in this list that don't exist in structures such as 20910396Sakash.bagdia@arm.com * the ROB. The instruction doesn't have to be the last instruction in 21010396Sakash.bagdia@arm.com * the list, but will be once this function completes. 21110396Sakash.bagdia@arm.com * @todo: Remove only up until that inst? Squashed inst is most likely 21210396Sakash.bagdia@arm.com * valid. 21310396Sakash.bagdia@arm.com */ 21410396Sakash.bagdia@arm.com void removeBackInst(DynInstPtr &inst); 21510396Sakash.bagdia@arm.com 21610396Sakash.bagdia@arm.com /** Remove an instruction from the front of the list. It is expected 21710396Sakash.bagdia@arm.com * that there are no instructions in front of it (that is, none are older 21810396Sakash.bagdia@arm.com * than the instruction being removed). Used when retiring instructions. 21910905Sandreas.sandberg@arm.com * @todo: Remove the argument to this function, and just have it remove 22010396Sakash.bagdia@arm.com * last instruction once it's verified that commit has the same ordering 22110396Sakash.bagdia@arm.com * as the instruction list. 22210396Sakash.bagdia@arm.com */ 22310396Sakash.bagdia@arm.com void removeFrontInst(DynInstPtr &inst); 22410396Sakash.bagdia@arm.com 22510396Sakash.bagdia@arm.com /** Remove all instructions that are not currently in the ROB. */ 22610396Sakash.bagdia@arm.com void removeInstsNotInROB(); 22710396Sakash.bagdia@arm.com 22810396Sakash.bagdia@arm.com /** Remove all instructions younger than the given sequence number. */ 22910396Sakash.bagdia@arm.com void removeInstsUntil(const InstSeqNum &seq_num); 23010396Sakash.bagdia@arm.com 23110905Sandreas.sandberg@arm.com /** Remove all instructions from the list. */ 23210396Sakash.bagdia@arm.com void removeAllInsts(); 23310396Sakash.bagdia@arm.com 23410396Sakash.bagdia@arm.com void dumpInsts(); 23510396Sakash.bagdia@arm.com 23610396Sakash.bagdia@arm.com /** Basically a wrapper function so that instructions executed at 23710396Sakash.bagdia@arm.com * commit can tell the instruction queue that they have completed. 23810396Sakash.bagdia@arm.com * Eventually this hack should be removed. 23910396Sakash.bagdia@arm.com */ 24010396Sakash.bagdia@arm.com void wakeDependents(DynInstPtr &inst); 24110396Sakash.bagdia@arm.com 24210396Sakash.bagdia@arm.com public: 24310396Sakash.bagdia@arm.com /** List of all the instructions in flight. */ 24410396Sakash.bagdia@arm.com list<DynInstPtr> instList; 24510396Sakash.bagdia@arm.com 24610396Sakash.bagdia@arm.com //not sure these should be private. 24710396Sakash.bagdia@arm.com protected: 24810396Sakash.bagdia@arm.com /** The fetch stage. */ 24910396Sakash.bagdia@arm.com typename CPUPolicy::Fetch fetch; 25010396Sakash.bagdia@arm.com 25110396Sakash.bagdia@arm.com /** The fetch stage's status. */ 25210396Sakash.bagdia@arm.com typename CPUPolicy::Fetch::Status fetchStatus; 25310396Sakash.bagdia@arm.com 25410396Sakash.bagdia@arm.com /** The decode stage. */ 25510396Sakash.bagdia@arm.com typename CPUPolicy::Decode decode; 25610396Sakash.bagdia@arm.com 25710396Sakash.bagdia@arm.com /** The decode stage's status. */ 25810396Sakash.bagdia@arm.com typename CPUPolicy::Decode::Status decodeStatus; 25910396Sakash.bagdia@arm.com 26010396Sakash.bagdia@arm.com /** The dispatch stage. */ 26110396Sakash.bagdia@arm.com typename CPUPolicy::Rename rename; 26210396Sakash.bagdia@arm.com 26310396Sakash.bagdia@arm.com /** The dispatch stage's status. */ 264 typename CPUPolicy::Rename::Status renameStatus; 265 266 /** The issue/execute/writeback stages. */ 267 typename CPUPolicy::IEW iew; 268 269 /** The issue/execute/writeback stage's status. */ 270 typename CPUPolicy::IEW::Status iewStatus; 271 272 /** The commit stage. */ 273 typename CPUPolicy::Commit commit; 274 275 /** The fetch stage's status. */ 276 typename CPUPolicy::Commit::Status commitStatus; 277 278 //Might want to just pass these objects in to the constructors of the 279 //appropriate stage. regFile is in iew, freeList in dispatch, renameMap 280 //in dispatch, and the rob in commit. 281 /** The register file. */ 282 typename CPUPolicy::RegFile regFile; 283 284 /** The free list. */ 285 typename CPUPolicy::FreeList freeList; 286 287 /** The rename map. */ 288 typename CPUPolicy::RenameMap renameMap; 289 290 /** The re-order buffer. */ 291 typename CPUPolicy::ROB rob; 292 293 public: 294 /** Typedefs from the Impl to get the structs that each of the 295 * time buffers should use. 296 */ 297 typedef typename CPUPolicy::TimeStruct TimeStruct; 298 299 typedef typename CPUPolicy::FetchStruct FetchStruct; 300 301 typedef typename CPUPolicy::DecodeStruct DecodeStruct; 302 303 typedef typename CPUPolicy::RenameStruct RenameStruct; 304 305 typedef typename CPUPolicy::IEWStruct IEWStruct; 306 307 /** The main time buffer to do backwards communication. */ 308 TimeBuffer<TimeStruct> timeBuffer; 309 310 /** The fetch stage's instruction queue. */ 311 TimeBuffer<FetchStruct> fetchQueue; 312 313 /** The decode stage's instruction queue. */ 314 TimeBuffer<DecodeStruct> decodeQueue; 315 316 /** The rename stage's instruction queue. */ 317 TimeBuffer<RenameStruct> renameQueue; 318 319 /** The IEW stage's instruction queue. */ 320 TimeBuffer<IEWStruct> iewQueue; 321 322 public: 323 /** The temporary exec context to support older accessors. */ 324 CPUExecContext *cpuXC; 325 326 /** Temporary function to get pointer to exec context. */ 327 ExecContext *xcBase() 328 { 329 return thread[0]->getProxy(); 330 } 331 332 CPUExecContext *cpuXCBase() 333 { 334 return thread[0]; 335 } 336 337 InstSeqNum globalSeqNum; 338 339#if FULL_SYSTEM 340 System *system; 341 342 MemoryController *memCtrl; 343 PhysicalMemory *physmem; 344 345 AlphaITB *itb; 346 AlphaDTB *dtb; 347 348// SWContext *swCtx; 349#endif 350 std::vector<CPUExecContext *> thread; 351 352 FunctionalMemory *mem; 353 354 MemInterface *icacheInterface; 355 MemInterface *dcacheInterface; 356 357 bool deferRegistration; 358 359 Counter numInsts; 360 361 Counter funcExeInst; 362}; 363 364#endif 365