simple_thread.hh revision 2395
12SN/A/* 21762SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A */ 282665SN/A 292665SN/A#ifndef __CPU_EXEC_CONTEXT_HH__ 302SN/A#define __CPU_EXEC_CONTEXT_HH__ 312SN/A 322SN/A#include "config/full_system.hh" 332SN/A#include "mem/physical.hh" 341298SN/A#include "mem/request.hh" 351298SN/A#include "sim/host.hh" 361259SN/A#include "sim/serialize.hh" 372SN/A#include "targetarch/byte_swap.hh" 382SN/A 39146SN/Aclass Memory; 40146SN/Aclass BaseCPU; 417632SBrad.Beckmann@amd.com 428232Snate@binkert.org#if FULL_SYSTEM 433348SN/A 448229Snate@binkert.org#include "sim/system.hh" 453348SN/A#include "targetarch/alpha_memory.hh" 463348SN/A 4756SN/Aclass FunctionProfile; 48695SN/Aclass ProfileNode; 498832SAli.Saidi@ARM.comclass MemoryController; 502SN/Anamespace Kernel { class Binning; class Statistics; } 512SN/A 522SN/A#else // !FULL_SYSTEM 531298SN/A 541298SN/A#include "sim/process.hh" 553187SN/A 568975Sandreas.hansson@arm.com#endif // FULL_SYSTEM 573187SN/A 588948Sandreas.hansson@arm.com// 593187SN/A// The ExecContext object represents a functional context for 603187SN/A// instruction execution. It incorporates everything required for 613187SN/A// architecture-level functional simulation of a single thread. 623187SN/A// 633187SN/A 643187SN/Aclass ExecContext 653187SN/A{ 663187SN/A public: 673187SN/A enum Status 683262SN/A { 693349SN/A /// Initialized but not running yet. All CPUs start in 703262SN/A /// this state, but most transition to Active on cycle 1. 713262SN/A /// In MP or SMT systems, non-primary contexts will stay 723262SN/A /// in this state until a thread is assigned to them. 733262SN/A Unallocated, 748975Sandreas.hansson@arm.com 757544SN/A /// Running. Instructions should be executed only when 767544SN/A /// the context is in this state. 777544SN/A Active, 787544SN/A 797544SN/A /// Temporarily inactive. Entered while waiting for 807544SN/A /// synchronization, etc. 817544SN/A Suspended, 827544SN/A 833262SN/A /// Permanently shut down. Entered when target executes 843262SN/A /// m5exit pseudo-instruction. When all contexts enter 857544SN/A /// this state, the simulation will terminate. 867544SN/A Halted 877544SN/A }; 887544SN/A 893262SN/A private: 903262SN/A Status _status; 913262SN/A 923262SN/A public: 935034SN/A Status status() const { return _status; } 945034SN/A 952SN/A /// Set the status to Active. Optional delay indicates number of 963187SN/A /// cycles to wait before beginning execution. 973187SN/A void activate(int delay = 1); 989814Sandreas.hansson@arm.com 993187SN/A /// Set the status to Suspended. 1003187SN/A void suspend(); 1013187SN/A 1025034SN/A /// Set the status to Unallocated. 1035034SN/A void deallocate(); 1045034SN/A 1055034SN/A /// Set the status to Halted. 1067544SN/A void halt(); 1078832SAli.Saidi@ARM.com 1089814Sandreas.hansson@arm.com public: 1095034SN/A RegFile regs; // correct-path register context 1105034SN/A 1115034SN/A // pointer to CPU associated with this context 1125034SN/A BaseCPU *cpu; 1135034SN/A 1148436SBrad.Beckmann@amd.com // Current instruction 1158436SBrad.Beckmann@amd.com MachInst inst; 1162SN/A 1177544SN/A // Index of hardware thread context on the CPU that this represents. 1187544SN/A int thread_num; 1193187SN/A 1205034SN/A // ID of this context w.r.t. the System or Process object to which 1212SN/A // it belongs. For full-system mode, this is the system CPU ID. 1222SN/A int cpu_id; 1232SN/A 1242SN/A System *system; 1259814Sandreas.hansson@arm.com Memory *mem; 1269814Sandreas.hansson@arm.com 1279814Sandreas.hansson@arm.com#if FULL_SYSTEM 1282SN/A AlphaITB *itb; 1292SN/A AlphaDTB *dtb; 1302SN/A 1318436SBrad.Beckmann@amd.com // the following two fields are redundant, since we can always 1325606SN/A // look them up through the system pointer, but we'll leave them 1331298SN/A // here for now for convenience 1343187SN/A MemoryController *memctrl; 1357544SN/A// PhysicalMemory *physmem; 1363187SN/A 1373187SN/A Kernel::Binning *kernelBinning; 1389294Sandreas.hansson@arm.com Kernel::Statistics *kernelStats; 1399294Sandreas.hansson@arm.com bool bin; 1403187SN/A bool fnbin; 1413187SN/A 1428922Swilliam.wang@arm.com FunctionProfile *profile; 1433187SN/A ProfileNode *profileNode; 1448922Swilliam.wang@arm.com Addr profilePC; 1453187SN/A void dumpFuncProfile(); 1468922Swilliam.wang@arm.com 1473187SN/A#else 1483187SN/A Process *process; 1493187SN/A 1503187SN/A // Address space ID. Note that this is used for TIMING cache 1513187SN/A // simulation only; all functional memory accesses should use 1524579SN/A // one of the FunctionalMemory pointers above. 1534579SN/A short asid; 1542SN/A 1552SN/A#endif 1562SN/A 1572SN/A /** 1583349SN/A * Temporary storage to pass the source address from copy_load to 1592SN/A * copy_store. 1604628SN/A * @todo Remove this temporary when we have a better way to do it. 1614628SN/A */ 1627544SN/A Addr copySrcAddr; 1637544SN/A /** 1647544SN/A * Temp storage for the physical source address of a copy. 1657544SN/A * @todo Remove this temporary when we have a better way to do it. 1668436SBrad.Beckmann@amd.com */ 1674628SN/A Addr copySrcPhysAddr; 1688436SBrad.Beckmann@amd.com 1698436SBrad.Beckmann@amd.com 1704628SN/A /* 1713187SN/A * number of executed instructions, for matching with syscall trace 1723187SN/A * points in EIO files. 1733187SN/A */ 1743187SN/A Counter func_exe_inst; 1753187SN/A 1763187SN/A // 1771298SN/A // Count failed store conditionals so we can warn of apparent 1784628SN/A // application deadlock situations. 1794628SN/A unsigned storeCondFailures; 1801298SN/A 1811298SN/A // constructor: initialize context from given process structure 1821298SN/A#if FULL_SYSTEM 1838436SBrad.Beckmann@amd.com ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 1848436SBrad.Beckmann@amd.com AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); 1859301Snilay@cs.wisc.edu#else 1868436SBrad.Beckmann@amd.com ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 1872SN/A Memory *_mem, Process *_process, int _asid); 1888436SBrad.Beckmann@amd.com#endif 1898436SBrad.Beckmann@amd.com virtual ~ExecContext(); 1908436SBrad.Beckmann@amd.com 1918436SBrad.Beckmann@amd.com virtual void takeOverFrom(ExecContext *oldContext); 1928436SBrad.Beckmann@amd.com 1938436SBrad.Beckmann@amd.com void regStats(const std::string &name); 1948436SBrad.Beckmann@amd.com 1958436SBrad.Beckmann@amd.com void serialize(std::ostream &os); 1962SN/A void unserialize(Checkpoint *cp, const std::string §ion); 1978436SBrad.Beckmann@amd.com 1988436SBrad.Beckmann@amd.com#if FULL_SYSTEM 1992SN/A bool validInstAddr(Addr addr) { return true; } 2008436SBrad.Beckmann@amd.com bool validDataAddr(Addr addr) { return true; } 2018436SBrad.Beckmann@amd.com int getInstAsid() { return regs.instAsid(); } 2028436SBrad.Beckmann@amd.com int getDataAsid() { return regs.dataAsid(); } 2038436SBrad.Beckmann@amd.com 2048436SBrad.Beckmann@amd.com Fault translateInstReq(CpuRequestPtr &req) 2058436SBrad.Beckmann@amd.com { 2068436SBrad.Beckmann@amd.com return itb->translate(req); 2078436SBrad.Beckmann@amd.com } 2088436SBrad.Beckmann@amd.com 2098436SBrad.Beckmann@amd.com Fault translateDataReadReq(CpuRequestPtr &req) 2108853Sandreas.hansson@arm.com { 2118436SBrad.Beckmann@amd.com return dtb->translate(req, false); 2128436SBrad.Beckmann@amd.com } 2132SN/A 2142SN/A Fault translateDataWriteReq(CpuRequestPtr &req) 2152SN/A { 2162SN/A return dtb->translate(req, true); 2173187SN/A } 2182SN/A 2193187SN/A#else 2203187SN/A bool validInstAddr(Addr addr) 2212SN/A { return process->validInstAddr(addr); } 2222SN/A 2232SN/A bool validDataAddr(Addr addr) 2242SN/A { return process->validDataAddr(addr); } 2252SN/A 226729SN/A int getInstAsid() { return asid; } 2272SN/A int getDataAsid() { return asid; } 228695SN/A 2292SN/A Fault translateInstReq(CpuRequestPtr &req) 2302SN/A { 2312SN/A return process->pTable->translate(req); 2322SN/A } 233695SN/A 2342SN/A Fault translateDataReadReq(CpuRequestPtr &req) 2352SN/A { 2362SN/A return process->pTable->translate(req); 2372SN/A } 238695SN/A 2392SN/A Fault translateDataWriteReq(CpuRequestPtr &req) 2402SN/A { 2412SN/A return process->pTable->translate(req); 2422SN/A } 2432SN/A 2442SN/A#endif 2452SN/A 2462SN/A template <class T> 2472SN/A Fault read(CpuRequestPtr &req, T &data) 2489180Sandreas.hansson@arm.com { 2492SN/A#if FULL_SYSTEM && defined(TARGET_ALPHA) 2501298SN/A if (req->flags & LOCKED) { 2517544SN/A MiscRegFile *cregs = &req->xc->regs.miscRegs; 2527544SN/A cregs->lock_addr = req->paddr; 2537544SN/A cregs->lock_flag = true; 2547823Ssteve.reinhardt@amd.com } 2552SN/A#endif 2562SN/A 2572SN/A Fault error; 2587544SN/A error = mem->prot_read(req->paddr, data, req->size); 2597544SN/A data = gtoh(data); 2602SN/A return error; 2612SN/A } 2622SN/A 2632SN/A template <class T> 2641899SN/A Fault write(CpuRequestPtr &req, T &data) 2651899SN/A { 2662SN/A#if FULL_SYSTEM && defined(TARGET_ALPHA) 2672SN/A 2682SN/A MiscRegFile *cregs; 2695736SN/A 2702SN/A // If this is a store conditional, act appropriately 2717544SN/A if (req->flags & LOCKED) { 2727544SN/A cregs = &req->xc->regs.miscRegs; 2731298SN/A 2741298SN/A if (req->flags & UNCACHEABLE) { 2753187SN/A // Don't update result register (see stq_c in isa_desc) 2763187SN/A req->result = 2; 2774628SN/A req->xc->storeCondFailures = 0;//Needed? [RGD] 2783187SN/A } else { 2793187SN/A req->result = cregs->lock_flag; 2807544SN/A if (!cregs->lock_flag || 2811298SN/A ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) { 2825736SN/A cregs->lock_flag = false; 2833187SN/A if (((++req->xc->storeCondFailures) % 100000) == 0) { 2842SN/A std::cerr << "Warning: " 2855736SN/A << req->xc->storeCondFailures 2865736SN/A << " consecutive store conditional failures " 2873187SN/A << "on cpu " << req->xc->cpu_id 2887544SN/A << std::endl; 2893187SN/A } 2902SN/A return No_Fault; 2919301Snilay@cs.wisc.edu } 2929301Snilay@cs.wisc.edu else req->xc->storeCondFailures = 0; 2939301Snilay@cs.wisc.edu } 2949301Snilay@cs.wisc.edu } 2959301Snilay@cs.wisc.edu 2969301Snilay@cs.wisc.edu // Need to clear any locked flags on other proccessors for 2979301Snilay@cs.wisc.edu // this address. Only do this for succsful Store Conditionals 2989301Snilay@cs.wisc.edu // and all other stores (WH64?). Unsuccessful Store 2997657Ssteve.reinhardt@amd.com // Conditionals would have returned above, and wouldn't fall 3009301Snilay@cs.wisc.edu // through. 3019301Snilay@cs.wisc.edu for (int i = 0; i < system->execContexts.size(); i++){ 3022SN/A cregs = &system->execContexts[i]->regs.miscRegs; 3037544SN/A if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) { 3047544SN/A cregs->lock_flag = false; 3058832SAli.Saidi@ARM.com } 3067544SN/A } 3077544SN/A 3087544SN/A#endif 3098832SAli.Saidi@ARM.com return mem->prot_write(req->paddr, (T)htog(data), req->size); 3107544SN/A } 3117544SN/A 3127544SN/A virtual bool misspeculating(); 3133187SN/A 3142SN/A 3152SN/A MachInst getInst() { return inst; } 3164628SN/A 3171298SN/A void setInst(MachInst new_inst) 3183187SN/A { 3198853Sandreas.hansson@arm.com inst = new_inst; 3203187SN/A } 3214628SN/A 3227657Ssteve.reinhardt@amd.com Fault instRead(CpuRequestPtr &req) 3237657Ssteve.reinhardt@amd.com { 3247657Ssteve.reinhardt@amd.com panic("instRead not implemented"); 3253187SN/A // return funcPhysMem->read(req, inst); 3268949Sandreas.hansson@arm.com return No_Fault; 3273187SN/A } 3283187SN/A 3293187SN/A // 3303187SN/A // New accessors for new decoder. 3317657Ssteve.reinhardt@amd.com // 3328436SBrad.Beckmann@amd.com uint64_t readIntReg(int reg_idx) 3338436SBrad.Beckmann@amd.com { 3343187SN/A return regs.intRegFile[reg_idx]; 3353204SN/A } 336145SN/A 3373262SN/A float readFloatRegSingle(int reg_idx) 338145SN/A { 3393187SN/A return (float)regs.floatRegFile.d[reg_idx]; 3402SN/A } 3414628SN/A 3421298SN/A double readFloatRegDouble(int reg_idx) 3437657Ssteve.reinhardt@amd.com { 3447657Ssteve.reinhardt@amd.com return regs.floatRegFile.d[reg_idx]; 3457657Ssteve.reinhardt@amd.com } 3464628SN/A 3478949Sandreas.hansson@arm.com uint64_t readFloatRegInt(int reg_idx) 3483187SN/A { 3493187SN/A return regs.floatRegFile.q[reg_idx]; 3503187SN/A } 3513187SN/A 3523187SN/A void setIntReg(int reg_idx, uint64_t val) 3533187SN/A { 3547657Ssteve.reinhardt@amd.com regs.intRegFile[reg_idx] = val; 3558436SBrad.Beckmann@amd.com } 3563187SN/A 3573262SN/A void setFloatRegSingle(int reg_idx, float val) 358145SN/A { 3593262SN/A regs.floatRegFile.d[reg_idx] = (double)val; 360145SN/A } 3613187SN/A 3622SN/A void setFloatRegDouble(int reg_idx, double val) 3632SN/A { 3642SN/A regs.floatRegFile.d[reg_idx] = val; 3653187SN/A } 3662SN/A 3678975Sandreas.hansson@arm.com void setFloatRegInt(int reg_idx, uint64_t val) 3687544SN/A { 3693187SN/A regs.floatRegFile.q[reg_idx] = val; 3703187SN/A } 3713187SN/A 3722SN/A uint64_t readPC() 3732SN/A { 3745314SN/A return regs.pc; 3755314SN/A } 3765314SN/A 3775314SN/A void setNextPC(uint64_t val) 3785314SN/A { 3795314SN/A regs.npc = val; 3805315SN/A } 3815315SN/A 3825315SN/A uint64_t readUniq() 3835315SN/A { 3845315SN/A return regs.miscRegs.uniq; 3855315SN/A } 3865315SN/A 387 void setUniq(uint64_t val) 388 { 389 regs.miscRegs.uniq = val; 390 } 391 392 uint64_t readFpcr() 393 { 394 return regs.miscRegs.fpcr; 395 } 396 397 void setFpcr(uint64_t val) 398 { 399 regs.miscRegs.fpcr = val; 400 } 401 402#if FULL_SYSTEM 403 uint64_t readIpr(int idx, Fault &fault); 404 Fault setIpr(int idx, uint64_t val); 405 int readIntrFlag() { return regs.intrflag; } 406 void setIntrFlag(int val) { regs.intrflag = val; } 407 Fault hwrei(); 408 bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } 409 void ev5_trap(Fault fault); 410 bool simPalCheck(int palFunc); 411#endif 412 413 /** Meant to be more generic trap function to be 414 * called when an instruction faults. 415 * @param fault The fault generated by executing the instruction. 416 * @todo How to do this properly so it's dependent upon ISA only? 417 */ 418 419 void trap(Fault fault); 420 421#if !FULL_SYSTEM 422 IntReg getSyscallArg(int i) 423 { 424 return regs.intRegFile[ArgumentReg0 + i]; 425 } 426 427 // used to shift args for indirect syscall 428 void setSyscallArg(int i, IntReg val) 429 { 430 regs.intRegFile[ArgumentReg0 + i] = val; 431 } 432 433 void setSyscallReturn(SyscallReturn return_value) 434 { 435 // check for error condition. Alpha syscall convention is to 436 // indicate success/failure in reg a3 (r19) and put the 437 // return value itself in the standard return value reg (v0). 438 const int RegA3 = 19; // only place this is used 439 if (return_value.successful()) { 440 // no error 441 regs.intRegFile[RegA3] = 0; 442 regs.intRegFile[ReturnValueReg] = return_value.value(); 443 } else { 444 // got an error, return details 445 regs.intRegFile[RegA3] = (IntReg) -1; 446 regs.intRegFile[ReturnValueReg] = -return_value.value(); 447 } 448 } 449 450 void syscall() 451 { 452 process->syscall(this); 453 } 454#endif 455}; 456 457 458// for non-speculative execution context, spec_mode is always false 459inline bool 460ExecContext::misspeculating() 461{ 462 return false; 463} 464 465#endif // __CPU_EXEC_CONTEXT_HH__ 466