regfile.hh revision 1684
14484Sbinkertn@umich.edu#ifndef __CPU_BETA_CPU_REGFILE_HH__
24484Sbinkertn@umich.edu#define __CPU_BETA_CPU_REGFILE_HH__
34484Sbinkertn@umich.edu
44484Sbinkertn@umich.edu// @todo: Destructor
54484Sbinkertn@umich.edu
64484Sbinkertn@umich.edu#include "arch/alpha/isa_traits.hh"
74484Sbinkertn@umich.edu#include "base/trace.hh"
84484Sbinkertn@umich.edu#include "cpu/beta_cpu/comm.hh"
94484Sbinkertn@umich.edu
104484Sbinkertn@umich.edu#ifdef FULL_SYSTEM
114484Sbinkertn@umich.edu#include "arch/alpha/ev5.hh"
124484Sbinkertn@umich.edu#include "kern/kernel_stats.hh"
134484Sbinkertn@umich.edu
144484Sbinkertn@umich.eduusing namespace EV5;
154484Sbinkertn@umich.edu#endif
164484Sbinkertn@umich.edu
174484Sbinkertn@umich.edu// This really only depends on the ISA, and not the Impl.  It might be nicer
184484Sbinkertn@umich.edu// to see if I can make it depend on nothing...
194484Sbinkertn@umich.edu// Things that are in the ifdef FULL_SYSTEM are pretty dependent on the ISA,
204484Sbinkertn@umich.edu// and should go in the AlphaFullCPU.
214484Sbinkertn@umich.edu
224484Sbinkertn@umich.edutemplate <class Impl>
234484Sbinkertn@umich.educlass PhysRegFile
244484Sbinkertn@umich.edu{
254484Sbinkertn@umich.edu    //Note that most of the definitions of the IntReg, FloatReg, etc. exist
264484Sbinkertn@umich.edu    //within the Impl/ISA class and not within this PhysRegFile class.
274484Sbinkertn@umich.edu
284484Sbinkertn@umich.edu    //Will need some way to allow stuff like swap_palshadow to access the
294484Sbinkertn@umich.edu    //correct registers.  Might require code changes to swap_palshadow and
304484Sbinkertn@umich.edu    //other execution contexts.
314484Sbinkertn@umich.edu
324484Sbinkertn@umich.edu    //Will make these registers public for now, but they probably should
334484Sbinkertn@umich.edu    //be private eventually with some accessor functions.
344484Sbinkertn@umich.edu  public:
354484Sbinkertn@umich.edu    typedef typename Impl::ISA ISA;
364484Sbinkertn@umich.edu    typedef typename Impl::FullCPU FullCPU;
374484Sbinkertn@umich.edu
384484Sbinkertn@umich.edu    PhysRegFile(unsigned _numPhysicalIntRegs,
394484Sbinkertn@umich.edu                unsigned _numPhysicalFloatRegs);
404484Sbinkertn@umich.edu
414484Sbinkertn@umich.edu    //Everything below should be pretty well identical to the normal
424484Sbinkertn@umich.edu    //register file that exists within AlphaISA class.
434484Sbinkertn@umich.edu    //The duplication is unfortunate but it's better than having
444484Sbinkertn@umich.edu    //different ways to access certain registers.
454484Sbinkertn@umich.edu
464484Sbinkertn@umich.edu    //Add these in later when everything else is in place
474484Sbinkertn@umich.edu//    void serialize(std::ostream &os);
484494Ssaidi@eecs.umich.edu//    void unserialize(Checkpoint *cp, const std::string &section);
494494Ssaidi@eecs.umich.edu
504494Ssaidi@eecs.umich.edu    uint64_t readIntReg(PhysRegIndex reg_idx)
514484Sbinkertn@umich.edu    {
524484Sbinkertn@umich.edu        assert(reg_idx < numPhysicalIntRegs);
534484Sbinkertn@umich.edu
544484Sbinkertn@umich.edu        DPRINTF(IEW, "RegFile: Access to int register %i, has data "
554484Sbinkertn@umich.edu                "%i\n", int(reg_idx), intRegFile[reg_idx]);
564484Sbinkertn@umich.edu        return intRegFile[reg_idx];
574484Sbinkertn@umich.edu    }
584484Sbinkertn@umich.edu
594484Sbinkertn@umich.edu    float readFloatRegSingle(PhysRegIndex reg_idx)
604484Sbinkertn@umich.edu    {
614484Sbinkertn@umich.edu        // Remove the base Float reg dependency.
624484Sbinkertn@umich.edu        reg_idx = reg_idx - numPhysicalIntRegs;
634484Sbinkertn@umich.edu
644484Sbinkertn@umich.edu        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
654484Sbinkertn@umich.edu
664484Sbinkertn@umich.edu        DPRINTF(IEW, "RegFile: Access to float register %i as single, has "
674484Sbinkertn@umich.edu                "data %8.8f\n", int(reg_idx), (float)floatRegFile[reg_idx].d);
684484Sbinkertn@umich.edu
694484Sbinkertn@umich.edu        return (float)floatRegFile[reg_idx].d;
704484Sbinkertn@umich.edu    }
714484Sbinkertn@umich.edu
724484Sbinkertn@umich.edu    double readFloatRegDouble(PhysRegIndex reg_idx)
734484Sbinkertn@umich.edu    {
744484Sbinkertn@umich.edu        // Remove the base Float reg dependency.
754484Sbinkertn@umich.edu        reg_idx = reg_idx - numPhysicalIntRegs;
764484Sbinkertn@umich.edu
774484Sbinkertn@umich.edu        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
784484Sbinkertn@umich.edu
794484Sbinkertn@umich.edu        DPRINTF(IEW, "RegFile: Access to float register %i as double, has "
804484Sbinkertn@umich.edu                " data %8.8f\n", int(reg_idx), floatRegFile[reg_idx].d);
814484Sbinkertn@umich.edu
824484Sbinkertn@umich.edu        return floatRegFile[reg_idx].d;
834484Sbinkertn@umich.edu    }
844484Sbinkertn@umich.edu
854484Sbinkertn@umich.edu    uint64_t readFloatRegInt(PhysRegIndex reg_idx)
864484Sbinkertn@umich.edu    {
874484Sbinkertn@umich.edu        // Remove the base Float reg dependency.
884484Sbinkertn@umich.edu        reg_idx = reg_idx - numPhysicalIntRegs;
894484Sbinkertn@umich.edu
904484Sbinkertn@umich.edu        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
914484Sbinkertn@umich.edu
924484Sbinkertn@umich.edu        DPRINTF(IEW, "RegFile: Access to float register %i as int, has data "
934484Sbinkertn@umich.edu                "%lli\n", int(reg_idx), floatRegFile[reg_idx].q);
944484Sbinkertn@umich.edu
954484Sbinkertn@umich.edu        return floatRegFile[reg_idx].q;
964484Sbinkertn@umich.edu    }
974484Sbinkertn@umich.edu
984484Sbinkertn@umich.edu    void setIntReg(PhysRegIndex reg_idx, uint64_t val)
994484Sbinkertn@umich.edu    {
1004484Sbinkertn@umich.edu        assert(reg_idx < numPhysicalIntRegs);
1014484Sbinkertn@umich.edu
1024484Sbinkertn@umich.edu        DPRINTF(IEW, "RegFile: Setting int register %i to %lli\n",
1034484Sbinkertn@umich.edu                int(reg_idx), val);
1044484Sbinkertn@umich.edu
1054484Sbinkertn@umich.edu        intRegFile[reg_idx] = val;
1064484Sbinkertn@umich.edu    }
1074484Sbinkertn@umich.edu
1084484Sbinkertn@umich.edu    void setFloatRegSingle(PhysRegIndex reg_idx, float val)
1094484Sbinkertn@umich.edu    {
1104484Sbinkertn@umich.edu        // Remove the base Float reg dependency.
1114484Sbinkertn@umich.edu        reg_idx = reg_idx - numPhysicalIntRegs;
1124484Sbinkertn@umich.edu
1134484Sbinkertn@umich.edu        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1144484Sbinkertn@umich.edu
1154484Sbinkertn@umich.edu        DPRINTF(IEW, "RegFile: Setting float register %i to %8.8f\n",
1164484Sbinkertn@umich.edu                int(reg_idx), val);
1174484Sbinkertn@umich.edu
1184484Sbinkertn@umich.edu        floatRegFile[reg_idx].d = (double)val;
1194484Sbinkertn@umich.edu    }
1204484Sbinkertn@umich.edu
1214484Sbinkertn@umich.edu    void setFloatRegDouble(PhysRegIndex reg_idx, double val)
1224484Sbinkertn@umich.edu    {
1234484Sbinkertn@umich.edu        // Remove the base Float reg dependency.
1244484Sbinkertn@umich.edu        reg_idx = reg_idx - numPhysicalIntRegs;
1254484Sbinkertn@umich.edu
1264484Sbinkertn@umich.edu        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1274484Sbinkertn@umich.edu
1284484Sbinkertn@umich.edu        DPRINTF(IEW, "RegFile: Setting float register %i to %8.8f\n",
1294484Sbinkertn@umich.edu                int(reg_idx), val);
1304484Sbinkertn@umich.edu
1314484Sbinkertn@umich.edu        floatRegFile[reg_idx].d = val;
1324484Sbinkertn@umich.edu    }
1334484Sbinkertn@umich.edu
1344484Sbinkertn@umich.edu    void setFloatRegInt(PhysRegIndex reg_idx, uint64_t val)
1354484Sbinkertn@umich.edu    {
1364484Sbinkertn@umich.edu        // Remove the base Float reg dependency.
1374484Sbinkertn@umich.edu        reg_idx = reg_idx - numPhysicalIntRegs;
1384484Sbinkertn@umich.edu
1394484Sbinkertn@umich.edu        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1404484Sbinkertn@umich.edu
1414484Sbinkertn@umich.edu        DPRINTF(IEW, "RegFile: Setting float register %i to %lli\n",
1424484Sbinkertn@umich.edu                int(reg_idx), val);
1434484Sbinkertn@umich.edu
1444484Sbinkertn@umich.edu        floatRegFile[reg_idx].q = val;
1454484Sbinkertn@umich.edu    }
1464484Sbinkertn@umich.edu
1474484Sbinkertn@umich.edu    uint64_t readPC()
1484484Sbinkertn@umich.edu    {
1494484Sbinkertn@umich.edu        return pc;
1504484Sbinkertn@umich.edu    }
1514484Sbinkertn@umich.edu
1524484Sbinkertn@umich.edu    void setPC(uint64_t val)
1534484Sbinkertn@umich.edu    {
1544484Sbinkertn@umich.edu        pc = val;
1554484Sbinkertn@umich.edu    }
1564484Sbinkertn@umich.edu
1574484Sbinkertn@umich.edu    void setNextPC(uint64_t val)
1584484Sbinkertn@umich.edu    {
1594484Sbinkertn@umich.edu        npc = val;
1604484Sbinkertn@umich.edu    }
1614484Sbinkertn@umich.edu
1624484Sbinkertn@umich.edu    //Consider leaving this stuff and below in some implementation specific
1634484Sbinkertn@umich.edu    //file as opposed to the general register file.  Or have a derived class.
1644484Sbinkertn@umich.edu    uint64_t readUniq()
1654484Sbinkertn@umich.edu    {
1664484Sbinkertn@umich.edu        return miscRegs.uniq;
1674484Sbinkertn@umich.edu    }
1684484Sbinkertn@umich.edu
1694484Sbinkertn@umich.edu    void setUniq(uint64_t val)
1704484Sbinkertn@umich.edu    {
1714484Sbinkertn@umich.edu        miscRegs.uniq = val;
1724484Sbinkertn@umich.edu    }
1734484Sbinkertn@umich.edu
1744484Sbinkertn@umich.edu    uint64_t readFpcr()
17510037SARM gem5 Developers    {
1764484Sbinkertn@umich.edu        return miscRegs.fpcr;
1774484Sbinkertn@umich.edu    }
1784484Sbinkertn@umich.edu
1794484Sbinkertn@umich.edu    void setFpcr(uint64_t val)
1804484Sbinkertn@umich.edu    {
1814484Sbinkertn@umich.edu        miscRegs.fpcr = val;
1824484Sbinkertn@umich.edu    }
1834484Sbinkertn@umich.edu
1844484Sbinkertn@umich.edu#ifdef FULL_SYSTEM
1854484Sbinkertn@umich.edu    uint64_t readIpr(int idx, Fault &fault);
1864484Sbinkertn@umich.edu    Fault setIpr(int idx, uint64_t val);
1874484Sbinkertn@umich.edu    InternalProcReg *getIpr() { return ipr; }
1884484Sbinkertn@umich.edu    int readIntrFlag() { return intrflag; }
1894484Sbinkertn@umich.edu    void setIntrFlag(int val) { intrflag = val; }
1904484Sbinkertn@umich.edu#endif
1914484Sbinkertn@umich.edu
1924484Sbinkertn@umich.edu    // These should be private eventually, but will be public for now
1934484Sbinkertn@umich.edu    // so that I can hack around the initregs issue.
1944484Sbinkertn@umich.edu  public:
1954484Sbinkertn@umich.edu    /** (signed) integer register file. */
1964484Sbinkertn@umich.edu    IntReg *intRegFile;
1974484Sbinkertn@umich.edu
1984484Sbinkertn@umich.edu    /** Floating point register file. */
1994484Sbinkertn@umich.edu    FloatReg *floatRegFile;
2004484Sbinkertn@umich.edu
2014484Sbinkertn@umich.edu    /** Miscellaneous register file. */
2024484Sbinkertn@umich.edu    MiscRegFile miscRegs;
2034484Sbinkertn@umich.edu
2044484Sbinkertn@umich.edu    /** Program counter. */
2054484Sbinkertn@umich.edu    Addr pc;
2064484Sbinkertn@umich.edu
2074484Sbinkertn@umich.edu    /** Next-cycle program counter. */
2084484Sbinkertn@umich.edu    Addr npc;
2094484Sbinkertn@umich.edu
2104484Sbinkertn@umich.edu#ifdef FULL_SYSTEM
2114484Sbinkertn@umich.edu  private:
2124484Sbinkertn@umich.edu    // This is ISA specifc stuff; remove it eventually once ISAImpl is used
2134484Sbinkertn@umich.edu    IntReg palregs[NumIntRegs];	// PAL shadow registers
2144484Sbinkertn@umich.edu    InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs
2154484Sbinkertn@umich.edu    int intrflag;			// interrupt flag
2164484Sbinkertn@umich.edu    bool pal_shadow;		// using pal_shadow registers
2174484Sbinkertn@umich.edu#endif
2184484Sbinkertn@umich.edu
2194484Sbinkertn@umich.edu  private:
2204484Sbinkertn@umich.edu    FullCPU *cpu;
2214484Sbinkertn@umich.edu
2224484Sbinkertn@umich.edu  public:
2234484Sbinkertn@umich.edu    void setCPU(FullCPU *cpu_ptr) { cpu = cpu_ptr; }
2244484Sbinkertn@umich.edu
2254484Sbinkertn@umich.edu    unsigned numPhysicalIntRegs;
2264484Sbinkertn@umich.edu    unsigned numPhysicalFloatRegs;
2274484Sbinkertn@umich.edu};
2284484Sbinkertn@umich.edu
2294484Sbinkertn@umich.edutemplate <class Impl>
2304484Sbinkertn@umich.eduPhysRegFile<Impl>::PhysRegFile(unsigned _numPhysicalIntRegs,
2314484Sbinkertn@umich.edu                               unsigned _numPhysicalFloatRegs)
2324484Sbinkertn@umich.edu    : numPhysicalIntRegs(_numPhysicalIntRegs),
2334484Sbinkertn@umich.edu      numPhysicalFloatRegs(_numPhysicalFloatRegs)
2344484Sbinkertn@umich.edu{
2354484Sbinkertn@umich.edu    intRegFile = new IntReg[numPhysicalIntRegs];
2364484Sbinkertn@umich.edu    floatRegFile = new FloatReg[numPhysicalFloatRegs];
2374484Sbinkertn@umich.edu
2384484Sbinkertn@umich.edu    memset(intRegFile, 0, sizeof(*intRegFile));
2394484Sbinkertn@umich.edu    memset(floatRegFile, 0, sizeof(*floatRegFile));
2404484Sbinkertn@umich.edu}
2414484Sbinkertn@umich.edu
2424484Sbinkertn@umich.edu#ifdef FULL_SYSTEM
2434484Sbinkertn@umich.edu
2444484Sbinkertn@umich.edu//Problem:  This code doesn't make sense at the RegFile level because it
2454484Sbinkertn@umich.edu//needs things such as the itb and dtb.  Either put it at the CPU level or
2464484Sbinkertn@umich.edu//the DynInst level.
2474484Sbinkertn@umich.edutemplate <class Impl>
2484484Sbinkertn@umich.eduuint64_t
2494484Sbinkertn@umich.eduPhysRegFile<Impl>::readIpr(int idx, Fault &fault)
2504484Sbinkertn@umich.edu{
2514484Sbinkertn@umich.edu    uint64_t retval = 0;    // return value, default 0
2524484Sbinkertn@umich.edu
2534484Sbinkertn@umich.edu    switch (idx) {
2544484Sbinkertn@umich.edu      case ISA::IPR_PALtemp0:
2554484Sbinkertn@umich.edu      case ISA::IPR_PALtemp1:
2564484Sbinkertn@umich.edu      case ISA::IPR_PALtemp2:
2574484Sbinkertn@umich.edu      case ISA::IPR_PALtemp3:
2584484Sbinkertn@umich.edu      case ISA::IPR_PALtemp4:
2594484Sbinkertn@umich.edu      case ISA::IPR_PALtemp5:
2604484Sbinkertn@umich.edu      case ISA::IPR_PALtemp6:
2614484Sbinkertn@umich.edu      case ISA::IPR_PALtemp7:
2624484Sbinkertn@umich.edu      case ISA::IPR_PALtemp8:
2634484Sbinkertn@umich.edu      case ISA::IPR_PALtemp9:
2644484Sbinkertn@umich.edu      case ISA::IPR_PALtemp10:
2654484Sbinkertn@umich.edu      case ISA::IPR_PALtemp11:
2664484Sbinkertn@umich.edu      case ISA::IPR_PALtemp12:
2674484Sbinkertn@umich.edu      case ISA::IPR_PALtemp13:
2684484Sbinkertn@umich.edu      case ISA::IPR_PALtemp14:
2694484Sbinkertn@umich.edu      case ISA::IPR_PALtemp15:
2704484Sbinkertn@umich.edu      case ISA::IPR_PALtemp16:
2714484Sbinkertn@umich.edu      case ISA::IPR_PALtemp17:
2724484Sbinkertn@umich.edu      case ISA::IPR_PALtemp18:
2734484Sbinkertn@umich.edu      case ISA::IPR_PALtemp19:
2744484Sbinkertn@umich.edu      case ISA::IPR_PALtemp20:
2754484Sbinkertn@umich.edu      case ISA::IPR_PALtemp21:
2764484Sbinkertn@umich.edu      case ISA::IPR_PALtemp22:
2774484Sbinkertn@umich.edu      case ISA::IPR_PALtemp23:
2784484Sbinkertn@umich.edu      case ISA::IPR_PAL_BASE:
2794484Sbinkertn@umich.edu
2804484Sbinkertn@umich.edu      case ISA::IPR_IVPTBR:
2814484Sbinkertn@umich.edu      case ISA::IPR_DC_MODE:
2824484Sbinkertn@umich.edu      case ISA::IPR_MAF_MODE:
2834484Sbinkertn@umich.edu      case ISA::IPR_ISR:
2844484Sbinkertn@umich.edu      case ISA::IPR_EXC_ADDR:
2854484Sbinkertn@umich.edu      case ISA::IPR_IC_PERR_STAT:
2864484Sbinkertn@umich.edu      case ISA::IPR_DC_PERR_STAT:
2874484Sbinkertn@umich.edu      case ISA::IPR_MCSR:
2884484Sbinkertn@umich.edu      case ISA::IPR_ASTRR:
2894484Sbinkertn@umich.edu      case ISA::IPR_ASTER:
2904484Sbinkertn@umich.edu      case ISA::IPR_SIRR:
2914484Sbinkertn@umich.edu      case ISA::IPR_ICSR:
2924484Sbinkertn@umich.edu      case ISA::IPR_ICM:
2934484Sbinkertn@umich.edu      case ISA::IPR_DTB_CM:
2944484Sbinkertn@umich.edu      case ISA::IPR_IPLR:
2954484Sbinkertn@umich.edu      case ISA::IPR_INTID:
2964484Sbinkertn@umich.edu      case ISA::IPR_PMCTR:
2974484Sbinkertn@umich.edu        // no side-effect
2984484Sbinkertn@umich.edu        retval = ipr[idx];
2994484Sbinkertn@umich.edu        break;
3004484Sbinkertn@umich.edu
3014484Sbinkertn@umich.edu      case ISA::IPR_CC:
3024484Sbinkertn@umich.edu        retval |= ipr[idx] & ULL(0xffffffff00000000);
3034484Sbinkertn@umich.edu        retval |= curTick  & ULL(0x00000000ffffffff);
3044484Sbinkertn@umich.edu        break;
3054484Sbinkertn@umich.edu
3064484Sbinkertn@umich.edu      case ISA::IPR_VA:
3074484Sbinkertn@umich.edu        retval = ipr[idx];
3084484Sbinkertn@umich.edu        break;
3094484Sbinkertn@umich.edu
3104484Sbinkertn@umich.edu      case ISA::IPR_VA_FORM:
3114484Sbinkertn@umich.edu      case ISA::IPR_MM_STAT:
3124484Sbinkertn@umich.edu      case ISA::IPR_IFAULT_VA_FORM:
3134484Sbinkertn@umich.edu      case ISA::IPR_EXC_MASK:
3144484Sbinkertn@umich.edu      case ISA::IPR_EXC_SUM:
3154484Sbinkertn@umich.edu        retval = ipr[idx];
3164484Sbinkertn@umich.edu        break;
3174484Sbinkertn@umich.edu
3184484Sbinkertn@umich.edu      case ISA::IPR_DTB_PTE:
3194484Sbinkertn@umich.edu        {
3204484Sbinkertn@umich.edu            typename ISA::PTE &pte = cpu->dtb->index(1);
3214484Sbinkertn@umich.edu
3224484Sbinkertn@umich.edu            retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
3234484Sbinkertn@umich.edu            retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
3244484Sbinkertn@umich.edu            retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12;
3254484Sbinkertn@umich.edu            retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1;
3264484Sbinkertn@umich.edu            retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2;
3274484Sbinkertn@umich.edu            retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4;
3284484Sbinkertn@umich.edu            retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57;
3294484Sbinkertn@umich.edu        }
3304484Sbinkertn@umich.edu        break;
3314484Sbinkertn@umich.edu
3324484Sbinkertn@umich.edu        // write only registers
3334484Sbinkertn@umich.edu      case ISA::IPR_HWINT_CLR:
3344484Sbinkertn@umich.edu      case ISA::IPR_SL_XMIT:
3354484Sbinkertn@umich.edu      case ISA::IPR_DC_FLUSH:
3364484Sbinkertn@umich.edu      case ISA::IPR_IC_FLUSH:
3374484Sbinkertn@umich.edu      case ISA::IPR_ALT_MODE:
3384484Sbinkertn@umich.edu      case ISA::IPR_DTB_IA:
3394484Sbinkertn@umich.edu      case ISA::IPR_DTB_IAP:
3404484Sbinkertn@umich.edu      case ISA::IPR_ITB_IA:
3414484Sbinkertn@umich.edu      case ISA::IPR_ITB_IAP:
3424484Sbinkertn@umich.edu        fault = Unimplemented_Opcode_Fault;
3434484Sbinkertn@umich.edu        break;
3444484Sbinkertn@umich.edu
3454484Sbinkertn@umich.edu      default:
3464484Sbinkertn@umich.edu        // invalid IPR
3474484Sbinkertn@umich.edu        fault = Unimplemented_Opcode_Fault;
3484484Sbinkertn@umich.edu        break;
3494484Sbinkertn@umich.edu    }
3504484Sbinkertn@umich.edu
3514484Sbinkertn@umich.edu    return retval;
3524484Sbinkertn@umich.edu}
3534484Sbinkertn@umich.edu
3544484Sbinkertn@umich.eduextern int break_ipl;
3554484Sbinkertn@umich.edu
3564484Sbinkertn@umich.edutemplate <class Impl>
3574484Sbinkertn@umich.eduFault
3584484Sbinkertn@umich.eduPhysRegFile<Impl>::setIpr(int idx, uint64_t val)
3594484Sbinkertn@umich.edu{
3604484Sbinkertn@umich.edu    uint64_t old;
3614484Sbinkertn@umich.edu
3624484Sbinkertn@umich.edu    switch (idx) {
3634484Sbinkertn@umich.edu      case ISA::IPR_PALtemp0:
3644484Sbinkertn@umich.edu      case ISA::IPR_PALtemp1:
3654484Sbinkertn@umich.edu      case ISA::IPR_PALtemp2:
3664484Sbinkertn@umich.edu      case ISA::IPR_PALtemp3:
3674484Sbinkertn@umich.edu      case ISA::IPR_PALtemp4:
3684484Sbinkertn@umich.edu      case ISA::IPR_PALtemp5:
3694484Sbinkertn@umich.edu      case ISA::IPR_PALtemp6:
3704484Sbinkertn@umich.edu      case ISA::IPR_PALtemp7:
3714484Sbinkertn@umich.edu      case ISA::IPR_PALtemp8:
3724484Sbinkertn@umich.edu      case ISA::IPR_PALtemp9:
3734484Sbinkertn@umich.edu      case ISA::IPR_PALtemp10:
3744484Sbinkertn@umich.edu      case ISA::IPR_PALtemp11:
3754484Sbinkertn@umich.edu      case ISA::IPR_PALtemp12:
3764484Sbinkertn@umich.edu      case ISA::IPR_PALtemp13:
3774484Sbinkertn@umich.edu      case ISA::IPR_PALtemp14:
3784484Sbinkertn@umich.edu      case ISA::IPR_PALtemp15:
3794484Sbinkertn@umich.edu      case ISA::IPR_PALtemp16:
3804484Sbinkertn@umich.edu      case ISA::IPR_PALtemp17:
3814484Sbinkertn@umich.edu      case ISA::IPR_PALtemp18:
3824484Sbinkertn@umich.edu      case ISA::IPR_PALtemp19:
3834484Sbinkertn@umich.edu      case ISA::IPR_PALtemp20:
3844484Sbinkertn@umich.edu      case ISA::IPR_PALtemp21:
3854484Sbinkertn@umich.edu      case ISA::IPR_PALtemp22:
3864484Sbinkertn@umich.edu      case ISA::IPR_PAL_BASE:
3874484Sbinkertn@umich.edu      case ISA::IPR_IC_PERR_STAT:
3884484Sbinkertn@umich.edu      case ISA::IPR_DC_PERR_STAT:
3894484Sbinkertn@umich.edu      case ISA::IPR_PMCTR:
3904484Sbinkertn@umich.edu        // write entire quad w/ no side-effect
3914484Sbinkertn@umich.edu        ipr[idx] = val;
3924484Sbinkertn@umich.edu        break;
3934484Sbinkertn@umich.edu
3944484Sbinkertn@umich.edu      case ISA::IPR_CC_CTL:
3954484Sbinkertn@umich.edu        // This IPR resets the cycle counter.  We assume this only
3964484Sbinkertn@umich.edu        // happens once... let's verify that.
3974484Sbinkertn@umich.edu        assert(ipr[idx] == 0);
3984484Sbinkertn@umich.edu        ipr[idx] = 1;
3994484Sbinkertn@umich.edu        break;
4004484Sbinkertn@umich.edu
4014484Sbinkertn@umich.edu      case ISA::IPR_CC:
4024484Sbinkertn@umich.edu        // This IPR only writes the upper 64 bits.  It's ok to write
4034484Sbinkertn@umich.edu        // all 64 here since we mask out the lower 32 in rpcc (see
4044484Sbinkertn@umich.edu        // isa_desc).
4054484Sbinkertn@umich.edu        ipr[idx] = val;
4064484Sbinkertn@umich.edu        break;
4074484Sbinkertn@umich.edu
4084484Sbinkertn@umich.edu      case ISA::IPR_PALtemp23:
4094484Sbinkertn@umich.edu        // write entire quad w/ no side-effect
4104484Sbinkertn@umich.edu        old = ipr[idx];
4114484Sbinkertn@umich.edu        ipr[idx] = val;
4124484Sbinkertn@umich.edu        break;
4134484Sbinkertn@umich.edu
4144484Sbinkertn@umich.edu      case ISA::IPR_DTB_PTE:
4154484Sbinkertn@umich.edu        // write entire quad w/ no side-effect, tag is forthcoming
4164484Sbinkertn@umich.edu        ipr[idx] = val;
4174484Sbinkertn@umich.edu        break;
4184484Sbinkertn@umich.edu
4194484Sbinkertn@umich.edu      case ISA::IPR_EXC_ADDR:
4204484Sbinkertn@umich.edu        // second least significant bit in PC is always zero
4214484Sbinkertn@umich.edu        ipr[idx] = val & ~2;
4224484Sbinkertn@umich.edu        break;
4234484Sbinkertn@umich.edu
4244484Sbinkertn@umich.edu      case ISA::IPR_ASTRR:
4254484Sbinkertn@umich.edu      case ISA::IPR_ASTER:
4264484Sbinkertn@umich.edu        // only write least significant four bits - privilege mask
4274484Sbinkertn@umich.edu        ipr[idx] = val & 0xf;
4284484Sbinkertn@umich.edu        break;
4294484Sbinkertn@umich.edu
4304484Sbinkertn@umich.edu      case ISA::IPR_IPLR:
4314484Sbinkertn@umich.edu#ifdef DEBUG
4324484Sbinkertn@umich.edu        if (break_ipl != -1 && break_ipl == (val & 0x1f))
4334484Sbinkertn@umich.edu            debug_break();
4344484Sbinkertn@umich.edu#endif
4354484Sbinkertn@umich.edu
4364484Sbinkertn@umich.edu        // only write least significant five bits - interrupt level
4374484Sbinkertn@umich.edu        ipr[idx] = val & 0x1f;
4384484Sbinkertn@umich.edu        break;
4394484Sbinkertn@umich.edu
4404484Sbinkertn@umich.edu      case ISA::IPR_DTB_CM:
4414484Sbinkertn@umich.edu
4424484Sbinkertn@umich.edu      case ISA::IPR_ICM:
4434484Sbinkertn@umich.edu        // only write two mode bits - processor mode
4444484Sbinkertn@umich.edu        ipr[idx] = val & 0x18;
4454484Sbinkertn@umich.edu        break;
4464484Sbinkertn@umich.edu
4474484Sbinkertn@umich.edu      case ISA::IPR_ALT_MODE:
4484484Sbinkertn@umich.edu        // only write two mode bits - processor mode
4494484Sbinkertn@umich.edu        ipr[idx] = val & 0x18;
4504484Sbinkertn@umich.edu        break;
4514484Sbinkertn@umich.edu
4524484Sbinkertn@umich.edu      case ISA::IPR_MCSR:
4534484Sbinkertn@umich.edu        // more here after optimization...
4544484Sbinkertn@umich.edu        ipr[idx] = val;
4554484Sbinkertn@umich.edu        break;
4564484Sbinkertn@umich.edu
4574484Sbinkertn@umich.edu      case ISA::IPR_SIRR:
4584484Sbinkertn@umich.edu        // only write software interrupt mask
4594484Sbinkertn@umich.edu        ipr[idx] = val & 0x7fff0;
4604484Sbinkertn@umich.edu        break;
4614484Sbinkertn@umich.edu
4624484Sbinkertn@umich.edu      case ISA::IPR_ICSR:
4634484Sbinkertn@umich.edu        ipr[idx] = val & ULL(0xffffff0300);
4644484Sbinkertn@umich.edu        break;
4654484Sbinkertn@umich.edu
4664484Sbinkertn@umich.edu      case ISA::IPR_IVPTBR:
4674484Sbinkertn@umich.edu      case ISA::IPR_MVPTBR:
4684484Sbinkertn@umich.edu        ipr[idx] = val & ULL(0xffffffffc0000000);
4694484Sbinkertn@umich.edu        break;
4704484Sbinkertn@umich.edu
4714484Sbinkertn@umich.edu      case ISA::IPR_DC_TEST_CTL:
4724484Sbinkertn@umich.edu        ipr[idx] = val & 0x1ffb;
4734484Sbinkertn@umich.edu        break;
4744484Sbinkertn@umich.edu
4754484Sbinkertn@umich.edu      case ISA::IPR_DC_MODE:
4764484Sbinkertn@umich.edu      case ISA::IPR_MAF_MODE:
4774484Sbinkertn@umich.edu        ipr[idx] = val & 0x3f;
4784484Sbinkertn@umich.edu        break;
4794484Sbinkertn@umich.edu
4804484Sbinkertn@umich.edu      case ISA::IPR_ITB_ASN:
4814484Sbinkertn@umich.edu        ipr[idx] = val & 0x7f0;
4824484Sbinkertn@umich.edu        break;
4834484Sbinkertn@umich.edu
4844484Sbinkertn@umich.edu      case ISA::IPR_DTB_ASN:
4854484Sbinkertn@umich.edu        ipr[idx] = val & ULL(0xfe00000000000000);
4864484Sbinkertn@umich.edu        break;
4874484Sbinkertn@umich.edu
4884484Sbinkertn@umich.edu      case ISA::IPR_EXC_SUM:
4894484Sbinkertn@umich.edu      case ISA::IPR_EXC_MASK:
4904484Sbinkertn@umich.edu        // any write to this register clears it
4914484Sbinkertn@umich.edu        ipr[idx] = 0;
4924484Sbinkertn@umich.edu        break;
4934484Sbinkertn@umich.edu
4944484Sbinkertn@umich.edu      case ISA::IPR_INTID:
4954484Sbinkertn@umich.edu      case ISA::IPR_SL_RCV:
4964484Sbinkertn@umich.edu      case ISA::IPR_MM_STAT:
4974484Sbinkertn@umich.edu      case ISA::IPR_ITB_PTE_TEMP:
4984484Sbinkertn@umich.edu      case ISA::IPR_DTB_PTE_TEMP:
4994484Sbinkertn@umich.edu        // read-only registers
5004484Sbinkertn@umich.edu        return Unimplemented_Opcode_Fault;
5014484Sbinkertn@umich.edu
5024484Sbinkertn@umich.edu      case ISA::IPR_HWINT_CLR:
5034484Sbinkertn@umich.edu      case ISA::IPR_SL_XMIT:
5044484Sbinkertn@umich.edu      case ISA::IPR_DC_FLUSH:
5054484Sbinkertn@umich.edu      case ISA::IPR_IC_FLUSH:
5064484Sbinkertn@umich.edu        // the following are write only
5074484Sbinkertn@umich.edu        ipr[idx] = val;
5084484Sbinkertn@umich.edu        break;
5094484Sbinkertn@umich.edu
5104484Sbinkertn@umich.edu      case ISA::IPR_DTB_IA:
5114484Sbinkertn@umich.edu        // really a control write
5124484Sbinkertn@umich.edu        ipr[idx] = 0;
5134484Sbinkertn@umich.edu
5144484Sbinkertn@umich.edu        cpu->dtb->flushAll();
5154484Sbinkertn@umich.edu        break;
5164484Sbinkertn@umich.edu
5174484Sbinkertn@umich.edu      case ISA::IPR_DTB_IAP:
5184484Sbinkertn@umich.edu        // really a control write
5194484Sbinkertn@umich.edu        ipr[idx] = 0;
5204484Sbinkertn@umich.edu
5214484Sbinkertn@umich.edu        cpu->dtb->flushProcesses();
5224484Sbinkertn@umich.edu        break;
5234484Sbinkertn@umich.edu
5244484Sbinkertn@umich.edu      case ISA::IPR_DTB_IS:
5254484Sbinkertn@umich.edu        // really a control write
5264484Sbinkertn@umich.edu        ipr[idx] = val;
5274484Sbinkertn@umich.edu
5284484Sbinkertn@umich.edu        cpu->dtb->flushAddr(val, DTB_ASN_ASN(ipr[ISA::IPR_DTB_ASN]));
5294484Sbinkertn@umich.edu        break;
5304484Sbinkertn@umich.edu
5314484Sbinkertn@umich.edu      case ISA::IPR_DTB_TAG: {
5324484Sbinkertn@umich.edu          struct ISA::PTE pte;
5334484Sbinkertn@umich.edu
5344484Sbinkertn@umich.edu          // FIXME: granularity hints NYI...
5354484Sbinkertn@umich.edu          if (DTB_PTE_GH(ipr[ISA::IPR_DTB_PTE]) != 0)
5364484Sbinkertn@umich.edu              panic("PTE GH field != 0");
5374484Sbinkertn@umich.edu
5384484Sbinkertn@umich.edu          // write entire quad
5394484Sbinkertn@umich.edu          ipr[idx] = val;
5404484Sbinkertn@umich.edu
5414484Sbinkertn@umich.edu          // construct PTE for new entry
5424484Sbinkertn@umich.edu          pte.ppn = DTB_PTE_PPN(ipr[ISA::IPR_DTB_PTE]);
5434484Sbinkertn@umich.edu          pte.xre = DTB_PTE_XRE(ipr[ISA::IPR_DTB_PTE]);
5444484Sbinkertn@umich.edu          pte.xwe = DTB_PTE_XWE(ipr[ISA::IPR_DTB_PTE]);
5454484Sbinkertn@umich.edu          pte.fonr = DTB_PTE_FONR(ipr[ISA::IPR_DTB_PTE]);
5464484Sbinkertn@umich.edu          pte.fonw = DTB_PTE_FONW(ipr[ISA::IPR_DTB_PTE]);
5474484Sbinkertn@umich.edu          pte.asma = DTB_PTE_ASMA(ipr[ISA::IPR_DTB_PTE]);
5484484Sbinkertn@umich.edu          pte.asn = DTB_ASN_ASN(ipr[ISA::IPR_DTB_ASN]);
5494484Sbinkertn@umich.edu
5504484Sbinkertn@umich.edu          // insert new TAG/PTE value into data TLB
5514484Sbinkertn@umich.edu          cpu->dtb->insert(val, pte);
5524484Sbinkertn@umich.edu      }
5534484Sbinkertn@umich.edu        break;
5544484Sbinkertn@umich.edu
5554484Sbinkertn@umich.edu      case ISA::IPR_ITB_PTE: {
5564484Sbinkertn@umich.edu          struct ISA::PTE pte;
5574484Sbinkertn@umich.edu
5584484Sbinkertn@umich.edu          // FIXME: granularity hints NYI...
5594484Sbinkertn@umich.edu          if (ITB_PTE_GH(val) != 0)
5604484Sbinkertn@umich.edu              panic("PTE GH field != 0");
5614484Sbinkertn@umich.edu
5624484Sbinkertn@umich.edu          // write entire quad
5634484Sbinkertn@umich.edu          ipr[idx] = val;
5644484Sbinkertn@umich.edu
5654484Sbinkertn@umich.edu          // construct PTE for new entry
5664484Sbinkertn@umich.edu          pte.ppn = ITB_PTE_PPN(val);
5674484Sbinkertn@umich.edu          pte.xre = ITB_PTE_XRE(val);
5684484Sbinkertn@umich.edu          pte.xwe = 0;
5694484Sbinkertn@umich.edu          pte.fonr = ITB_PTE_FONR(val);
5704484Sbinkertn@umich.edu          pte.fonw = ITB_PTE_FONW(val);
5714484Sbinkertn@umich.edu          pte.asma = ITB_PTE_ASMA(val);
5724484Sbinkertn@umich.edu          pte.asn = ITB_ASN_ASN(ipr[ISA::IPR_ITB_ASN]);
5734484Sbinkertn@umich.edu
5744484Sbinkertn@umich.edu          // insert new TAG/PTE value into data TLB
5754484Sbinkertn@umich.edu          cpu->itb->insert(ipr[ISA::IPR_ITB_TAG], pte);
5764484Sbinkertn@umich.edu      }
5774484Sbinkertn@umich.edu        break;
5784484Sbinkertn@umich.edu
5794484Sbinkertn@umich.edu      case ISA::IPR_ITB_IA:
5804484Sbinkertn@umich.edu        // really a control write
5814484Sbinkertn@umich.edu        ipr[idx] = 0;
5824484Sbinkertn@umich.edu
5834484Sbinkertn@umich.edu        cpu->itb->flushAll();
5844484Sbinkertn@umich.edu        break;
5854484Sbinkertn@umich.edu
5864484Sbinkertn@umich.edu      case ISA::IPR_ITB_IAP:
5874484Sbinkertn@umich.edu        // really a control write
5884484Sbinkertn@umich.edu        ipr[idx] = 0;
5894484Sbinkertn@umich.edu
5904484Sbinkertn@umich.edu        cpu->itb->flushProcesses();
5914484Sbinkertn@umich.edu        break;
5924484Sbinkertn@umich.edu
5934484Sbinkertn@umich.edu      case ISA::IPR_ITB_IS:
5944484Sbinkertn@umich.edu        // really a control write
5954484Sbinkertn@umich.edu        ipr[idx] = val;
5964484Sbinkertn@umich.edu
5974484Sbinkertn@umich.edu        cpu->itb->flushAddr(val, ITB_ASN_ASN(ipr[ISA::IPR_ITB_ASN]));
5984484Sbinkertn@umich.edu        break;
5994484Sbinkertn@umich.edu
6004484Sbinkertn@umich.edu      default:
6014484Sbinkertn@umich.edu        // invalid IPR
6024484Sbinkertn@umich.edu        return Unimplemented_Opcode_Fault;
6034484Sbinkertn@umich.edu    }
6044484Sbinkertn@umich.edu
6054484Sbinkertn@umich.edu    // no error...
6064484Sbinkertn@umich.edu    return No_Fault;
6074484Sbinkertn@umich.edu}
6084484Sbinkertn@umich.edu
6094484Sbinkertn@umich.edu#endif // #ifdef FULL_SYSTEM
6104484Sbinkertn@umich.edu
6114484Sbinkertn@umich.edu#endif // __CPU_BETA_CPU_REGFILE_HH__
6124484Sbinkertn@umich.edu