cpu.hh revision 1689
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_BETA_CPU_FULL_CPU_HH__ 37#define __CPU_BETA_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 "cpu/base_cpu.hh" 46#include "cpu/beta_cpu/comm.hh" 47#include "cpu/beta_cpu/cpu_policy.hh" 48#include "cpu/exec_context.hh" 49#include "sim/process.hh" 50 51#ifdef FULL_SYSTEM 52#include "arch/alpha/ev5.hh" 53using namespace EV5; 54#endif 55 56class FunctionalMemory; 57class Process; 58 59class BaseFullCPU : public BaseCPU 60{ 61 //Stuff that's pretty ISA independent will go here. 62 public: 63 typedef BaseCPU::Params Params; 64 65#ifdef FULL_SYSTEM 66 BaseFullCPU(Params ¶ms); 67#else 68 BaseFullCPU(Params ¶ms); 69#endif // FULL_SYSTEM 70 71 protected: 72 int cpu_id; 73}; 74 75template <class Impl> 76class FullBetaCPU : public BaseFullCPU 77{ 78 public: 79 //Put typedefs from the Impl here. 80 typedef typename Impl::ISA ISA; 81 typedef typename Impl::CPUPol CPUPolicy; 82 typedef typename Impl::Params Params; 83 typedef typename Impl::DynInstPtr DynInstPtr; 84 85 public: 86 enum Status { 87 Running, 88 Idle, 89 Halted, 90 Blocked // ? 91 }; 92 93 Status _status; 94 95 private: 96 class TickEvent : public Event 97 { 98 private: 99 FullBetaCPU<Impl> *cpu; 100 101 public: 102 TickEvent(FullBetaCPU<Impl> *c); 103 void process(); 104 const char *description(); 105 }; 106 107 TickEvent tickEvent; 108 109 /// Schedule tick event, regardless of its current state. 110 void scheduleTickEvent(int delay) 111 { 112 if (tickEvent.squashed()) 113 tickEvent.reschedule(curTick + delay); 114 else if (!tickEvent.scheduled()) 115 tickEvent.schedule(curTick + delay); 116 } 117 118 /// Unschedule tick event, regardless of its current state. 119 void unscheduleTickEvent() 120 { 121 if (tickEvent.scheduled()) 122 tickEvent.squash(); 123 } 124 125 public: 126 FullBetaCPU(Params ¶ms); 127 ~FullBetaCPU(); 128 129 void fullCPURegStats(); 130 131 void tick(); 132 133 void init(); 134 135 void activateContext(int thread_num, int delay); 136 void suspendContext(int thread_num); 137 void deallocateContext(int thread_num); 138 void haltContext(int thread_num); 139 140 void switchOut(); 141 void takeOverFrom(BaseCPU *oldCPU); 142 143 /** Get the current instruction sequence number, and increment it. */ 144 InstSeqNum getAndIncrementInstSeq(); 145 146#ifdef FULL_SYSTEM 147 /** Check if this address is a valid instruction address. */ 148 bool validInstAddr(Addr addr) { return true; } 149 150 /** Check if this address is a valid data address. */ 151 bool validDataAddr(Addr addr) { return true; } 152 153 /** Get instruction asid. */ 154 int getInstAsid() 155 { return ITB_ASN_ASN(regFile.getIpr()[ISA::IPR_ITB_ASN]); } 156 157 /** Get data asid. */ 158 int getDataAsid() 159 { return DTB_ASN_ASN(regFile.getIpr()[ISA::IPR_DTB_ASN]); } 160#else 161 bool validInstAddr(Addr addr) 162 { return thread[0]->validInstAddr(addr); } 163 164 bool validDataAddr(Addr addr) 165 { return thread[0]->validDataAddr(addr); } 166 167 int getInstAsid() { return thread[0]->asid; } 168 int getDataAsid() { return thread[0]->asid; } 169 170#endif 171 172 // 173 // New accessors for new decoder. 174 // 175 uint64_t readIntReg(int reg_idx); 176 177 float readFloatRegSingle(int reg_idx); 178 179 double readFloatRegDouble(int reg_idx); 180 181 uint64_t readFloatRegInt(int reg_idx); 182 183 void setIntReg(int reg_idx, uint64_t val); 184 185 void setFloatRegSingle(int reg_idx, float val); 186 187 void setFloatRegDouble(int reg_idx, double val); 188 189 void setFloatRegInt(int reg_idx, uint64_t 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 ExecContext *xc; 324 325 /** Temporary function to get pointer to exec context. */ 326 ExecContext *xcBase() 327 { 328#ifdef FULL_SYSTEM 329 return system->execContexts[0]; 330#else 331 return thread[0]; 332#endif 333 } 334 335 InstSeqNum globalSeqNum; 336 337#ifdef FULL_SYSTEM 338 System *system; 339 340 MemoryController *memCtrl; 341 PhysicalMemory *physmem; 342 343 AlphaITB *itb; 344 AlphaDTB *dtb; 345 346// SWContext *swCtx; 347#else 348 std::vector<ExecContext *> thread; 349#endif 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