simple_thread.hh revision 8808:8af87554ad7e
1955SN/A/* 2955SN/A * Copyright (c) 2001-2006 The Regents of The University of Michigan 37816Ssteve.reinhardt@amd.com * All rights reserved. 45871Snate@binkert.org * 51762SN/A * Redistribution and use in source and binary forms, with or without 6955SN/A * modification, are permitted provided that the following conditions are 7955SN/A * met: redistributions of source code must retain the above copyright 8955SN/A * notice, this list of conditions and the following disclaimer; 9955SN/A * redistributions in binary form must reproduce the above copyright 10955SN/A * notice, this list of conditions and the following disclaimer in the 11955SN/A * documentation and/or other materials provided with the distribution; 12955SN/A * neither the name of the copyright holders nor the names of its 13955SN/A * contributors may be used to endorse or promote products derived from 14955SN/A * this software without specific prior written permission. 15955SN/A * 16955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27955SN/A * 28955SN/A * Authors: Steve Reinhardt 29955SN/A * Nathan Binkert 302665Ssaidi@eecs.umich.edu */ 312665Ssaidi@eecs.umich.edu 325863Snate@binkert.org#ifndef __CPU_SIMPLE_THREAD_HH__ 33955SN/A#define __CPU_SIMPLE_THREAD_HH__ 34955SN/A 35955SN/A#include "arch/isa.hh" 36955SN/A#include "arch/isa_traits.hh" 37955SN/A#include "arch/registers.hh" 382632Sstever@eecs.umich.edu#include "arch/tlb.hh" 392632Sstever@eecs.umich.edu#include "arch/types.hh" 402632Sstever@eecs.umich.edu#include "base/types.hh" 412632Sstever@eecs.umich.edu#include "config/the_isa.hh" 42955SN/A#include "cpu/decode.hh" 432632Sstever@eecs.umich.edu#include "cpu/thread_context.hh" 442632Sstever@eecs.umich.edu#include "cpu/thread_state.hh" 452761Sstever@eecs.umich.edu#include "debug/FloatRegs.hh" 462632Sstever@eecs.umich.edu#include "debug/IntRegs.hh" 472632Sstever@eecs.umich.edu#include "mem/page_table.hh" 482632Sstever@eecs.umich.edu#include "mem/request.hh" 492761Sstever@eecs.umich.edu#include "sim/byteswap.hh" 502761Sstever@eecs.umich.edu#include "sim/eventq.hh" 512761Sstever@eecs.umich.edu#include "sim/process.hh" 522632Sstever@eecs.umich.edu#include "sim/serialize.hh" 532632Sstever@eecs.umich.edu#include "sim/system.hh" 542761Sstever@eecs.umich.edu 552761Sstever@eecs.umich.educlass BaseCPU; 562761Sstever@eecs.umich.edu 572761Sstever@eecs.umich.edu 582761Sstever@eecs.umich.educlass FunctionProfile; 592632Sstever@eecs.umich.educlass ProfileNode; 602632Sstever@eecs.umich.edu 612632Sstever@eecs.umich.edunamespace TheISA { 622632Sstever@eecs.umich.edu namespace Kernel { 632632Sstever@eecs.umich.edu class Statistics; 642632Sstever@eecs.umich.edu }; 652632Sstever@eecs.umich.edu}; 66955SN/A 67955SN/A/** 68955SN/A * The SimpleThread object provides a combination of the ThreadState 695863Snate@binkert.org * object and the ThreadContext interface. It implements the 705863Snate@binkert.org * ThreadContext interface so that a ProxyThreadContext class can be 715863Snate@binkert.org * made using SimpleThread as the template parameter (see 725863Snate@binkert.org * thread_context.hh). It adds to the ThreadState object by adding all 735863Snate@binkert.org * the objects needed for simple functional execution, including a 745863Snate@binkert.org * simple architectural register file, and pointers to the ITB and DTB 755863Snate@binkert.org * in full system mode. For CPU models that do not need more advanced 765863Snate@binkert.org * ways to hold state (i.e. a separate physical register file, or 775863Snate@binkert.org * separate fetch and commit PC's), this SimpleThread class provides 785863Snate@binkert.org * all the necessary state for full architecture-level functional 795863Snate@binkert.org * simulation. See the AtomicSimpleCPU or TimingSimpleCPU for 805863Snate@binkert.org * examples. 815863Snate@binkert.org */ 825863Snate@binkert.org 835863Snate@binkert.orgclass SimpleThread : public ThreadState 845863Snate@binkert.org{ 855863Snate@binkert.org protected: 865863Snate@binkert.org typedef TheISA::MachInst MachInst; 875863Snate@binkert.org typedef TheISA::MiscReg MiscReg; 885863Snate@binkert.org typedef TheISA::FloatReg FloatReg; 895863Snate@binkert.org typedef TheISA::FloatRegBits FloatRegBits; 905863Snate@binkert.org public: 915863Snate@binkert.org typedef ThreadContext::Status Status; 925863Snate@binkert.org 935863Snate@binkert.org protected: 945863Snate@binkert.org union { 955863Snate@binkert.org FloatReg f[TheISA::NumFloatRegs]; 965863Snate@binkert.org FloatRegBits i[TheISA::NumFloatRegs]; 975863Snate@binkert.org } floatRegs; 985863Snate@binkert.org TheISA::IntReg intRegs[TheISA::NumIntRegs]; 995863Snate@binkert.org TheISA::ISA isa; // one "instance" of the current ISA. 1006654Snate@binkert.org 101955SN/A TheISA::PCState _pcState; 1025396Ssaidi@eecs.umich.edu 1035863Snate@binkert.org /** Did this instruction execute or is it predicated false */ 1045863Snate@binkert.org bool predicate; 1054202Sbinkertn@umich.edu 1065863Snate@binkert.org public: 1075863Snate@binkert.org std::string name() const 1085863Snate@binkert.org { 1095863Snate@binkert.org return csprintf("%s.[tid:%i]", cpu->name(), tc->threadId()); 110955SN/A } 1116654Snate@binkert.org 1125273Sstever@gmail.com // pointer to CPU associated with this SimpleThread 1135871Snate@binkert.org BaseCPU *cpu; 1145273Sstever@gmail.com 1156655Snate@binkert.org ProxyThreadContext<SimpleThread> *tc; 1166655Snate@binkert.org 1176655Snate@binkert.org System *system; 1186655Snate@binkert.org 1196655Snate@binkert.org TheISA::TLB *itb; 1206655Snate@binkert.org TheISA::TLB *dtb; 1215871Snate@binkert.org 1226654Snate@binkert.org Decoder decoder; 1235396Ssaidi@eecs.umich.edu 1247816Ssteve.reinhardt@amd.com // constructor: initialize SimpleThread from given process structure 1257816Ssteve.reinhardt@amd.com // FS 1267816Ssteve.reinhardt@amd.com SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system, 1277816Ssteve.reinhardt@amd.com TheISA::TLB *_itb, TheISA::TLB *_dtb, 1287816Ssteve.reinhardt@amd.com bool use_kernel_stats = true); 1297816Ssteve.reinhardt@amd.com // SE 1307816Ssteve.reinhardt@amd.com SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, 1317816Ssteve.reinhardt@amd.com TheISA::TLB *_itb, TheISA::TLB *_dtb); 1327816Ssteve.reinhardt@amd.com 1337816Ssteve.reinhardt@amd.com SimpleThread(); 1347816Ssteve.reinhardt@amd.com 1357816Ssteve.reinhardt@amd.com virtual ~SimpleThread(); 1365871Snate@binkert.org 1375871Snate@binkert.org virtual void takeOverFrom(ThreadContext *oldContext); 1386121Snate@binkert.org 1395871Snate@binkert.org void regStats(const std::string &name); 1405871Snate@binkert.org 1416003Snate@binkert.org void copyTC(ThreadContext *context); 1426655Snate@binkert.org 143955SN/A void copyState(ThreadContext *oldContext); 1445871Snate@binkert.org 1455871Snate@binkert.org void serialize(std::ostream &os); 1465871Snate@binkert.org void unserialize(Checkpoint *cp, const std::string §ion); 1475871Snate@binkert.org 148955SN/A /*************************************************************** 1496121Snate@binkert.org * SimpleThread functions to provide CPU with access to various 1506121Snate@binkert.org * state. 1516121Snate@binkert.org **************************************************************/ 1521533SN/A 1536655Snate@binkert.org /** Returns the pointer to this SimpleThread's ThreadContext. Used 1546655Snate@binkert.org * when a ThreadContext must be passed to objects outside of the 1556655Snate@binkert.org * CPU. 1566655Snate@binkert.org */ 1575871Snate@binkert.org ThreadContext *getTC() { return tc; } 1585871Snate@binkert.org 1595863Snate@binkert.org void demapPage(Addr vaddr, uint64_t asn) 1605871Snate@binkert.org { 1615871Snate@binkert.org itb->demapPage(vaddr, asn); 1625871Snate@binkert.org dtb->demapPage(vaddr, asn); 1635871Snate@binkert.org } 1645871Snate@binkert.org 1655863Snate@binkert.org void demapInstPage(Addr vaddr, uint64_t asn) 1666121Snate@binkert.org { 1675863Snate@binkert.org itb->demapPage(vaddr, asn); 1685871Snate@binkert.org } 1694678Snate@binkert.org 1704678Snate@binkert.org void demapDataPage(Addr vaddr, uint64_t asn) 1714678Snate@binkert.org { 1724678Snate@binkert.org dtb->demapPage(vaddr, asn); 1734678Snate@binkert.org } 1744678Snate@binkert.org 1754678Snate@binkert.org void dumpFuncProfile(); 1764678Snate@binkert.org 1774678Snate@binkert.org Fault hwrei(); 1784678Snate@binkert.org 1794678Snate@binkert.org bool simPalCheck(int palFunc); 1807827Snate@binkert.org 1817827Snate@binkert.org /******************************************* 1826121Snate@binkert.org * ThreadContext interface functions. 1834678Snate@binkert.org ******************************************/ 1845871Snate@binkert.org 1855871Snate@binkert.org BaseCPU *getCpuPtr() { return cpu; } 1865871Snate@binkert.org 1875871Snate@binkert.org TheISA::TLB *getITBPtr() { return itb; } 1885871Snate@binkert.org 1895871Snate@binkert.org TheISA::TLB *getDTBPtr() { return dtb; } 1905871Snate@binkert.org 1915871Snate@binkert.org Decoder *getDecoderPtr() { return &decoder; } 1925871Snate@binkert.org 1935871Snate@binkert.org System *getSystemPtr() { return system; } 1945871Snate@binkert.org 1955871Snate@binkert.org PortProxy* getPhysProxy() { return physProxy; } 1965871Snate@binkert.org 1975990Ssaidi@eecs.umich.edu /** Return a virtual port. This port cannot be cached locally in an object. 1985871Snate@binkert.org * After a CPU switch it may point to the wrong memory object which could 1995871Snate@binkert.org * mean stale data. 2005871Snate@binkert.org */ 2014678Snate@binkert.org FSTranslatingPortProxy* getVirtProxy() { return virtProxy; } 2026654Snate@binkert.org 2035871Snate@binkert.org Status status() const { return _status; } 2045871Snate@binkert.org 2055871Snate@binkert.org void setStatus(Status newStatus) { _status = newStatus; } 2065871Snate@binkert.org 2075871Snate@binkert.org /// Set the status to Active. Optional delay indicates number of 2085871Snate@binkert.org /// cycles to wait before beginning execution. 2095871Snate@binkert.org void activate(int delay = 1); 2105871Snate@binkert.org 2115871Snate@binkert.org /// Set the status to Suspended. 2124678Snate@binkert.org void suspend(); 2135871Snate@binkert.org 2144678Snate@binkert.org /// Set the status to Halted. 2155871Snate@binkert.org void halt(); 2165871Snate@binkert.org 2175871Snate@binkert.org virtual bool misspeculating(); 2185871Snate@binkert.org 2195871Snate@binkert.org void copyArchRegs(ThreadContext *tc); 2205871Snate@binkert.org 2215871Snate@binkert.org void clearArchRegs() 2225871Snate@binkert.org { 2235871Snate@binkert.org _pcState = 0; 2246121Snate@binkert.org memset(intRegs, 0, sizeof(intRegs)); 2256121Snate@binkert.org memset(floatRegs.i, 0, sizeof(floatRegs.i)); 2265863Snate@binkert.org isa.clear(); 227955SN/A } 228955SN/A 2292632Sstever@eecs.umich.edu // 2302632Sstever@eecs.umich.edu // New accessors for new decoder. 231955SN/A // 232955SN/A uint64_t readIntReg(int reg_idx) 233955SN/A { 234955SN/A int flatIndex = isa.flattenIntIndex(reg_idx); 2355863Snate@binkert.org assert(flatIndex < TheISA::NumIntRegs); 236955SN/A uint64_t regVal = intRegs[flatIndex]; 2372632Sstever@eecs.umich.edu DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n", 2382632Sstever@eecs.umich.edu reg_idx, flatIndex, regVal); 2392632Sstever@eecs.umich.edu return regVal; 2402632Sstever@eecs.umich.edu } 2412632Sstever@eecs.umich.edu 2422632Sstever@eecs.umich.edu FloatReg readFloatReg(int reg_idx) 2432632Sstever@eecs.umich.edu { 2442632Sstever@eecs.umich.edu int flatIndex = isa.flattenFloatIndex(reg_idx); 2452632Sstever@eecs.umich.edu assert(flatIndex < TheISA::NumFloatRegs); 2462632Sstever@eecs.umich.edu FloatReg regVal = floatRegs.f[flatIndex]; 2472632Sstever@eecs.umich.edu DPRINTF(FloatRegs, "Reading float reg %d (%d) as %f, %#x.\n", 2482632Sstever@eecs.umich.edu reg_idx, flatIndex, regVal, floatRegs.i[flatIndex]); 2492632Sstever@eecs.umich.edu return regVal; 2503718Sstever@eecs.umich.edu } 2513718Sstever@eecs.umich.edu 2523718Sstever@eecs.umich.edu FloatRegBits readFloatRegBits(int reg_idx) 2533718Sstever@eecs.umich.edu { 2543718Sstever@eecs.umich.edu int flatIndex = isa.flattenFloatIndex(reg_idx); 2555863Snate@binkert.org assert(flatIndex < TheISA::NumFloatRegs); 2565863Snate@binkert.org FloatRegBits regVal = floatRegs.i[flatIndex]; 2573718Sstever@eecs.umich.edu DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x, %f.\n", 2583718Sstever@eecs.umich.edu reg_idx, flatIndex, regVal, floatRegs.f[flatIndex]); 2596121Snate@binkert.org return regVal; 2605863Snate@binkert.org } 2613718Sstever@eecs.umich.edu 2623718Sstever@eecs.umich.edu void setIntReg(int reg_idx, uint64_t val) 2632634Sstever@eecs.umich.edu { 2642634Sstever@eecs.umich.edu int flatIndex = isa.flattenIntIndex(reg_idx); 2655863Snate@binkert.org assert(flatIndex < TheISA::NumIntRegs); 2662638Sstever@eecs.umich.edu DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n", 2672632Sstever@eecs.umich.edu reg_idx, flatIndex, val); 2682632Sstever@eecs.umich.edu intRegs[flatIndex] = val; 2692632Sstever@eecs.umich.edu } 2702632Sstever@eecs.umich.edu 2712632Sstever@eecs.umich.edu void setFloatReg(int reg_idx, FloatReg val) 2722632Sstever@eecs.umich.edu { 2731858SN/A int flatIndex = isa.flattenFloatIndex(reg_idx); 2743716Sstever@eecs.umich.edu assert(flatIndex < TheISA::NumFloatRegs); 2752638Sstever@eecs.umich.edu floatRegs.f[flatIndex] = val; 2762638Sstever@eecs.umich.edu DPRINTF(FloatRegs, "Setting float reg %d (%d) to %f, %#x.\n", 2772638Sstever@eecs.umich.edu reg_idx, flatIndex, val, floatRegs.i[flatIndex]); 2782638Sstever@eecs.umich.edu } 2792638Sstever@eecs.umich.edu 2802638Sstever@eecs.umich.edu void setFloatRegBits(int reg_idx, FloatRegBits val) 2812638Sstever@eecs.umich.edu { 2825863Snate@binkert.org int flatIndex = isa.flattenFloatIndex(reg_idx); 2835863Snate@binkert.org assert(flatIndex < TheISA::NumFloatRegs); 2845863Snate@binkert.org floatRegs.i[flatIndex] = val; 285955SN/A DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x, %#f.\n", 2865341Sstever@gmail.com reg_idx, flatIndex, val, floatRegs.f[flatIndex]); 2875341Sstever@gmail.com } 2885863Snate@binkert.org 2897756SAli.Saidi@ARM.com TheISA::PCState 2905341Sstever@gmail.com pcState() 2916121Snate@binkert.org { 2924494Ssaidi@eecs.umich.edu return _pcState; 2936121Snate@binkert.org } 2941105SN/A 2952667Sstever@eecs.umich.edu void 2962667Sstever@eecs.umich.edu pcState(const TheISA::PCState &val) 2972667Sstever@eecs.umich.edu { 2982667Sstever@eecs.umich.edu _pcState = val; 2996121Snate@binkert.org } 3002667Sstever@eecs.umich.edu 3015341Sstever@gmail.com Addr 3025863Snate@binkert.org instAddr() 3035341Sstever@gmail.com { 3045341Sstever@gmail.com return _pcState.instAddr(); 3055341Sstever@gmail.com } 3065863Snate@binkert.org 3075341Sstever@gmail.com Addr 3085341Sstever@gmail.com nextInstAddr() 3095341Sstever@gmail.com { 3105863Snate@binkert.org return _pcState.nextInstAddr(); 3115341Sstever@gmail.com } 3125341Sstever@gmail.com 3135341Sstever@gmail.com MicroPC 3145341Sstever@gmail.com microPC() 3155341Sstever@gmail.com { 3165341Sstever@gmail.com return _pcState.microPC(); 3175341Sstever@gmail.com } 3185341Sstever@gmail.com 3195341Sstever@gmail.com bool readPredicate() 3205341Sstever@gmail.com { 3215863Snate@binkert.org return predicate; 3225341Sstever@gmail.com } 3235863Snate@binkert.org 3247756SAli.Saidi@ARM.com void setPredicate(bool val) 3255341Sstever@gmail.com { 3265863Snate@binkert.org predicate = val; 3276121Snate@binkert.org } 3286121Snate@binkert.org 3295397Ssaidi@eecs.umich.edu MiscReg 3305397Ssaidi@eecs.umich.edu readMiscRegNoEffect(int misc_reg, ThreadID tid = 0) 3317727SAli.Saidi@ARM.com { 3325341Sstever@gmail.com return isa.readMiscRegNoEffect(misc_reg); 3336168Snate@binkert.org } 3346168Snate@binkert.org 3355341Sstever@gmail.com MiscReg 3367756SAli.Saidi@ARM.com readMiscReg(int misc_reg, ThreadID tid = 0) 3377756SAli.Saidi@ARM.com { 3387756SAli.Saidi@ARM.com return isa.readMiscReg(misc_reg, tc); 3397756SAli.Saidi@ARM.com } 3407756SAli.Saidi@ARM.com 3417756SAli.Saidi@ARM.com void 3425341Sstever@gmail.com setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid = 0) 3435341Sstever@gmail.com { 3445341Sstever@gmail.com return isa.setMiscRegNoEffect(misc_reg, val); 3455341Sstever@gmail.com } 3465863Snate@binkert.org 3475341Sstever@gmail.com void 3485341Sstever@gmail.com setMiscReg(int misc_reg, const MiscReg &val, ThreadID tid = 0) 3496121Snate@binkert.org { 3506121Snate@binkert.org return isa.setMiscReg(misc_reg, val, tc); 3517756SAli.Saidi@ARM.com } 3525341Sstever@gmail.com 3536814Sgblack@eecs.umich.edu int 3547756SAli.Saidi@ARM.com flattenIntIndex(int reg) 3556814Sgblack@eecs.umich.edu { 3565863Snate@binkert.org return isa.flattenIntIndex(reg); 3576121Snate@binkert.org } 3585341Sstever@gmail.com 3595863Snate@binkert.org int 3605341Sstever@gmail.com flattenFloatIndex(int reg) 3616121Snate@binkert.org { 3626121Snate@binkert.org return isa.flattenFloatIndex(reg); 3636121Snate@binkert.org } 3645742Snate@binkert.org 3655742Snate@binkert.org unsigned readStCondFailures() { return storeCondFailures; } 3665341Sstever@gmail.com 3675742Snate@binkert.org void setStCondFailures(unsigned sc_failures) 3685742Snate@binkert.org { storeCondFailures = sc_failures; } 3695341Sstever@gmail.com 3706017Snate@binkert.org void syscall(int64_t callnum) 3716121Snate@binkert.org { 3726017Snate@binkert.org process->syscall(callnum, tc); 3737816Ssteve.reinhardt@amd.com } 3747756SAli.Saidi@ARM.com}; 3757756SAli.Saidi@ARM.com 3767756SAli.Saidi@ARM.com 3777756SAli.Saidi@ARM.com// for non-speculative execution context, spec_mode is always false 3787756SAli.Saidi@ARM.cominline bool 3797756SAli.Saidi@ARM.comSimpleThread::misspeculating() 3807756SAli.Saidi@ARM.com{ 3817756SAli.Saidi@ARM.com return false; 3827816Ssteve.reinhardt@amd.com} 3837816Ssteve.reinhardt@amd.com 3847816Ssteve.reinhardt@amd.com#endif // __CPU_CPU_EXEC_CONTEXT_HH__ 3857816Ssteve.reinhardt@amd.com