thread_context.hh revision 2159
11689SN/A/*
22326SN/A * Copyright (c) 2001-2005 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
291689SN/A#ifndef __CPU_EXEC_CONTEXT_HH__
301689SN/A#define __CPU_EXEC_CONTEXT_HH__
311060SN/A
321060SN/A#include "config/full_system.hh"
331689SN/A#include "mem/functional/functional.hh"
341060SN/A#include "mem/mem_req.hh"
351060SN/A#include "sim/host.hh"
361060SN/A#include "sim/serialize.hh"
371060SN/A#include "arch/isa_traits.hh"
386658Snate@binkert.org//#include "arch/isa_registers.hh"
392292SN/A#include "sim/byteswap.hh"
401717SN/A
415529Snate@binkert.org// forward declaration: see functional_memory.hh
421060SN/Aclass FunctionalMemory;
436221Snate@binkert.orgclass PhysicalMemory;
446221Snate@binkert.orgclass BaseCPU;
451681SN/A
465529Snate@binkert.org#if FULL_SYSTEM
472873Sktlim@umich.edu
484329Sktlim@umich.edu#include "sim/system.hh"
494329Sktlim@umich.edu#include "targetarch/alpha_memory.hh"
504329Sktlim@umich.edu
512292SN/Aclass FunctionProfile;
522292SN/Aclass ProfileNode;
532292SN/Aclass MemoryController;
542292SN/Anamespace Kernel { class Binning; class Statistics; }
552820Sktlim@umich.edu
562292SN/A#else // !FULL_SYSTEM
572820Sktlim@umich.edu
582820Sktlim@umich.edu#include "sim/process.hh"
595529Snate@binkert.org
602307SN/A#endif // FULL_SYSTEM
611060SN/A
622292SN/A//
632292SN/A// The ExecContext object represents a functional context for
642292SN/A// instruction execution.  It incorporates everything required for
651060SN/A// architecture-level functional simulation of a single thread.
661060SN/A//
671060SN/A
681060SN/Aclass ExecContext
691060SN/A{
701060SN/A  protected:
711681SN/A    typedef TheISA::RegFile RegFile;
726221Snate@binkert.org    typedef TheISA::MachInst MachInst;
736221Snate@binkert.org    typedef TheISA::MiscRegFile MiscRegFile;
746221Snate@binkert.org    typedef TheISA::MiscReg MiscReg;
756221Snate@binkert.org  public:
762292SN/A    enum Status
772292SN/A    {
782820Sktlim@umich.edu        /// Initialized but not running yet.  All CPUs start in
792820Sktlim@umich.edu        /// this state, but most transition to Active on cycle 1.
802292SN/A        /// In MP or SMT systems, non-primary contexts will stay
812292SN/A        /// in this state until a thread is assigned to them.
822820Sktlim@umich.edu        Unallocated,
832820Sktlim@umich.edu
842292SN/A        /// Running.  Instructions should be executed only when
852292SN/A        /// the context is in this state.
862292SN/A        Active,
872292SN/A
882292SN/A        /// Temporarily inactive.  Entered while waiting for
892292SN/A        /// initialization,synchronization, etc.
902292SN/A        Suspended,
912292SN/A
921060SN/A        /// Permanently shut down.  Entered when target executes
931060SN/A        /// m5exit pseudo-instruction.  When all contexts enter
941681SN/A        /// this state, the simulation will terminate.
951062SN/A        Halted
962292SN/A    };
971062SN/A
982301SN/A  private:
992301SN/A    Status _status;
1001062SN/A
1012727Sktlim@umich.edu  public:
1021062SN/A    Status status() const { return _status; }
1031062SN/A
1041062SN/A    void setStatus(Status newStatus) { _status = newStatus; }
1051062SN/A
1061062SN/A    /// Set the status to Active.  Optional delay indicates number of
1071062SN/A    /// cycles to wait before beginning execution.
1081062SN/A    void activate(int delay = 1);
1091062SN/A
1101062SN/A    /// Set the status to Suspended.
1111062SN/A    void suspend();
1121062SN/A
1131062SN/A    /// Set the status to Unallocated.
1141062SN/A    void deallocate();
1151062SN/A
1161062SN/A    /// Set the status to Halted.
1171062SN/A    void halt();
1181062SN/A
1191062SN/A  public:
1201062SN/A    RegFile regs;	// correct-path register context
1211062SN/A
1221062SN/A    // pointer to CPU associated with this context
1231062SN/A    BaseCPU *cpu;
1241062SN/A
1251062SN/A    // Current instruction
1261062SN/A    MachInst inst;
1271062SN/A
1281062SN/A    // Index of hardware thread context on the CPU that this represents.
1291062SN/A    int thread_num;
1301062SN/A
1311062SN/A    // ID of this context w.r.t. the System or Process object to which
1321062SN/A    // it belongs.  For full-system mode, this is the system CPU ID.
1331062SN/A    int cpu_id;
1341062SN/A
1351062SN/A#if FULL_SYSTEM
1361062SN/A    FunctionalMemory *mem;
1371062SN/A    AlphaITB *itb;
1381062SN/A    AlphaDTB *dtb;
1391062SN/A    System *system;
1401062SN/A
1411062SN/A    // the following two fields are redundant, since we can always
1421062SN/A    // look them up through the system pointer, but we'll leave them
1432292SN/A    // here for now for convenience
1442292SN/A    MemoryController *memctrl;
1452292SN/A    PhysicalMemory *physmem;
1462292SN/A
1471062SN/A    Kernel::Binning *kernelBinning;
1481062SN/A    Kernel::Statistics *kernelStats;
1491062SN/A    bool bin;
1501062SN/A    bool fnbin;
1511062SN/A
1521062SN/A    FunctionProfile *profile;
1531062SN/A    ProfileNode *profileNode;
1542292SN/A    Addr profilePC;
1552292SN/A    void dumpFuncProfile();
1562292SN/A
1572292SN/A#else
1582292SN/A    Process *process;
1592292SN/A
1602292SN/A    FunctionalMemory *mem;	// functional storage for process address space
1612292SN/A
1622292SN/A    // Address space ID.  Note that this is used for TIMING cache
1632292SN/A    // simulation only; all functional memory accesses should use
1642301SN/A    // one of the FunctionalMemory pointers above.
1652727Sktlim@umich.edu    short asid;
1662353SN/A
1672727Sktlim@umich.edu#endif
1682727Sktlim@umich.edu
1692727Sktlim@umich.edu    /**
1706221Snate@binkert.org     * Temporary storage to pass the source address from copy_load to
1712353SN/A     * copy_store.
1722727Sktlim@umich.edu     * @todo Remove this temporary when we have a better way to do it.
1732727Sktlim@umich.edu     */
1742727Sktlim@umich.edu    Addr copySrcAddr;
1752727Sktlim@umich.edu    /**
1762353SN/A     * Temp storage for the physical source address of a copy.
1772727Sktlim@umich.edu     * @todo Remove this temporary when we have a better way to do it.
1782727Sktlim@umich.edu     */
1792727Sktlim@umich.edu    Addr copySrcPhysAddr;
1806221Snate@binkert.org
1812301SN/A
1822301SN/A    /*
1832727Sktlim@umich.edu     * number of executed instructions, for matching with syscall trace
1842301SN/A     * points in EIO files.
1852727Sktlim@umich.edu     */
1866221Snate@binkert.org    Counter func_exe_inst;
1872301SN/A
1882301SN/A    //
1892727Sktlim@umich.edu    // Count failed store conditionals so we can warn of apparent
1902301SN/A    // application deadlock situations.
1912727Sktlim@umich.edu    unsigned storeCondFailures;
1926221Snate@binkert.org
1932301SN/A    // constructor: initialize context from given process structure
1942301SN/A#if FULL_SYSTEM
1952727Sktlim@umich.edu    ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
1962301SN/A                AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
1972727Sktlim@umich.edu#else
1986221Snate@binkert.org    ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
1992301SN/A    ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
2002301SN/A                int _asid);
2012727Sktlim@umich.edu#endif
2022301SN/A    virtual ~ExecContext();
2032301SN/A
2042301SN/A    virtual void takeOverFrom(ExecContext *oldContext);
2052301SN/A
2062727Sktlim@umich.edu    void regStats(const std::string &name);
2072727Sktlim@umich.edu
2082727Sktlim@umich.edu    void serialize(std::ostream &os);
2092727Sktlim@umich.edu    void unserialize(Checkpoint *cp, const std::string &section);
2102727Sktlim@umich.edu
2112727Sktlim@umich.edu#if FULL_SYSTEM
2122727Sktlim@umich.edu    bool validInstAddr(Addr addr) { return true; }
2132727Sktlim@umich.edu    bool validDataAddr(Addr addr) { return true; }
2142727Sktlim@umich.edu    int getInstAsid() { return regs.instAsid(); }
2152301SN/A    int getDataAsid() { return regs.dataAsid(); }
2162301SN/A
2176221Snate@binkert.org    Fault translateInstReq(MemReqPtr &req)
2182301SN/A    {
2192301SN/A        return itb->translate(req);
2202727Sktlim@umich.edu    }
2212301SN/A
2222326SN/A    Fault translateDataReadReq(MemReqPtr &req)
2236221Snate@binkert.org    {
2242301SN/A        return dtb->translate(req, false);
2252301SN/A    }
2262727Sktlim@umich.edu
2272301SN/A    Fault translateDataWriteReq(MemReqPtr &req)
2282326SN/A    {
2296221Snate@binkert.org        return dtb->translate(req, true);
2302301SN/A    }
2312301SN/A
2322727Sktlim@umich.edu#else
2332301SN/A    bool validInstAddr(Addr addr)
2342326SN/A    { return process->validInstAddr(addr); }
2356221Snate@binkert.org
2362301SN/A    bool validDataAddr(Addr addr)
2372301SN/A    { return process->validDataAddr(addr); }
2382727Sktlim@umich.edu
2392301SN/A    int getInstAsid() { return asid; }
2402326SN/A    int getDataAsid() { return asid; }
2416221Snate@binkert.org
2422301SN/A    Fault dummyTranslation(MemReqPtr &req)
2432301SN/A    {
2442727Sktlim@umich.edu#if 0
2452301SN/A        assert((req->vaddr >> 48 & 0xffff) == 0);
2462326SN/A#endif
2472301SN/A
2482301SN/A        // put the asid in the upper 16 bits of the paddr
2492727Sktlim@umich.edu        req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
2502301SN/A        req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
2512326SN/A        return NoFault;
2522301SN/A    }
2532326SN/A    Fault translateInstReq(MemReqPtr &req)
2542301SN/A    {
2552301SN/A        return dummyTranslation(req);
2562727Sktlim@umich.edu    }
2572301SN/A    Fault translateDataReadReq(MemReqPtr &req)
2582326SN/A    {
2592301SN/A        return dummyTranslation(req);
2602326SN/A    }
2612301SN/A    Fault translateDataWriteReq(MemReqPtr &req)
2622301SN/A    {
2632727Sktlim@umich.edu        return dummyTranslation(req);
2642326SN/A    }
2651062SN/A
2661062SN/A#endif
2671681SN/A
2681060SN/A    template <class T>
2692292SN/A    Fault read(MemReqPtr &req, T &data)
2701060SN/A    {
2716221Snate@binkert.org#if FULL_SYSTEM && defined(TARGET_ALPHA)
2722292SN/A        if (req->flags & LOCKED) {
2732292SN/A            MiscRegFile *cregs = &req->xc->regs.miscRegs;
2742292SN/A            cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr);
2752292SN/A            cregs->setReg(TheISA::Lock_Flag_DepTag, true);
2762292SN/A        }
2772292SN/A#endif
2782292SN/A
2792292SN/A        Fault error;
2802292SN/A        error = mem->read(req, data);
2812733Sktlim@umich.edu        data = LittleEndianGuest::gtoh(data);
2821060SN/A        return error;
2831060SN/A    }
2841681SN/A
2851060SN/A    template <class T>
2862292SN/A    Fault write(MemReqPtr &req, T &data)
2871060SN/A    {
2881060SN/A#if FULL_SYSTEM && defined(TARGET_ALPHA)
2891060SN/A
2901060SN/A        MiscRegFile *cregs;
2911060SN/A
2921060SN/A        // If this is a store conditional, act appropriately
2931060SN/A        if (req->flags & LOCKED) {
2941060SN/A            cregs = &req->xc->regs.miscRegs;
2951060SN/A
2962292SN/A            if (req->flags & UNCACHEABLE) {
2972292SN/A                // Don't update result register (see stq_c in isa_desc)
2981060SN/A                req->result = 2;
2991060SN/A                req->xc->storeCondFailures = 0;//Needed? [RGD]
3001060SN/A            } else {
3011060SN/A                bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag);
3021681SN/A                Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag);
3031060SN/A                req->result = lock_flag;
3042292SN/A                if (!lock_flag ||
3051060SN/A                    ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
3061060SN/A                    cregs->setReg(TheISA::Lock_Flag_DepTag, false);
3071060SN/A                    if (((++req->xc->storeCondFailures) % 100000) == 0) {
3081060SN/A                        std::cerr << "Warning: "
3091060SN/A                                  << req->xc->storeCondFailures
3101060SN/A                                  << " consecutive store conditional failures "
3111060SN/A                                  << "on cpu " << req->xc->cpu_id
3121681SN/A                                  << std::endl;
3131060SN/A                    }
3142292SN/A                    return NoFault;
3151060SN/A                }
3161060SN/A                else req->xc->storeCondFailures = 0;
3171060SN/A            }
3181060SN/A        }
3191060SN/A
3201060SN/A        // Need to clear any locked flags on other proccessors for
3211060SN/A        // this address.  Only do this for succsful Store Conditionals
3221681SN/A        // and all other stores (WH64?).  Unsuccessful Store
3231060SN/A        // Conditionals would have returned above, and wouldn't fall
3246221Snate@binkert.org        // through.
3251060SN/A        for (int i = 0; i < system->execContexts.size(); i++){
3262292SN/A            cregs = &system->execContexts[i]->regs.miscRegs;
3272292SN/A            if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
3282292SN/A                (req->paddr & ~0xf)) {
3292292SN/A                cregs->setReg(TheISA::Lock_Flag_DepTag, false);
3301060SN/A            }
3311060SN/A        }
3321681SN/A
3331060SN/A#endif
3342292SN/A        return mem->write(req, (T)LittleEndianGuest::htog(data));
3351060SN/A    }
3362292SN/A
3371060SN/A    virtual bool misspeculating();
3381060SN/A
3392307SN/A
3402863Sktlim@umich.edu    MachInst getInst() { return inst; }
3412843Sktlim@umich.edu
3422307SN/A    void setInst(MachInst new_inst)
3432843Sktlim@umich.edu    {
3442843Sktlim@umich.edu        inst = new_inst;
3452863Sktlim@umich.edu    }
3461681SN/A
3471681SN/A    Fault instRead(MemReqPtr &req)
3482316SN/A    {
3491681SN/A        return mem->read(req, inst);
3502843Sktlim@umich.edu    }
3512843Sktlim@umich.edu
3522843Sktlim@umich.edu    //
3532843Sktlim@umich.edu    // New accessors for new decoder.
3542843Sktlim@umich.edu    //
3552843Sktlim@umich.edu    uint64_t readIntReg(int reg_idx)
3562843Sktlim@umich.edu    {
3571681SN/A        return regs.intRegFile[reg_idx];
3582348SN/A    }
3592307SN/A
3602367SN/A    float readFloatRegSingle(int reg_idx)
3612367SN/A    {
3621681SN/A        return (float)regs.floatRegFile.d[reg_idx];
3632307SN/A    }
3642307SN/A
3652307SN/A    double readFloatRegDouble(int reg_idx)
3662307SN/A    {
3676221Snate@binkert.org        return regs.floatRegFile.d[reg_idx];
3686221Snate@binkert.org    }
3696221Snate@binkert.org
3706221Snate@binkert.org    uint64_t readFloatRegInt(int reg_idx)
3716221Snate@binkert.org    {
3722307SN/A        return regs.floatRegFile.q[reg_idx];
3731681SN/A    }
3741681SN/A
3752307SN/A    void setIntReg(int reg_idx, uint64_t val)
3761681SN/A    {
3772307SN/A        regs.intRegFile[reg_idx] = val;
3781060SN/A    }
3792348SN/A
3802307SN/A    void setFloatRegSingle(int reg_idx, float val)
3812307SN/A    {
3822307SN/A        regs.floatRegFile.d[reg_idx] = (double)val;
3832307SN/A    }
3841060SN/A
3852307SN/A    void setFloatRegDouble(int reg_idx, double val)
3862307SN/A    {
3872307SN/A        regs.floatRegFile.d[reg_idx] = val;
3881060SN/A    }
3892307SN/A
3902307SN/A    void setFloatRegInt(int reg_idx, uint64_t val)
3911060SN/A    {
3926221Snate@binkert.org        regs.floatRegFile.q[reg_idx] = val;
3936221Snate@binkert.org    }
3946221Snate@binkert.org
3956221Snate@binkert.org    uint64_t readPC()
3962307SN/A    {
3971060SN/A        return regs.pc;
3982307SN/A    }
3992307SN/A
4002873Sktlim@umich.edu    void setNextPC(uint64_t val)
4012307SN/A    {
4021060SN/A        regs.npc = val;
4031060SN/A    }
4041060SN/A
4051681SN/A    MiscReg readMiscReg(int misc_reg)
4061060SN/A    {
4076221Snate@binkert.org        return regs.miscRegs.readReg(misc_reg);
4082107SN/A    }
4096221Snate@binkert.org
4102107SN/A    MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
4112292SN/A    {
4122292SN/A        return regs.miscRegs.readRegWithEffect(misc_reg, fault, this);
4132107SN/A    }
4142292SN/A
4152326SN/A    Fault setMiscReg(int misc_reg, const MiscReg &val)
4162292SN/A    {
4172107SN/A        return regs.miscRegs.setReg(misc_reg, val);
4182292SN/A    }
4192935Sksewell@umich.edu
4204632Sgblack@eecs.umich.edu    Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
4212935Sksewell@umich.edu    {
4222292SN/A        return regs.miscRegs.setRegWithEffect(misc_reg, val, this);
4232292SN/A    }
4242292SN/A
4252292SN/A#if FULL_SYSTEM
4262292SN/A    int readIntrFlag() { return regs.intrflag; }
4272107SN/A    void setIntrFlag(int val) { regs.intrflag = val; }
4282292SN/A    Fault hwrei();
4292107SN/A    bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
4302292SN/A    void ev5_trap(Fault fault);
4312292SN/A    bool simPalCheck(int palFunc);
4322107SN/A#endif
4332702Sktlim@umich.edu
4342107SN/A    /** Meant to be more generic trap function to be
4352107SN/A     *  called when an instruction faults.
4362107SN/A     *  @param fault The fault generated by executing the instruction.
4372107SN/A     *  @todo How to do this properly so it's dependent upon ISA only?
4386221Snate@binkert.org     */
4392292SN/A
4402292SN/A    void trap(Fault fault);
4412292SN/A
4422292SN/A#if !FULL_SYSTEM
4432292SN/A    TheISA::IntReg getSyscallArg(int i)
4442292SN/A    {
4452292SN/A        return regs.intRegFile[TheISA::ArgumentReg0 + i];
4462292SN/A    }
4472935Sksewell@umich.edu
4484632Sgblack@eecs.umich.edu    // used to shift args for indirect syscall
4493969Sgblack@eecs.umich.edu    void setSyscallArg(int i, TheISA::IntReg val)
4504632Sgblack@eecs.umich.edu    {
4513795Sgblack@eecs.umich.edu        regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
4523795Sgblack@eecs.umich.edu    }
4533795Sgblack@eecs.umich.edu
4543093Sksewell@umich.edu    void setSyscallReturn(SyscallReturn return_value)
4553093Sksewell@umich.edu    {
4563093Sksewell@umich.edu        // check for error condition.  Alpha syscall convention is to
4574632Sgblack@eecs.umich.edu        // indicate success/failure in reg a3 (r19) and put the
4583093Sksewell@umich.edu        // return value itself in the standard return value reg (v0).
4594632Sgblack@eecs.umich.edu        const int RegA3 = 19;	// only place this is used
4604636Sgblack@eecs.umich.edu        if (return_value.successful()) {
4612292SN/A            // no error
4622292SN/A            regs.intRegFile[RegA3] = 0;
4632292SN/A            regs.intRegFile[TheISA::ReturnValueReg] = return_value.value();
4642292SN/A        } else {
4652292SN/A            // got an error, return details
4662292SN/A            regs.intRegFile[RegA3] = (TheISA::IntReg) -1;
4672292SN/A            regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value();
4682292SN/A        }
4696221Snate@binkert.org    }
4702292SN/A
4712292SN/A    void syscall()
4722292SN/A    {
4732292SN/A        process->syscall(this);
4742292SN/A    }
4752292SN/A#endif
4762292SN/A};
4773795Sgblack@eecs.umich.edu
4783732Sktlim@umich.edu
4792292SN/A// for non-speculative execution context, spec_mode is always false
4802292SN/Ainline bool
4812292SN/AExecContext::misspeculating()
4822292SN/A{
4832292SN/A    return false;
4842292SN/A}
4852292SN/A
4862292SN/A#endif // __CPU_EXEC_CONTEXT_HH__
4876221Snate@binkert.org