regfile.hh revision 1062
11689SN/A#ifndef __REGFILE_HH__
27855SAli.Saidi@ARM.com#define __REGFILE_HH__
37855SAli.Saidi@ARM.com
47855SAli.Saidi@ARM.com// @todo: Destructor
57855SAli.Saidi@ARM.com
67855SAli.Saidi@ARM.comusing namespace std;
77855SAli.Saidi@ARM.com
87855SAli.Saidi@ARM.com#include "arch/alpha/isa_traits.hh"
97855SAli.Saidi@ARM.com#include "cpu/beta_cpu/comm.hh"
107855SAli.Saidi@ARM.com
117855SAli.Saidi@ARM.com// This really only depends on the ISA, and not the Impl.  It might be nicer
127855SAli.Saidi@ARM.com// to see if I can make it depend on nothing...
137855SAli.Saidi@ARM.com// Things that are in the ifdef FULL_SYSTEM are pretty dependent on the ISA,
142316SN/A// and should go in the AlphaFullCPU.
151689SN/A
161689SN/Atemplate <class Impl>
171689SN/Aclass PhysRegFile
181689SN/A{
191689SN/A    //Note that most of the definitions of the IntReg, FloatReg, etc. exist
201689SN/A    //within the Impl/ISA class and not within this PhysRegFile class.
211689SN/A
221689SN/A    //Will need some way to allow stuff like swap_palshadow to access the
231689SN/A    //correct registers.  Might require code changes to swap_palshadow and
241689SN/A    //other execution contexts.
251689SN/A
261689SN/A    //Will make these registers public for now, but they probably should
271689SN/A    //be private eventually with some accessor functions.
281689SN/A  public:
291689SN/A    typedef typename Impl::ISA ISA;
301689SN/A
311689SN/A    PhysRegFile(unsigned _numPhysicalIntRegs,
321689SN/A                unsigned _numPhysicalFloatRegs);
331689SN/A
341689SN/A    //Everything below should be pretty well identical to the normal
351689SN/A    //register file that exists within AlphaISA class.
361689SN/A    //The duplication is unfortunate but it's better than having
371689SN/A    //different ways to access certain registers.
381689SN/A
392665Ssaidi@eecs.umich.edu    //Add these in later when everything else is in place
402665Ssaidi@eecs.umich.edu//    void serialize(std::ostream &os);
412756Sksewell@umich.edu//    void unserialize(Checkpoint *cp, const std::string &section);
421689SN/A
431689SN/A    uint64_t readIntReg(PhysRegIndex reg_idx)
442292SN/A    {
452292SN/A        assert(reg_idx < numPhysicalIntRegs);
461060SN/A
471461SN/A        DPRINTF(IEW, "RegFile: Access to int register %i, has data "
487813Ssteve.reinhardt@amd.com                "%i\n", int(reg_idx), intRegFile[reg_idx]);
492292SN/A        return intRegFile[reg_idx];
502329SN/A    }
511060SN/A
525529Snate@binkert.org    float readFloatRegSingle(PhysRegIndex reg_idx)
535529Snate@binkert.org    {
542292SN/A        // Remove the base Float reg dependency.
552292SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
562292SN/A
572292SN/A        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
582316SN/A
592316SN/A        DPRINTF(IEW, "RegFile: Access to float register %i as single, has "
602316SN/A                "data %8.8f\n", int(reg_idx), (float)floatRegFile[reg_idx].d);
612316SN/A
622316SN/A        return (float)floatRegFile[reg_idx].d;
632316SN/A    }
642316SN/A
652316SN/A    double readFloatRegDouble(PhysRegIndex reg_idx)
662316SN/A    {
672316SN/A        // Remove the base Float reg dependency.
682316SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
692316SN/A
702316SN/A        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
712316SN/A
722316SN/A        DPRINTF(IEW, "RegFile: Access to float register %i as double, has "
732316SN/A                " data %8.8f\n", int(reg_idx), floatRegFile[reg_idx].d);
742316SN/A
752316SN/A        return floatRegFile[reg_idx].d;
762316SN/A    }
772329SN/A
782292SN/A    uint64_t readFloatRegInt(PhysRegIndex reg_idx)
791060SN/A    {
802292SN/A        // Remove the base Float reg dependency.
811060SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
821060SN/A
831060SN/A        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
842733Sktlim@umich.edu
851061SN/A        DPRINTF(IEW, "RegFile: Access to float register %i as int, has data "
861061SN/A                "%lli\n", int(reg_idx), floatRegFile[reg_idx].q);
871060SN/A
882292SN/A        return floatRegFile[reg_idx].q;
891061SN/A    }
901060SN/A
911061SN/A    void setIntReg(PhysRegIndex reg_idx, uint64_t val)
922292SN/A    {
931061SN/A        assert(reg_idx < numPhysicalIntRegs);
941061SN/A
951060SN/A        DPRINTF(IEW, "RegFile: Setting int register %i to %lli\n",
962316SN/A                int(reg_idx), val);
972292SN/A
982292SN/A        intRegFile[reg_idx] = val;
992292SN/A    }
1002292SN/A
1012348SN/A    void setFloatRegSingle(PhysRegIndex reg_idx, float val)
1022348SN/A    {
1032348SN/A        // Remove the base Float reg dependency.
1042292SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
1052292SN/A
1062292SN/A        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1076221Snate@binkert.org
1082292SN/A        DPRINTF(IEW, "RegFile: Setting float register %i to %8.8f\n",
1092292SN/A                int(reg_idx), val);
1106221Snate@binkert.org
1112292SN/A        floatRegFile[reg_idx].d = (double)val;
1122292SN/A    }
1135336Shines@cs.fsu.edu
1142292SN/A    void setFloatRegDouble(PhysRegIndex reg_idx, double val)
1152292SN/A    {
1162292SN/A        // Remove the base Float reg dependency.
1172292SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
1182292SN/A
1192292SN/A        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1202292SN/A
1212292SN/A        DPRINTF(IEW, "RegFile: Setting float register %i to %8.8f\n",
1222292SN/A                int(reg_idx), val);
1232292SN/A
1242292SN/A        floatRegFile[reg_idx].d = val;
1252292SN/A    }
1261060SN/A
1271060SN/A    void setFloatRegInt(PhysRegIndex reg_idx, uint64_t val)
1281060SN/A    {
1292292SN/A        // Remove the base Float reg dependency.
1302292SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
1312292SN/A
1322292SN/A        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1332292SN/A
1342292SN/A        DPRINTF(IEW, "RegFile: Setting float register %i to %lli\n",
1352292SN/A                int(reg_idx), val);
1362292SN/A
1372292SN/A        floatRegFile[reg_idx].q = val;
1381060SN/A    }
1391060SN/A
1401060SN/A    uint64_t readPC()
1412292SN/A    {
1422292SN/A        return pc;
1432292SN/A    }
1442292SN/A
1452292SN/A    void setPC(uint64_t val)
1462292SN/A    {
1472292SN/A        pc = val;
1482292SN/A    }
1491060SN/A
1501060SN/A    void setNextPC(uint64_t val)
1512292SN/A    {
1525529Snate@binkert.org        npc = val;
1531060SN/A    }
1542292SN/A
1552292SN/A    //Consider leaving this stuff and below in some implementation specific
1562292SN/A    //file as opposed to the general register file.  Or have a derived class.
1572292SN/A    uint64_t readUniq()
1581062SN/A    {
1591062SN/A        return miscRegs.uniq;
1602292SN/A    }
1612292SN/A
1622292SN/A    void setUniq(uint64_t val)
1632292SN/A    {
1641060SN/A        miscRegs.uniq = val;
1651060SN/A    }
1662292SN/A
1672292SN/A    uint64_t readFpcr()
1682292SN/A    {
1691060SN/A        return miscRegs.fpcr;
1701060SN/A    }
1712292SN/A
1721060SN/A    void setFpcr(uint64_t val)
1731060SN/A    {
1742348SN/A        miscRegs.fpcr = val;
1752292SN/A    }
1762292SN/A
1772965Sksewell@umich.edu#ifdef FULL_SYSTEM
1782965Sksewell@umich.edu    uint64_t readIpr(int idx, Fault &fault);
1792965Sksewell@umich.edu    Fault setIpr(int idx, uint64_t val);
1802316SN/A    int readIntrFlag() { return intrflag; }
1812316SN/A    void setIntrFlag(int val) { intrflag = val; }
1822316SN/A#endif
1832292SN/A
1842292SN/A    // These should be private eventually, but will be public for now
1852292SN/A    // so that I can hack around the initregs issue.
1862292SN/A  public:
1876221Snate@binkert.org    /** (signed) integer register file. */
1882292SN/A    IntReg *intRegFile;
1892292SN/A
1902292SN/A    /** Floating point register file. */
1912292SN/A    FloatReg *floatRegFile;
1922292SN/A
1931060SN/A    /** Miscellaneous register file. */
1941060SN/A    MiscRegFile miscRegs;
1952292SN/A
1962292SN/A    Addr pc;            // program counter
1972292SN/A    Addr npc;            // next-cycle program counter
1982843Sktlim@umich.edu
1992863Sktlim@umich.edu  private:
2002843Sktlim@umich.edu    unsigned numPhysicalIntRegs;
2012843Sktlim@umich.edu    unsigned numPhysicalFloatRegs;
2022843Sktlim@umich.edu};
2032307SN/A
2042348SN/Atemplate <class Impl>
2052843Sktlim@umich.eduPhysRegFile<Impl>::PhysRegFile(unsigned _numPhysicalIntRegs,
2062316SN/A                               unsigned _numPhysicalFloatRegs)
2072348SN/A    : numPhysicalIntRegs(_numPhysicalIntRegs),
2082307SN/A      numPhysicalFloatRegs(_numPhysicalFloatRegs)
2092307SN/A{
2102292SN/A    intRegFile = new IntReg[numPhysicalIntRegs];
2111060SN/A    floatRegFile = new FloatReg[numPhysicalFloatRegs];
2121060SN/A
2132292SN/A    memset(intRegFile, 0, sizeof(*intRegFile));
2142292SN/A    memset(floatRegFile, 0, sizeof(*floatRegFile));
2152292SN/A}
2161060SN/A
2171060SN/A#ifdef FULL_SYSTEM
2182292SN/A
2196221Snate@binkert.org//Problem:  This code doesn't make sense at the RegFile level because it
2202292SN/A//needs things such as the itb and dtb.  Either put it at the CPU level or
2212348SN/A//the DynInst level.
2226221Snate@binkert.orgtemplate <class Impl>
2232348SN/Auint64_t
2242348SN/APhysRegFile<Impl>::readIpr(int idx, Fault &fault)
2252680Sktlim@umich.edu{
2262348SN/A    uint64_t retval = 0;    // return value, default 0
2276221Snate@binkert.org
2282292SN/A    switch (idx) {
2291060SN/A      case ISA::IPR_PALtemp0:
2302292SN/A      case ISA::IPR_PALtemp1:
2312348SN/A      case ISA::IPR_PALtemp2:
2322348SN/A      case ISA::IPR_PALtemp3:
2332292SN/A      case ISA::IPR_PALtemp4:
2341060SN/A      case ISA::IPR_PALtemp5:
2352292SN/A      case ISA::IPR_PALtemp6:
2362292SN/A      case ISA::IPR_PALtemp7:
2372292SN/A      case ISA::IPR_PALtemp8:
2382292SN/A      case ISA::IPR_PALtemp9:
2392292SN/A      case ISA::IPR_PALtemp10:
2402292SN/A      case ISA::IPR_PALtemp11:
2412292SN/A      case ISA::IPR_PALtemp12:
2422292SN/A      case ISA::IPR_PALtemp13:
2432292SN/A      case ISA::IPR_PALtemp14:
2442292SN/A      case ISA::IPR_PALtemp15:
2452292SN/A      case ISA::IPR_PALtemp16:
2462292SN/A      case ISA::IPR_PALtemp17:
2472292SN/A      case ISA::IPR_PALtemp18:
2482292SN/A      case ISA::IPR_PALtemp19:
2492292SN/A      case ISA::IPR_PALtemp20:
2502292SN/A      case ISA::IPR_PALtemp21:
2512348SN/A      case ISA::IPR_PALtemp22:
2526221Snate@binkert.org      case ISA::IPR_PALtemp23:
2532316SN/A      case ISA::IPR_PAL_BASE:
2542348SN/A
2556221Snate@binkert.org      case ISA::IPR_IVPTBR:
2562292SN/A      case ISA::IPR_DC_MODE:
2572680Sktlim@umich.edu      case ISA::IPR_MAF_MODE:
2586221Snate@binkert.org      case ISA::IPR_ISR:
2592292SN/A      case ISA::IPR_EXC_ADDR:
2607784SAli.Saidi@ARM.com      case ISA::IPR_IC_PERR_STAT:
2617784SAli.Saidi@ARM.com      case ISA::IPR_DC_PERR_STAT:
2627784SAli.Saidi@ARM.com      case ISA::IPR_MCSR:
2637784SAli.Saidi@ARM.com      case ISA::IPR_ASTRR:
2647784SAli.Saidi@ARM.com      case ISA::IPR_ASTER:
2658137SAli.Saidi@ARM.com      case ISA::IPR_SIRR:
2668137SAli.Saidi@ARM.com      case ISA::IPR_ICSR:
2677784SAli.Saidi@ARM.com      case ISA::IPR_ICM:
2684035Sktlim@umich.edu      case ISA::IPR_DTB_CM:
2694035Sktlim@umich.edu      case ISA::IPR_IPLR:
2704035Sktlim@umich.edu      case ISA::IPR_INTID:
2717847Sminkyu.jeong@arm.com      case ISA::IPR_PMCTR:
2727847Sminkyu.jeong@arm.com    // no side-effect
2737847Sminkyu.jeong@arm.com    retval = ipr[idx];
2744035Sktlim@umich.edu    break;
2754035Sktlim@umich.edu
2762292SN/A      case ISA::IPR_CC:
2771060SN/A    retval |= ipr[idx] & ULL(0xffffffff00000000);
2781060SN/A    retval |= curTick  & ULL(0x00000000ffffffff);
2792292SN/A    break;
2802292SN/A
2812292SN/A      case ISA::IPR_VA:
2821061SN/A    // SFX: unlocks interrupt status registers
2831060SN/A    retval = ipr[idx];
2842292SN/A
2851060SN/A        if (!misspeculating())
2861060SN/A            regs.intrlock = false;
2872965Sksewell@umich.edu    break;
2882965Sksewell@umich.edu
2892965Sksewell@umich.edu      case ISA::IPR_VA_FORM:
2902292SN/A      case ISA::IPR_MM_STAT:
2911060SN/A      case ISA::IPR_IFAULT_VA_FORM:
2921060SN/A      case ISA::IPR_EXC_MASK:
2932292SN/A      case ISA::IPR_EXC_SUM:
2946221Snate@binkert.org    retval = ipr[idx];
2952292SN/A    break;
2962292SN/A
2976221Snate@binkert.org      case ISA::IPR_DTB_PTE:
2982292SN/A    {
2992292SN/A        ISA::PTE &pte = dtb->index(!misspeculating());
3006221Snate@binkert.org
3012292SN/A        retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
3021684SN/A        retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
3037720Sgblack@eecs.umich.edu        retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12;
3047720Sgblack@eecs.umich.edu        retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1;
3057720Sgblack@eecs.umich.edu        retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2;
3067720Sgblack@eecs.umich.edu        retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4;
3077720Sgblack@eecs.umich.edu        retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57;
3087720Sgblack@eecs.umich.edu    }
3091684SN/A    break;
3102348SN/A
3117720Sgblack@eecs.umich.edu    // write only registers
3122292SN/A      case ISA::IPR_HWINT_CLR:
3137720Sgblack@eecs.umich.edu      case ISA::IPR_SL_XMIT:
3147720Sgblack@eecs.umich.edu      case ISA::IPR_DC_FLUSH:
3154636Sgblack@eecs.umich.edu      case ISA::IPR_IC_FLUSH:
3164636Sgblack@eecs.umich.edu      case ISA::IPR_ALT_MODE:
3177720Sgblack@eecs.umich.edu      case ISA::IPR_DTB_IA:
3182756Sksewell@umich.edu      case ISA::IPR_DTB_IAP:
3191684SN/A      case ISA::IPR_ITB_IA:
3201060SN/A      case ISA::IPR_ITB_IAP:
3211060SN/A    fault = Unimplemented_Opcode_Fault;
3221060SN/A    break;
3231060SN/A
3241060SN/A      default:
3251060SN/A    // invalid IPR
3261060SN/A    fault = Unimplemented_Opcode_Fault;
3271060SN/A    break;
3281060SN/A    }
3292292SN/A
3302292SN/A    return retval;
3312292SN/A}
3322292SN/A
3331060SN/A#ifdef DEBUG
3341060SN/A// Cause the simulator to break when changing to the following IPL
3351060SN/Aint break_ipl = -1;
3361060SN/A#endif
3371060SN/A
3381060SN/Atemplate <class Impl>
3391060SN/AFault
3401060SN/APhysRegFile<Impl>::setIpr(int idx, uint64_t val)
3411060SN/A{
3421060SN/A    uint64_t old;
3431060SN/A
3441060SN/A    if (misspeculating())
3452292SN/A    return No_Fault;
3461060SN/A
3471060SN/A    switch (idx) {
3481060SN/A      case ISA::IPR_PALtemp0:
3492292SN/A      case ISA::IPR_PALtemp1:
3502733Sktlim@umich.edu      case ISA::IPR_PALtemp2:
3512733Sktlim@umich.edu      case ISA::IPR_PALtemp3:
3521060SN/A      case ISA::IPR_PALtemp4:
3532348SN/A      case ISA::IPR_PALtemp5:
3542292SN/A      case ISA::IPR_PALtemp6:
3551060SN/A      case ISA::IPR_PALtemp7:
3562292SN/A      case ISA::IPR_PALtemp8:
3572292SN/A      case ISA::IPR_PALtemp9:
3582292SN/A      case ISA::IPR_PALtemp10:
3592292SN/A      case ISA::IPR_PALtemp11:
3602292SN/A      case ISA::IPR_PALtemp12:
3612292SN/A      case ISA::IPR_PALtemp13:
3622292SN/A      case ISA::IPR_PALtemp14:
3632292SN/A      case ISA::IPR_PALtemp15:
3642292SN/A      case ISA::IPR_PALtemp16:
3652292SN/A      case ISA::IPR_PALtemp17:
3662292SN/A      case ISA::IPR_PALtemp18:
3676221Snate@binkert.org      case ISA::IPR_PALtemp19:
3682292SN/A      case ISA::IPR_PALtemp20:
3692292SN/A      case ISA::IPR_PALtemp21:
3702292SN/A      case ISA::IPR_PALtemp22:
3712292SN/A      case ISA::IPR_PAL_BASE:
3722292SN/A      case ISA::IPR_IC_PERR_STAT:
3732680Sktlim@umich.edu      case ISA::IPR_DC_PERR_STAT:
3742292SN/A      case ISA::IPR_PMCTR:
3752292SN/A    // write entire quad w/ no side-effect
3766221Snate@binkert.org    ipr[idx] = val;
3772292SN/A    break;
3781060SN/A
3791060SN/A      case ISA::IPR_CC_CTL:
3801060SN/A    // This IPR resets the cycle counter.  We assume this only
3812292SN/A    // happens once... let's verify that.
3822292SN/A    assert(ipr[idx] == 0);
3832292SN/A    ipr[idx] = 1;
3841060SN/A    break;
3851060SN/A
3861060SN/A      case ISA::IPR_CC:
3872292SN/A    // This IPR only writes the upper 64 bits.  It's ok to write
3882292SN/A    // all 64 here since we mask out the lower 32 in rpcc (see
3891060SN/A    // isa_desc).
3901060SN/A    ipr[idx] = val;
3911060SN/A    break;
3921060SN/A
3931060SN/A      case ISA::IPR_PALtemp23:
3941060SN/A    // write entire quad w/ no side-effect
3951060SN/A    old = ipr[idx];
3961062SN/A    ipr[idx] = val;
3972292SN/A    kernelStats.context(old, val);
3982292SN/A    break;
3992292SN/A
4002292SN/A      case ISA::IPR_DTB_PTE:
4016221Snate@binkert.org    // write entire quad w/ no side-effect, tag is forthcoming
4022292SN/A    ipr[idx] = val;
4032843Sktlim@umich.edu    break;
4042843Sktlim@umich.edu
4052348SN/A      case ISA::IPR_EXC_ADDR:
4062348SN/A    // second least significant bit in PC is always zero
4072307SN/A    ipr[idx] = val & ~2;
4082307SN/A    break;
4092348SN/A
4102348SN/A      case ISA::IPR_ASTRR:
4112348SN/A      case ISA::IPR_ASTER:
4122292SN/A    // only write least significant four bits - privilege mask
4132292SN/A    ipr[idx] = val & 0xf;
4143640Sktlim@umich.edu    break;
4153640Sktlim@umich.edu
4163640Sktlim@umich.edu      case ISA::IPR_IPLR:
4177720Sgblack@eecs.umich.edu#ifdef DEBUG
4182348SN/A    if (break_ipl != -1 && break_ipl == (val & 0x1f))
4192348SN/A        debug_break();
4207720Sgblack@eecs.umich.edu#endif
4214636Sgblack@eecs.umich.edu
4222292SN/A    // only write least significant five bits - interrupt level
4232292SN/A    ipr[idx] = val & 0x1f;
4242292SN/A    kernelStats.swpipl(ipr[idx]);
4257855SAli.Saidi@ARM.com    break;
4267855SAli.Saidi@ARM.com
4277855SAli.Saidi@ARM.com      case ISA::IPR_DTB_CM:
4284035Sktlim@umich.edu    kernelStats.mode((val & 0x18) != 0);
4294035Sktlim@umich.edu
4304035Sktlim@umich.edu      case ISA::IPR_ICM:
4314035Sktlim@umich.edu    // only write two mode bits - processor mode
4324035Sktlim@umich.edu    ipr[idx] = val & 0x18;
4334035Sktlim@umich.edu    break;
4344035Sktlim@umich.edu
4354035Sktlim@umich.edu      case ISA::IPR_ALT_MODE:
4364035Sktlim@umich.edu    // only write two mode bits - processor mode
4374035Sktlim@umich.edu    ipr[idx] = val & 0x18;
4382292SN/A    break;
4396221Snate@binkert.org
4402292SN/A      case ISA::IPR_MCSR:
4412292SN/A    // more here after optimization...
4422292SN/A    ipr[idx] = val;
4432292SN/A    break;
4442348SN/A
4452301SN/A      case ISA::IPR_SIRR:
4462301SN/A    // only write software interrupt mask
4472292SN/A    ipr[idx] = val & 0x7fff0;
4485999Snate@binkert.org    break;
4492292SN/A
4502292SN/A      case ISA::IPR_ICSR:
4515999Snate@binkert.org    ipr[idx] = val & ULL(0xffffff0300);
4522292SN/A    break;
4532292SN/A
4542292SN/A      case ISA::IPR_IVPTBR:
4555999Snate@binkert.org      case ISA::IPR_MVPTBR:
4562292SN/A    ipr[idx] = val & ULL(0xffffffffc0000000);
4572292SN/A    break;
4582292SN/A
4595999Snate@binkert.org      case ISA::IPR_DC_TEST_CTL:
4602292SN/A    ipr[idx] = val & 0x1ffb;
4615999Snate@binkert.org    break;
4622292SN/A
4635999Snate@binkert.org      case ISA::IPR_DC_MODE:
4641062SN/A      case ISA::IPR_MAF_MODE:
4652316SN/A    ipr[idx] = val & 0x3f;
4665999Snate@binkert.org    break;
4672316SN/A
4685999Snate@binkert.org      case ISA::IPR_ITB_ASN:
4692316SN/A    ipr[idx] = val & 0x7f0;
4705999Snate@binkert.org    break;
4712316SN/A
4725999Snate@binkert.org      case ISA::IPR_DTB_ASN:
4732316SN/A    ipr[idx] = val & ULL(0xfe00000000000000);
4745999Snate@binkert.org    break;
4752316SN/A
4765999Snate@binkert.org      case ISA::IPR_EXC_SUM:
4777897Shestness@cs.utexas.edu      case ISA::IPR_EXC_MASK:
4787897Shestness@cs.utexas.edu    // any write to this register clears it
4797897Shestness@cs.utexas.edu    ipr[idx] = 0;
4807897Shestness@cs.utexas.edu    break;
4817897Shestness@cs.utexas.edu
4827897Shestness@cs.utexas.edu      case ISA::IPR_INTID:
4832301SN/A      case ISA::IPR_SL_RCV:
4842348SN/A      case ISA::IPR_MM_STAT:
4855999Snate@binkert.org      case ISA::IPR_ITB_PTE_TEMP:
4862348SN/A      case ISA::IPR_DTB_PTE_TEMP:
4875999Snate@binkert.org    // read-only registers
4881060SN/A    return Unimplemented_Opcode_Fault;
4891060SN/A
4902292SN/A      case ISA::IPR_HWINT_CLR:
491      case ISA::IPR_SL_XMIT:
492      case ISA::IPR_DC_FLUSH:
493      case ISA::IPR_IC_FLUSH:
494    // the following are write only
495    ipr[idx] = val;
496    break;
497
498      case ISA::IPR_DTB_IA:
499    // really a control write
500    ipr[idx] = 0;
501
502    dtb->flushAll();
503    break;
504
505      case ISA::IPR_DTB_IAP:
506    // really a control write
507    ipr[idx] = 0;
508
509    dtb->flushProcesses();
510    break;
511
512      case ISA::IPR_DTB_IS:
513    // really a control write
514    ipr[idx] = val;
515
516    dtb->flushAddr(val, DTB_ASN_ASN(ipr[ISA::IPR_DTB_ASN]));
517    break;
518
519      case ISA::IPR_DTB_TAG: {
520      struct ISA::PTE pte;
521
522      // FIXME: granularity hints NYI...
523      if (DTB_PTE_GH(ipr[ISA::IPR_DTB_PTE]) != 0)
524          panic("PTE GH field != 0");
525
526      // write entire quad
527      ipr[idx] = val;
528
529      // construct PTE for new entry
530      pte.ppn = DTB_PTE_PPN(ipr[ISA::IPR_DTB_PTE]);
531      pte.xre = DTB_PTE_XRE(ipr[ISA::IPR_DTB_PTE]);
532      pte.xwe = DTB_PTE_XWE(ipr[ISA::IPR_DTB_PTE]);
533      pte.fonr = DTB_PTE_FONR(ipr[ISA::IPR_DTB_PTE]);
534      pte.fonw = DTB_PTE_FONW(ipr[ISA::IPR_DTB_PTE]);
535      pte.asma = DTB_PTE_ASMA(ipr[ISA::IPR_DTB_PTE]);
536      pte.asn = DTB_ASN_ASN(ipr[ISA::IPR_DTB_ASN]);
537
538      // insert new TAG/PTE value into data TLB
539      dtb->insert(val, pte);
540      }
541    break;
542
543      case ISA::IPR_ITB_PTE: {
544      struct ISA::PTE pte;
545
546      // FIXME: granularity hints NYI...
547      if (ITB_PTE_GH(val) != 0)
548          panic("PTE GH field != 0");
549
550      // write entire quad
551      ipr[idx] = val;
552
553      // construct PTE for new entry
554      pte.ppn = ITB_PTE_PPN(val);
555      pte.xre = ITB_PTE_XRE(val);
556      pte.xwe = 0;
557      pte.fonr = ITB_PTE_FONR(val);
558      pte.fonw = ITB_PTE_FONW(val);
559      pte.asma = ITB_PTE_ASMA(val);
560      pte.asn = ITB_ASN_ASN(ipr[ISA::IPR_ITB_ASN]);
561
562      // insert new TAG/PTE value into data TLB
563      itb->insert(ipr[ISA::IPR_ITB_TAG], pte);
564      }
565    break;
566
567      case ISA::IPR_ITB_IA:
568    // really a control write
569    ipr[idx] = 0;
570
571    itb->flushAll();
572    break;
573
574      case ISA::IPR_ITB_IAP:
575    // really a control write
576    ipr[idx] = 0;
577
578    itb->flushProcesses();
579    break;
580
581      case ISA::IPR_ITB_IS:
582    // really a control write
583    ipr[idx] = val;
584
585    itb->flushAddr(val, ITB_ASN_ASN(ipr[ISA::IPR_ITB_ASN]));
586    break;
587
588      default:
589    // invalid IPR
590    return Unimplemented_Opcode_Fault;
591    }
592
593    // no error...
594    return No_Fault;
595}
596
597#endif // #ifdef FULL_SYSTEM
598
599#endif // __REGFILE_HH__
600