regfile.hh revision 2107
12810SN/A/*
210028SGiacomo.Gabrielli@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
38856Sandreas.hansson@arm.com * All rights reserved.
48856Sandreas.hansson@arm.com *
58856Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68856Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78856Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88856Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98856Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108856Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118856Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128856Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138856Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
142810SN/A * this software without specific prior written permission.
152810SN/A *
162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810SN/A */
282810SN/A
292810SN/A#ifndef __CPU_O3_CPU_REGFILE_HH__
302810SN/A#define __CPU_O3_CPU_REGFILE_HH__
312810SN/A
322810SN/A// @todo: Destructor
332810SN/A
342810SN/A#include "arch/alpha/isa_traits.hh"
352810SN/A#include "arch/alpha/faults.hh"
362810SN/A#include "base/trace.hh"
372810SN/A#include "config/full_system.hh"
382810SN/A#include "cpu/o3/comm.hh"
392810SN/A
402810SN/A#if FULL_SYSTEM
414458SN/A#include "arch/alpha/ev5.hh"
424458SN/A#include "kern/kernel_stats.hh"
432810SN/A
442810SN/Ausing namespace EV5;
452810SN/A#endif
462810SN/A
472810SN/A// This really only depends on the ISA, and not the Impl.  It might be nicer
482810SN/A// to see if I can make it depend on nothing...
492810SN/A// Things that are in the ifdef FULL_SYSTEM are pretty dependent on the ISA,
502810SN/A// and should go in the AlphaFullCPU.
512810SN/A
522810SN/Atemplate <class Impl>
537676Snate@binkert.orgclass PhysRegFile
547676Snate@binkert.org{
557676Snate@binkert.org  protected:
562810SN/A    typedef TheISA::Addr Addr;
572810SN/A    typedef TheISA::IntReg IntReg;
582825SN/A    typedef TheISA::FloatReg FloatReg;
592810SN/A    typedef TheISA::MiscRegFile MiscRegFile;
602810SN/A    //Note that most of the definitions of the IntReg, FloatReg, etc. exist
616215Snate@binkert.org    //within the Impl/ISA class and not within this PhysRegFile class.
628232Snate@binkert.org
638232Snate@binkert.org    //Will need some way to allow stuff like swap_palshadow to access the
645338Sstever@gmail.com    //correct registers.  Might require code changes to swap_palshadow and
652810SN/A    //other execution contexts.
662810SN/A
678914Sandreas.hansson@arm.com    //Will make these registers public for now, but they probably should
688229Snate@binkert.org    //be private eventually with some accessor functions.
695034SN/A  public:
702811SN/A    typedef typename Impl::FullCPU FullCPU;
718786Sgblack@eecs.umich.edu
724626SN/A    PhysRegFile(unsigned _numPhysicalIntRegs,
738833Sdam.sunwoo@arm.com                unsigned _numPhysicalFloatRegs);
742810SN/A
753194SN/A    //Everything below should be pretty well identical to the normal
762810SN/A    //register file that exists within AlphaISA class.
772810SN/A    //The duplication is unfortunate but it's better than having
782810SN/A    //different ways to access certain registers.
792810SN/A
802810SN/A    //Add these in later when everything else is in place
814628SN/A//    void serialize(std::ostream &os);
824628SN/A//    void unserialize(Checkpoint *cp, const std::string &section);
834628SN/A
844628SN/A    uint64_t readIntReg(PhysRegIndex reg_idx)
854628SN/A    {
864628SN/A        assert(reg_idx < numPhysicalIntRegs);
874628SN/A
884628SN/A        DPRINTF(IEW, "RegFile: Access to int register %i, has data "
898737Skoansin.tan@gmail.com                "%i\n", int(reg_idx), intRegFile[reg_idx]);
904628SN/A        return intRegFile[reg_idx];
914628SN/A    }
924628SN/A
934628SN/A    float readFloatRegSingle(PhysRegIndex reg_idx)
944628SN/A    {
954628SN/A        // Remove the base Float reg dependency.
964628SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
9710345SCurtis.Dunham@arm.com
984628SN/A        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
994628SN/A
1004628SN/A        DPRINTF(IEW, "RegFile: Access to float register %i as single, has "
1014628SN/A                "data %8.8f\n", int(reg_idx), (float)floatRegFile[reg_idx].d);
1024628SN/A
1034628SN/A        return (float)floatRegFile[reg_idx].d;
1044628SN/A    }
1054628SN/A
1064628SN/A    double readFloatRegDouble(PhysRegIndex reg_idx)
1074628SN/A    {
1084628SN/A        // Remove the base Float reg dependency.
1094628SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
1104628SN/A
1118737Skoansin.tan@gmail.com        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1124628SN/A
1138856Sandreas.hansson@arm.com        DPRINTF(IEW, "RegFile: Access to float register %i as double, has "
1148856Sandreas.hansson@arm.com                " data %8.8f\n", int(reg_idx), floatRegFile[reg_idx].d);
1158856Sandreas.hansson@arm.com
1168856Sandreas.hansson@arm.com        return floatRegFile[reg_idx].d;
1178856Sandreas.hansson@arm.com    }
1188856Sandreas.hansson@arm.com
1198856Sandreas.hansson@arm.com    uint64_t readFloatRegInt(PhysRegIndex reg_idx)
1208856Sandreas.hansson@arm.com    {
1218856Sandreas.hansson@arm.com        // Remove the base Float reg dependency.
1228922Swilliam.wang@arm.com        reg_idx = reg_idx - numPhysicalIntRegs;
1232810SN/A
1248856Sandreas.hansson@arm.com        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1252844SN/A
1268856Sandreas.hansson@arm.com        DPRINTF(IEW, "RegFile: Access to float register %i as int, has data "
1278856Sandreas.hansson@arm.com                "%lli\n", int(reg_idx), floatRegFile[reg_idx].q);
1288856Sandreas.hansson@arm.com
1298856Sandreas.hansson@arm.com        return floatRegFile[reg_idx].q;
1308856Sandreas.hansson@arm.com    }
1318856Sandreas.hansson@arm.com
1328856Sandreas.hansson@arm.com    void setIntReg(PhysRegIndex reg_idx, uint64_t val)
1338856Sandreas.hansson@arm.com    {
1348856Sandreas.hansson@arm.com        assert(reg_idx < numPhysicalIntRegs);
1358914Sandreas.hansson@arm.com
1368856Sandreas.hansson@arm.com        DPRINTF(IEW, "RegFile: Setting int register %i to %lli\n",
1378856Sandreas.hansson@arm.com                int(reg_idx), val);
1383738SN/A
1394458SN/A        intRegFile[reg_idx] = val;
1408856Sandreas.hansson@arm.com    }
1418975Sandreas.hansson@arm.com
1428922Swilliam.wang@arm.com    void setFloatRegSingle(PhysRegIndex reg_idx, float val)
1438914Sandreas.hansson@arm.com    {
1442810SN/A        // Remove the base Float reg dependency.
1458856Sandreas.hansson@arm.com        reg_idx = reg_idx - numPhysicalIntRegs;
1468856Sandreas.hansson@arm.com
1478856Sandreas.hansson@arm.com        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1488914Sandreas.hansson@arm.com
1498856Sandreas.hansson@arm.com        DPRINTF(IEW, "RegFile: Setting float register %i to %8.8f\n",
1508922Swilliam.wang@arm.com                int(reg_idx), val);
1518856Sandreas.hansson@arm.com
1523013SN/A        floatRegFile[reg_idx].d = (double)val;
1538856Sandreas.hansson@arm.com    }
1548856Sandreas.hansson@arm.com
1558856Sandreas.hansson@arm.com    void setFloatRegDouble(PhysRegIndex reg_idx, double val)
1568856Sandreas.hansson@arm.com    {
1578856Sandreas.hansson@arm.com        // Remove the base Float reg dependency.
1588856Sandreas.hansson@arm.com        reg_idx = reg_idx - numPhysicalIntRegs;
1598856Sandreas.hansson@arm.com
1608856Sandreas.hansson@arm.com        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1618922Swilliam.wang@arm.com
1628856Sandreas.hansson@arm.com        DPRINTF(IEW, "RegFile: Setting float register %i to %8.8f\n",
1635314SN/A                int(reg_idx), val);
1642811SN/A
1658856Sandreas.hansson@arm.com        floatRegFile[reg_idx].d = val;
1668856Sandreas.hansson@arm.com    }
1672810SN/A
1682810SN/A    void setFloatRegInt(PhysRegIndex reg_idx, uint64_t val)
1698856Sandreas.hansson@arm.com    {
1702810SN/A        // Remove the base Float reg dependency.
1712810SN/A        reg_idx = reg_idx - numPhysicalIntRegs;
17210345SCurtis.Dunham@arm.com
17310345SCurtis.Dunham@arm.com        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
1748856Sandreas.hansson@arm.com
1758856Sandreas.hansson@arm.com        DPRINTF(IEW, "RegFile: Setting float register %i to %lli\n",
1768856Sandreas.hansson@arm.com                int(reg_idx), val);
1778856Sandreas.hansson@arm.com
1783606SN/A        floatRegFile[reg_idx].q = val;
1798914Sandreas.hansson@arm.com    }
1808975Sandreas.hansson@arm.com
1818914Sandreas.hansson@arm.com    uint64_t readPC()
1822810SN/A    {
1832810SN/A        return pc;
1842897SN/A    }
1852897SN/A
1868856Sandreas.hansson@arm.com    void setPC(uint64_t val)
1874458SN/A    {
18810344Sandreas.hansson@arm.com        pc = val;
18910344Sandreas.hansson@arm.com    }
19010344Sandreas.hansson@arm.com
19110344Sandreas.hansson@arm.com    void setNextPC(uint64_t val)
1928856Sandreas.hansson@arm.com    {
1932811SN/A        npc = val;
1942810SN/A    }
1958856Sandreas.hansson@arm.com
1968856Sandreas.hansson@arm.com    //Consider leaving this stuff and below in some implementation specific
1973338SN/A    //file as opposed to the general register file.  Or have a derived class.
1984626SN/A    uint64_t readUniq()
1994626SN/A    {
2004626SN/A        return miscRegs.uniq;
2014626SN/A    }
2024626SN/A
2034626SN/A    void setUniq(uint64_t val)
2044626SN/A    {
2054626SN/A        miscRegs.uniq = val;
2064628SN/A    }
2074628SN/A
2084628SN/A    uint64_t readFpcr()
2094666SN/A    {
2104628SN/A        return miscRegs.fpcr;
2114628SN/A    }
2124628SN/A
2134628SN/A    void setFpcr(uint64_t val)
2144628SN/A    {
2154628SN/A        miscRegs.fpcr = val;
2164628SN/A    }
2174628SN/A
2184628SN/A#if FULL_SYSTEM
2194628SN/A    uint64_t readIpr(int idx, Fault * &fault);
2204628SN/A    Fault * setIpr(int idx, uint64_t val);
2214628SN/A    InternalProcReg *getIpr() { return ipr; }
2227667Ssteve.reinhardt@amd.com    int readIntrFlag() { return intrflag; }
2234628SN/A    void setIntrFlag(int val) { intrflag = val; }
2244628SN/A#endif
2254628SN/A
2267667Ssteve.reinhardt@amd.com    // These should be private eventually, but will be public for now
2274628SN/A    // so that I can hack around the initregs issue.
2284628SN/A  public:
2294628SN/A    /** (signed) integer register file. */
2304628SN/A    IntReg *intRegFile;
2314628SN/A
2329347SAndreas.Sandberg@arm.com    /** Floating point register file. */
2339347SAndreas.Sandberg@arm.com    FloatReg *floatRegFile;
2349347SAndreas.Sandberg@arm.com
2359347SAndreas.Sandberg@arm.com    /** Miscellaneous register file. */
2369347SAndreas.Sandberg@arm.com    MiscRegFile miscRegs;
2379347SAndreas.Sandberg@arm.com
2389347SAndreas.Sandberg@arm.com    /** Program counter. */
2399347SAndreas.Sandberg@arm.com    Addr pc;
2409347SAndreas.Sandberg@arm.com
2419347SAndreas.Sandberg@arm.com    /** Next-cycle program counter. */
2429347SAndreas.Sandberg@arm.com    Addr npc;
2439347SAndreas.Sandberg@arm.com
2449347SAndreas.Sandberg@arm.com#if FULL_SYSTEM
2459347SAndreas.Sandberg@arm.com  private:
2469347SAndreas.Sandberg@arm.com    // This is ISA specifc stuff; remove it eventually once ISAImpl is used
2479347SAndreas.Sandberg@arm.com    IntReg palregs[NumIntRegs];	// PAL shadow registers
2489347SAndreas.Sandberg@arm.com    InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs
2499347SAndreas.Sandberg@arm.com    int intrflag;			// interrupt flag
2509347SAndreas.Sandberg@arm.com    bool pal_shadow;		// using pal_shadow registers
2514626SN/A#endif
2526227Snate@binkert.org
2534626SN/A  private:
2544630SN/A    FullCPU *cpu;
2554630SN/A
2564630SN/A  public:
2579288Sandreas.hansson@arm.com    void setCPU(FullCPU *cpu_ptr) { cpu = cpu_ptr; }
2589263Smrinmoy.ghosh@arm.com
2599263Smrinmoy.ghosh@arm.com    unsigned numPhysicalIntRegs;
2609263Smrinmoy.ghosh@arm.com    unsigned numPhysicalFloatRegs;
2619263Smrinmoy.ghosh@arm.com};
2629263Smrinmoy.ghosh@arm.com
2639263Smrinmoy.ghosh@arm.comtemplate <class Impl>
2649263Smrinmoy.ghosh@arm.comPhysRegFile<Impl>::PhysRegFile(unsigned _numPhysicalIntRegs,
2659288Sandreas.hansson@arm.com                               unsigned _numPhysicalFloatRegs)
2664630SN/A    : numPhysicalIntRegs(_numPhysicalIntRegs),
2674626SN/A      numPhysicalFloatRegs(_numPhysicalFloatRegs)
2684626SN/A{
2694626SN/A    intRegFile = new IntReg[numPhysicalIntRegs];
2706122SSteve.Reinhardt@amd.com    floatRegFile = new FloatReg[numPhysicalFloatRegs];
2719529Sandreas.hansson@arm.com
2724626SN/A    memset(intRegFile, 0, sizeof(*intRegFile));
2738134SAli.Saidi@ARM.com    memset(floatRegFile, 0, sizeof(*floatRegFile));
2748134SAli.Saidi@ARM.com}
2758134SAli.Saidi@ARM.com
2769529Sandreas.hansson@arm.com#if FULL_SYSTEM
2778134SAli.Saidi@ARM.com
2782810SN/A//Problem:  This code doesn't make sense at the RegFile level because it
2792810SN/A//needs things such as the itb and dtb.  Either put it at the CPU level or
2802810SN/A//the DynInst level.
2812810SN/Atemplate <class Impl>
2822810SN/Auint64_t
2832810SN/APhysRegFile<Impl>::readIpr(int idx, Fault * &fault)
2846122SSteve.Reinhardt@amd.com{
2856122SSteve.Reinhardt@amd.com    uint64_t retval = 0;    // return value, default 0
2866122SSteve.Reinhardt@amd.com
2872810SN/A    switch (idx) {
2889288Sandreas.hansson@arm.com      case TheISA::IPR_PALtemp0:
2892810SN/A      case TheISA::IPR_PALtemp1:
2904626SN/A      case TheISA::IPR_PALtemp2:
2914626SN/A      case TheISA::IPR_PALtemp3:
2922810SN/A      case TheISA::IPR_PALtemp4:
2932810SN/A      case TheISA::IPR_PALtemp5:
2942810SN/A      case TheISA::IPR_PALtemp6:
2952810SN/A      case TheISA::IPR_PALtemp7:
2966122SSteve.Reinhardt@amd.com      case TheISA::IPR_PALtemp8:
2976122SSteve.Reinhardt@amd.com      case TheISA::IPR_PALtemp9:
2986122SSteve.Reinhardt@amd.com      case TheISA::IPR_PALtemp10:
2999529Sandreas.hansson@arm.com      case TheISA::IPR_PALtemp11:
3006122SSteve.Reinhardt@amd.com      case TheISA::IPR_PALtemp12:
3018833Sdam.sunwoo@arm.com      case TheISA::IPR_PALtemp13:
3028833Sdam.sunwoo@arm.com      case TheISA::IPR_PALtemp14:
3038833Sdam.sunwoo@arm.com      case TheISA::IPR_PALtemp15:
3046978SLisa.Hsu@amd.com      case TheISA::IPR_PALtemp16:
3052810SN/A      case TheISA::IPR_PALtemp17:
3062810SN/A      case TheISA::IPR_PALtemp18:
3072810SN/A      case TheISA::IPR_PALtemp19:
3082810SN/A      case TheISA::IPR_PALtemp20:
3092810SN/A      case TheISA::IPR_PALtemp21:
3102810SN/A      case TheISA::IPR_PALtemp22:
3112810SN/A      case TheISA::IPR_PALtemp23:
3125999Snate@binkert.org      case TheISA::IPR_PAL_BASE:
3132810SN/A
3142810SN/A      case TheISA::IPR_IVPTBR:
3152810SN/A      case TheISA::IPR_DC_MODE:
3162810SN/A      case TheISA::IPR_MAF_MODE:
3172810SN/A      case TheISA::IPR_ISR:
3182810SN/A      case TheISA::IPR_EXC_ADDR:
3195999Snate@binkert.org      case TheISA::IPR_IC_PERR_STAT:
3202810SN/A      case TheISA::IPR_DC_PERR_STAT:
3212810SN/A      case TheISA::IPR_MCSR:
3222810SN/A      case TheISA::IPR_ASTRR:
3232810SN/A      case TheISA::IPR_ASTER:
3242810SN/A      case TheISA::IPR_SIRR:
3252810SN/A      case TheISA::IPR_ICSR:
3262810SN/A      case TheISA::IPR_ICM:
3272810SN/A      case TheISA::IPR_DTB_CM:
3282810SN/A      case TheISA::IPR_IPLR:
3295999Snate@binkert.org      case TheISA::IPR_INTID:
3302810SN/A      case TheISA::IPR_PMCTR:
3312810SN/A        // no side-effect
3322810SN/A        retval = ipr[idx];
3332810SN/A        break;
3342810SN/A
3352810SN/A      case TheISA::IPR_CC:
3364022SN/A        retval |= ipr[idx] & ULL(0xffffffff00000000);
3372810SN/A        retval |= curTick  & ULL(0x00000000ffffffff);
3382810SN/A        break;
3392810SN/A
3402810SN/A      case TheISA::IPR_VA:
3412810SN/A        retval = ipr[idx];
3422810SN/A        break;
3434022SN/A
3442810SN/A      case TheISA::IPR_VA_FORM:
3452810SN/A      case TheISA::IPR_MM_STAT:
3462810SN/A      case TheISA::IPR_IFAULT_VA_FORM:
3472810SN/A      case TheISA::IPR_EXC_MASK:
3482810SN/A      case TheISA::IPR_EXC_SUM:
3492810SN/A        retval = ipr[idx];
3504022SN/A        break;
3512810SN/A
3522810SN/A      case TheISA::IPR_DTB_PTE:
3532810SN/A        {
3542810SN/A            TheISA::PTE &pte = cpu->dtb->index(1);
3552810SN/A
3562810SN/A            retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
3575999Snate@binkert.org            retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
3582810SN/A            retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12;
3595999Snate@binkert.org            retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1;
3602810SN/A            retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2;
3612810SN/A            retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4;
3622810SN/A            retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57;
3632810SN/A        }
3642810SN/A        break;
3655999Snate@binkert.org
3662810SN/A        // write only registers
3672810SN/A      case TheISA::IPR_HWINT_CLR:
3685999Snate@binkert.org      case TheISA::IPR_SL_XMIT:
3692810SN/A      case TheISA::IPR_DC_FLUSH:
3704626SN/A      case TheISA::IPR_IC_FLUSH:
3715999Snate@binkert.org      case TheISA::IPR_ALT_MODE:
3724626SN/A      case TheISA::IPR_DTB_IA:
3734626SN/A      case TheISA::IPR_DTB_IAP:
3745999Snate@binkert.org      case TheISA::IPR_ITB_IA:
3754626SN/A      case TheISA::IPR_ITB_IAP:
3764626SN/A        fault = UnimplementedOpcodeFault;
3774626SN/A        break;
3784626SN/A
3794626SN/A      default:
3804626SN/A        // invalid IPR
3815999Snate@binkert.org        fault = UnimplementedOpcodeFault;
3824626SN/A        break;
3834626SN/A    }
3844626SN/A
3854626SN/A    return retval;
3864626SN/A}
3874626SN/A
3885999Snate@binkert.orgextern int break_ipl;
3894626SN/A
3904626SN/Atemplate <class Impl>
3914626SN/AFault *
3924626SN/APhysRegFile<Impl>::setIpr(int idx, uint64_t val)
3935999Snate@binkert.org{
3944626SN/A    uint64_t old;
3954626SN/A
3964626SN/A    switch (idx) {
3974626SN/A      case TheISA::IPR_PALtemp0:
3984626SN/A      case TheISA::IPR_PALtemp1:
3994626SN/A      case TheISA::IPR_PALtemp2:
4005999Snate@binkert.org      case TheISA::IPR_PALtemp3:
4014626SN/A      case TheISA::IPR_PALtemp4:
4024626SN/A      case TheISA::IPR_PALtemp5:
4034626SN/A      case TheISA::IPR_PALtemp6:
4047461Snate@binkert.org      case TheISA::IPR_PALtemp7:
4054626SN/A      case TheISA::IPR_PALtemp8:
4064626SN/A      case TheISA::IPR_PALtemp9:
4074626SN/A      case TheISA::IPR_PALtemp10:
4084626SN/A      case TheISA::IPR_PALtemp11:
4094626SN/A      case TheISA::IPR_PALtemp12:
4104626SN/A      case TheISA::IPR_PALtemp13:
4117461Snate@binkert.org      case TheISA::IPR_PALtemp14:
4124626SN/A      case TheISA::IPR_PALtemp15:
4134626SN/A      case TheISA::IPR_PALtemp16:
4144626SN/A      case TheISA::IPR_PALtemp17:
4154626SN/A      case TheISA::IPR_PALtemp18:
4164626SN/A      case TheISA::IPR_PALtemp19:
4174626SN/A      case TheISA::IPR_PALtemp20:
4184626SN/A      case TheISA::IPR_PALtemp21:
4194626SN/A      case TheISA::IPR_PALtemp22:
4204626SN/A      case TheISA::IPR_PAL_BASE:
4214626SN/A      case TheISA::IPR_IC_PERR_STAT:
4224626SN/A      case TheISA::IPR_DC_PERR_STAT:
4234626SN/A      case TheISA::IPR_PMCTR:
4244626SN/A        // write entire quad w/ no side-effect
4254626SN/A        ipr[idx] = val;
4264626SN/A        break;
4274626SN/A
4284626SN/A      case TheISA::IPR_CC_CTL:
4294626SN/A        // This IPR resets the cycle counter.  We assume this only
4304626SN/A        // happens once... let's verify that.
4314626SN/A        assert(ipr[idx] == 0);
4324626SN/A        ipr[idx] = 1;
4335999Snate@binkert.org        break;
4344626SN/A
4355999Snate@binkert.org      case TheISA::IPR_CC:
4364626SN/A        // This IPR only writes the upper 64 bits.  It's ok to write
4375999Snate@binkert.org        // all 64 here since we mask out the lower 32 in rpcc (see
4384626SN/A        // isa_desc).
4392810SN/A        ipr[idx] = val;
4402810SN/A        break;
4412810SN/A
4422810SN/A      case TheISA::IPR_PALtemp23:
4432810SN/A        // write entire quad w/ no side-effect
4442810SN/A        old = ipr[idx];
4452810SN/A        ipr[idx] = val;
4462810SN/A        break;
4472810SN/A
4482810SN/A      case TheISA::IPR_DTB_PTE:
4495034SN/A        // write entire quad w/ no side-effect, tag is forthcoming
4505034SN/A        ipr[idx] = val;
4515034SN/A        break;
4523606SN/A
4532858SN/A      case TheISA::IPR_EXC_ADDR:
4542858SN/A        // second least significant bit in PC is always zero
4559294Sandreas.hansson@arm.com        ipr[idx] = val & ~2;
4569294Sandreas.hansson@arm.com        break;
4579294Sandreas.hansson@arm.com
4589294Sandreas.hansson@arm.com      case TheISA::IPR_ASTRR:
4598922Swilliam.wang@arm.com      case TheISA::IPR_ASTER:
4602810SN/A        // only write least significant four bits - privilege mask
4612810SN/A        ipr[idx] = val & 0xf;
4622810SN/A        break;
4632810SN/A
4646227Snate@binkert.org      case TheISA::IPR_IPLR:
4656227Snate@binkert.org        // only write least significant five bits - interrupt level
4662810SN/A        ipr[idx] = val & 0x1f;
4672810SN/A        break;
4682810SN/A
4692810SN/A      case TheISA::IPR_DTB_CM:
4704626SN/A
4716666Ssteve.reinhardt@amd.com      case TheISA::IPR_ICM:
4724626SN/A        // only write two mode bits - processor mode
4734626SN/A        ipr[idx] = val & 0x18;
4748883SAli.Saidi@ARM.com        break;
4756122SSteve.Reinhardt@amd.com
4764628SN/A      case TheISA::IPR_ALT_MODE:
4774628SN/A        // only write two mode bits - processor mode
4784902SN/A        ipr[idx] = val & 0x18;
4794628SN/A        break;
4804628SN/A
4814628SN/A      case TheISA::IPR_MCSR:
4824628SN/A        // more here after optimization...
4834628SN/A        ipr[idx] = val;
4844902SN/A        break;
4854628SN/A
4864902SN/A      case TheISA::IPR_SIRR:
4874902SN/A        // only write software interrupt mask
4884902SN/A        ipr[idx] = val & 0x7fff0;
4894628SN/A        break;
4904628SN/A
4914628SN/A      case TheISA::IPR_ICSR:
4924902SN/A        ipr[idx] = val & ULL(0xffffff0300);
4934902SN/A        break;
4944902SN/A
4954902SN/A      case TheISA::IPR_IVPTBR:
4964902SN/A      case TheISA::IPR_MVPTBR:
4974902SN/A        ipr[idx] = val & ULL(0xffffffffc0000000);
4984902SN/A        break;
4994902SN/A
5004628SN/A      case TheISA::IPR_DC_TEST_CTL:
5012810SN/A        ipr[idx] = val & 0x1ffb;
5022810SN/A        break;
5032810SN/A
5049529Sandreas.hansson@arm.com      case TheISA::IPR_DC_MODE:
5052810SN/A      case TheISA::IPR_MAF_MODE:
5062810SN/A        ipr[idx] = val & 0x3f;
5072810SN/A        break;
5082810SN/A
5092810SN/A      case TheISA::IPR_ITB_ASN:
5102810SN/A        ipr[idx] = val & 0x7f0;
5112810SN/A        break;
5122810SN/A
5132810SN/A      case TheISA::IPR_DTB_ASN:
5142810SN/A        ipr[idx] = val & ULL(0xfe00000000000000);
5152810SN/A        break;
5162810SN/A
5172810SN/A      case TheISA::IPR_EXC_SUM:
5182810SN/A      case TheISA::IPR_EXC_MASK:
5199288Sandreas.hansson@arm.com        // any write to this register clears it
5204630SN/A        ipr[idx] = 0;
5212810SN/A        break;
5224630SN/A
5234630SN/A      case TheISA::IPR_INTID:
5242810SN/A      case TheISA::IPR_SL_RCV:
5252810SN/A      case TheISA::IPR_MM_STAT:
5262810SN/A      case TheISA::IPR_ITB_PTE_TEMP:
5272810SN/A      case TheISA::IPR_DTB_PTE_TEMP:
5282810SN/A        // read-only registers
5292810SN/A        return UnimplementedOpcodeFault;
5302810SN/A
5312810SN/A      case TheISA::IPR_HWINT_CLR:
5322810SN/A      case TheISA::IPR_SL_XMIT:
5332810SN/A      case TheISA::IPR_DC_FLUSH:
5342810SN/A      case TheISA::IPR_IC_FLUSH:
5352810SN/A        // the following are write only
5364630SN/A        ipr[idx] = val;
5374630SN/A        break;
5384630SN/A
5399288Sandreas.hansson@arm.com      case TheISA::IPR_DTB_IA:
5404630SN/A        // really a control write
5412810SN/A        ipr[idx] = 0;
5422810SN/A
5432810SN/A        cpu->dtb->flushAll();
5442810SN/A        break;
5452810SN/A
5462810SN/A      case TheISA::IPR_DTB_IAP:
5472810SN/A        // really a control write
5482810SN/A        ipr[idx] = 0;
5494458SN/A
5502810SN/A        cpu->dtb->flushProcesses();
5514458SN/A        break;
5522810SN/A
5532810SN/A      case TheISA::IPR_DTB_IS:
5542810SN/A        // really a control write
5552810SN/A        ipr[idx] = val;
5562810SN/A
5572810SN/A        cpu->dtb->flushAddr(val, DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN]));
5584458SN/A        break;
5592810SN/A
5605875Ssteve.reinhardt@amd.com      case TheISA::IPR_DTB_TAG: {
5615875Ssteve.reinhardt@amd.com          struct TheISA::PTE pte;
5625875Ssteve.reinhardt@amd.com
5635875Ssteve.reinhardt@amd.com          // FIXME: granularity hints NYI...
5645875Ssteve.reinhardt@amd.com          if (DTB_PTE_GH(ipr[TheISA::IPR_DTB_PTE]) != 0)
5652811SN/A              panic("PTE GH field != 0");
5663503SN/A
5679342SAndreas.Sandberg@arm.com          // write entire quad
5683503SN/A          ipr[idx] = val;
56910028SGiacomo.Gabrielli@arm.com
5704626SN/A          // construct PTE for new entry
57110028SGiacomo.Gabrielli@arm.com          pte.ppn = DTB_PTE_PPN(ipr[TheISA::IPR_DTB_PTE]);
5724626SN/A          pte.xre = DTB_PTE_XRE(ipr[TheISA::IPR_DTB_PTE]);
5738833Sdam.sunwoo@arm.com          pte.xwe = DTB_PTE_XWE(ipr[TheISA::IPR_DTB_PTE]);
5743503SN/A          pte.fonr = DTB_PTE_FONR(ipr[TheISA::IPR_DTB_PTE]);
5758833Sdam.sunwoo@arm.com          pte.fonw = DTB_PTE_FONW(ipr[TheISA::IPR_DTB_PTE]);
5768833Sdam.sunwoo@arm.com          pte.asma = DTB_PTE_ASMA(ipr[TheISA::IPR_DTB_PTE]);
57710020Smatt.horsnell@ARM.com          pte.asn = DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN]);
5784626SN/A
5794626SN/A          // insert new TAG/PTE value into data TLB
5804626SN/A          cpu->dtb->insert(val, pte);
5814626SN/A      }
5823503SN/A        break;
5833503SN/A
5848833Sdam.sunwoo@arm.com      case TheISA::IPR_ITB_PTE: {
5856978SLisa.Hsu@amd.com          struct TheISA::PTE pte;
5868833Sdam.sunwoo@arm.com
5878833Sdam.sunwoo@arm.com          // FIXME: granularity hints NYI...
5886978SLisa.Hsu@amd.com          if (ITB_PTE_GH(val) != 0)
5896978SLisa.Hsu@amd.com              panic("PTE GH field != 0");
5903503SN/A
5912810SN/A          // write entire quad
5922810SN/A          ipr[idx] = val;
5932810SN/A
594          // construct PTE for new entry
595          pte.ppn = ITB_PTE_PPN(val);
596          pte.xre = ITB_PTE_XRE(val);
597          pte.xwe = 0;
598          pte.fonr = ITB_PTE_FONR(val);
599          pte.fonw = ITB_PTE_FONW(val);
600          pte.asma = ITB_PTE_ASMA(val);
601          pte.asn = ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN]);
602
603          // insert new TAG/PTE value into data TLB
604          cpu->itb->insert(ipr[TheISA::IPR_ITB_TAG], pte);
605      }
606        break;
607
608      case TheISA::IPR_ITB_IA:
609        // really a control write
610        ipr[idx] = 0;
611
612        cpu->itb->flushAll();
613        break;
614
615      case TheISA::IPR_ITB_IAP:
616        // really a control write
617        ipr[idx] = 0;
618
619        cpu->itb->flushProcesses();
620        break;
621
622      case TheISA::IPR_ITB_IS:
623        // really a control write
624        ipr[idx] = val;
625
626        cpu->itb->flushAddr(val, ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN]));
627        break;
628
629      default:
630        // invalid IPR
631        return UnimplementedOpcodeFault;
632    }
633
634    // no error...
635    return NoFault;
636}
637
638#endif // #if FULL_SYSTEM
639
640#endif // __CPU_O3_CPU_REGFILE_HH__
641