simple_thread.hh revision 237
16145SN/A/* 26145SN/A * Copyright (c) 2003 The Regents of The University of Michigan 36145SN/A * All rights reserved. 46145SN/A * 56145SN/A * Redistribution and use in source and binary forms, with or without 66145SN/A * modification, are permitted provided that the following conditions are 76145SN/A * met: redistributions of source code must retain the above copyright 86145SN/A * notice, this list of conditions and the following disclaimer; 96145SN/A * redistributions in binary form must reproduce the above copyright 106145SN/A * notice, this list of conditions and the following disclaimer in the 116145SN/A * documentation and/or other materials provided with the distribution; 126145SN/A * neither the name of the copyright holders nor the names of its 136145SN/A * contributors may be used to endorse or promote products derived from 146145SN/A * this software without specific prior written permission. 156145SN/A * 166145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276145SN/A */ 286145SN/A 296145SN/A#ifndef __EXEC_CONTEXT_HH__ 307054SN/A#define __EXEC_CONTEXT_HH__ 317054SN/A 327054SN/A#include "sim/host.hh" 337054SN/A#include "mem/mem_req.hh" 347054SN/A#include "sim/serialize.hh" 357054SN/A 367054SN/A// forward declaration: see functional_memory.hh 377054SN/Aclass FunctionalMemory; 387054SN/Aclass PhysicalMemory; 396145SN/Aclass BaseCPU; 409594Snilay@cs.wisc.edu 419594Snilay@cs.wisc.edu#ifdef FULL_SYSTEM 426145SN/A 437002SN/A#include "targetarch/alpha_memory.hh" 447002SN/Aclass MemoryController; 457454SN/A 467002SN/A#include "kern/tru64/kernel_stats.hh" 478257SBrad.Beckmann@amd.com#include "sim/system.hh" 488608Snilay@cs.wisc.edu 499594Snilay@cs.wisc.edu#else // !FULL_SYSTEM 506145SN/A 518257SBrad.Beckmann@amd.com#include "sim/prog.hh" 526145SN/A 536145SN/A#endif // FULL_SYSTEM 547454SN/A 5511664Stushar@ece.gatech.edu// 566145SN/A// The ExecContext object represents a functional context for 5711320Ssteve.reinhardt@amd.com// instruction execution. It incorporates everything required for 587054SN/A// architecture-level functional simulation of a single thread. 598257SBrad.Beckmann@amd.com// 608257SBrad.Beckmann@amd.com 6111664Stushar@ece.gatech.educlass ExecContext 6211664Stushar@ece.gatech.edu{ 636879SN/A public: 646879SN/A enum Status { Unallocated, Active, Suspended, Halted }; 6510005Snilay@cs.wisc.edu 666879SN/A private: 679594Snilay@cs.wisc.edu Status _status; 687054SN/A 697054SN/A public: 7011096Snilay@cs.wisc.edu Status status() const { return _status; } 7111096Snilay@cs.wisc.edu 726145SN/A void setStatus(Status new_status); 739594Snilay@cs.wisc.edu 749799Snilay@cs.wisc.edu#ifdef FULL_SYSTEM 757054SN/A public: 766881SN/A KernelStats kernelStats; 7711096Snilay@cs.wisc.edu#endif 7811664Stushar@ece.gatech.edu 7911664Stushar@ece.gatech.edu public: 8011664Stushar@ece.gatech.edu RegFile regs; // correct-path register context 817054SN/A 829799Snilay@cs.wisc.edu // pointer to CPU associated with this context 836145SN/A BaseCPU *cpu; 8411096Snilay@cs.wisc.edu 8511096Snilay@cs.wisc.edu // Index of hardware thread context on the CPU that this represents. 8611096Snilay@cs.wisc.edu int thread_num; 8711096Snilay@cs.wisc.edu 8811096Snilay@cs.wisc.edu // ID of this context w.r.t. the System or Process object to which 8911096Snilay@cs.wisc.edu // it belongs. For full-system mode, this is the system CPU ID. 9011096Snilay@cs.wisc.edu int cpu_id; 9111096Snilay@cs.wisc.edu 9211096Snilay@cs.wisc.edu#ifdef FULL_SYSTEM 9311096Snilay@cs.wisc.edu 9411096Snilay@cs.wisc.edu FunctionalMemory *mem; 9511096Snilay@cs.wisc.edu AlphaItb *itb; 9611096Snilay@cs.wisc.edu AlphaDtb *dtb; 9711096Snilay@cs.wisc.edu System *system; 9811096Snilay@cs.wisc.edu 996145SN/A // the following two fields are redundant, since we can always 1008257SBrad.Beckmann@amd.com // look them up through the system pointer, but we'll leave them 1018257SBrad.Beckmann@amd.com // here for now for convenience 1026881SN/A MemoryController *memCtrl; 1038257SBrad.Beckmann@amd.com PhysicalMemory *physmem; 1046145SN/A 1056145SN/A#else 1067054SN/A Process *process; 1077054SN/A 1086145SN/A FunctionalMemory *mem; // functional storage for process address space 1097054SN/A 1107054SN/A // Address space ID. Note that this is used for TIMING cache 1117054SN/A // simulation only; all functional memory accesses should use 1126145SN/A // one of the FunctionalMemory pointers above. 1136145SN/A short asid; 1149594Snilay@cs.wisc.edu 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(Checkpoint *cp, 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