cpu.hh revision 2190
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 52#if FULL_SYSTEM 53#include "arch/alpha/ev5.hh" 54using namespace EV5; 55#endif 56 57class ExecContext; 58class FunctionalMemory; 59class Process; 60 61class BaseFullCPU : public BaseCPU 62{ 63 //Stuff that's pretty ISA independent will go here. 64 public: 65 typedef BaseCPU::Params Params; 66 67#if FULL_SYSTEM 68 BaseFullCPU(Params ¶ms); 69#else 70 BaseFullCPU(Params ¶ms); 71#endif // FULL_SYSTEM 72 73 protected: 74 int cpu_id; 75}; 76 77template <class Impl> 78class FullO3CPU : public BaseFullCPU 79{ 80 public: 81 //Put typedefs from the Impl here. 82 typedef typename Impl::CPUPol CPUPolicy; 83 typedef typename Impl::Params Params; 84 typedef typename Impl::DynInstPtr DynInstPtr; 85 86 public: 87 enum Status { 88 Running, 89 Idle, 90 Halted, 91 Blocked // ? 92 }; 93 94 Status _status; 95 96 private: 97 class TickEvent : public Event 98 { 99 private: 100 FullO3CPU<Impl> *cpu; 101 102 public: 103 TickEvent(FullO3CPU<Impl> *c); 104 void process(); 105 const char *description(); 106 }; 107 108 TickEvent tickEvent; 109 110 /// Schedule tick event, regardless of its current state. 111 void scheduleTickEvent(int delay) 112 { 113 if (tickEvent.squashed()) 114 tickEvent.reschedule(curTick + delay); 115 else if (!tickEvent.scheduled()) 116 tickEvent.schedule(curTick + delay); 117 } 118 119 /// Unschedule tick event, regardless of its current state. 120 void unscheduleTickEvent() 121 { 122 if (tickEvent.scheduled()) 123 tickEvent.squash(); 124 } 125 126 public: 127 FullO3CPU(Params ¶ms); 128 ~FullO3CPU(); 129 130 void fullCPURegStats(); 131 132 void tick(); 133 134 void init(); 135 136 void activateContext(int thread_num, int delay); 137 void suspendContext(int thread_num); 138 void deallocateContext(int thread_num); 139 void haltContext(int thread_num); 140 141 void switchOut(); 142 void takeOverFrom(BaseCPU *oldCPU); 143 144 /** Get the current instruction sequence number, and increment it. */ 145 InstSeqNum getAndIncrementInstSeq(); 146 147#if FULL_SYSTEM 148 /** Check if this address is a valid instruction address. */ 149 bool validInstAddr(Addr addr) { return true; } 150 151 /** Check if this address is a valid data address. */ 152 bool validDataAddr(Addr addr) { return true; } 153 154 /** Get instruction asid. */ 155 int getInstAsid() 156 { return ITB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_ITB_ASN)); } 157 158 /** Get data asid. */ 159 int getDataAsid() 160 { return DTB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_DTB_ASN)); } 161#else 162 bool validInstAddr(Addr addr) 163 { return thread[0]->validInstAddr(addr); } 164 165 bool validDataAddr(Addr addr) 166 { return thread[0]->validDataAddr(addr); } 167 168 int getInstAsid() { return thread[0]->getInstAsid(); } 169 int getDataAsid() { return thread[0]->getDataAsid(); } 170 171#endif 172 173 // 174 // New accessors for new decoder. 175 // 176 uint64_t readIntReg(int reg_idx); 177 178 float readFloatRegSingle(int reg_idx); 179 180 double readFloatRegDouble(int reg_idx); 181 182 uint64_t readFloatRegInt(int reg_idx); 183 184 void setIntReg(int reg_idx, uint64_t val); 185 186 void setFloatRegSingle(int reg_idx, float val); 187 188 void setFloatRegDouble(int reg_idx, double val); 189 190 void setFloatRegInt(int reg_idx, uint64_t val); 191 192 uint64_t readPC(); 193 194 void setNextPC(uint64_t val); 195 196 void setPC(Addr new_PC); 197 198 /** Function to add instruction onto the head of the list of the 199 * instructions. Used when new instructions are fetched. 200 */ 201 void addInst(DynInstPtr &inst); 202 203 /** Function to tell the CPU that an instruction has completed. */ 204 void instDone(); 205 206 /** Remove all instructions in back of the given instruction, but leave 207 * that instruction in the list. This is useful in a squash, when there 208 * are instructions in this list that don't exist in structures such as 209 * the ROB. The instruction doesn't have to be the last instruction in 210 * the list, but will be once this function completes. 211 * @todo: Remove only up until that inst? Squashed inst is most likely 212 * valid. 213 */ 214 void removeBackInst(DynInstPtr &inst); 215 216 /** Remove an instruction from the front of the list. It is expected 217 * that there are no instructions in front of it (that is, none are older 218 * than the instruction being removed). Used when retiring instructions. 219 * @todo: Remove the argument to this function, and just have it remove 220 * last instruction once it's verified that commit has the same ordering 221 * as the instruction list. 222 */ 223 void removeFrontInst(DynInstPtr &inst); 224 225 /** Remove all instructions that are not currently in the ROB. */ 226 void removeInstsNotInROB(); 227 228 /** Remove all instructions younger than the given sequence number. */ 229 void removeInstsUntil(const InstSeqNum &seq_num); 230 231 /** Remove all instructions from the list. */ 232 void removeAllInsts(); 233 234 void dumpInsts(); 235 236 /** Basically a wrapper function so that instructions executed at 237 * commit can tell the instruction queue that they have completed. 238 * Eventually this hack should be removed. 239 */ 240 void wakeDependents(DynInstPtr &inst); 241 242 public: 243 /** List of all the instructions in flight. */ 244 list<DynInstPtr> instList; 245 246 //not sure these should be private. 247 protected: 248 /** The fetch stage. */ 249 typename CPUPolicy::Fetch fetch; 250 251 /** The fetch stage's status. */ 252 typename CPUPolicy::Fetch::Status fetchStatus; 253 254 /** The decode stage. */ 255 typename CPUPolicy::Decode decode; 256 257 /** The decode stage's status. */ 258 typename CPUPolicy::Decode::Status decodeStatus; 259 260 /** The dispatch stage. */ 261 typename CPUPolicy::Rename rename; 262 263 /** 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