thread_context.hh revision 180
1/* 2 * Copyright (c) 2003 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#ifndef __EXEC_CONTEXT_HH__ 30#define __EXEC_CONTEXT_HH__ 31 32#include "sim/host.hh" 33#include "targetarch/mem_req.hh" 34 35// forward declaration: see functional_memory.hh 36class FunctionalMemory; 37class PhysicalMemory; 38class BaseCPU; 39 40#ifdef FULL_SYSTEM 41 42#include "targetarch/alpha_memory.hh" 43class MemoryController; 44 45#include "kern/tru64/kernel_stats.hh" 46#include "sim/system.hh" 47 48#else // !FULL_SYSTEM 49 50#include "sim/prog.hh" 51 52#endif // FULL_SYSTEM 53 54// 55// The ExecContext object represents a functional context for 56// instruction execution. It incorporates everything required for 57// architecture-level functional simulation of a single thread. 58// 59 60class ExecContext 61{ 62 public: 63 enum Status { Unallocated, Active, Suspended, Halted }; 64 65 private: 66 Status _status; 67 68 public: 69 Status status() const { return _status; } 70 71 // Unlike setStatus(), initStatus() has no side effects other than 72 // setting the _status variable. 73 void initStatus(Status init_status) { _status = init_status; } 74 75 void setStatus(Status new_status); 76 77#ifdef FULL_SYSTEM 78 public: 79 KernelStats kernelStats; 80#endif 81 82 public: 83 RegFile regs; // correct-path register context 84 85 // pointer to CPU associated with this context 86 BaseCPU *cpu; 87 88 // Index of hardware thread context on the CPU that this represents. 89 int thread_num; 90 91 // ID of this context w.r.t. the System or Process object to which 92 // it belongs. For full-system mode, this is the system CPU ID. 93 int cpu_id; 94 95#ifdef FULL_SYSTEM 96 97 FunctionalMemory *mem; 98 AlphaItb *itb; 99 AlphaDtb *dtb; 100 System *system; 101 102 // the following two fields are redundant, since we can always 103 // look them up through the system pointer, but we'll leave them 104 // here for now for convenience 105 MemoryController *memCtrl; 106 PhysicalMemory *physmem; 107 108#else 109 Process *process; 110 111 FunctionalMemory *mem; // functional storage for process address space 112 113 // Address space ID. Note that this is used for TIMING cache 114 // simulation only; all functional memory accesses should use 115 // one of the FunctionalMemory pointers above. 116 short asid; 117 118#endif 119 120 121 /* 122 * number of executed instructions, for matching with syscall trace 123 * points in EIO files. 124 */ 125 Counter func_exe_insn; 126 127 // 128 // Count failed store conditionals so we can warn of apparent 129 // application deadlock situations. 130 unsigned storeCondFailures; 131 132 // constructor: initialize context from given process structure 133#ifdef FULL_SYSTEM 134 ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 135 AlphaItb *_itb, AlphaDtb *_dtb, FunctionalMemory *_dem); 136#else 137 ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); 138 ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, 139 int _asid); 140#endif 141 virtual ~ExecContext() {} 142 143 virtual void takeOverFrom(ExecContext *oldContext); 144 145 void regStats(const std::string &name); 146 147#ifdef FULL_SYSTEM 148 bool validInstAddr(Addr addr) { return true; } 149 bool validDataAddr(Addr addr) { return true; } 150 int getInstAsid() { return ITB_ASN_ASN(regs.ipr[TheISA::IPR_ITB_ASN]); } 151 int getDataAsid() { return DTB_ASN_ASN(regs.ipr[TheISA::IPR_DTB_ASN]); } 152 153 Fault translateInstReq(MemReqPtr req) 154 { 155 return itb->translate(req); 156 } 157 158 Fault translateDataReadReq(MemReqPtr req) 159 { 160 return dtb->translate(req, false); 161 } 162 163 Fault translateDataWriteReq(MemReqPtr req) 164 { 165 return dtb->translate(req, true); 166 } 167 168#else 169 bool validInstAddr(Addr addr) 170 { return process->validInstAddr(addr); } 171 172 bool validDataAddr(Addr addr) 173 { return process->validDataAddr(addr); } 174 175 int getInstAsid() { return asid; } 176 int getDataAsid() { return asid; } 177 178 Fault dummyTranslation(MemReqPtr req) 179 { 180#if 0 181 assert((req->vaddr >> 48 & 0xffff) == 0); 182#endif 183 184 // put the asid in the upper 16 bits of the paddr 185 req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); 186 req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; 187 return No_Fault; 188 } 189 Fault translateInstReq(MemReqPtr req) 190 { 191 return dummyTranslation(req); 192 } 193 Fault translateDataReadReq(MemReqPtr req) 194 { 195 return dummyTranslation(req); 196 } 197 Fault translateDataWriteReq(MemReqPtr req) 198 { 199 return dummyTranslation(req); 200 } 201 202#endif 203 204 template <class T> 205 Fault read(MemReqPtr req, T& data) 206 { 207#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM) 208 if (req->flags & LOCKED) { 209 MiscRegFile *cregs = &req->xc->regs.miscRegs; 210 cregs->lock_addr = req->paddr; 211 cregs->lock_flag = true; 212 } 213#endif 214 return mem->read(req, data); 215 } 216 217 template <class T> 218 Fault write(MemReqPtr req, T& data) 219 { 220#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM) 221 222 MiscRegFile *cregs; 223 224 // If this is a store conditional, act appropriately 225 if (req->flags & LOCKED) { 226 cregs = &req->xc->regs.miscRegs; 227 228 if (req->flags & UNCACHEABLE) { 229 // Don't update result register (see stq_c in isa_desc) 230 req->result = 2; 231 req->xc->storeCondFailures = 0;//Needed? [RGD] 232 } else { 233 req->result = cregs->lock_flag; 234 if (!cregs->lock_flag || 235 ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) { 236 cregs->lock_flag = false; 237 if (((++req->xc->storeCondFailures) % 100000) == 0) { 238 std::cerr << "Warning: " 239 << req->xc->storeCondFailures 240 << " consecutive store conditional failures " 241 << "on cpu " << req->xc->cpu_id 242 << std::endl; 243 } 244 return No_Fault; 245 } 246 else req->xc->storeCondFailures = 0; 247 } 248 } 249 250 // Need to clear any locked flags on other proccessors for 251 // this address. Only do this for succsful Store Conditionals 252 // and all other stores (WH64?). Unsuccessful Store 253 // Conditionals would have returned above, and wouldn't fall 254 // through. 255 for (int i = 0; i < system->execContexts.size(); i++){ 256 cregs = &system->execContexts[i]->regs.miscRegs; 257 if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) { 258 cregs->lock_flag = false; 259 } 260 } 261 262#endif 263 return mem->write(req, data); 264 } 265 266 virtual bool misspeculating(); 267 268 269 // 270 // New accessors for new decoder. 271 // 272 uint64_t readIntReg(int reg_idx) 273 { 274 return regs.intRegFile[reg_idx]; 275 } 276 277 float readFloatRegSingle(int reg_idx) 278 { 279 return (float)regs.floatRegFile.d[reg_idx]; 280 } 281 282 double readFloatRegDouble(int reg_idx) 283 { 284 return regs.floatRegFile.d[reg_idx]; 285 } 286 287 uint64_t readFloatRegInt(int reg_idx) 288 { 289 return regs.floatRegFile.q[reg_idx]; 290 } 291 292 void setIntReg(int reg_idx, uint64_t val) 293 { 294 regs.intRegFile[reg_idx] = val; 295 } 296 297 void setFloatRegSingle(int reg_idx, float val) 298 { 299 regs.floatRegFile.d[reg_idx] = (double)val; 300 } 301 302 void setFloatRegDouble(int reg_idx, double val) 303 { 304 regs.floatRegFile.d[reg_idx] = val; 305 } 306 307 void setFloatRegInt(int reg_idx, uint64_t val) 308 { 309 regs.floatRegFile.q[reg_idx] = val; 310 } 311 312 uint64_t readPC() 313 { 314 return regs.pc; 315 } 316 317 void setNextPC(uint64_t val) 318 { 319 regs.npc = val; 320 } 321 322 uint64_t readUniq() 323 { 324 return regs.miscRegs.uniq; 325 } 326 327 void setUniq(uint64_t val) 328 { 329 regs.miscRegs.uniq = val; 330 } 331 332 uint64_t readFpcr() 333 { 334 return regs.miscRegs.fpcr; 335 } 336 337 void setFpcr(uint64_t val) 338 { 339 regs.miscRegs.fpcr = val; 340 } 341 342#ifdef FULL_SYSTEM 343 uint64_t readIpr(int idx, Fault &fault); 344 Fault setIpr(int idx, uint64_t val); 345 Fault hwrei(); 346 void ev5_trap(Fault fault); 347 bool simPalCheck(int palFunc); 348#endif 349 350#ifndef FULL_SYSTEM 351 void syscall() 352 { 353 process->syscall(this); 354 } 355#endif 356}; 357 358 359// for non-speculative execution context, spec_mode is always false 360inline bool 361ExecContext::misspeculating() 362{ 363 return false; 364} 365 366#endif // __EXEC_CONTEXT_HH__ 367