simple_thread.hh revision 217
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 "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 { Unallocated, Active, Suspended, Halted }; 65 66 private: 67 Status _status; 68 69 public: 70 Status status() const { return _status; } 71 72 void setStatus(Status new_status); 73 74#ifdef FULL_SYSTEM 75 public: 76 KernelStats kernelStats; 77#endif 78 79 public: 80 RegFile regs; // correct-path register context 81 82 // pointer to CPU associated with this context 83 BaseCPU *cpu; 84 85 // Index of hardware thread context on the CPU that this represents. 86 int thread_num; 87 88 // ID of this context w.r.t. the System or Process object to which 89 // it belongs. For full-system mode, this is the system CPU ID. 90 int cpu_id; 91 92#ifdef FULL_SYSTEM 93 94 FunctionalMemory *mem; 95 AlphaItb *itb; 96 AlphaDtb *dtb; 97 System *system; 98 99 // the following two fields are redundant, since we can always 100 // look them up through the system pointer, but we'll leave them 101 // here for now for convenience 102 MemoryController *memCtrl; 103 PhysicalMemory *physmem; 104 105#else 106 Process *process; 107 108 FunctionalMemory *mem; // functional storage for process address space 109 110 // Address space ID. Note that this is used for TIMING cache 111 // simulation only; all functional memory accesses should use 112 // one of the FunctionalMemory pointers above. 113 short asid; 114 115#endif 116 117 118 /* 119 * number of executed instructions, for matching with syscall trace 120 * points in EIO files. 121 */ 122 Counter func_exe_insn; 123 124 // 125 // Count failed store conditionals so we can warn of apparent 126 // application deadlock situations. 127 unsigned storeCondFailures; 128 129 // constructor: initialize context from given process structure 130#ifdef FULL_SYSTEM 131 ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 132 AlphaItb *_itb, AlphaDtb *_dtb, FunctionalMemory *_dem); 133#else 134 ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); 135 ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, 136 int _asid); 137#endif 138 virtual ~ExecContext() {} 139 140 virtual void takeOverFrom(ExecContext *oldContext); 141 142 void regStats(const std::string &name); 143 144 void serialize(std::ostream &os); 145 void unserialize(IniFile &db, const std::string §ion); 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