thread_context.hh revision 246
12632SN/A/* 22632SN/A * Copyright (c) 2003 The Regents of The University of Michigan 32632SN/A * All rights reserved. 42632SN/A * 52632SN/A * Redistribution and use in source and binary forms, with or without 62632SN/A * modification, are permitted provided that the following conditions are 72632SN/A * met: redistributions of source code must retain the above copyright 82632SN/A * notice, this list of conditions and the following disclaimer; 92632SN/A * redistributions in binary form must reproduce the above copyright 102632SN/A * notice, this list of conditions and the following disclaimer in the 112632SN/A * documentation and/or other materials provided with the distribution; 122632SN/A * neither the name of the copyright holders nor the names of its 132632SN/A * contributors may be used to endorse or promote products derived from 142632SN/A * this software without specific prior written permission. 152632SN/A * 162632SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172632SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182632SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192632SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202632SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212632SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222632SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232632SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242632SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252632SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262632SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272632SN/A */ 282632SN/A 292632SN/A#ifndef __EXEC_CONTEXT_HH__ 302632SN/A#define __EXEC_CONTEXT_HH__ 312632SN/A 322632SN/A#include "sim/host.hh" 33#include "mem/mem_req.hh" 34#include "sim/serialize.hh" 35 36// forward declaration: see functional_memory.hh 37class FunctionalMemory; 38class PhysicalMemory; 39class BaseCPU; 40 41#ifdef FULL_SYSTEM 42 43#include "targetarch/alpha_memory.hh" 44class MemoryController; 45 46#include "kern/tru64/kernel_stats.hh" 47#include "sim/system.hh" 48 49#else // !FULL_SYSTEM 50 51#include "sim/prog.hh" 52 53#endif // FULL_SYSTEM 54 55// 56// The ExecContext object represents a functional context for 57// instruction execution. It incorporates everything required for 58// architecture-level functional simulation of a single thread. 59// 60 61class ExecContext 62{ 63 public: 64 enum Status 65 { 66 /// Initialized but not running yet. All CPUs start in 67 /// this state, but most transition to Active on cycle 1. 68 /// In MP or SMT systems, non-primary contexts will stay 69 /// in this state until a thread is assigned to them. 70 Unallocated, 71 72 /// Running. Instructions should be executed only when 73 /// the context is in this state. 74 Active, 75 76 /// Temporarily inactive. Entered while waiting for 77 /// synchronization, etc. 78 Suspended, 79 80 /// Permanently shut down. Entered when target executes 81 /// m5exit pseudo-instruction. When all contexts enter 82 /// this state, the simulation will terminate. 83 Halted 84 }; 85 86 private: 87 Status _status; 88 89 public: 90 Status status() const { return _status; } 91 92 void setStatus(Status new_status); 93 94#ifdef FULL_SYSTEM 95 public: 96 KernelStats kernelStats; 97#endif 98 99 public: 100 RegFile regs; // correct-path register context 101 102 // pointer to CPU associated with this context 103 BaseCPU *cpu; 104 105 // Index of hardware thread context on the CPU that this represents. 106 int thread_num; 107 108 // ID of this context w.r.t. the System or Process object to which 109 // it belongs. For full-system mode, this is the system CPU ID. 110 int cpu_id; 111 112#ifdef FULL_SYSTEM 113 114 FunctionalMemory *mem; 115 AlphaItb *itb; 116 AlphaDtb *dtb; 117 System *system; 118 119 // the following two fields are redundant, since we can always 120 // look them up through the system pointer, but we'll leave them 121 // here for now for convenience 122 MemoryController *memCtrl; 123 PhysicalMemory *physmem; 124 125#else 126 Process *process; 127 128 FunctionalMemory *mem; // functional storage for process address space 129 130 // Address space ID. Note that this is used for TIMING cache 131 // simulation only; all functional memory accesses should use 132 // one of the FunctionalMemory pointers above. 133 short asid; 134 135#endif 136 137 138 /* 139 * number of executed instructions, for matching with syscall trace 140 * points in EIO files. 141 */ 142 Counter func_exe_insn; 143 144 // 145 // Count failed store conditionals so we can warn of apparent 146 // application deadlock situations. 147 unsigned storeCondFailures; 148 149 // constructor: initialize context from given process structure 150#ifdef FULL_SYSTEM 151 ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 152 AlphaItb *_itb, AlphaDtb *_dtb, FunctionalMemory *_dem); 153#else 154 ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); 155 ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, 156 int _asid); 157#endif 158 virtual ~ExecContext() {} 159 160 virtual void takeOverFrom(ExecContext *oldContext); 161 162 void regStats(const std::string &name); 163 164 void serialize(std::ostream &os); 165 void unserialize(Checkpoint *cp, const std::string §ion); 166 167#ifdef FULL_SYSTEM 168 bool validInstAddr(Addr addr) { return true; } 169 bool validDataAddr(Addr addr) { return true; } 170 int getInstAsid() { return ITB_ASN_ASN(regs.ipr[TheISA::IPR_ITB_ASN]); } 171 int getDataAsid() { return DTB_ASN_ASN(regs.ipr[TheISA::IPR_DTB_ASN]); } 172 173 Fault translateInstReq(MemReqPtr req) 174 { 175 return itb->translate(req); 176 } 177 178 Fault translateDataReadReq(MemReqPtr req) 179 { 180 return dtb->translate(req, false); 181 } 182 183 Fault translateDataWriteReq(MemReqPtr req) 184 { 185 return dtb->translate(req, true); 186 } 187 188#else 189 bool validInstAddr(Addr addr) 190 { return process->validInstAddr(addr); } 191 192 bool validDataAddr(Addr addr) 193 { return process->validDataAddr(addr); } 194 195 int getInstAsid() { return asid; } 196 int getDataAsid() { return asid; } 197 198 Fault dummyTranslation(MemReqPtr req) 199 { 200#if 0 201 assert((req->vaddr >> 48 & 0xffff) == 0); 202#endif 203 204 // put the asid in the upper 16 bits of the paddr 205 req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); 206 req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; 207 return No_Fault; 208 } 209 Fault translateInstReq(MemReqPtr req) 210 { 211 return dummyTranslation(req); 212 } 213 Fault translateDataReadReq(MemReqPtr req) 214 { 215 return dummyTranslation(req); 216 } 217 Fault translateDataWriteReq(MemReqPtr req) 218 { 219 return dummyTranslation(req); 220 } 221 222#endif 223 224 template <class T> 225 Fault read(MemReqPtr req, T& data) 226 { 227#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM) 228 if (req->flags & LOCKED) { 229 MiscRegFile *cregs = &req->xc->regs.miscRegs; 230 cregs->lock_addr = req->paddr; 231 cregs->lock_flag = true; 232 } 233#endif 234 return mem->read(req, data); 235 } 236 237 template <class T> 238 Fault write(MemReqPtr req, T& data) 239 { 240#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM) 241 242 MiscRegFile *cregs; 243 244 // If this is a store conditional, act appropriately 245 if (req->flags & LOCKED) { 246 cregs = &req->xc->regs.miscRegs; 247 248 if (req->flags & UNCACHEABLE) { 249 // Don't update result register (see stq_c in isa_desc) 250 req->result = 2; 251 req->xc->storeCondFailures = 0;//Needed? [RGD] 252 } else { 253 req->result = cregs->lock_flag; 254 if (!cregs->lock_flag || 255 ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) { 256 cregs->lock_flag = false; 257 if (((++req->xc->storeCondFailures) % 100000) == 0) { 258 std::cerr << "Warning: " 259 << req->xc->storeCondFailures 260 << " consecutive store conditional failures " 261 << "on cpu " << req->xc->cpu_id 262 << std::endl; 263 } 264 return No_Fault; 265 } 266 else req->xc->storeCondFailures = 0; 267 } 268 } 269 270 // Need to clear any locked flags on other proccessors for 271 // this address. Only do this for succsful Store Conditionals 272 // and all other stores (WH64?). Unsuccessful Store 273 // Conditionals would have returned above, and wouldn't fall 274 // through. 275 for (int i = 0; i < system->execContexts.size(); i++){ 276 cregs = &system->execContexts[i]->regs.miscRegs; 277 if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) { 278 cregs->lock_flag = false; 279 } 280 } 281 282#endif 283 return mem->write(req, data); 284 } 285 286 virtual bool misspeculating(); 287 288 289 // 290 // New accessors for new decoder. 291 // 292 uint64_t readIntReg(int reg_idx) 293 { 294 return regs.intRegFile[reg_idx]; 295 } 296 297 float readFloatRegSingle(int reg_idx) 298 { 299 return (float)regs.floatRegFile.d[reg_idx]; 300 } 301 302 double readFloatRegDouble(int reg_idx) 303 { 304 return regs.floatRegFile.d[reg_idx]; 305 } 306 307 uint64_t readFloatRegInt(int reg_idx) 308 { 309 return regs.floatRegFile.q[reg_idx]; 310 } 311 312 void setIntReg(int reg_idx, uint64_t val) 313 { 314 regs.intRegFile[reg_idx] = val; 315 } 316 317 void setFloatRegSingle(int reg_idx, float val) 318 { 319 regs.floatRegFile.d[reg_idx] = (double)val; 320 } 321 322 void setFloatRegDouble(int reg_idx, double val) 323 { 324 regs.floatRegFile.d[reg_idx] = val; 325 } 326 327 void setFloatRegInt(int reg_idx, uint64_t val) 328 { 329 regs.floatRegFile.q[reg_idx] = val; 330 } 331 332 uint64_t readPC() 333 { 334 return regs.pc; 335 } 336 337 void setNextPC(uint64_t val) 338 { 339 regs.npc = val; 340 } 341 342 uint64_t readUniq() 343 { 344 return regs.miscRegs.uniq; 345 } 346 347 void setUniq(uint64_t val) 348 { 349 regs.miscRegs.uniq = val; 350 } 351 352 uint64_t readFpcr() 353 { 354 return regs.miscRegs.fpcr; 355 } 356 357 void setFpcr(uint64_t val) 358 { 359 regs.miscRegs.fpcr = val; 360 } 361 362#ifdef FULL_SYSTEM 363 uint64_t readIpr(int idx, Fault &fault); 364 Fault setIpr(int idx, uint64_t val); 365 Fault hwrei(); 366 void ev5_trap(Fault fault); 367 bool simPalCheck(int palFunc); 368#endif 369 370#ifndef FULL_SYSTEM 371 void syscall() 372 { 373 process->syscall(this); 374 } 375#endif 376}; 377 378 379// for non-speculative execution context, spec_mode is always false 380inline bool 381ExecContext::misspeculating() 382{ 383 return false; 384} 385 386#endif // __EXEC_CONTEXT_HH__ 387