cpu.hh revision 2665:a124942bacb8
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 * Authors: Kevin Lim 29 */ 30 31//Todo: Add in a lot of the functions that are ISA specific. Also define 32//the functions that currently exist within the base cpu class. Define 33//everything for the simobject stuff so it can be serialized and 34//instantiated, add in debugging statements everywhere. Have CPU schedule 35//itself properly. Threads! 36// Avoid running stages and advancing queues if idle/stalled. 37 38#ifndef __CPU_O3_CPU_FULL_CPU_HH__ 39#define __CPU_O3_CPU_FULL_CPU_HH__ 40 41#include <iostream> 42#include <list> 43#include <vector> 44 45#include "base/statistics.hh" 46#include "base/timebuf.hh" 47#include "config/full_system.hh" 48#include "cpu/base.hh" 49#include "cpu/cpu_exec_context.hh" 50#include "cpu/o3/comm.hh" 51#include "cpu/o3/cpu_policy.hh" 52#include "sim/process.hh" 53 54class ExecContext; 55class FunctionalMemory; 56class Process; 57 58class BaseFullCPU : public BaseCPU 59{ 60 //Stuff that's pretty ISA independent will go here. 61 public: 62 typedef BaseCPU::Params Params; 63 64#if FULL_SYSTEM 65 BaseFullCPU(Params ¶ms); 66#else 67 BaseFullCPU(Params ¶ms); 68#endif // FULL_SYSTEM 69 70 protected: 71 int cpu_id; 72}; 73 74template <class Impl> 75class FullO3CPU : public BaseFullCPU 76{ 77 public: 78 //Put typedefs from the Impl here. 79 typedef typename Impl::CPUPol CPUPolicy; 80 typedef typename Impl::Params Params; 81 typedef typename Impl::DynInstPtr DynInstPtr; 82 83 public: 84 enum Status { 85 Running, 86 Idle, 87 Halted, 88 Blocked // ? 89 }; 90 91 Status _status; 92 93 private: 94 class TickEvent : public Event 95 { 96 private: 97 FullO3CPU<Impl> *cpu; 98 99 public: 100 TickEvent(FullO3CPU<Impl> *c); 101 void process(); 102 const char *description(); 103 }; 104 105 TickEvent tickEvent; 106 107 /// Schedule tick event, regardless of its current state. 108 void scheduleTickEvent(int delay) 109 { 110 if (tickEvent.squashed()) 111 tickEvent.reschedule(curTick + delay); 112 else if (!tickEvent.scheduled()) 113 tickEvent.schedule(curTick + delay); 114 } 115 116 /// Unschedule tick event, regardless of its current state. 117 void unscheduleTickEvent() 118 { 119 if (tickEvent.scheduled()) 120 tickEvent.squash(); 121 } 122 123 public: 124 FullO3CPU(Params ¶ms); 125 ~FullO3CPU(); 126 127 void fullCPURegStats(); 128 129 void tick(); 130 131 void init(); 132 133 void activateContext(int thread_num, int delay); 134 void suspendContext(int thread_num); 135 void deallocateContext(int thread_num); 136 void haltContext(int thread_num); 137 138 void switchOut(); 139 void takeOverFrom(BaseCPU *oldCPU); 140 141 /** Get the current instruction sequence number, and increment it. */ 142 InstSeqNum getAndIncrementInstSeq(); 143 144#if FULL_SYSTEM 145 /** Check if this address is a valid instruction address. */ 146 bool validInstAddr(Addr addr) { return true; } 147 148 /** Check if this address is a valid data address. */ 149 bool validDataAddr(Addr addr) { return true; } 150 151 /** Get instruction asid. */ 152 int getInstAsid() 153 { return regFile.miscRegs.getInstAsid(); } 154 155 /** Get data asid. */ 156 int getDataAsid() 157 { return regFile.miscRegs.getDataAsid(); } 158#else 159 bool validInstAddr(Addr addr) 160 { return thread[0]->validInstAddr(addr); } 161 162 bool validDataAddr(Addr addr) 163 { return thread[0]->validDataAddr(addr); } 164 165 int getInstAsid() { return thread[0]->getInstAsid(); } 166 int getDataAsid() { return thread[0]->getDataAsid(); } 167 168#endif 169 170 // 171 // New accessors for new decoder. 172 // 173 uint64_t readIntReg(int reg_idx); 174 175 FloatReg readFloatReg(int reg_idx); 176 177 FloatReg readFloatReg(int reg_idx, int width); 178 179 FloatRegBits readFloatRegBits(int reg_idx); 180 181 FloatRegBits readFloatRegBits(int reg_idx, int width); 182 183 void setIntReg(int reg_idx, uint64_t val); 184 185 void setFloatReg(int reg_idx, FloatReg val, int width); 186 187 void setFloatReg(int reg_idx, FloatReg val, int width); 188 189 void setFloatRegBits(int reg_idx, FloatRegBits val); 190 191 void setFloatRegBits(int reg_idx, FloatRegBits val); 192 193 uint64_t readPC(); 194 195 void setNextPC(uint64_t val); 196 197 void setPC(Addr new_PC); 198 199 /** Function to add instruction onto the head of the list of the 200 * instructions. Used when new instructions are fetched. 201 */ 202 void addInst(DynInstPtr &inst); 203 204 /** Function to tell the CPU that an instruction has completed. */ 205 void instDone(); 206 207 /** Remove all instructions in back of the given instruction, but leave 208 * that instruction in the list. This is useful in a squash, when there 209 * are instructions in this list that don't exist in structures such as 210 * the ROB. The instruction doesn't have to be the last instruction in 211 * the list, but will be once this function completes. 212 * @todo: Remove only up until that inst? Squashed inst is most likely 213 * valid. 214 */ 215 void removeBackInst(DynInstPtr &inst); 216 217 /** Remove an instruction from the front of the list. It is expected 218 * that there are no instructions in front of it (that is, none are older 219 * than the instruction being removed). Used when retiring instructions. 220 * @todo: Remove the argument to this function, and just have it remove 221 * last instruction once it's verified that commit has the same ordering 222 * as the instruction list. 223 */ 224 void removeFrontInst(DynInstPtr &inst); 225 226 /** Remove all instructions that are not currently in the ROB. */ 227 void removeInstsNotInROB(); 228 229 /** Remove all instructions younger than the given sequence number. */ 230 void removeInstsUntil(const InstSeqNum &seq_num); 231 232 /** Remove all instructions from the list. */ 233 void removeAllInsts(); 234 235 void dumpInsts(); 236 237 /** Basically a wrapper function so that instructions executed at 238 * commit can tell the instruction queue that they have completed. 239 * Eventually this hack should be removed. 240 */ 241 void wakeDependents(DynInstPtr &inst); 242 243 public: 244 /** List of all the instructions in flight. */ 245 list<DynInstPtr> instList; 246 247 //not sure these should be private. 248 protected: 249 /** The fetch stage. */ 250 typename CPUPolicy::Fetch fetch; 251 252 /** The fetch stage's status. */ 253 typename CPUPolicy::Fetch::Status fetchStatus; 254 255 /** The decode stage. */ 256 typename CPUPolicy::Decode decode; 257 258 /** The decode stage's status. */ 259 typename CPUPolicy::Decode::Status decodeStatus; 260 261 /** The dispatch stage. */ 262 typename CPUPolicy::Rename rename; 263 264 /** The dispatch stage's status. */ 265 typename CPUPolicy::Rename::Status renameStatus; 266 267 /** The issue/execute/writeback stages. */ 268 typename CPUPolicy::IEW iew; 269 270 /** The issue/execute/writeback stage's status. */ 271 typename CPUPolicy::IEW::Status iewStatus; 272 273 /** The commit stage. */ 274 typename CPUPolicy::Commit commit; 275 276 /** The fetch stage's status. */ 277 typename CPUPolicy::Commit::Status commitStatus; 278 279 //Might want to just pass these objects in to the constructors of the 280 //appropriate stage. regFile is in iew, freeList in dispatch, renameMap 281 //in dispatch, and the rob in commit. 282 /** The register file. */ 283 typename CPUPolicy::RegFile regFile; 284 285 /** The free list. */ 286 typename CPUPolicy::FreeList freeList; 287 288 /** The rename map. */ 289 typename CPUPolicy::RenameMap renameMap; 290 291 /** The re-order buffer. */ 292 typename CPUPolicy::ROB rob; 293 294 public: 295 /** Typedefs from the Impl to get the structs that each of the 296 * time buffers should use. 297 */ 298 typedef typename CPUPolicy::TimeStruct TimeStruct; 299 300 typedef typename CPUPolicy::FetchStruct FetchStruct; 301 302 typedef typename CPUPolicy::DecodeStruct DecodeStruct; 303 304 typedef typename CPUPolicy::RenameStruct RenameStruct; 305 306 typedef typename CPUPolicy::IEWStruct IEWStruct; 307 308 /** The main time buffer to do backwards communication. */ 309 TimeBuffer<TimeStruct> timeBuffer; 310 311 /** The fetch stage's instruction queue. */ 312 TimeBuffer<FetchStruct> fetchQueue; 313 314 /** The decode stage's instruction queue. */ 315 TimeBuffer<DecodeStruct> decodeQueue; 316 317 /** The rename stage's instruction queue. */ 318 TimeBuffer<RenameStruct> renameQueue; 319 320 /** The IEW stage's instruction queue. */ 321 TimeBuffer<IEWStruct> iewQueue; 322 323 public: 324 /** The temporary exec context to support older accessors. */ 325 CPUExecContext *cpuXC; 326 327 /** Temporary function to get pointer to exec context. */ 328 ExecContext *xcBase() 329 { 330 return thread[0]->getProxy(); 331 } 332 333 CPUExecContext *cpuXCBase() 334 { 335 return thread[0]; 336 } 337 338 InstSeqNum globalSeqNum; 339 340#if FULL_SYSTEM 341 System *system; 342 343 MemoryController *memCtrl; 344 PhysicalMemory *physmem; 345 346 AlphaITB *itb; 347 AlphaDTB *dtb; 348 349// SWContext *swCtx; 350#endif 351 std::vector<CPUExecContext *> thread; 352 353 FunctionalMemory *mem; 354 355 MemInterface *icacheInterface; 356 MemInterface *dcacheInterface; 357 358 bool deferRegistration; 359 360 Counter numInsts; 361 362 Counter funcExeInst; 363}; 364 365#endif 366