simple_thread.hh revision 8793
112837Sgabeblack@google.com/* 212837Sgabeblack@google.com * Copyright (c) 2001-2006 The Regents of The University of Michigan 312837Sgabeblack@google.com * All rights reserved. 412837Sgabeblack@google.com * 512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412837Sgabeblack@google.com * this software without specific prior written permission. 1512837Sgabeblack@google.com * 1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712837Sgabeblack@google.com * 2812837Sgabeblack@google.com * Authors: Steve Reinhardt 2912837Sgabeblack@google.com * Nathan Binkert 3012837Sgabeblack@google.com */ 3112837Sgabeblack@google.com 3212837Sgabeblack@google.com#ifndef __CPU_SIMPLE_THREAD_HH__ 3312837Sgabeblack@google.com#define __CPU_SIMPLE_THREAD_HH__ 3412837Sgabeblack@google.com 3512837Sgabeblack@google.com#include "arch/isa.hh" 3613087Sgabeblack@google.com#include "arch/isa_traits.hh" 3712837Sgabeblack@google.com#include "arch/registers.hh" 3812837Sgabeblack@google.com#include "arch/tlb.hh" 3912837Sgabeblack@google.com#include "arch/types.hh" 4012914Sgabeblack@google.com#include "base/types.hh" 4112914Sgabeblack@google.com#include "config/full_system.hh" 4212914Sgabeblack@google.com#include "config/the_isa.hh" 4312914Sgabeblack@google.com#include "cpu/decode.hh" 4412914Sgabeblack@google.com#include "cpu/thread_context.hh" 4512914Sgabeblack@google.com#include "cpu/thread_state.hh" 4612914Sgabeblack@google.com#include "debug/FloatRegs.hh" 4712951Sgabeblack@google.com#include "debug/IntRegs.hh" 4812951Sgabeblack@google.com#include "mem/page_table.hh" 4912951Sgabeblack@google.com#include "mem/request.hh" 5012982Sgabeblack@google.com#include "sim/byteswap.hh" 5112951Sgabeblack@google.com#include "sim/eventq.hh" 5212952Sgabeblack@google.com#include "sim/process.hh" 5312952Sgabeblack@google.com#include "sim/serialize.hh" 5412952Sgabeblack@google.com#include "sim/system.hh" 5512952Sgabeblack@google.com 5612952Sgabeblack@google.comclass BaseCPU; 5712952Sgabeblack@google.com 5812951Sgabeblack@google.com 5912951Sgabeblack@google.comclass FunctionProfile; 6012951Sgabeblack@google.comclass ProfileNode; 6112837Sgabeblack@google.comclass FunctionalPort; 6212837Sgabeblack@google.comclass PhysicalPort; 6312837Sgabeblack@google.comclass TranslatingPort; 6412837Sgabeblack@google.com 6512837Sgabeblack@google.comnamespace TheISA { 6612837Sgabeblack@google.com namespace Kernel { 6712837Sgabeblack@google.com class Statistics; 6812837Sgabeblack@google.com }; 6912837Sgabeblack@google.com}; 7012837Sgabeblack@google.com 7112837Sgabeblack@google.com/** 7212837Sgabeblack@google.com * The SimpleThread object provides a combination of the ThreadState 7312837Sgabeblack@google.com * object and the ThreadContext interface. It implements the 7412837Sgabeblack@google.com * ThreadContext interface so that a ProxyThreadContext class can be 7512837Sgabeblack@google.com * made using SimpleThread as the template parameter (see 7612837Sgabeblack@google.com * thread_context.hh). It adds to the ThreadState object by adding all 7712837Sgabeblack@google.com * the objects needed for simple functional execution, including a 7812837Sgabeblack@google.com * simple architectural register file, and pointers to the ITB and DTB 7912837Sgabeblack@google.com * in full system mode. For CPU models that do not need more advanced 8012951Sgabeblack@google.com * ways to hold state (i.e. a separate physical register file, or 8113091Sgabeblack@google.com * separate fetch and commit PC's), this SimpleThread class provides 8213091Sgabeblack@google.com * all the necessary state for full architecture-level functional 8312951Sgabeblack@google.com * simulation. See the AtomicSimpleCPU or TimingSimpleCPU for 8412837Sgabeblack@google.com * examples. 8513382Sgabeblack@google.com */ 8613091Sgabeblack@google.com 8713091Sgabeblack@google.comclass SimpleThread : public ThreadState 8813091Sgabeblack@google.com{ 8913091Sgabeblack@google.com protected: 9013091Sgabeblack@google.com typedef TheISA::MachInst MachInst; 9112837Sgabeblack@google.com typedef TheISA::MiscReg MiscReg; 9212837Sgabeblack@google.com typedef TheISA::FloatReg FloatReg; 9312837Sgabeblack@google.com typedef TheISA::FloatRegBits FloatRegBits; 9412837Sgabeblack@google.com public: 9512837Sgabeblack@google.com typedef ThreadContext::Status Status; 9612837Sgabeblack@google.com 9712837Sgabeblack@google.com protected: 9812982Sgabeblack@google.com union { 9913191Sgabeblack@google.com FloatReg f[TheISA::NumFloatRegs]; 10012982Sgabeblack@google.com FloatRegBits i[TheISA::NumFloatRegs]; 10112837Sgabeblack@google.com } floatRegs; 10212837Sgabeblack@google.com TheISA::IntReg intRegs[TheISA::NumIntRegs]; 10312951Sgabeblack@google.com TheISA::ISA isa; // one "instance" of the current ISA. 10412837Sgabeblack@google.com 10512837Sgabeblack@google.com TheISA::PCState _pcState; 10612837Sgabeblack@google.com 10712837Sgabeblack@google.com /** Did this instruction execute or is it predicated false */ 10812837Sgabeblack@google.com bool predicate; 10912837Sgabeblack@google.com 11012837Sgabeblack@google.com public: 11112837Sgabeblack@google.com std::string name() const 11212837Sgabeblack@google.com { 11312837Sgabeblack@google.com return csprintf("%s.[tid:%i]", cpu->name(), tc->threadId()); 11412837Sgabeblack@google.com } 11512837Sgabeblack@google.com 11612837Sgabeblack@google.com // pointer to CPU associated with this SimpleThread 11712837Sgabeblack@google.com BaseCPU *cpu; 11812837Sgabeblack@google.com 11912837Sgabeblack@google.com ProxyThreadContext<SimpleThread> *tc; 12012837Sgabeblack@google.com 12112837Sgabeblack@google.com System *system; 12212837Sgabeblack@google.com 12312837Sgabeblack@google.com TheISA::TLB *itb; 12412837Sgabeblack@google.com TheISA::TLB *dtb; 12512837Sgabeblack@google.com 12612837Sgabeblack@google.com Decoder decoder; 12712837Sgabeblack@google.com 12812837Sgabeblack@google.com // constructor: initialize SimpleThread from given process structure 12912837Sgabeblack@google.com // FS 13012837Sgabeblack@google.com SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, 13112837Sgabeblack@google.com TheISA::TLB *_itb, TheISA::TLB *_dtb, 13212837Sgabeblack@google.com bool use_kernel_stats = true); 13312837Sgabeblack@google.com // SE 13412837Sgabeblack@google.com SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, 13512837Sgabeblack@google.com TheISA::TLB *_itb, TheISA::TLB *_dtb); 13612837Sgabeblack@google.com 13712837Sgabeblack@google.com SimpleThread(); 13812837Sgabeblack@google.com 13912837Sgabeblack@google.com virtual ~SimpleThread(); 14012837Sgabeblack@google.com 14112837Sgabeblack@google.com virtual void takeOverFrom(ThreadContext *oldContext); 14212837Sgabeblack@google.com 14312837Sgabeblack@google.com void regStats(const std::string &name); 14412837Sgabeblack@google.com 14512837Sgabeblack@google.com void copyTC(ThreadContext *context); 14612837Sgabeblack@google.com 14712837Sgabeblack@google.com void copyState(ThreadContext *oldContext); 14812837Sgabeblack@google.com 14912837Sgabeblack@google.com void serialize(std::ostream &os); 15012837Sgabeblack@google.com void unserialize(Checkpoint *cp, const std::string §ion); 15112837Sgabeblack@google.com 15212837Sgabeblack@google.com /*************************************************************** 15312837Sgabeblack@google.com * SimpleThread functions to provide CPU with access to various 15412837Sgabeblack@google.com * state. 15512837Sgabeblack@google.com **************************************************************/ 15612837Sgabeblack@google.com 15712837Sgabeblack@google.com /** Returns the pointer to this SimpleThread's ThreadContext. Used 15812837Sgabeblack@google.com * when a ThreadContext must be passed to objects outside of the 15912837Sgabeblack@google.com * CPU. 16012837Sgabeblack@google.com */ 16112837Sgabeblack@google.com ThreadContext *getTC() { return tc; } 16212837Sgabeblack@google.com 16312837Sgabeblack@google.com void demapPage(Addr vaddr, uint64_t asn) 16412837Sgabeblack@google.com { 16512837Sgabeblack@google.com itb->demapPage(vaddr, asn); 16612837Sgabeblack@google.com dtb->demapPage(vaddr, asn); 16712837Sgabeblack@google.com } 16812837Sgabeblack@google.com 16912837Sgabeblack@google.com void demapInstPage(Addr vaddr, uint64_t asn) 17013292Sgabeblack@google.com { 17113292Sgabeblack@google.com itb->demapPage(vaddr, asn); 17213292Sgabeblack@google.com } 17313292Sgabeblack@google.com 17413292Sgabeblack@google.com void demapDataPage(Addr vaddr, uint64_t asn) 17513292Sgabeblack@google.com { 17612837Sgabeblack@google.com dtb->demapPage(vaddr, asn); 17712837Sgabeblack@google.com } 17812837Sgabeblack@google.com 17912837Sgabeblack@google.com void dumpFuncProfile(); 18012837Sgabeblack@google.com 18112837Sgabeblack@google.com Fault hwrei(); 18212837Sgabeblack@google.com 18312928Sgabeblack@google.com bool simPalCheck(int palFunc); 18412928Sgabeblack@google.com 18512928Sgabeblack@google.com /******************************************* 18612928Sgabeblack@google.com * ThreadContext interface functions. 18712864Sgabeblack@google.com ******************************************/ 18813191Sgabeblack@google.com 18912864Sgabeblack@google.com BaseCPU *getCpuPtr() { return cpu; } 19012837Sgabeblack@google.com 19112837Sgabeblack@google.com TheISA::TLB *getITBPtr() { return itb; } 19212837Sgabeblack@google.com 19312837Sgabeblack@google.com TheISA::TLB *getDTBPtr() { return dtb; } 19412837Sgabeblack@google.com 19512837Sgabeblack@google.com Decoder *getDecoderPtr() { return &decoder; } 19612837Sgabeblack@google.com 19712837Sgabeblack@google.com System *getSystemPtr() { return system; } 19812837Sgabeblack@google.com 19912837Sgabeblack@google.com FunctionalPort *getPhysPort() { return physPort; } 20012837Sgabeblack@google.com 20112837Sgabeblack@google.com /** Return a virtual port. This port cannot be cached locally in an object. 20212837Sgabeblack@google.com * After a CPU switch it may point to the wrong memory object which could 20312837Sgabeblack@google.com * mean stale data. 20412837Sgabeblack@google.com */ 20512837Sgabeblack@google.com VirtualPort *getVirtPort() { return virtPort; } 20612837Sgabeblack@google.com 20712837Sgabeblack@google.com Status status() const { return _status; } 20812837Sgabeblack@google.com 20912837Sgabeblack@google.com void setStatus(Status newStatus) { _status = newStatus; } 21012837Sgabeblack@google.com 21112837Sgabeblack@google.com /// Set the status to Active. Optional delay indicates number of 21212837Sgabeblack@google.com /// cycles to wait before beginning execution. 21312837Sgabeblack@google.com void activate(int delay = 1); 21412837Sgabeblack@google.com 21512837Sgabeblack@google.com /// Set the status to Suspended. 21612837Sgabeblack@google.com void suspend(); 21712837Sgabeblack@google.com 21812929Sgabeblack@google.com /// Set the status to Halted. 21912929Sgabeblack@google.com void halt(); 22012929Sgabeblack@google.com 22112837Sgabeblack@google.com virtual bool misspeculating(); 22212837Sgabeblack@google.com 22312837Sgabeblack@google.com void copyArchRegs(ThreadContext *tc); 22412837Sgabeblack@google.com 22512837Sgabeblack@google.com void clearArchRegs() 22612837Sgabeblack@google.com { 22712837Sgabeblack@google.com _pcState = 0; 22812837Sgabeblack@google.com memset(intRegs, 0, sizeof(intRegs)); 22912837Sgabeblack@google.com memset(floatRegs.i, 0, sizeof(floatRegs.i)); 23012837Sgabeblack@google.com isa.clear(); 23112837Sgabeblack@google.com } 23212837Sgabeblack@google.com 23312837Sgabeblack@google.com // 23412837Sgabeblack@google.com // New accessors for new decoder. 23512914Sgabeblack@google.com // 23612909Sgabeblack@google.com uint64_t readIntReg(int reg_idx) 23712914Sgabeblack@google.com { 23812914Sgabeblack@google.com int flatIndex = isa.flattenIntIndex(reg_idx); 23912914Sgabeblack@google.com assert(flatIndex < TheISA::NumIntRegs); 24012914Sgabeblack@google.com uint64_t regVal = intRegs[flatIndex]; 24112909Sgabeblack@google.com DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n", 24212837Sgabeblack@google.com reg_idx, flatIndex, regVal); 24312837Sgabeblack@google.com return regVal; 24412837Sgabeblack@google.com } 24512837Sgabeblack@google.com 24612837Sgabeblack@google.com FloatReg readFloatReg(int reg_idx) 24712837Sgabeblack@google.com { 24812951Sgabeblack@google.com int flatIndex = isa.flattenFloatIndex(reg_idx); 24912951Sgabeblack@google.com assert(flatIndex < TheISA::NumFloatRegs); 25012837Sgabeblack@google.com FloatReg regVal = floatRegs.f[flatIndex]; 25112837Sgabeblack@google.com DPRINTF(FloatRegs, "Reading float reg %d (%d) as %f, %#x.\n", 25212837Sgabeblack@google.com reg_idx, flatIndex, regVal, floatRegs.i[flatIndex]); 25312837Sgabeblack@google.com return regVal; 25412837Sgabeblack@google.com } 25512837Sgabeblack@google.com 25612837Sgabeblack@google.com FloatRegBits readFloatRegBits(int reg_idx) 25712837Sgabeblack@google.com { 25812837Sgabeblack@google.com int flatIndex = isa.flattenFloatIndex(reg_idx); 25912837Sgabeblack@google.com assert(flatIndex < TheISA::NumFloatRegs); 26012837Sgabeblack@google.com FloatRegBits regVal = floatRegs.i[flatIndex]; 26112837Sgabeblack@google.com DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x, %f.\n", 26212837Sgabeblack@google.com reg_idx, flatIndex, regVal, floatRegs.f[flatIndex]); 26312837Sgabeblack@google.com return regVal; 26412837Sgabeblack@google.com } 26512837Sgabeblack@google.com 26612837Sgabeblack@google.com void setIntReg(int reg_idx, uint64_t val) 26712837Sgabeblack@google.com { 26812837Sgabeblack@google.com int flatIndex = isa.flattenIntIndex(reg_idx); 26912837Sgabeblack@google.com assert(flatIndex < TheISA::NumIntRegs); 27012837Sgabeblack@google.com DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n", 27112837Sgabeblack@google.com reg_idx, flatIndex, val); 27212837Sgabeblack@google.com intRegs[flatIndex] = val; 27312837Sgabeblack@google.com } 27412837Sgabeblack@google.com 27512837Sgabeblack@google.com void setFloatReg(int reg_idx, FloatReg val) 27612837Sgabeblack@google.com { 27712837Sgabeblack@google.com int flatIndex = isa.flattenFloatIndex(reg_idx); 27812837Sgabeblack@google.com assert(flatIndex < TheISA::NumFloatRegs); 27912837Sgabeblack@google.com floatRegs.f[flatIndex] = val; 28012837Sgabeblack@google.com DPRINTF(FloatRegs, "Setting float reg %d (%d) to %f, %#x.\n", 28112837Sgabeblack@google.com reg_idx, flatIndex, val, floatRegs.i[flatIndex]); 28212929Sgabeblack@google.com } 28312929Sgabeblack@google.com 28412929Sgabeblack@google.com void setFloatRegBits(int reg_idx, FloatRegBits val) 28512837Sgabeblack@google.com { 28612837Sgabeblack@google.com int flatIndex = isa.flattenFloatIndex(reg_idx); 28712837Sgabeblack@google.com assert(flatIndex < TheISA::NumFloatRegs); 28812837Sgabeblack@google.com floatRegs.i[flatIndex] = val; 28912837Sgabeblack@google.com DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x, %#f.\n", 29012837Sgabeblack@google.com reg_idx, flatIndex, val, floatRegs.f[flatIndex]); 29112837Sgabeblack@google.com } 29212837Sgabeblack@google.com 29312952Sgabeblack@google.com TheISA::PCState 29412952Sgabeblack@google.com pcState() 29512952Sgabeblack@google.com { 29612952Sgabeblack@google.com return _pcState; 29712952Sgabeblack@google.com } 29812952Sgabeblack@google.com 29912952Sgabeblack@google.com void 30013135Sgabeblack@google.com pcState(const TheISA::PCState &val) 30113135Sgabeblack@google.com { 30212952Sgabeblack@google.com _pcState = val; 30312952Sgabeblack@google.com } 30412952Sgabeblack@google.com 30512952Sgabeblack@google.com Addr 30612952Sgabeblack@google.com instAddr() 30712952Sgabeblack@google.com { 30812952Sgabeblack@google.com return _pcState.instAddr(); 30912952Sgabeblack@google.com } 31013135Sgabeblack@google.com 31113135Sgabeblack@google.com Addr 31212952Sgabeblack@google.com nextInstAddr() 31312952Sgabeblack@google.com { 31412952Sgabeblack@google.com return _pcState.nextInstAddr(); 31512952Sgabeblack@google.com } 31612952Sgabeblack@google.com 31712952Sgabeblack@google.com MicroPC 31812952Sgabeblack@google.com microPC() 31912952Sgabeblack@google.com { 32013210Sgabeblack@google.com return _pcState.microPC(); 32113210Sgabeblack@google.com } 32212952Sgabeblack@google.com 32312837Sgabeblack@google.com bool readPredicate() 32412909Sgabeblack@google.com { 32512909Sgabeblack@google.com return predicate; 32612909Sgabeblack@google.com } 32712909Sgabeblack@google.com 32812909Sgabeblack@google.com void setPredicate(bool val) 32912914Sgabeblack@google.com { 33012914Sgabeblack@google.com predicate = val; 33112914Sgabeblack@google.com } 33212914Sgabeblack@google.com 33312909Sgabeblack@google.com MiscReg 33412837Sgabeblack@google.com readMiscRegNoEffect(int misc_reg, ThreadID tid = 0) 33512837Sgabeblack@google.com { 33612930Sgabeblack@google.com return isa.readMiscRegNoEffect(misc_reg); 33712930Sgabeblack@google.com } 33812930Sgabeblack@google.com 33912837Sgabeblack@google.com MiscReg 34012837Sgabeblack@google.com readMiscReg(int misc_reg, ThreadID tid = 0) 34112837Sgabeblack@google.com { 34212837Sgabeblack@google.com return isa.readMiscReg(misc_reg, tc); 34312837Sgabeblack@google.com } 34412837Sgabeblack@google.com 34512901Sgabeblack@google.com void 34612901Sgabeblack@google.com setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid = 0) 34712901Sgabeblack@google.com { 34812901Sgabeblack@google.com return isa.setMiscRegNoEffect(misc_reg, val); 34912901Sgabeblack@google.com } 35012901Sgabeblack@google.com 35112907Sgabeblack@google.com void 35213087Sgabeblack@google.com setMiscReg(int misc_reg, const MiscReg &val, ThreadID tid = 0) 35313087Sgabeblack@google.com { 35413087Sgabeblack@google.com return isa.setMiscReg(misc_reg, val, tc); 35513087Sgabeblack@google.com } 35612907Sgabeblack@google.com 35712907Sgabeblack@google.com int 35813087Sgabeblack@google.com flattenIntIndex(int reg) 35913087Sgabeblack@google.com { 36013087Sgabeblack@google.com return isa.flattenIntIndex(reg); 36113087Sgabeblack@google.com } 36212907Sgabeblack@google.com 36312907Sgabeblack@google.com int 36413087Sgabeblack@google.com flattenFloatIndex(int reg) 36513087Sgabeblack@google.com { 36612907Sgabeblack@google.com return isa.flattenFloatIndex(reg); 36712837Sgabeblack@google.com } 36812837Sgabeblack@google.com 36912837Sgabeblack@google.com unsigned readStCondFailures() { return storeCondFailures; } 370 371 void setStCondFailures(unsigned sc_failures) 372 { storeCondFailures = sc_failures; } 373 374 void syscall(int64_t callnum) 375 { 376 process->syscall(callnum, tc); 377 } 378}; 379 380 381// for non-speculative execution context, spec_mode is always false 382inline bool 383SimpleThread::misspeculating() 384{ 385 return false; 386} 387 388#endif // __CPU_CPU_EXEC_CONTEXT_HH__ 389