thread_context.hh revision 217
17860SN/A/*
27860SN/A * Copyright (c) 2003 The Regents of The University of Michigan
37860SN/A * All rights reserved.
49988Snilay@cs.wisc.edu *
58825Snilay@cs.wisc.edu * Redistribution and use in source and binary forms, with or without
69988Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are
77935SN/A * met: redistributions of source code must retain the above copyright
87935SN/A * notice, this list of conditions and the following disclaimer;
97935SN/A * redistributions in binary form must reproduce the above copyright
107860SN/A * notice, this list of conditions and the following disclaimer in the
117860SN/A * documentation and/or other materials provided with the distribution;
127860SN/A * neither the name of the copyright holders nor the names of its
1310315Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from
148825Snilay@cs.wisc.edu * this software without specific prior written permission.
159885Sstever@gmail.com *
169885Sstever@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179988Snilay@cs.wisc.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188825Snilay@cs.wisc.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198825Snilay@cs.wisc.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2010315Snilay@cs.wisc.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218825Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2210038SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239449SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249449SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258464SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2610798Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278660SN/A */
288825Snilay@cs.wisc.edu
298825Snilay@cs.wisc.edu#ifndef __EXEC_CONTEXT_HH__
307935SN/A#define __EXEC_CONTEXT_HH__
317935SN/A
327935SN/A#include "sim/host.hh"
337935SN/A#include "mem/mem_req.hh"
347935SN/A#include "sim/serialize.hh"
357935SN/A
367935SN/A// forward declaration: see functional_memory.hh
378893Ssaidi@eecs.umich.educlass FunctionalMemory;
387860SN/Aclass PhysicalMemory;
399885Sstever@gmail.comclass BaseCPU;
409885Sstever@gmail.com
419885Sstever@gmail.com#ifdef FULL_SYSTEM
4210315Snilay@cs.wisc.edu
439988Snilay@cs.wisc.edu#include "targetarch/alpha_memory.hh"
4410315Snilay@cs.wisc.educlass MemoryController;
459885Sstever@gmail.com
469885Sstever@gmail.com#include "kern/tru64/kernel_stats.hh"
477860SN/A#include "sim/system.hh"
487860SN/A
4910038SAli.Saidi@ARM.com#else // !FULL_SYSTEM
507860SN/A
5110451Snilay@cs.wisc.edu#include "sim/prog.hh"
528210SN/A
5310451Snilay@cs.wisc.edu#endif // FULL_SYSTEM
5410451Snilay@cs.wisc.edu
557860SN/A//
567860SN/A// The ExecContext object represents a functional context for
577860SN/A// instruction execution.  It incorporates everything required for
589481Snilay@cs.wisc.edu// architecture-level functional simulation of a single thread.
597860SN/A//
607860SN/A
619885Sstever@gmail.comclass ExecContext
627860SN/A{
637860SN/A  public:
647860SN/A    enum Status { Unallocated, Active, Suspended, Halted };
657860SN/A
667860SN/A  private:
677860SN/A    Status _status;
687860SN/A
6910451Snilay@cs.wisc.edu  public:
7010451Snilay@cs.wisc.edu    Status status() const { return _status; }
7110451Snilay@cs.wisc.edu
727860SN/A    void setStatus(Status new_status);
738825Snilay@cs.wisc.edu
747860SN/A#ifdef FULL_SYSTEM
7510038SAli.Saidi@ARM.com  public:
767860SN/A    KernelStats kernelStats;
779988Snilay@cs.wisc.edu#endif
7810451Snilay@cs.wisc.edu
7910451Snilay@cs.wisc.edu  public:
8010451Snilay@cs.wisc.edu    RegFile regs;	// correct-path register context
817860SN/A
8210451Snilay@cs.wisc.edu    // pointer to CPU associated with this context
837860SN/A    BaseCPU *cpu;
847860SN/A
857860SN/A    // Index of hardware thread context on the CPU that this represents.
867860SN/A    int thread_num;
877860SN/A
887860SN/A    // ID of this context w.r.t. the System or Process object to which
897860SN/A    // it belongs.  For full-system mode, this is the system CPU ID.
907860SN/A    int cpu_id;
918825Snilay@cs.wisc.edu
929449SAli.Saidi@ARM.com#ifdef FULL_SYSTEM
937860SN/A
947860SN/A    FunctionalMemory *mem;
9510038SAli.Saidi@ARM.com    AlphaItb *itb;
967860SN/A    AlphaDtb *dtb;
977860SN/A    System *system;
987860SN/A
997860SN/A    // the following two fields are redundant, since we can always
1007860SN/A    // look them up through the system pointer, but we'll leave them
1018825Snilay@cs.wisc.edu    // here for now for convenience
10210451Snilay@cs.wisc.edu    MemoryController *memCtrl;
10310451Snilay@cs.wisc.edu    PhysicalMemory *physmem;
10410451Snilay@cs.wisc.edu
10510451Snilay@cs.wisc.edu#else
10610451Snilay@cs.wisc.edu    Process *process;
1077860SN/A
1087860SN/A    FunctionalMemory *mem;	// functional storage for process address space
1098825Snilay@cs.wisc.edu
1107860SN/A    // Address space ID.  Note that this is used for TIMING cache
1117860SN/A    // simulation only; all functional memory accesses should use
1127860SN/A    // one of the FunctionalMemory pointers above.
11310451Snilay@cs.wisc.edu    short asid;
1147860SN/A
11510451Snilay@cs.wisc.edu#endif
1169885Sstever@gmail.com
1177860SN/A
1187860SN/A    /*
1197860SN/A     * number of executed instructions, for matching with syscall trace
1207860SN/A     * points in EIO files.
1217860SN/A     */
1227860SN/A    Counter func_exe_insn;
1237860SN/A
1247860SN/A    //
1257860SN/A    // Count failed store conditionals so we can warn of apparent
12610242Ssteve.reinhardt@amd.com    // application deadlock situations.
1277860SN/A    unsigned storeCondFailures;
1288521SN/A
1299449SAli.Saidi@ARM.com    // constructor: initialize context from given process structure
1307860SN/A#ifdef FULL_SYSTEM
1317860SN/A    ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
1327860SN/A                AlphaItb *_itb, AlphaDtb *_dtb, FunctionalMemory *_dem);
1337860SN/A#else
1347860SN/A    ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
1357860SN/A    ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
1367860SN/A                int _asid);
1377860SN/A#endif
1389481Snilay@cs.wisc.edu    virtual ~ExecContext() {}
13910798Ssteve.reinhardt@amd.com
14010451Snilay@cs.wisc.edu    virtual void takeOverFrom(ExecContext *oldContext);
14110451Snilay@cs.wisc.edu
1429481Snilay@cs.wisc.edu    void regStats(const std::string &name);
1439481Snilay@cs.wisc.edu
1449481Snilay@cs.wisc.edu    void serialize(std::ostream &os);
1459988Snilay@cs.wisc.edu    void unserialize(IniFile &db, const std::string &section);
1469481Snilay@cs.wisc.edu
1479481Snilay@cs.wisc.edu#ifdef FULL_SYSTEM
1489481Snilay@cs.wisc.edu    bool validInstAddr(Addr addr) { return true; }
1499481Snilay@cs.wisc.edu    bool validDataAddr(Addr addr) { return true; }
1509481Snilay@cs.wisc.edu    int getInstAsid() { return ITB_ASN_ASN(regs.ipr[TheISA::IPR_ITB_ASN]); }
1517860SN/A    int getDataAsid() { return DTB_ASN_ASN(regs.ipr[TheISA::IPR_DTB_ASN]); }
15211103Snilay@cs.wisc.edu
1539885Sstever@gmail.com    Fault translateInstReq(MemReqPtr req)
1548893Ssaidi@eecs.umich.edu    {
1557860SN/A        return itb->translate(req);
1569885Sstever@gmail.com    }
15710636Snilay@cs.wisc.edu
1589988Snilay@cs.wisc.edu    Fault translateDataReadReq(MemReqPtr req)
1597860SN/A    {
1609348SAli.Saidi@ARM.com        return dtb->translate(req, false);
16110900Snilay@cs.wisc.edu    }
1627860SN/A
16310451Snilay@cs.wisc.edu    Fault translateDataWriteReq(MemReqPtr req)
1647860SN/A    {
1658835SAli.Saidi@ARM.com        return dtb->translate(req, true);
1669348SAli.Saidi@ARM.com    }
16710036SAli.Saidi@ARM.com
16810451Snilay@cs.wisc.edu#else
1698835SAli.Saidi@ARM.com    bool validInstAddr(Addr addr)
1709885Sstever@gmail.com    { return process->validInstAddr(addr); }
17110451Snilay@cs.wisc.edu
17210451Snilay@cs.wisc.edu    bool validDataAddr(Addr addr)
1737860SN/A    { return process->validDataAddr(addr); }
1748893Ssaidi@eecs.umich.edu
1757860SN/A    int getInstAsid() { return asid; }
1769885Sstever@gmail.com    int getDataAsid() { return asid; }
1779885Sstever@gmail.com
1789885Sstever@gmail.com    Fault dummyTranslation(MemReqPtr req)
1799885Sstever@gmail.com    {
1809885Sstever@gmail.com#if 0
1819988Snilay@cs.wisc.edu        assert((req->vaddr >> 48 & 0xffff) == 0);
1829885Sstever@gmail.com#endif
18310036SAli.Saidi@ARM.com
18410451Snilay@cs.wisc.edu        // put the asid in the upper 16 bits of the paddr
1859885Sstever@gmail.com        req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
18610038SAli.Saidi@ARM.com        req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
18710038SAli.Saidi@ARM.com        return No_Fault;
18810038SAli.Saidi@ARM.com    }
18910038SAli.Saidi@ARM.com    Fault translateInstReq(MemReqPtr req)
19010038SAli.Saidi@ARM.com    {
19110798Ssteve.reinhardt@amd.com        return dummyTranslation(req);
19210038SAli.Saidi@ARM.com    }
19310038SAli.Saidi@ARM.com    Fault translateDataReadReq(MemReqPtr req)
19410038SAli.Saidi@ARM.com    {
19510038SAli.Saidi@ARM.com        return dummyTranslation(req);
19610038SAli.Saidi@ARM.com    }
19710038SAli.Saidi@ARM.com    Fault translateDataWriteReq(MemReqPtr req)
19810038SAli.Saidi@ARM.com    {
19910038SAli.Saidi@ARM.com        return dummyTranslation(req);
20010038SAli.Saidi@ARM.com    }
20110038SAli.Saidi@ARM.com
20210038SAli.Saidi@ARM.com#endif
20310038SAli.Saidi@ARM.com
20410038SAli.Saidi@ARM.com    template <class T>
20510038SAli.Saidi@ARM.com    Fault read(MemReqPtr req, T& data)
20610038SAli.Saidi@ARM.com    {
20710038SAli.Saidi@ARM.com#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM)
20810038SAli.Saidi@ARM.com        if (req->flags & LOCKED) {
20910038SAli.Saidi@ARM.com            MiscRegFile *cregs = &req->xc->regs.miscRegs;
2107860SN/A            cregs->lock_addr = req->paddr;
2117860SN/A            cregs->lock_flag = true;
2128825Snilay@cs.wisc.edu        }
2139988Snilay@cs.wisc.edu#endif
21410038SAli.Saidi@ARM.com        return mem->read(req, data);
2157860SN/A    }
2168825Snilay@cs.wisc.edu
2178825Snilay@cs.wisc.edu    template <class T>
2188825Snilay@cs.wisc.edu    Fault write(MemReqPtr req, T& data)
2198825Snilay@cs.wisc.edu    {
2209885Sstever@gmail.com#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM)
2219988Snilay@cs.wisc.edu
22210038SAli.Saidi@ARM.com        MiscRegFile *cregs;
2239265SAli.Saidi@ARM.com
2248825Snilay@cs.wisc.edu        // If this is a store conditional, act appropriately
2258893Ssaidi@eecs.umich.edu        if (req->flags & LOCKED) {
2267860SN/A            cregs = &req->xc->regs.miscRegs;
2277860SN/A
2287860SN/A            if (req->flags & UNCACHEABLE) {
22910451Snilay@cs.wisc.edu                // Don't update result register (see stq_c in isa_desc)
23010451Snilay@cs.wisc.edu                req->result = 2;
2319988Snilay@cs.wisc.edu                req->xc->storeCondFailures = 0;//Needed? [RGD]
2327860SN/A            } else {
2337860SN/A                req->result = cregs->lock_flag;
2347860SN/A                if (!cregs->lock_flag ||
2357860SN/A                    ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) {
23610451Snilay@cs.wisc.edu                    cregs->lock_flag = false;
2379988Snilay@cs.wisc.edu                    if (((++req->xc->storeCondFailures) % 100000) == 0) {
2387860SN/A                        std::cerr << "Warning: "
2397860SN/A                                  << req->xc->storeCondFailures
2407860SN/A                                  << " consecutive store conditional failures "
2417860SN/A                                  << "on cpu " << req->xc->cpu_id
2429988Snilay@cs.wisc.edu                                  << std::endl;
2437860SN/A                    }
2447860SN/A                    return No_Fault;
24510900Snilay@cs.wisc.edu                }
2467860SN/A                else req->xc->storeCondFailures = 0;
2477860SN/A            }
2487860SN/A        }
24910451Snilay@cs.wisc.edu
25010451Snilay@cs.wisc.edu        // Need to clear any locked flags on other proccessors for
2519988Snilay@cs.wisc.edu        // this address.  Only do this for succsful Store Conditionals
25210451Snilay@cs.wisc.edu        // and all other stores (WH64?).  Unsuccessful Store
2537860SN/A        // Conditionals would have returned above, and wouldn't fall
2547860SN/A        // through.
2557860SN/A        for (int i = 0; i < system->execContexts.size(); i++){
2569988Snilay@cs.wisc.edu            cregs = &system->execContexts[i]->regs.miscRegs;
2577860SN/A            if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) {
2587860SN/A                cregs->lock_flag = false;
25910900Snilay@cs.wisc.edu            }
2607860SN/A        }
2617860SN/A
2627860SN/A#endif
2639988Snilay@cs.wisc.edu        return mem->write(req, data);
2647860SN/A    }
26510451Snilay@cs.wisc.edu
26610900Snilay@cs.wisc.edu    virtual bool misspeculating();
26710451Snilay@cs.wisc.edu
26810451Snilay@cs.wisc.edu
26910451Snilay@cs.wisc.edu    //
27010451Snilay@cs.wisc.edu    // New accessors for new decoder.
27110451Snilay@cs.wisc.edu    //
27210451Snilay@cs.wisc.edu    uint64_t readIntReg(int reg_idx)
27310900Snilay@cs.wisc.edu    {
2747860SN/A        return regs.intRegFile[reg_idx];
2757860SN/A    }
2767860SN/A
27710451Snilay@cs.wisc.edu    float readFloatRegSingle(int reg_idx)
27810451Snilay@cs.wisc.edu    {
2799988Snilay@cs.wisc.edu        return (float)regs.floatRegFile.d[reg_idx];
28010451Snilay@cs.wisc.edu    }
2817860SN/A
28210451Snilay@cs.wisc.edu    double readFloatRegDouble(int reg_idx)
2837860SN/A    {
2849988Snilay@cs.wisc.edu        return regs.floatRegFile.d[reg_idx];
28510451Snilay@cs.wisc.edu    }
2867860SN/A
28710900Snilay@cs.wisc.edu    uint64_t readFloatRegInt(int reg_idx)
2887860SN/A    {
2897860SN/A        return regs.floatRegFile.q[reg_idx];
2907860SN/A    }
29110451Snilay@cs.wisc.edu
29210451Snilay@cs.wisc.edu    void setIntReg(int reg_idx, uint64_t val)
2939988Snilay@cs.wisc.edu    {
29410451Snilay@cs.wisc.edu        regs.intRegFile[reg_idx] = val;
2957860SN/A    }
29610451Snilay@cs.wisc.edu
2977860SN/A    void setFloatRegSingle(int reg_idx, float val)
2989988Snilay@cs.wisc.edu    {
29910451Snilay@cs.wisc.edu        regs.floatRegFile.d[reg_idx] = (double)val;
30010451Snilay@cs.wisc.edu    }
30110900Snilay@cs.wisc.edu
3027860SN/A    void setFloatRegDouble(int reg_idx, double val)
3037860SN/A    {
3047860SN/A        regs.floatRegFile.d[reg_idx] = val;
30510451Snilay@cs.wisc.edu    }
30610451Snilay@cs.wisc.edu
3079988Snilay@cs.wisc.edu    void setFloatRegInt(int reg_idx, uint64_t val)
30810451Snilay@cs.wisc.edu    {
3097860SN/A        regs.floatRegFile.q[reg_idx] = val;
31010451Snilay@cs.wisc.edu    }
3117860SN/A
3129988Snilay@cs.wisc.edu    uint64_t readPC()
3137860SN/A    {
31410451Snilay@cs.wisc.edu        return regs.pc;
31510900Snilay@cs.wisc.edu    }
3167860SN/A
31710451Snilay@cs.wisc.edu    void setNextPC(uint64_t val)
3187860SN/A    {
3199988Snilay@cs.wisc.edu        regs.npc = val;
3207860SN/A    }
32110451Snilay@cs.wisc.edu
32210900Snilay@cs.wisc.edu    uint64_t readUniq()
3237860SN/A    {
32410451Snilay@cs.wisc.edu        return regs.miscRegs.uniq;
3257860SN/A    }
3269988Snilay@cs.wisc.edu
3277860SN/A    void setUniq(uint64_t val)
32810451Snilay@cs.wisc.edu    {
32910900Snilay@cs.wisc.edu        regs.miscRegs.uniq = val;
3307860SN/A    }
33110451Snilay@cs.wisc.edu
3327860SN/A    uint64_t readFpcr()
3339988Snilay@cs.wisc.edu    {
3347860SN/A        return regs.miscRegs.fpcr;
33510451Snilay@cs.wisc.edu    }
33610900Snilay@cs.wisc.edu
3377860SN/A    void setFpcr(uint64_t val)
33810451Snilay@cs.wisc.edu    {
3397860SN/A        regs.miscRegs.fpcr = val;
3409988Snilay@cs.wisc.edu    }
3417860SN/A
34210451Snilay@cs.wisc.edu#ifdef FULL_SYSTEM
34310900Snilay@cs.wisc.edu    uint64_t readIpr(int idx, Fault &fault);
3447860SN/A    Fault setIpr(int idx, uint64_t val);
34510451Snilay@cs.wisc.edu    Fault hwrei();
3467860SN/A    void ev5_trap(Fault fault);
3479988Snilay@cs.wisc.edu    bool simPalCheck(int palFunc);
3487860SN/A#endif
34910451Snilay@cs.wisc.edu
35010900Snilay@cs.wisc.edu#ifndef FULL_SYSTEM
3517860SN/A    void syscall()
35210451Snilay@cs.wisc.edu    {
3537860SN/A        process->syscall(this);
3549988Snilay@cs.wisc.edu    }
3557860SN/A#endif
35610451Snilay@cs.wisc.edu};
35710900Snilay@cs.wisc.edu
3587860SN/A
35910451Snilay@cs.wisc.edu// for non-speculative execution context, spec_mode is always false
3607860SN/Ainline bool
3619988Snilay@cs.wisc.eduExecContext::misspeculating()
3627860SN/A{
36310451Snilay@cs.wisc.edu    return false;
36410900Snilay@cs.wisc.edu}
3657860SN/A
36610451Snilay@cs.wisc.edu#endif // __EXEC_CONTEXT_HH__
3677860SN/A