simple_thread.hh revision 5803
11689SN/A/*
22316SN/A * Copyright (c) 2001-2006 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 * Authors: Steve Reinhardt
292965Sksewell@umich.edu *          Nathan Binkert
301689SN/A */
311689SN/A
322733Sktlim@umich.edu#ifndef __CPU_SIMPLE_THREAD_HH__
332733Sktlim@umich.edu#define __CPU_SIMPLE_THREAD_HH__
342733Sktlim@umich.edu
352292SN/A#include "arch/isa_traits.hh"
362329SN/A#include "arch/regfile.hh"
372292SN/A#include "arch/syscallreturn.hh"
383577Sgblack@eecs.umich.edu#include "arch/tlb.hh"
392292SN/A#include "config/full_system.hh"
401060SN/A#include "cpu/thread_context.hh"
412292SN/A#include "cpu/thread_state.hh"
421717SN/A#include "mem/request.hh"
432292SN/A#include "sim/byteswap.hh"
442292SN/A#include "sim/eventq.hh"
452790Sktlim@umich.edu#include "sim/host.hh"
462790Sktlim@umich.edu#include "sim/serialize.hh"
472790Sktlim@umich.edu
482790Sktlim@umich.educlass BaseCPU;
495529Snate@binkert.org
505529Snate@binkert.org#if FULL_SYSTEM
511061SN/A
522292SN/A#include "sim/system.hh"
532292SN/A
545606Snate@binkert.orgclass FunctionProfile;
551060SN/Aclass ProfileNode;
565769Snate@binkert.orgclass FunctionalPort;
571060SN/Aclass PhysicalPort;
581060SN/A
591061SN/Anamespace TheISA {
601060SN/A    namespace Kernel {
612292SN/A        class Statistics;
621062SN/A    };
632316SN/A};
642316SN/A
652292SN/A#else // !FULL_SYSTEM
662292SN/A
672292SN/A#include "sim/process.hh"
682292SN/A#include "mem/page_table.hh"
692292SN/Aclass TranslatingPort;
705336Shines@cs.fsu.edu
712292SN/A#endif // FULL_SYSTEM
724873Sstever@eecs.umich.edu
732292SN/A/**
742292SN/A * The SimpleThread object provides a combination of the ThreadState
752292SN/A * object and the ThreadContext interface. It implements the
765529Snate@binkert.org * ThreadContext interface so that a ProxyThreadContext class can be
774329Sktlim@umich.edu * made using SimpleThread as the template parameter (see
784329Sktlim@umich.edu * thread_context.hh). It adds to the ThreadState object by adding all
792292SN/A * the objects needed for simple functional execution, including a
802292SN/A * simple architectural register file, and pointers to the ITB and DTB
812292SN/A * in full system mode. For CPU models that do not need more advanced
822292SN/A * ways to hold state (i.e. a separate physical register file, or
832292SN/A * separate fetch and commit PC's), this SimpleThread class provides
842292SN/A * all the necessary state for full architecture-level functional
855529Snate@binkert.org * simulation.  See the AtomicSimpleCPU or TimingSimpleCPU for
862843Sktlim@umich.edu * examples.
872316SN/A */
882874Sktlim@umich.edu
892292SN/Aclass SimpleThread : public ThreadState
902292SN/A{
912292SN/A  protected:
922980Sgblack@eecs.umich.edu    typedef TheISA::RegFile RegFile;
932292SN/A    typedef TheISA::MachInst MachInst;
942292SN/A    typedef TheISA::MiscRegFile MiscRegFile;
952292SN/A    typedef TheISA::MiscReg MiscReg;
962292SN/A    typedef TheISA::FloatReg FloatReg;
972292SN/A    typedef TheISA::FloatRegBits FloatRegBits;
982292SN/A  public:
992292SN/A    typedef ThreadContext::Status Status;
1002292SN/A
1012292SN/A  protected:
1024329Sktlim@umich.edu    RegFile regs;       // correct-path register context
1032292SN/A
1042292SN/A  public:
1052292SN/A    // pointer to CPU associated with this SimpleThread
1062292SN/A    BaseCPU *cpu;
1072292SN/A
1082292SN/A    ProxyThreadContext<SimpleThread> *tc;
1092292SN/A
1102292SN/A    System *system;
1114329Sktlim@umich.edu
1122292SN/A    TheISA::ITB *itb;
1132292SN/A    TheISA::DTB *dtb;
1142292SN/A
1154329Sktlim@umich.edu    // constructor: initialize SimpleThread from given process structure
1162292SN/A#if FULL_SYSTEM
1172292SN/A    SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
1182292SN/A                 TheISA::ITB *_itb, TheISA::DTB *_dtb,
1192292SN/A                 bool use_kernel_stats = true);
1202292SN/A#else
1212292SN/A    SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process,
1222292SN/A                 TheISA::ITB *_itb, TheISA::DTB *_dtb, int _asid);
1232292SN/A#endif
1244035Sktlim@umich.edu
1254035Sktlim@umich.edu    SimpleThread();
1264035Sktlim@umich.edu
1272292SN/A    virtual ~SimpleThread();
1282680Sktlim@umich.edu
1294636Sgblack@eecs.umich.edu    virtual void takeOverFrom(ThreadContext *oldContext);
1302292SN/A
1313640Sktlim@umich.edu    void regStats(const std::string &name);
1323640Sktlim@umich.edu
1333640Sktlim@umich.edu    void copyTC(ThreadContext *context);
1342292SN/A
1352292SN/A    void copyState(ThreadContext *oldContext);
1362292SN/A
1372292SN/A    void serialize(std::ostream &os);
1382292SN/A    void unserialize(Checkpoint *cp, const std::string &section);
1392292SN/A
1402292SN/A    /***************************************************************
1412292SN/A     *  SimpleThread functions to provide CPU with access to various
1422292SN/A     *  state, and to provide address translation methods.
1432292SN/A     **************************************************************/
1442292SN/A
1452292SN/A    /** Returns the pointer to this SimpleThread's ThreadContext. Used
1462132SN/A     *  when a ThreadContext must be passed to objects outside of the
1472301SN/A     *  CPU.
1481062SN/A     */
1491062SN/A    ThreadContext *getTC() { return tc; }
1501062SN/A
1511062SN/A    Fault translateInstReq(RequestPtr &req)
1521062SN/A    {
1531062SN/A        return itb->translate(req, tc);
1541062SN/A    }
1551062SN/A
1561062SN/A    Fault translateDataReadReq(RequestPtr &req)
1571062SN/A    {
1581062SN/A        return dtb->translate(req, tc, false);
1591062SN/A    }
1601062SN/A
1611062SN/A    Fault translateDataWriteReq(RequestPtr &req)
1621062SN/A    {
1631062SN/A        return dtb->translate(req, tc, true);
1641062SN/A    }
1651062SN/A
1661062SN/A    void demapPage(Addr vaddr, uint64_t asn)
1671062SN/A    {
1681062SN/A        itb->demapPage(vaddr, asn);
1692292SN/A        dtb->demapPage(vaddr, asn);
1701062SN/A    }
1711062SN/A
1721062SN/A    void demapInstPage(Addr vaddr, uint64_t asn)
1731062SN/A    {
1741062SN/A        itb->demapPage(vaddr, asn);
1752301SN/A    }
1762316SN/A
1772301SN/A    void demapDataPage(Addr vaddr, uint64_t asn)
1782301SN/A    {
1792301SN/A        dtb->demapPage(vaddr, asn);
1802301SN/A    }
1812301SN/A
1822301SN/A#if FULL_SYSTEM
1832316SN/A    int getInstAsid() { return regs.instAsid(); }
1842301SN/A    int getDataAsid() { return regs.dataAsid(); }
1852301SN/A
1862301SN/A    void dumpFuncProfile();
1872301SN/A
1882301SN/A    Fault hwrei();
1892301SN/A
1902316SN/A    bool simPalCheck(int palFunc);
1912301SN/A
1922301SN/A#endif
1932301SN/A
1942301SN/A    /*******************************************
1952301SN/A     * ThreadContext interface functions.
1962301SN/A     ******************************************/
1972316SN/A
1982301SN/A    BaseCPU *getCpuPtr() { return cpu; }
1992301SN/A
2002301SN/A    TheISA::ITB *getITBPtr() { return itb; }
2012301SN/A
2022301SN/A    TheISA::DTB *getDTBPtr() { return dtb; }
2032301SN/A
2042316SN/A    System *getSystemPtr() { return system; }
2052301SN/A
2062301SN/A#if FULL_SYSTEM
2072301SN/A    FunctionalPort *getPhysPort() { return physPort; }
2082301SN/A
2092301SN/A    /** Return a virtual port. This port cannot be cached locally in an object.
2102301SN/A     * After a CPU switch it may point to the wrong memory object which could
2112316SN/A     * mean stale data.
2122301SN/A     */
2132301SN/A    VirtualPort *getVirtPort() { return virtPort; }
2142301SN/A#endif
2152301SN/A
2162301SN/A    Status status() const { return _status; }
2172301SN/A
2182316SN/A    void setStatus(Status newStatus) { _status = newStatus; }
2192301SN/A
2202301SN/A    /// Set the status to Active.  Optional delay indicates number of
2212301SN/A    /// cycles to wait before beginning execution.
2222301SN/A    void activate(int delay = 1);
2232301SN/A
2242301SN/A    /// Set the status to Suspended.
2252316SN/A    void suspend();
2262301SN/A
2272301SN/A    /// Set the status to Unallocated.
2282301SN/A    void deallocate();
2291062SN/A
2301062SN/A    /// Set the status to Halted.
2311062SN/A    void halt();
2321062SN/A
2332980Sgblack@eecs.umich.edu    virtual bool misspeculating();
2342292SN/A
2352292SN/A    Fault instRead(RequestPtr &req)
2362292SN/A    {
2372292SN/A        panic("instRead not implemented");
2382292SN/A        // return funcPhysMem->read(req, inst);
2392292SN/A        return NoFault;
2402292SN/A    }
2411060SN/A
2421060SN/A    void copyArchRegs(ThreadContext *tc);
2431060SN/A
2441060SN/A    void clearArchRegs() { regs.clear(); }
2451060SN/A
2461060SN/A    //
2471060SN/A    // New accessors for new decoder.
2481060SN/A    //
2491060SN/A    uint64_t readIntReg(int reg_idx)
2501060SN/A    {
2511061SN/A        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
2521060SN/A        return regs.readIntReg(flatIndex);
2532292SN/A    }
2542292SN/A
2552292SN/A    FloatReg readFloatReg(int reg_idx, int width)
2562292SN/A    {
2572292SN/A        int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
2582292SN/A        return regs.readFloatReg(flatIndex, width);
2592292SN/A    }
2602292SN/A
2612292SN/A    FloatReg readFloatReg(int reg_idx)
2622292SN/A    {
2632292SN/A        int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
2641060SN/A        return regs.readFloatReg(flatIndex);
2651060SN/A    }
2661060SN/A
2671060SN/A    FloatRegBits readFloatRegBits(int reg_idx, int width)
2681060SN/A    {
2691060SN/A        int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
2701060SN/A        return regs.readFloatRegBits(flatIndex, width);
2711061SN/A    }
2721060SN/A
2732292SN/A    FloatRegBits readFloatRegBits(int reg_idx)
2741060SN/A    {
2751060SN/A        int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
2761060SN/A        return regs.readFloatRegBits(flatIndex);
2771060SN/A    }
2781060SN/A
2791060SN/A    void setIntReg(int reg_idx, uint64_t val)
2801060SN/A    {
2811061SN/A        int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx);
2821060SN/A        regs.setIntReg(flatIndex, val);
2832292SN/A    }
2842292SN/A
2852292SN/A    void setFloatReg(int reg_idx, FloatReg val, int width)
2862292SN/A    {
2872292SN/A        int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
2882292SN/A        regs.setFloatReg(flatIndex, val, width);
2892292SN/A    }
2902980Sgblack@eecs.umich.edu
2912292SN/A    void setFloatReg(int reg_idx, FloatReg val)
2922292SN/A    {
2932292SN/A        int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
2942292SN/A        regs.setFloatReg(flatIndex, val);
2952292SN/A    }
2962292SN/A
2972292SN/A    void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
2982292SN/A    {
2992292SN/A        int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
3002292SN/A        regs.setFloatRegBits(flatIndex, val, width);
3012292SN/A    }
3022292SN/A
3032292SN/A    void setFloatRegBits(int reg_idx, FloatRegBits val)
3042292SN/A    {
3052292SN/A        int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx);
3062292SN/A        regs.setFloatRegBits(flatIndex, val);
3071060SN/A    }
3081060SN/A
3091060SN/A    uint64_t readPC()
3101060SN/A    {
3111061SN/A        return regs.readPC();
3121060SN/A    }
3132292SN/A
3141060SN/A    void setPC(uint64_t val)
3152292SN/A    {
3162292SN/A        regs.setPC(val);
3171060SN/A    }
3182292SN/A
3192292SN/A    uint64_t readMicroPC()
3202292SN/A    {
3212292SN/A        return microPC;
3224035Sktlim@umich.edu    }
3231060SN/A
3241060SN/A    void setMicroPC(uint64_t val)
3254329Sktlim@umich.edu    {
3264329Sktlim@umich.edu        microPC = val;
3274329Sktlim@umich.edu    }
3284329Sktlim@umich.edu
3292292SN/A    uint64_t readNextPC()
3305100Ssaidi@eecs.umich.edu    {
3311060SN/A        return regs.readNextPC();
3321060SN/A    }
3331061SN/A
3342863Sktlim@umich.edu    void setNextPC(uint64_t val)
3352843Sktlim@umich.edu    {
3361060SN/A        regs.setNextPC(val);
3372843Sktlim@umich.edu    }
3382863Sktlim@umich.edu
3392863Sktlim@umich.edu    uint64_t readNextMicroPC()
3402316SN/A    {
3412316SN/A        return nextMicroPC;
3422316SN/A    }
3432316SN/A
3442843Sktlim@umich.edu    void setNextMicroPC(uint64_t val)
3452316SN/A    {
3462316SN/A        nextMicroPC = val;
3472843Sktlim@umich.edu    }
3482307SN/A
3492307SN/A    uint64_t readNextNPC()
3502307SN/A    {
3512307SN/A        return regs.readNextNPC();
3522307SN/A    }
3532843Sktlim@umich.edu
3542843Sktlim@umich.edu    void setNextNPC(uint64_t val)
3552864Sktlim@umich.edu    {
3562843Sktlim@umich.edu        regs.setNextNPC(val);
3572843Sktlim@umich.edu    }
3582843Sktlim@umich.edu
3592843Sktlim@umich.edu    MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid = 0)
3602307SN/A    {
3612307SN/A        return regs.readMiscRegNoEffect(misc_reg);
3622316SN/A    }
3632307SN/A
3642307SN/A    MiscReg readMiscReg(int misc_reg, unsigned tid = 0)
3652307SN/A    {
3662307SN/A        return regs.readMiscReg(misc_reg, tc);
3672307SN/A    }
3682307SN/A
3692680Sktlim@umich.edu    void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0)
3702307SN/A    {
3712307SN/A        return regs.setMiscRegNoEffect(misc_reg, val);
3722307SN/A    }
3732307SN/A
3742307SN/A    void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid = 0)
3752307SN/A    {
3762307SN/A        return regs.setMiscReg(misc_reg, val, tc);
3772292SN/A    }
3782132SN/A
3792316SN/A    unsigned readStCondFailures() { return storeCondFailures; }
3803867Sbinkertn@umich.edu
3813867Sbinkertn@umich.edu    void setStCondFailures(unsigned sc_failures)
3823867Sbinkertn@umich.edu    { storeCondFailures = sc_failures; }
3833867Sbinkertn@umich.edu
3842316SN/A#if !FULL_SYSTEM
3853867Sbinkertn@umich.edu    TheISA::IntReg getSyscallArg(int i)
3862316SN/A    {
3872316SN/A        assert(i < TheISA::NumArgumentRegs);
3882316SN/A        TheISA::IntReg val = regs.readIntReg(
3892316SN/A                TheISA::flattenIntIndex(getTC(), TheISA::ArgumentReg[i]));
3902316SN/A#if THE_ISA == SPARC_ISA
3912316SN/A        if (bits(this->readMiscRegNoEffect(
3922316SN/A                        SparcISA::MISCREG_PSTATE), 3, 3)) {
3932292SN/A            val = bits(val, 31, 0);
3942292SN/A        }
3952292SN/A#endif
3962292SN/A        return val;
3972733Sktlim@umich.edu    }
3982292SN/A
3992292SN/A    // used to shift args for indirect syscall
4002733Sktlim@umich.edu    void setSyscallArg(int i, TheISA::IntReg val)
4012292SN/A    {
4022292SN/A        assert(i < TheISA::NumArgumentRegs);
4032292SN/A        regs.setIntReg(TheISA::flattenIntIndex(getTC(),
4042292SN/A                    TheISA::ArgumentReg[i]), val);
4052292SN/A    }
4062292SN/A
4072292SN/A    void setSyscallReturn(SyscallReturn return_value)
4082292SN/A    {
4092292SN/A        TheISA::setSyscallReturn(return_value, getTC());
4102292SN/A    }
4112292SN/A
4123867Sbinkertn@umich.edu    void syscall(int64_t callnum)
4133867Sbinkertn@umich.edu    {
4142292SN/A        process->syscall(callnum, tc);
4153867Sbinkertn@umich.edu    }
4162292SN/A#endif
4172292SN/A};
4182292SN/A
4192292SN/A
4202292SN/A// for non-speculative execution context, spec_mode is always false
4212292SN/Ainline bool
4222292SN/ASimpleThread::misspeculating()
4232702Sktlim@umich.edu{
4242292SN/A    return false;
4252292SN/A}
4262292SN/A
4272292SN/A#endif // __CPU_CPU_EXEC_CONTEXT_HH__
4282292SN/A