thread_context.hh revision 2159
11689SN/A/* 22326SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 291689SN/A#ifndef __CPU_EXEC_CONTEXT_HH__ 301689SN/A#define __CPU_EXEC_CONTEXT_HH__ 311060SN/A 321060SN/A#include "config/full_system.hh" 331689SN/A#include "mem/functional/functional.hh" 341060SN/A#include "mem/mem_req.hh" 351060SN/A#include "sim/host.hh" 361060SN/A#include "sim/serialize.hh" 371060SN/A#include "arch/isa_traits.hh" 386658Snate@binkert.org//#include "arch/isa_registers.hh" 392292SN/A#include "sim/byteswap.hh" 401717SN/A 415529Snate@binkert.org// forward declaration: see functional_memory.hh 421060SN/Aclass FunctionalMemory; 436221Snate@binkert.orgclass PhysicalMemory; 446221Snate@binkert.orgclass BaseCPU; 451681SN/A 465529Snate@binkert.org#if FULL_SYSTEM 472873Sktlim@umich.edu 484329Sktlim@umich.edu#include "sim/system.hh" 494329Sktlim@umich.edu#include "targetarch/alpha_memory.hh" 504329Sktlim@umich.edu 512292SN/Aclass FunctionProfile; 522292SN/Aclass ProfileNode; 532292SN/Aclass MemoryController; 542292SN/Anamespace Kernel { class Binning; class Statistics; } 552820Sktlim@umich.edu 562292SN/A#else // !FULL_SYSTEM 572820Sktlim@umich.edu 582820Sktlim@umich.edu#include "sim/process.hh" 595529Snate@binkert.org 602307SN/A#endif // FULL_SYSTEM 611060SN/A 622292SN/A// 632292SN/A// The ExecContext object represents a functional context for 642292SN/A// instruction execution. It incorporates everything required for 651060SN/A// architecture-level functional simulation of a single thread. 661060SN/A// 671060SN/A 681060SN/Aclass ExecContext 691060SN/A{ 701060SN/A protected: 711681SN/A typedef TheISA::RegFile RegFile; 726221Snate@binkert.org typedef TheISA::MachInst MachInst; 736221Snate@binkert.org typedef TheISA::MiscRegFile MiscRegFile; 746221Snate@binkert.org typedef TheISA::MiscReg MiscReg; 756221Snate@binkert.org public: 762292SN/A enum Status 772292SN/A { 782820Sktlim@umich.edu /// Initialized but not running yet. All CPUs start in 792820Sktlim@umich.edu /// this state, but most transition to Active on cycle 1. 802292SN/A /// In MP or SMT systems, non-primary contexts will stay 812292SN/A /// in this state until a thread is assigned to them. 822820Sktlim@umich.edu Unallocated, 832820Sktlim@umich.edu 842292SN/A /// Running. Instructions should be executed only when 852292SN/A /// the context is in this state. 862292SN/A Active, 872292SN/A 882292SN/A /// Temporarily inactive. Entered while waiting for 892292SN/A /// initialization,synchronization, etc. 902292SN/A Suspended, 912292SN/A 921060SN/A /// Permanently shut down. Entered when target executes 931060SN/A /// m5exit pseudo-instruction. When all contexts enter 941681SN/A /// this state, the simulation will terminate. 951062SN/A Halted 962292SN/A }; 971062SN/A 982301SN/A private: 992301SN/A Status _status; 1001062SN/A 1012727Sktlim@umich.edu public: 1021062SN/A Status status() const { return _status; } 1031062SN/A 1041062SN/A void setStatus(Status newStatus) { _status = newStatus; } 1051062SN/A 1061062SN/A /// Set the status to Active. Optional delay indicates number of 1071062SN/A /// cycles to wait before beginning execution. 1081062SN/A void activate(int delay = 1); 1091062SN/A 1101062SN/A /// Set the status to Suspended. 1111062SN/A void suspend(); 1121062SN/A 1131062SN/A /// Set the status to Unallocated. 1141062SN/A void deallocate(); 1151062SN/A 1161062SN/A /// Set the status to Halted. 1171062SN/A void halt(); 1181062SN/A 1191062SN/A public: 1201062SN/A RegFile regs; // correct-path register context 1211062SN/A 1221062SN/A // pointer to CPU associated with this context 1231062SN/A BaseCPU *cpu; 1241062SN/A 1251062SN/A // Current instruction 1261062SN/A MachInst inst; 1271062SN/A 1281062SN/A // Index of hardware thread context on the CPU that this represents. 1291062SN/A int thread_num; 1301062SN/A 1311062SN/A // ID of this context w.r.t. the System or Process object to which 1321062SN/A // it belongs. For full-system mode, this is the system CPU ID. 1331062SN/A int cpu_id; 1341062SN/A 1351062SN/A#if FULL_SYSTEM 1361062SN/A FunctionalMemory *mem; 1371062SN/A AlphaITB *itb; 1381062SN/A AlphaDTB *dtb; 1391062SN/A System *system; 1401062SN/A 1411062SN/A // the following two fields are redundant, since we can always 1421062SN/A // look them up through the system pointer, but we'll leave them 1432292SN/A // here for now for convenience 1442292SN/A MemoryController *memctrl; 1452292SN/A PhysicalMemory *physmem; 1462292SN/A 1471062SN/A Kernel::Binning *kernelBinning; 1481062SN/A Kernel::Statistics *kernelStats; 1491062SN/A bool bin; 1501062SN/A bool fnbin; 1511062SN/A 1521062SN/A FunctionProfile *profile; 1531062SN/A ProfileNode *profileNode; 1542292SN/A Addr profilePC; 1552292SN/A void dumpFuncProfile(); 1562292SN/A 1572292SN/A#else 1582292SN/A Process *process; 1592292SN/A 1602292SN/A FunctionalMemory *mem; // functional storage for process address space 1612292SN/A 1622292SN/A // Address space ID. Note that this is used for TIMING cache 1632292SN/A // simulation only; all functional memory accesses should use 1642301SN/A // one of the FunctionalMemory pointers above. 1652727Sktlim@umich.edu short asid; 1662353SN/A 1672727Sktlim@umich.edu#endif 1682727Sktlim@umich.edu 1692727Sktlim@umich.edu /** 1706221Snate@binkert.org * Temporary storage to pass the source address from copy_load to 1712353SN/A * copy_store. 1722727Sktlim@umich.edu * @todo Remove this temporary when we have a better way to do it. 1732727Sktlim@umich.edu */ 1742727Sktlim@umich.edu Addr copySrcAddr; 1752727Sktlim@umich.edu /** 1762353SN/A * Temp storage for the physical source address of a copy. 1772727Sktlim@umich.edu * @todo Remove this temporary when we have a better way to do it. 1782727Sktlim@umich.edu */ 1792727Sktlim@umich.edu Addr copySrcPhysAddr; 1806221Snate@binkert.org 1812301SN/A 1822301SN/A /* 1832727Sktlim@umich.edu * number of executed instructions, for matching with syscall trace 1842301SN/A * points in EIO files. 1852727Sktlim@umich.edu */ 1866221Snate@binkert.org Counter func_exe_inst; 1872301SN/A 1882301SN/A // 1892727Sktlim@umich.edu // Count failed store conditionals so we can warn of apparent 1902301SN/A // application deadlock situations. 1912727Sktlim@umich.edu unsigned storeCondFailures; 1926221Snate@binkert.org 1932301SN/A // constructor: initialize context from given process structure 1942301SN/A#if FULL_SYSTEM 1952727Sktlim@umich.edu ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, 1962301SN/A AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); 1972727Sktlim@umich.edu#else 1986221Snate@binkert.org ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); 1992301SN/A ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, 2002301SN/A int _asid); 2012727Sktlim@umich.edu#endif 2022301SN/A virtual ~ExecContext(); 2032301SN/A 2042301SN/A virtual void takeOverFrom(ExecContext *oldContext); 2052301SN/A 2062727Sktlim@umich.edu void regStats(const std::string &name); 2072727Sktlim@umich.edu 2082727Sktlim@umich.edu void serialize(std::ostream &os); 2092727Sktlim@umich.edu void unserialize(Checkpoint *cp, const std::string §ion); 2102727Sktlim@umich.edu 2112727Sktlim@umich.edu#if FULL_SYSTEM 2122727Sktlim@umich.edu bool validInstAddr(Addr addr) { return true; } 2132727Sktlim@umich.edu bool validDataAddr(Addr addr) { return true; } 2142727Sktlim@umich.edu int getInstAsid() { return regs.instAsid(); } 2152301SN/A int getDataAsid() { return regs.dataAsid(); } 2162301SN/A 2176221Snate@binkert.org Fault translateInstReq(MemReqPtr &req) 2182301SN/A { 2192301SN/A return itb->translate(req); 2202727Sktlim@umich.edu } 2212301SN/A 2222326SN/A Fault translateDataReadReq(MemReqPtr &req) 2236221Snate@binkert.org { 2242301SN/A return dtb->translate(req, false); 2252301SN/A } 2262727Sktlim@umich.edu 2272301SN/A Fault translateDataWriteReq(MemReqPtr &req) 2282326SN/A { 2296221Snate@binkert.org return dtb->translate(req, true); 2302301SN/A } 2312301SN/A 2322727Sktlim@umich.edu#else 2332301SN/A bool validInstAddr(Addr addr) 2342326SN/A { return process->validInstAddr(addr); } 2356221Snate@binkert.org 2362301SN/A bool validDataAddr(Addr addr) 2372301SN/A { return process->validDataAddr(addr); } 2382727Sktlim@umich.edu 2392301SN/A int getInstAsid() { return asid; } 2402326SN/A int getDataAsid() { return asid; } 2416221Snate@binkert.org 2422301SN/A Fault dummyTranslation(MemReqPtr &req) 2432301SN/A { 2442727Sktlim@umich.edu#if 0 2452301SN/A assert((req->vaddr >> 48 & 0xffff) == 0); 2462326SN/A#endif 2472301SN/A 2482301SN/A // put the asid in the upper 16 bits of the paddr 2492727Sktlim@umich.edu req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); 2502301SN/A req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; 2512326SN/A return NoFault; 2522301SN/A } 2532326SN/A Fault translateInstReq(MemReqPtr &req) 2542301SN/A { 2552301SN/A return dummyTranslation(req); 2562727Sktlim@umich.edu } 2572301SN/A Fault translateDataReadReq(MemReqPtr &req) 2582326SN/A { 2592301SN/A return dummyTranslation(req); 2602326SN/A } 2612301SN/A Fault translateDataWriteReq(MemReqPtr &req) 2622301SN/A { 2632727Sktlim@umich.edu return dummyTranslation(req); 2642326SN/A } 2651062SN/A 2661062SN/A#endif 2671681SN/A 2681060SN/A template <class T> 2692292SN/A Fault read(MemReqPtr &req, T &data) 2701060SN/A { 2716221Snate@binkert.org#if FULL_SYSTEM && defined(TARGET_ALPHA) 2722292SN/A if (req->flags & LOCKED) { 2732292SN/A MiscRegFile *cregs = &req->xc->regs.miscRegs; 2742292SN/A cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); 2752292SN/A cregs->setReg(TheISA::Lock_Flag_DepTag, true); 2762292SN/A } 2772292SN/A#endif 2782292SN/A 2792292SN/A Fault error; 2802292SN/A error = mem->read(req, data); 2812733Sktlim@umich.edu data = LittleEndianGuest::gtoh(data); 2821060SN/A return error; 2831060SN/A } 2841681SN/A 2851060SN/A template <class T> 2862292SN/A Fault write(MemReqPtr &req, T &data) 2871060SN/A { 2881060SN/A#if FULL_SYSTEM && defined(TARGET_ALPHA) 2891060SN/A 2901060SN/A MiscRegFile *cregs; 2911060SN/A 2921060SN/A // If this is a store conditional, act appropriately 2931060SN/A if (req->flags & LOCKED) { 2941060SN/A cregs = &req->xc->regs.miscRegs; 2951060SN/A 2962292SN/A if (req->flags & UNCACHEABLE) { 2972292SN/A // Don't update result register (see stq_c in isa_desc) 2981060SN/A req->result = 2; 2991060SN/A req->xc->storeCondFailures = 0;//Needed? [RGD] 3001060SN/A } else { 3011060SN/A bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); 3021681SN/A Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); 3031060SN/A req->result = lock_flag; 3042292SN/A if (!lock_flag || 3051060SN/A ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { 3061060SN/A cregs->setReg(TheISA::Lock_Flag_DepTag, false); 3071060SN/A if (((++req->xc->storeCondFailures) % 100000) == 0) { 3081060SN/A std::cerr << "Warning: " 3091060SN/A << req->xc->storeCondFailures 3101060SN/A << " consecutive store conditional failures " 3111060SN/A << "on cpu " << req->xc->cpu_id 3121681SN/A << std::endl; 3131060SN/A } 3142292SN/A return NoFault; 3151060SN/A } 3161060SN/A else req->xc->storeCondFailures = 0; 3171060SN/A } 3181060SN/A } 3191060SN/A 3201060SN/A // Need to clear any locked flags on other proccessors for 3211060SN/A // this address. Only do this for succsful Store Conditionals 3221681SN/A // and all other stores (WH64?). Unsuccessful Store 3231060SN/A // Conditionals would have returned above, and wouldn't fall 3246221Snate@binkert.org // through. 3251060SN/A for (int i = 0; i < system->execContexts.size(); i++){ 3262292SN/A cregs = &system->execContexts[i]->regs.miscRegs; 3272292SN/A if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == 3282292SN/A (req->paddr & ~0xf)) { 3292292SN/A cregs->setReg(TheISA::Lock_Flag_DepTag, false); 3301060SN/A } 3311060SN/A } 3321681SN/A 3331060SN/A#endif 3342292SN/A return mem->write(req, (T)LittleEndianGuest::htog(data)); 3351060SN/A } 3362292SN/A 3371060SN/A virtual bool misspeculating(); 3381060SN/A 3392307SN/A 3402863Sktlim@umich.edu MachInst getInst() { return inst; } 3412843Sktlim@umich.edu 3422307SN/A void setInst(MachInst new_inst) 3432843Sktlim@umich.edu { 3442843Sktlim@umich.edu inst = new_inst; 3452863Sktlim@umich.edu } 3461681SN/A 3471681SN/A Fault instRead(MemReqPtr &req) 3482316SN/A { 3491681SN/A return mem->read(req, inst); 3502843Sktlim@umich.edu } 3512843Sktlim@umich.edu 3522843Sktlim@umich.edu // 3532843Sktlim@umich.edu // New accessors for new decoder. 3542843Sktlim@umich.edu // 3552843Sktlim@umich.edu uint64_t readIntReg(int reg_idx) 3562843Sktlim@umich.edu { 3571681SN/A return regs.intRegFile[reg_idx]; 3582348SN/A } 3592307SN/A 3602367SN/A float readFloatRegSingle(int reg_idx) 3612367SN/A { 3621681SN/A return (float)regs.floatRegFile.d[reg_idx]; 3632307SN/A } 3642307SN/A 3652307SN/A double readFloatRegDouble(int reg_idx) 3662307SN/A { 3676221Snate@binkert.org return regs.floatRegFile.d[reg_idx]; 3686221Snate@binkert.org } 3696221Snate@binkert.org 3706221Snate@binkert.org uint64_t readFloatRegInt(int reg_idx) 3716221Snate@binkert.org { 3722307SN/A return regs.floatRegFile.q[reg_idx]; 3731681SN/A } 3741681SN/A 3752307SN/A void setIntReg(int reg_idx, uint64_t val) 3761681SN/A { 3772307SN/A regs.intRegFile[reg_idx] = val; 3781060SN/A } 3792348SN/A 3802307SN/A void setFloatRegSingle(int reg_idx, float val) 3812307SN/A { 3822307SN/A regs.floatRegFile.d[reg_idx] = (double)val; 3832307SN/A } 3841060SN/A 3852307SN/A void setFloatRegDouble(int reg_idx, double val) 3862307SN/A { 3872307SN/A regs.floatRegFile.d[reg_idx] = val; 3881060SN/A } 3892307SN/A 3902307SN/A void setFloatRegInt(int reg_idx, uint64_t val) 3911060SN/A { 3926221Snate@binkert.org regs.floatRegFile.q[reg_idx] = val; 3936221Snate@binkert.org } 3946221Snate@binkert.org 3956221Snate@binkert.org uint64_t readPC() 3962307SN/A { 3971060SN/A return regs.pc; 3982307SN/A } 3992307SN/A 4002873Sktlim@umich.edu void setNextPC(uint64_t val) 4012307SN/A { 4021060SN/A regs.npc = val; 4031060SN/A } 4041060SN/A 4051681SN/A MiscReg readMiscReg(int misc_reg) 4061060SN/A { 4076221Snate@binkert.org return regs.miscRegs.readReg(misc_reg); 4082107SN/A } 4096221Snate@binkert.org 4102107SN/A MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) 4112292SN/A { 4122292SN/A return regs.miscRegs.readRegWithEffect(misc_reg, fault, this); 4132107SN/A } 4142292SN/A 4152326SN/A Fault setMiscReg(int misc_reg, const MiscReg &val) 4162292SN/A { 4172107SN/A return regs.miscRegs.setReg(misc_reg, val); 4182292SN/A } 4192935Sksewell@umich.edu 4204632Sgblack@eecs.umich.edu Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) 4212935Sksewell@umich.edu { 4222292SN/A return regs.miscRegs.setRegWithEffect(misc_reg, val, this); 4232292SN/A } 4242292SN/A 4252292SN/A#if FULL_SYSTEM 4262292SN/A int readIntrFlag() { return regs.intrflag; } 4272107SN/A void setIntrFlag(int val) { regs.intrflag = val; } 4282292SN/A Fault hwrei(); 4292107SN/A bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } 4302292SN/A void ev5_trap(Fault fault); 4312292SN/A bool simPalCheck(int palFunc); 4322107SN/A#endif 4332702Sktlim@umich.edu 4342107SN/A /** Meant to be more generic trap function to be 4352107SN/A * called when an instruction faults. 4362107SN/A * @param fault The fault generated by executing the instruction. 4372107SN/A * @todo How to do this properly so it's dependent upon ISA only? 4386221Snate@binkert.org */ 4392292SN/A 4402292SN/A void trap(Fault fault); 4412292SN/A 4422292SN/A#if !FULL_SYSTEM 4432292SN/A TheISA::IntReg getSyscallArg(int i) 4442292SN/A { 4452292SN/A return regs.intRegFile[TheISA::ArgumentReg0 + i]; 4462292SN/A } 4472935Sksewell@umich.edu 4484632Sgblack@eecs.umich.edu // used to shift args for indirect syscall 4493969Sgblack@eecs.umich.edu void setSyscallArg(int i, TheISA::IntReg val) 4504632Sgblack@eecs.umich.edu { 4513795Sgblack@eecs.umich.edu regs.intRegFile[TheISA::ArgumentReg0 + i] = val; 4523795Sgblack@eecs.umich.edu } 4533795Sgblack@eecs.umich.edu 4543093Sksewell@umich.edu void setSyscallReturn(SyscallReturn return_value) 4553093Sksewell@umich.edu { 4563093Sksewell@umich.edu // check for error condition. Alpha syscall convention is to 4574632Sgblack@eecs.umich.edu // indicate success/failure in reg a3 (r19) and put the 4583093Sksewell@umich.edu // return value itself in the standard return value reg (v0). 4594632Sgblack@eecs.umich.edu const int RegA3 = 19; // only place this is used 4604636Sgblack@eecs.umich.edu if (return_value.successful()) { 4612292SN/A // no error 4622292SN/A regs.intRegFile[RegA3] = 0; 4632292SN/A regs.intRegFile[TheISA::ReturnValueReg] = return_value.value(); 4642292SN/A } else { 4652292SN/A // got an error, return details 4662292SN/A regs.intRegFile[RegA3] = (TheISA::IntReg) -1; 4672292SN/A regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value(); 4682292SN/A } 4696221Snate@binkert.org } 4702292SN/A 4712292SN/A void syscall() 4722292SN/A { 4732292SN/A process->syscall(this); 4742292SN/A } 4752292SN/A#endif 4762292SN/A}; 4773795Sgblack@eecs.umich.edu 4783732Sktlim@umich.edu 4792292SN/A// for non-speculative execution context, spec_mode is always false 4802292SN/Ainline bool 4812292SN/AExecContext::misspeculating() 4822292SN/A{ 4832292SN/A return false; 4842292SN/A} 4852292SN/A 4862292SN/A#endif // __CPU_EXEC_CONTEXT_HH__ 4876221Snate@binkert.org