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 &section);
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