cpu.hh revision 2632:1bb2f91485ea
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29//Todo: Add in a lot of the functions that are ISA specific. Also define 30//the functions that currently exist within the base cpu class. Define 31//everything for the simobject stuff so it can be serialized and 32//instantiated, add in debugging statements everywhere. Have CPU schedule 33//itself properly. Threads! 34// Avoid running stages and advancing queues if idle/stalled. 35 36#ifndef __CPU_O3_CPU_FULL_CPU_HH__ 37#define __CPU_O3_CPU_FULL_CPU_HH__ 38 39#include <iostream> 40#include <list> 41#include <vector> 42 43#include "base/statistics.hh" 44#include "base/timebuf.hh" 45#include "config/full_system.hh" 46#include "cpu/base.hh" 47#include "cpu/cpu_exec_context.hh" 48#include "cpu/o3/comm.hh" 49#include "cpu/o3/cpu_policy.hh" 50#include "sim/process.hh" 51 52class ExecContext; 53class FunctionalMemory; 54class Process; 55 56class BaseFullCPU : public BaseCPU 57{ 58 //Stuff that's pretty ISA independent will go here. 59 public: 60 typedef BaseCPU::Params Params; 61 62#if FULL_SYSTEM 63 BaseFullCPU(Params ¶ms); 64#else 65 BaseFullCPU(Params ¶ms); 66#endif // FULL_SYSTEM 67 68 protected: 69 int cpu_id; 70}; 71 72template <class Impl> 73class FullO3CPU : public BaseFullCPU 74{ 75 public: 76 //Put typedefs from the Impl here. 77 typedef typename Impl::CPUPol CPUPolicy; 78 typedef typename Impl::Params Params; 79 typedef typename Impl::DynInstPtr DynInstPtr; 80 81 public: 82 enum Status { 83 Running, 84 Idle, 85 Halted, 86 Blocked // ? 87 }; 88 89 Status _status; 90 91 private: 92 class TickEvent : public Event 93 { 94 private: 95 FullO3CPU<Impl> *cpu; 96 97 public: 98 TickEvent(FullO3CPU<Impl> *c); 99 void process(); 100 const char *description(); 101 }; 102 103 TickEvent tickEvent; 104 105 /// Schedule tick event, regardless of its current state. 106 void scheduleTickEvent(int delay) 107 { 108 if (tickEvent.squashed()) 109 tickEvent.reschedule(curTick + delay); 110 else if (!tickEvent.scheduled()) 111 tickEvent.schedule(curTick + delay); 112 } 113 114 /// Unschedule tick event, regardless of its current state. 115 void unscheduleTickEvent() 116 { 117 if (tickEvent.scheduled()) 118 tickEvent.squash(); 119 } 120 121 public: 122 FullO3CPU(Params ¶ms); 123 ~FullO3CPU(); 124 125 void fullCPURegStats(); 126 127 void tick(); 128 129 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