cpu.hh revision 2632
12391SN/A/* 22391SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 32391SN/A * All rights reserved. 42391SN/A * 52391SN/A * Redistribution and use in source and binary forms, with or without 62391SN/A * modification, are permitted provided that the following conditions are 72391SN/A * met: redistributions of source code must retain the above copyright 82391SN/A * notice, this list of conditions and the following disclaimer; 92391SN/A * redistributions in binary form must reproduce the above copyright 102391SN/A * notice, this list of conditions and the following disclaimer in the 112391SN/A * documentation and/or other materials provided with the distribution; 122391SN/A * neither the name of the copyright holders nor the names of its 132391SN/A * contributors may be used to endorse or promote products derived from 142391SN/A * this software without specific prior written permission. 152391SN/A * 162391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292391SN/A//Todo: Add in a lot of the functions that are ISA specific. Also define 302391SN/A//the functions that currently exist within the base cpu class. Define 312391SN/A//everything for the simobject stuff so it can be serialized and 322391SN/A//instantiated, add in debugging statements everywhere. Have CPU schedule 332391SN/A//itself properly. Threads! 342391SN/A// Avoid running stages and advancing queues if idle/stalled. 352391SN/A 362391SN/A#ifndef __CPU_O3_CPU_FULL_CPU_HH__ 372391SN/A#define __CPU_O3_CPU_FULL_CPU_HH__ 382462SN/A 392414SN/A#include <iostream> 402415SN/A#include <list> 412415SN/A#include <vector> 422416SN/A 432416SN/A#include "base/statistics.hh" 442462SN/A#include "base/timebuf.hh" 452391SN/A#include "config/full_system.hh" 462391SN/A#include "cpu/base.hh" 472391SN/A#include "cpu/cpu_exec_context.hh" 482462SN/A#include "cpu/o3/comm.hh" 492391SN/A#include "cpu/o3/cpu_policy.hh" 502413SN/A#include "sim/process.hh" 512413SN/A 522413SN/Aclass ExecContext; 532413SN/Aclass FunctionalMemory; 542413SN/Aclass Process; 552413SN/A 562640Sstever@eecs.umich.educlass BaseFullCPU : public BaseCPU 572413SN/A{ 582413SN/A //Stuff that's pretty ISA independent will go here. 592413SN/A public: 602630SN/A typedef BaseCPU::Params Params; 612413SN/A 622630SN/A#if FULL_SYSTEM 632413SN/A BaseFullCPU(Params ¶ms); 642630SN/A#else 652413SN/A BaseFullCPU(Params ¶ms); 662413SN/A#endif // FULL_SYSTEM 672413SN/A 682521SN/A protected: 692521SN/A int cpu_id; 702413SN/A}; 712413SN/A 722413SN/Atemplate <class Impl> 732413SN/Aclass FullO3CPU : public BaseFullCPU 742416SN/A{ 752416SN/A public: 762413SN/A //Put typedefs from the Impl here. 772415SN/A typedef typename Impl::CPUPol CPUPolicy; 782415SN/A typedef typename Impl::Params Params; 792630SN/A typedef typename Impl::DynInstPtr DynInstPtr; 802415SN/A 812415SN/A public: 822630SN/A enum Status { 832415SN/A Running, 842415SN/A Idle, 852415SN/A Halted, 862413SN/A Blocked // ? 872391SN/A }; 882391SN/A 892391SN/A Status _status; 902391SN/A 912391SN/A private: 922391SN/A class TickEvent : public Event 932391SN/A { 942391SN/A private: 952391SN/A FullO3CPU<Impl> *cpu; 962499SN/A 972391SN/A public: 982565SN/A TickEvent(FullO3CPU<Impl> *c); 992391SN/A void process(); 1002391SN/A const char *description(); 1012391SN/A }; 1022391SN/A 1032391SN/A TickEvent tickEvent; 1042391SN/A 1052565SN/A /// Schedule tick event, regardless of its current state. 1062391SN/A void scheduleTickEvent(int delay) 1072391SN/A { 1082391SN/A if (tickEvent.squashed()) 1092415SN/A tickEvent.reschedule(curTick + delay); 1102521SN/A else if (!tickEvent.scheduled()) 1112521SN/A tickEvent.schedule(curTick + delay); 1122541SN/A } 1132391SN/A 1142391SN/A /// Unschedule tick event, regardless of its current state. 1152414SN/A void unscheduleTickEvent() 1162413SN/A { 1172630SN/A if (tickEvent.scheduled()) 1182630SN/A tickEvent.squash(); 1192630SN/A } 1202413SN/A 1212413SN/A public: 1222391SN/A FullO3CPU(Params ¶ms); 1232391SN/A ~FullO3CPU(); 1242391SN/A 1252391SN/A void fullCPURegStats(); 1262497SN/A 1272391SN/A void tick(); 1282391SN/A 1292391SN/A void init(); 130 131 void activateContext(int thread_num, int delay); 132 void suspendContext(int thread_num); 133 void deallocateContext(int thread_num); 134 void haltContext(int thread_num); 135 136 void switchOut(); 137 void takeOverFrom(BaseCPU *oldCPU); 138 139 /** Get the current instruction sequence number, and increment it. */ 140 InstSeqNum getAndIncrementInstSeq(); 141 142#if FULL_SYSTEM 143 /** Check if this address is a valid instruction address. */ 144 bool validInstAddr(Addr addr) { return true; } 145 146 /** Check if this address is a valid data address. */ 147 bool validDataAddr(Addr addr) { return true; } 148 149 /** Get instruction asid. */ 150 int getInstAsid() 151 { return regFile.miscRegs.getInstAsid(); } 152 153 /** Get data asid. */ 154 int getDataAsid() 155 { return regFile.miscRegs.getDataAsid(); } 156#else 157 bool validInstAddr(Addr addr) 158 { return thread[0]->validInstAddr(addr); } 159 160 bool validDataAddr(Addr addr) 161 { return thread[0]->validDataAddr(addr); } 162 163 int getInstAsid() { return thread[0]->getInstAsid(); } 164 int getDataAsid() { return thread[0]->getDataAsid(); } 165 166#endif 167 168 // 169 // New accessors for new decoder. 170 // 171 uint64_t readIntReg(int reg_idx); 172 173 FloatReg readFloatReg(int reg_idx); 174 175 FloatReg readFloatReg(int reg_idx, int width); 176 177 FloatRegBits readFloatRegBits(int reg_idx); 178 179 FloatRegBits readFloatRegBits(int reg_idx, int width); 180 181 void setIntReg(int reg_idx, uint64_t val); 182 183 void setFloatReg(int reg_idx, FloatReg val, int width); 184 185 void setFloatReg(int reg_idx, FloatReg val, int width); 186 187 void setFloatRegBits(int reg_idx, FloatRegBits val); 188 189 void setFloatRegBits(int reg_idx, FloatRegBits val); 190 191 uint64_t readPC(); 192 193 void setNextPC(uint64_t val); 194 195 void setPC(Addr new_PC); 196 197 /** Function to add instruction onto the head of the list of the 198 * instructions. Used when new instructions are fetched. 199 */ 200 void addInst(DynInstPtr &inst); 201 202 /** Function to tell the CPU that an instruction has completed. */ 203 void instDone(); 204 205 /** Remove all instructions in back of the given instruction, but leave 206 * that instruction in the list. This is useful in a squash, when there 207 * are instructions in this list that don't exist in structures such as 208 * the ROB. The instruction doesn't have to be the last instruction in 209 * the list, but will be once this function completes. 210 * @todo: Remove only up until that inst? Squashed inst is most likely 211 * valid. 212 */ 213 void removeBackInst(DynInstPtr &inst); 214 215 /** Remove an instruction from the front of the list. It is expected 216 * that there are no instructions in front of it (that is, none are older 217 * than the instruction being removed). Used when retiring instructions. 218 * @todo: Remove the argument to this function, and just have it remove 219 * last instruction once it's verified that commit has the same ordering 220 * as the instruction list. 221 */ 222 void removeFrontInst(DynInstPtr &inst); 223 224 /** Remove all instructions that are not currently in the ROB. */ 225 void removeInstsNotInROB(); 226 227 /** Remove all instructions younger than the given sequence number. */ 228 void removeInstsUntil(const InstSeqNum &seq_num); 229 230 /** Remove all instructions from the list. */ 231 void removeAllInsts(); 232 233 void dumpInsts(); 234 235 /** Basically a wrapper function so that instructions executed at 236 * commit can tell the instruction queue that they have completed. 237 * Eventually this hack should be removed. 238 */ 239 void wakeDependents(DynInstPtr &inst); 240 241 public: 242 /** List of all the instructions in flight. */ 243 list<DynInstPtr> instList; 244 245 //not sure these should be private. 246 protected: 247 /** The fetch stage. */ 248 typename CPUPolicy::Fetch fetch; 249 250 /** The fetch stage's status. */ 251 typename CPUPolicy::Fetch::Status fetchStatus; 252 253 /** The decode stage. */ 254 typename CPUPolicy::Decode decode; 255 256 /** The decode stage's status. */ 257 typename CPUPolicy::Decode::Status decodeStatus; 258 259 /** The dispatch stage. */ 260 typename CPUPolicy::Rename rename; 261 262 /** The dispatch stage's status. */ 263 typename CPUPolicy::Rename::Status renameStatus; 264 265 /** The issue/execute/writeback stages. */ 266 typename CPUPolicy::IEW iew; 267 268 /** The issue/execute/writeback stage's status. */ 269 typename CPUPolicy::IEW::Status iewStatus; 270 271 /** The commit stage. */ 272 typename CPUPolicy::Commit commit; 273 274 /** The fetch stage's status. */ 275 typename CPUPolicy::Commit::Status commitStatus; 276 277 //Might want to just pass these objects in to the constructors of the 278 //appropriate stage. regFile is in iew, freeList in dispatch, renameMap 279 //in dispatch, and the rob in commit. 280 /** The register file. */ 281 typename CPUPolicy::RegFile regFile; 282 283 /** The free list. */ 284 typename CPUPolicy::FreeList freeList; 285 286 /** The rename map. */ 287 typename CPUPolicy::RenameMap renameMap; 288 289 /** The re-order buffer. */ 290 typename CPUPolicy::ROB rob; 291 292 public: 293 /** Typedefs from the Impl to get the structs that each of the 294 * time buffers should use. 295 */ 296 typedef typename CPUPolicy::TimeStruct TimeStruct; 297 298 typedef typename CPUPolicy::FetchStruct FetchStruct; 299 300 typedef typename CPUPolicy::DecodeStruct DecodeStruct; 301 302 typedef typename CPUPolicy::RenameStruct RenameStruct; 303 304 typedef typename CPUPolicy::IEWStruct IEWStruct; 305 306 /** The main time buffer to do backwards communication. */ 307 TimeBuffer<TimeStruct> timeBuffer; 308 309 /** The fetch stage's instruction queue. */ 310 TimeBuffer<FetchStruct> fetchQueue; 311 312 /** The decode stage's instruction queue. */ 313 TimeBuffer<DecodeStruct> decodeQueue; 314 315 /** The rename stage's instruction queue. */ 316 TimeBuffer<RenameStruct> renameQueue; 317 318 /** The IEW stage's instruction queue. */ 319 TimeBuffer<IEWStruct> iewQueue; 320 321 public: 322 /** The temporary exec context to support older accessors. */ 323 CPUExecContext *cpuXC; 324 325 /** Temporary function to get pointer to exec context. */ 326 ExecContext *xcBase() 327 { 328 return thread[0]->getProxy(); 329 } 330 331 CPUExecContext *cpuXCBase() 332 { 333 return thread[0]; 334 } 335 336 InstSeqNum globalSeqNum; 337 338#if FULL_SYSTEM 339 System *system; 340 341 MemoryController *memCtrl; 342 PhysicalMemory *physmem; 343 344 AlphaITB *itb; 345 AlphaDTB *dtb; 346 347// SWContext *swCtx; 348#endif 349 std::vector<CPUExecContext *> thread; 350 351 FunctionalMemory *mem; 352 353 MemInterface *icacheInterface; 354 MemInterface *dcacheInterface; 355 356 bool deferRegistration; 357 358 Counter numInsts; 359 360 Counter funcExeInst; 361}; 362 363#endif 364