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