cpu.hh revision 1684
110037SARM gem5 Developers//Todo: Add in a lot of the functions that are ISA specific. Also define 210037SARM gem5 Developers//the functions that currently exist within the base cpu class. Define 312531Sandreas.sandberg@arm.com//everything for the simobject stuff so it can be serialized and 410037SARM gem5 Developers//instantiated, add in debugging statements everywhere. Have CPU schedule 510037SARM gem5 Developers//itself properly. Constructor. Derived alpha class. Threads! 610037SARM gem5 Developers// Avoid running stages and advancing queues if idle/stalled. 710037SARM gem5 Developers 810037SARM gem5 Developers#ifndef __CPU_BETA_CPU_FULL_CPU_HH__ 910037SARM gem5 Developers#define __CPU_BETA_CPU_FULL_CPU_HH__ 1010037SARM gem5 Developers 1110037SARM gem5 Developers#include <iostream> 1210037SARM gem5 Developers#include <list> 1310037SARM gem5 Developers#include <vector> 1410037SARM gem5 Developers 1510037SARM gem5 Developers#include "base/statistics.hh" 1610037SARM gem5 Developers#include "base/timebuf.hh" 1710037SARM gem5 Developers#include "cpu/base_cpu.hh" 1810037SARM gem5 Developers#include "cpu/beta_cpu/comm.hh" 1910037SARM gem5 Developers#include "cpu/beta_cpu/cpu_policy.hh" 2010037SARM gem5 Developers#include "cpu/exec_context.hh" 2110037SARM gem5 Developers#include "sim/process.hh" 2210037SARM gem5 Developers 2310037SARM gem5 Developers#ifdef FULL_SYSTEM 2410037SARM gem5 Developers#include "arch/alpha/ev5.hh" 2510037SARM gem5 Developersusing namespace EV5; 2610037SARM gem5 Developers#endif 2710037SARM gem5 Developers 2810037SARM gem5 Developersclass FunctionalMemory; 2910037SARM gem5 Developersclass Process; 3010037SARM gem5 Developers 3110037SARM gem5 Developersclass BaseFullCPU : public BaseCPU 3210037SARM gem5 Developers{ 3310037SARM gem5 Developers //Stuff that's pretty ISA independent will go here. 3410037SARM gem5 Developers public: 3510037SARM gem5 Developers typedef BaseCPU::Params Params; 3610037SARM gem5 Developers 3710037SARM gem5 Developers#ifdef FULL_SYSTEM 3810037SARM gem5 Developers BaseFullCPU(Params ¶ms); 3910037SARM gem5 Developers#else 4010037SARM gem5 Developers BaseFullCPU(Params ¶ms); 4110037SARM gem5 Developers#endif // FULL_SYSTEM 4210474Sandreas.hansson@arm.com 4310037SARM gem5 Developers private: 4410037SARM gem5 Developers int cpu_id; 4512538Sgiacomo.travaglini@arm.com}; 4610037SARM gem5 Developers 4710037SARM gem5 Developerstemplate <class Impl> 4812538Sgiacomo.travaglini@arm.comclass FullBetaCPU : public BaseFullCPU 4912538Sgiacomo.travaglini@arm.com{ 5010037SARM gem5 Developers public: 5110037SARM gem5 Developers //Put typedefs from the Impl here. 5211576SDylan.Johnson@ARM.com typedef typename Impl::ISA ISA; 5311576SDylan.Johnson@ARM.com typedef typename Impl::CPUPol CPUPolicy; 5413362Sgiacomo.travaglini@arm.com typedef typename Impl::Params Params; 5513362Sgiacomo.travaglini@arm.com typedef typename Impl::DynInstPtr DynInstPtr; 5611576SDylan.Johnson@ARM.com 5713362Sgiacomo.travaglini@arm.com public: 5813362Sgiacomo.travaglini@arm.com enum Status { 5913362Sgiacomo.travaglini@arm.com Running, 6013362Sgiacomo.travaglini@arm.com Idle, 6113362Sgiacomo.travaglini@arm.com Halted, 6213362Sgiacomo.travaglini@arm.com Blocked // ? 6313362Sgiacomo.travaglini@arm.com }; 6413362Sgiacomo.travaglini@arm.com 6513362Sgiacomo.travaglini@arm.com Status _status; 6613362Sgiacomo.travaglini@arm.com 6713362Sgiacomo.travaglini@arm.com private: 6811576SDylan.Johnson@ARM.com class TickEvent : public Event 6911576SDylan.Johnson@ARM.com { 7011576SDylan.Johnson@ARM.com private: 7111576SDylan.Johnson@ARM.com FullBetaCPU<Impl> *cpu; 7211576SDylan.Johnson@ARM.com 7312538Sgiacomo.travaglini@arm.com public: 7411576SDylan.Johnson@ARM.com TickEvent(FullBetaCPU<Impl> *c); 7511576SDylan.Johnson@ARM.com void process(); 7612538Sgiacomo.travaglini@arm.com const char *description(); 7712538Sgiacomo.travaglini@arm.com }; 7811576SDylan.Johnson@ARM.com 7911576SDylan.Johnson@ARM.com TickEvent tickEvent; 8010037SARM gem5 Developers 8110037SARM gem5 Developers /// Schedule tick event, regardless of its current state. 8210037SARM gem5 Developers void scheduleTickEvent(int delay) 8310037SARM gem5 Developers { 8410037SARM gem5 Developers if (tickEvent.squashed()) 8510037SARM gem5 Developers tickEvent.reschedule(curTick + delay); 8610037SARM gem5 Developers else if (!tickEvent.scheduled()) 8710037SARM gem5 Developers tickEvent.schedule(curTick + delay); 8810474Sandreas.hansson@arm.com } 8910037SARM gem5 Developers 9010037SARM gem5 Developers /// Unschedule tick event, regardless of its current state. 9110037SARM gem5 Developers void unscheduleTickEvent() 9212538Sgiacomo.travaglini@arm.com { 9310037SARM gem5 Developers if (tickEvent.scheduled()) 9412538Sgiacomo.travaglini@arm.com tickEvent.squash(); 9512538Sgiacomo.travaglini@arm.com } 9610037SARM gem5 Developers 9710037SARM gem5 Developers public: 9810037SARM gem5 Developers FullBetaCPU(Params ¶ms); 9910037SARM gem5 Developers ~FullBetaCPU(); 10010037SARM gem5 Developers 10110037SARM gem5 Developers void fullCPURegStats(); 10210037SARM gem5 Developers 10310037SARM gem5 Developers void tick(); 10410037SARM gem5 Developers 10510037SARM gem5 Developers void init(); 10610037SARM gem5 Developers 10710037SARM gem5 Developers void activateContext(int thread_num, int delay); 10810037SARM gem5 Developers void suspendContext(int thread_num); 10910037SARM gem5 Developers void deallocateContext(int thread_num); 11010037SARM gem5 Developers void haltContext(int thread_num); 11110037SARM gem5 Developers 11210037SARM gem5 Developers void switchOut(); 11310037SARM gem5 Developers void takeOverFrom(BaseCPU *oldCPU); 11410037SARM gem5 Developers 11510537Sandreas.hansson@arm.com /** Get the current instruction sequence number, and increment it. */ 11610537Sandreas.hansson@arm.com InstSeqNum getAndIncrementInstSeq(); 11710037SARM gem5 Developers 11810037SARM gem5 Developers#ifdef FULL_SYSTEM 11910037SARM gem5 Developers /** Check if this address is a valid instruction address. */ 12010037SARM gem5 Developers bool validInstAddr(Addr addr) { return true; } 12110037SARM gem5 Developers 12210037SARM gem5 Developers /** Check if this address is a valid data address. */ 12310037SARM gem5 Developers bool validDataAddr(Addr addr) { return true; } 12410037SARM gem5 Developers 12510037SARM gem5 Developers /** Get instruction asid. */ 12610037SARM gem5 Developers int getInstAsid() 12710037SARM gem5 Developers { return ITB_ASN_ASN(regFile.getIpr()[ISA::IPR_ITB_ASN]); } 12810037SARM gem5 Developers 12910037SARM gem5 Developers /** Get data asid. */ 13010037SARM gem5 Developers int getDataAsid() 13110037SARM gem5 Developers { return DTB_ASN_ASN(regFile.getIpr()[ISA::IPR_DTB_ASN]); } 13210037SARM gem5 Developers#else 13310037SARM gem5 Developers bool validInstAddr(Addr addr) 13410037SARM gem5 Developers { return thread[0]->validInstAddr(addr); } 13510037SARM gem5 Developers 13610037SARM gem5 Developers bool validDataAddr(Addr addr) 13710037SARM gem5 Developers { return thread[0]->validDataAddr(addr); } 13810037SARM gem5 Developers 13910037SARM gem5 Developers int getInstAsid() { return thread[0]->asid; } 14010037SARM gem5 Developers int getDataAsid() { return thread[0]->asid; } 14110037SARM gem5 Developers 14210037SARM gem5 Developers#endif 14310037SARM gem5 Developers 14410474Sandreas.hansson@arm.com // 14510037SARM gem5 Developers // New accessors for new decoder. 14610037SARM gem5 Developers // 14710037SARM gem5 Developers uint64_t readIntReg(int reg_idx); 14810037SARM gem5 Developers 14910037SARM gem5 Developers float readFloatRegSingle(int reg_idx); 15010037SARM gem5 Developers 15110037SARM gem5 Developers double readFloatRegDouble(int reg_idx); 15212259Sgiacomo.travaglini@arm.com 15312488Sgiacomo.travaglini@arm.com uint64_t readFloatRegInt(int reg_idx); 15410037SARM gem5 Developers 15510037SARM gem5 Developers void setIntReg(int reg_idx, uint64_t val); 15610037SARM gem5 Developers 15710037SARM gem5 Developers void setFloatRegSingle(int reg_idx, float val); 15812259Sgiacomo.travaglini@arm.com 15912261Sgiacomo.travaglini@arm.com void setFloatRegDouble(int reg_idx, double val); 16010037SARM gem5 Developers 16110037SARM gem5 Developers void setFloatRegInt(int reg_idx, uint64_t val); 16210037SARM gem5 Developers 16310037SARM gem5 Developers uint64_t readPC(); 16410037SARM gem5 Developers 16510037SARM gem5 Developers void setNextPC(uint64_t val); 16610037SARM gem5 Developers 16710037SARM gem5 Developers void setPC(Addr new_PC); 16810037SARM gem5 Developers 16910037SARM gem5 Developers /** Function to add instruction onto the head of the list of the 17010037SARM gem5 Developers * instructions. Used when new instructions are fetched. 17110037SARM gem5 Developers */ 17210037SARM gem5 Developers void addInst(DynInstPtr &inst); 17310037SARM gem5 Developers 17410037SARM gem5 Developers /** Function to tell the CPU that an instruction has completed. */ 17512299Sandreas.sandberg@arm.com void instDone(); 17612299Sandreas.sandberg@arm.com 17712299Sandreas.sandberg@arm.com /** Remove all instructions in back of the given instruction, but leave 17812299Sandreas.sandberg@arm.com * that instruction in the list. This is useful in a squash, when there 17912299Sandreas.sandberg@arm.com * are instructions in this list that don't exist in structures such as 18012299Sandreas.sandberg@arm.com * the ROB. The instruction doesn't have to be the last instruction in 18112299Sandreas.sandberg@arm.com * the list, but will be once this function completes. 18212538Sgiacomo.travaglini@arm.com * @todo: Remove only up until that inst? Squashed inst is most likely 18312299Sandreas.sandberg@arm.com * valid. 18412538Sgiacomo.travaglini@arm.com */ 18512538Sgiacomo.travaglini@arm.com void removeBackInst(DynInstPtr &inst); 18612299Sandreas.sandberg@arm.com 18712531Sandreas.sandberg@arm.com /** Remove an instruction from the front of the list. It is expected 18812531Sandreas.sandberg@arm.com * that there are no instructions in front of it (that is, none are older 18912531Sandreas.sandberg@arm.com * than the instruction being removed). Used when retiring instructions. 19012539Sgiacomo.travaglini@arm.com * @todo: Remove the argument to this function, and just have it remove 19112531Sandreas.sandberg@arm.com * last instruction once it's verified that commit has the same ordering 19212531Sandreas.sandberg@arm.com * as the instruction list. 19312531Sandreas.sandberg@arm.com */ 19412531Sandreas.sandberg@arm.com void removeFrontInst(DynInstPtr &inst); 19512531Sandreas.sandberg@arm.com 19612531Sandreas.sandberg@arm.com /** Remove all instructions that are not currently in the ROB. */ 19712531Sandreas.sandberg@arm.com void removeInstsNotInROB(); 19812531Sandreas.sandberg@arm.com 19912531Sandreas.sandberg@arm.com /** Remove all instructions younger than the given sequence number. */ 20012531Sandreas.sandberg@arm.com void removeInstsUntil(const InstSeqNum &seq_num); 20112538Sgiacomo.travaglini@arm.com 20212531Sandreas.sandberg@arm.com /** Remove all instructions from the list. */ 20312538Sgiacomo.travaglini@arm.com void removeAllInsts(); 20412543Sgiacomo.travaglini@arm.com 20512531Sandreas.sandberg@arm.com void dumpInsts(); 20610037SARM gem5 Developers 207 /** Basically a wrapper function so that instructions executed at 208 * commit can tell the instruction queue that they have completed. 209 * Eventually this hack should be removed. 210 */ 211 void wakeDependents(DynInstPtr &inst); 212 213 public: 214 /** List of all the instructions in flight. */ 215 list<DynInstPtr> instList; 216 217 //not sure these should be private. 218 protected: 219 /** The fetch stage. */ 220 typename CPUPolicy::Fetch fetch; 221 222 /** The fetch stage's status. */ 223 typename CPUPolicy::Fetch::Status fetchStatus; 224 225 /** The decode stage. */ 226 typename CPUPolicy::Decode decode; 227 228 /** The decode stage's status. */ 229 typename CPUPolicy::Decode::Status decodeStatus; 230 231 /** The dispatch stage. */ 232 typename CPUPolicy::Rename rename; 233 234 /** The dispatch stage's status. */ 235 typename CPUPolicy::Rename::Status renameStatus; 236 237 /** The issue/execute/writeback stages. */ 238 typename CPUPolicy::IEW iew; 239 240 /** The issue/execute/writeback stage's status. */ 241 typename CPUPolicy::IEW::Status iewStatus; 242 243 /** The commit stage. */ 244 typename CPUPolicy::Commit commit; 245 246 /** The fetch stage's status. */ 247 typename CPUPolicy::Commit::Status commitStatus; 248 249 //Might want to just pass these objects in to the constructors of the 250 //appropriate stage. regFile is in iew, freeList in dispatch, renameMap 251 //in dispatch, and the rob in commit. 252 /** The register file. */ 253 typename CPUPolicy::RegFile regFile; 254 255 /** The free list. */ 256 typename CPUPolicy::FreeList freeList; 257 258 /** The rename map. */ 259 typename CPUPolicy::RenameMap renameMap; 260 261 /** The re-order buffer. */ 262 typename CPUPolicy::ROB rob; 263 264 public: 265 /** Typedefs from the Impl to get the structs that each of the 266 * time buffers should use. 267 */ 268 typedef typename CPUPolicy::TimeStruct TimeStruct; 269 270 typedef typename CPUPolicy::FetchStruct FetchStruct; 271 272 typedef typename CPUPolicy::DecodeStruct DecodeStruct; 273 274 typedef typename CPUPolicy::RenameStruct RenameStruct; 275 276 typedef typename CPUPolicy::IEWStruct IEWStruct; 277 278 /** The main time buffer to do backwards communication. */ 279 TimeBuffer<TimeStruct> timeBuffer; 280 281 /** The fetch stage's instruction queue. */ 282 TimeBuffer<FetchStruct> fetchQueue; 283 284 /** The decode stage's instruction queue. */ 285 TimeBuffer<DecodeStruct> decodeQueue; 286 287 /** The rename stage's instruction queue. */ 288 TimeBuffer<RenameStruct> renameQueue; 289 290 /** The IEW stage's instruction queue. */ 291 TimeBuffer<IEWStruct> iewQueue; 292 293 public: 294 /** The temporary exec context to support older accessors. */ 295 ExecContext *xc; 296 297 /** Temporary function to get pointer to exec context. */ 298 ExecContext *xcBase() 299 { 300#ifdef FULL_SYSTEM 301 return system->execContexts[0]; 302#else 303 return thread[0]; 304#endif 305 } 306 307 InstSeqNum globalSeqNum; 308 309#ifdef FULL_SYSTEM 310 System *system; 311 312 MemoryController *memCtrl; 313 PhysicalMemory *physmem; 314 315 AlphaITB *itb; 316 AlphaDTB *dtb; 317 318// SWContext *swCtx; 319#else 320 std::vector<ExecContext *> thread; 321#endif 322 323 FunctionalMemory *mem; 324 325 MemInterface *icacheInterface; 326 MemInterface *dcacheInterface; 327 328 bool deferRegistration; 329 330 Counter numInsts; 331 332 Counter funcExeInst; 333}; 334 335#endif 336