isa.hh revision 13545
12292SN/A/*
22329SN/A * Copyright (c) 2010, 2012-2018 ARM Limited
32292SN/A * All rights reserved
42292SN/A *
52292SN/A * The license below extends only to copyright in the software and shall
62292SN/A * not be construed as granting a license to any other intellectual
72292SN/A * property including but not limited to intellectual property relating
82292SN/A * to a hardware implementation of the functionality of the software
92292SN/A * licensed hereunder.  You may use the software subject to the license
102292SN/A * terms below provided that you ensure that this notice is replicated
112292SN/A * unmodified and in its entirety in all distributions of the software,
122292SN/A * modified or unmodified, in source code or in binary form.
132292SN/A *
142292SN/A * Copyright (c) 2009 The Regents of The University of Michigan
152292SN/A * All rights reserved.
162292SN/A *
172292SN/A * Redistribution and use in source and binary forms, with or without
182292SN/A * modification, are permitted provided that the following conditions are
192292SN/A * met: redistributions of source code must retain the above copyright
202292SN/A * notice, this list of conditions and the following disclaimer;
212292SN/A * redistributions in binary form must reproduce the above copyright
222292SN/A * notice, this list of conditions and the following disclaimer in the
232292SN/A * documentation and/or other materials provided with the distribution;
242292SN/A * neither the name of the copyright holders nor the names of its
252292SN/A * contributors may be used to endorse or promote products derived from
262292SN/A * this software without specific prior written permission.
272689Sktlim@umich.edu *
282689Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292689Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352329SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
364395Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392292SN/A *
402329SN/A * Authors: Gabe Black
413326Sktlim@umich.edu */
422292SN/A
432292SN/A#ifndef __ARCH_ARM_ISA_HH__
442292SN/A#define __ARCH_ARM_ISA_HH__
453348Sbinkertn@umich.edu
462669Sktlim@umich.edu#include "arch/arm/isa_device.hh"
472292SN/A#include "arch/arm/miscregs.hh"
482292SN/A#include "arch/arm/registers.hh"
492329SN/A#include "arch/arm/system.hh"
502329SN/A#include "arch/arm/tlb.hh"
512329SN/A#include "arch/arm/types.hh"
522329SN/A#include "arch/generic/traits.hh"
532329SN/A#include "debug/Checkpoint.hh"
542329SN/A#include "enums/VecRegRenameMode.hh"
552329SN/A#include "sim/sim_object.hh"
562329SN/A#include "enums/DecoderFlavour.hh"
572329SN/A
582329SN/Astruct ArmISAParams;
592292SN/Astruct DummyArmISADeviceParams;
602292SN/Aclass ThreadContext;
612292SN/Aclass Checkpoint;
622292SN/Aclass EventManager;
632292SN/A
642292SN/Anamespace ArmISA
652292SN/A{
662733Sktlim@umich.edu    class ISA : public SimObject
672292SN/A    {
682292SN/A      protected:
692907Sktlim@umich.edu        // Parent system
702292SN/A        ArmSystem *system;
712292SN/A
722292SN/A        // Micro Architecture
732292SN/A        const Enums::DecoderFlavour _decoderFlavour;
742292SN/A        const Enums::VecRegRenameMode _vecRegRenameMode;
752292SN/A
762292SN/A        /** Dummy device for to handle non-existing ISA devices */
774329Sktlim@umich.edu        DummyISADevice dummyDevice;
784329Sktlim@umich.edu
792292SN/A        // PMU belonging to this ISA
802292SN/A        BaseISADevice *pmu;
812292SN/A
822292SN/A        // Generic timer interface belonging to this ISA
832727Sktlim@umich.edu        std::unique_ptr<BaseISADevice> timer;
842727Sktlim@umich.edu
852727Sktlim@umich.edu        // GICv3 CPU interface belonging to this ISA
862907Sktlim@umich.edu        std::unique_ptr<BaseISADevice> gicv3CpuInterface;
874329Sktlim@umich.edu
882907Sktlim@umich.edu        // Cached copies of system-level properties
892348SN/A        bool highestELIs64;
902307SN/A        bool haveSecurity;
912307SN/A        bool haveLPAE;
922348SN/A        bool haveVirtualization;
932307SN/A        bool haveCrypto;
942307SN/A        bool haveLargeAsid64;
952348SN/A        bool haveGICv3CPUInterface;
962307SN/A        uint8_t physAddrRange;
972307SN/A
982292SN/A        /**
992292SN/A         * If true, accesses to IMPLEMENTATION DEFINED registers are treated
1002292SN/A         * as NOP hence not causing UNDEFINED INSTRUCTION.
1012292SN/A         */
1022292SN/A        bool impdefAsNop;
1032292SN/A
1042292SN/A        /** MiscReg metadata **/
1052292SN/A        struct MiscRegLUTEntry {
1062292SN/A            uint32_t lower;  // Lower half mapped to this register
1072292SN/A            uint32_t upper;  // Upper half mapped to this register
1082292SN/A            uint64_t _reset; // value taken on reset (i.e. initialization)
1092292SN/A            uint64_t _res0;  // reserved
1102292SN/A            uint64_t _res1;  // reserved
1112292SN/A            uint64_t _raz;   // read as zero (fixed at 0)
1122292SN/A            uint64_t _rao;   // read as one (fixed at 1)
1132292SN/A          public:
1142292SN/A            MiscRegLUTEntry() :
1152329SN/A              lower(0), upper(0),
1162292SN/A              _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
1172292SN/A            uint64_t reset() const { return _reset; }
1182292SN/A            uint64_t res0()  const { return _res0; }
1192292SN/A            uint64_t res1()  const { return _res1; }
1202292SN/A            uint64_t raz()   const { return _raz; }
1212292SN/A            uint64_t rao()   const { return _rao; }
1222292SN/A            // raz/rao implies writes ignored
1232292SN/A            uint64_t wi()    const { return _raz | _rao; }
1242292SN/A        };
1252292SN/A
1262292SN/A        /** Metadata table accessible via the value of the register */
1272292SN/A        static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
1282292SN/A
1292292SN/A        class MiscRegLUTEntryInitializer {
1302790Sktlim@umich.edu            struct MiscRegLUTEntry &entry;
1312790Sktlim@umich.edu            std::bitset<NUM_MISCREG_INFOS> &info;
1322669Sktlim@umich.edu            typedef const MiscRegLUTEntryInitializer& chain;
1332669Sktlim@umich.edu          public:
1342292SN/A            chain mapsTo(uint32_t l, uint32_t u = 0) const {
1352292SN/A                entry.lower = l;
1362292SN/A                entry.upper = u;
1372292SN/A                return *this;
1382292SN/A            }
1392292SN/A            chain res0(uint64_t mask) const {
1402292SN/A                entry._res0 = mask;
1412292SN/A                return *this;
1422292SN/A            }
1432292SN/A            chain res1(uint64_t mask) const {
1442292SN/A                entry._res1 = mask;
1452292SN/A                return *this;
1462292SN/A            }
1472292SN/A            chain raz(uint64_t mask) const {
1482292SN/A                entry._raz  = mask;
1492292SN/A                return *this;
1502292SN/A            }
1512292SN/A            chain rao(uint64_t mask) const {
1522292SN/A                entry._rao  = mask;
1532292SN/A                return *this;
1542292SN/A            }
1552292SN/A            chain implemented(bool v = true) const {
1562292SN/A                info[MISCREG_IMPLEMENTED] = v;
1572329SN/A                return *this;
1582292SN/A            }
1592292SN/A            chain unimplemented() const {
1602292SN/A                return implemented(false);
1612348SN/A            }
1622292SN/A            chain unverifiable(bool v = true) const {
1632292SN/A                info[MISCREG_UNVERIFIABLE] = v;
1642292SN/A                return *this;
1652348SN/A            }
1662292SN/A            chain warnNotFail(bool v = true) const {
1672292SN/A                info[MISCREG_WARN_NOT_FAIL] = v;
1682292SN/A                return *this;
1692348SN/A            }
1702292SN/A            chain mutex(bool v = true) const {
1712292SN/A                info[MISCREG_MUTEX] = v;
1722292SN/A                return *this;
1732292SN/A            }
1742292SN/A            chain banked(bool v = true) const {
1752292SN/A                info[MISCREG_BANKED] = v;
1762292SN/A                return *this;
1772292SN/A            }
1782292SN/A            chain bankedChild(bool v = true) const {
1792292SN/A                info[MISCREG_BANKED_CHILD] = v;
1802292SN/A                return *this;
1812292SN/A            }
1822292SN/A            chain userNonSecureRead(bool v = true) const {
1832292SN/A                info[MISCREG_USR_NS_RD] = v;
1842292SN/A                return *this;
1852292SN/A            }
1862292SN/A            chain userNonSecureWrite(bool v = true) const {
1872292SN/A                info[MISCREG_USR_NS_WR] = v;
1882292SN/A                return *this;
1892292SN/A            }
1902292SN/A            chain userSecureRead(bool v = true) const {
1912292SN/A                info[MISCREG_USR_S_RD] = v;
1922292SN/A                return *this;
1932292SN/A            }
1942292SN/A            chain userSecureWrite(bool v = true) const {
1952292SN/A                info[MISCREG_USR_S_WR] = v;
1962292SN/A                return *this;
1972292SN/A            }
1982292SN/A            chain user(bool v = true) const {
1992292SN/A                userNonSecureRead(v);
2002292SN/A                userNonSecureWrite(v);
2012292SN/A                userSecureRead(v);
2022292SN/A                userSecureWrite(v);
2032292SN/A                return *this;
2042292SN/A            }
2052678Sktlim@umich.edu            chain privNonSecureRead(bool v = true) const {
2062678Sktlim@umich.edu                info[MISCREG_PRI_NS_RD] = v;
2072292SN/A                return *this;
2082907Sktlim@umich.edu            }
2092907Sktlim@umich.edu            chain privNonSecureWrite(bool v = true) const {
2102907Sktlim@umich.edu                info[MISCREG_PRI_NS_WR] = v;
2112292SN/A                return *this;
2122698Sktlim@umich.edu            }
2132678Sktlim@umich.edu            chain privNonSecure(bool v = true) const {
2142678Sktlim@umich.edu                privNonSecureRead(v);
2152698Sktlim@umich.edu                privNonSecureWrite(v);
2163349Sbinkertn@umich.edu                return *this;
2172693Sktlim@umich.edu            }
2182292SN/A            chain privSecureRead(bool v = true) const {
2192292SN/A                info[MISCREG_PRI_S_RD] = v;
2202292SN/A                return *this;
2212292SN/A            }
2222292SN/A            chain privSecureWrite(bool v = true) const {
2232292SN/A                info[MISCREG_PRI_S_WR] = v;
2242292SN/A                return *this;
2252292SN/A            }
2262292SN/A            chain privSecure(bool v = true) const {
2272292SN/A                privSecureRead(v);
2282292SN/A                privSecureWrite(v);
2292292SN/A                return *this;
2302329SN/A            }
2312329SN/A            chain priv(bool v = true) const {
2322329SN/A                privSecure(v);
2332329SN/A                privNonSecure(v);
2342292SN/A                return *this;
2352292SN/A            }
2362733Sktlim@umich.edu            chain privRead(bool v = true) const {
2372292SN/A                privSecureRead(v);
2382292SN/A                privNonSecureRead(v);
2392292SN/A                return *this;
2402292SN/A            }
2412907Sktlim@umich.edu            chain hypRead(bool v = true) const {
2422907Sktlim@umich.edu                info[MISCREG_HYP_RD] = v;
2432669Sktlim@umich.edu                return *this;
2442907Sktlim@umich.edu            }
2452907Sktlim@umich.edu            chain hypWrite(bool v = true) const {
2462292SN/A                info[MISCREG_HYP_WR] = v;
2472698Sktlim@umich.edu                return *this;
2482678Sktlim@umich.edu            }
2492678Sktlim@umich.edu            chain hyp(bool v = true) const {
2502678Sktlim@umich.edu                hypRead(v);
2512698Sktlim@umich.edu                hypWrite(v);
2522678Sktlim@umich.edu                return *this;
2532678Sktlim@umich.edu            }
2542678Sktlim@umich.edu            chain monSecureRead(bool v = true) const {
2552678Sktlim@umich.edu                info[MISCREG_MON_NS0_RD] = v;
2562698Sktlim@umich.edu                return *this;
2572678Sktlim@umich.edu            }
2582698Sktlim@umich.edu            chain monSecureWrite(bool v = true) const {
2592678Sktlim@umich.edu                info[MISCREG_MON_NS0_WR] = v;
2602698Sktlim@umich.edu                return *this;
2612678Sktlim@umich.edu            }
2622698Sktlim@umich.edu            chain monNonSecureRead(bool v = true) const {
2632678Sktlim@umich.edu                info[MISCREG_MON_NS1_RD] = v;
2642678Sktlim@umich.edu                return *this;
2652678Sktlim@umich.edu            }
2662698Sktlim@umich.edu            chain monNonSecureWrite(bool v = true) const {
2672678Sktlim@umich.edu                info[MISCREG_MON_NS1_WR] = v;
2682678Sktlim@umich.edu                return *this;
2692678Sktlim@umich.edu            }
2702678Sktlim@umich.edu            chain mon(bool v = true) const {
2712678Sktlim@umich.edu                monSecureRead(v);
2722678Sktlim@umich.edu                monSecureWrite(v);
2732678Sktlim@umich.edu                monNonSecureRead(v);
2742678Sktlim@umich.edu                monNonSecureWrite(v);
2752678Sktlim@umich.edu                return *this;
2762678Sktlim@umich.edu            }
2772678Sktlim@umich.edu            chain monSecure(bool v = true) const {
2782678Sktlim@umich.edu                monSecureRead(v);
2792698Sktlim@umich.edu                monSecureWrite(v);
2802678Sktlim@umich.edu                return *this;
2812678Sktlim@umich.edu            }
2822698Sktlim@umich.edu            chain monNonSecure(bool v = true) const {
2832678Sktlim@umich.edu                monNonSecureRead(v);
2842678Sktlim@umich.edu                monNonSecureWrite(v);
2852678Sktlim@umich.edu                return *this;
2862678Sktlim@umich.edu            }
2872678Sktlim@umich.edu            chain allPrivileges(bool v = true) const {
2882678Sktlim@umich.edu                userNonSecureRead(v);
2892292SN/A                userNonSecureWrite(v);
2902292SN/A                userSecureRead(v);
2912292SN/A                userSecureWrite(v);
2922292SN/A                privNonSecureRead(v);
2934326Sgblack@eecs.umich.edu                privNonSecureWrite(v);
2942292SN/A                privSecureRead(v);
2954326Sgblack@eecs.umich.edu                privSecureWrite(v);
2964395Ssaidi@eecs.umich.edu                hypRead(v);
2974326Sgblack@eecs.umich.edu                hypWrite(v);
2982292SN/A                monSecureRead(v);
2992292SN/A                monSecureWrite(v);
3002292SN/A                monNonSecureRead(v);
3014326Sgblack@eecs.umich.edu                monNonSecureWrite(v);
3022292SN/A                return *this;
3034326Sgblack@eecs.umich.edu            }
3044395Ssaidi@eecs.umich.edu            chain nonSecure(bool v = true) const {
3054326Sgblack@eecs.umich.edu                userNonSecureRead(v);
3062292SN/A                userNonSecureWrite(v);
3072292SN/A                privNonSecureRead(v);
3082292SN/A                privNonSecureWrite(v);
3092669Sktlim@umich.edu                hypRead(v);
3102669Sktlim@umich.edu                hypWrite(v);
3112292SN/A                monNonSecureRead(v);
3122292SN/A                monNonSecureWrite(v);
3132292SN/A                return *this;
3144326Sgblack@eecs.umich.edu            }
3152292SN/A            chain secure(bool v = true) const {
3162292SN/A                userSecureRead(v);
3172292SN/A                userSecureWrite(v);
3182292SN/A                privSecureRead(v);
3192292SN/A                privSecureWrite(v);
3202292SN/A                monSecureRead(v);
3212292SN/A                monSecureWrite(v);
3222329SN/A                return *this;
3232292SN/A            }
3242292SN/A            chain reads(bool v) const {
3252292SN/A                userNonSecureRead(v);
3262292SN/A                userSecureRead(v);
3272292SN/A                privNonSecureRead(v);
3282292SN/A                privSecureRead(v);
3292292SN/A                hypRead(v);
3302292SN/A                monSecureRead(v);
3312292SN/A                monNonSecureRead(v);
3322292SN/A                return *this;
3332329SN/A            }
3342329SN/A            chain writes(bool v) const {
3352329SN/A                userNonSecureWrite(v);
3362292SN/A                userSecureWrite(v);
3372329SN/A                privNonSecureWrite(v);
3382329SN/A                privSecureWrite(v);
3392329SN/A                hypWrite(v);
3402292SN/A                monSecureWrite(v);
3412292SN/A                monNonSecureWrite(v);
3422292SN/A                return *this;
3432292SN/A            }
3442329SN/A            chain exceptUserMode() const {
3452292SN/A                user(0);
3462292SN/A                return *this;
3472292SN/A            }
3482292SN/A            MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
3492292SN/A                                       std::bitset<NUM_MISCREG_INFOS> &i)
3502292SN/A              : entry(e),
3512292SN/A                info(i)
3522292SN/A            {
3532292SN/A                // force unimplemented registers to be thusly declared
3542292SN/A                implemented(1);
3552292SN/A            }
3562329SN/A        };
3572329SN/A
3582292SN/A        const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
3592292SN/A            return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
3602292SN/A                                              miscRegInfo[reg]);
3612292SN/A        }
3622292SN/A
3632292SN/A        void initializeMiscRegMetadata();
3642292SN/A
3652292SN/A        MiscReg miscRegs[NumMiscRegs];
3662292SN/A        const IntRegIndex *intRegMap;
3672292SN/A
3682292SN/A        void
3692292SN/A        updateRegMap(CPSR cpsr)
3702348SN/A        {
3712307SN/A            if (cpsr.width == 0) {
3722307SN/A                intRegMap = IntReg64Map;
3732292SN/A            } else {
3742292SN/A                switch (cpsr.mode) {
3752292SN/A                  case MODE_USER:
3762292SN/A                  case MODE_SYSTEM:
3772292SN/A                    intRegMap = IntRegUsrMap;
3782292SN/A                    break;
3792292SN/A                  case MODE_FIQ:
3802292SN/A                    intRegMap = IntRegFiqMap;
3812292SN/A                    break;
3822292SN/A                  case MODE_IRQ:
3832292SN/A                    intRegMap = IntRegIrqMap;
3842292SN/A                    break;
3852292SN/A                  case MODE_SVC:
3862292SN/A                    intRegMap = IntRegSvcMap;
3872698Sktlim@umich.edu                    break;
3882698Sktlim@umich.edu                  case MODE_MON:
3892693Sktlim@umich.edu                    intRegMap = IntRegMonMap;
3902698Sktlim@umich.edu                    break;
3912678Sktlim@umich.edu                  case MODE_ABORT:
3922678Sktlim@umich.edu                    intRegMap = IntRegAbtMap;
3932329SN/A                    break;
3942292SN/A                  case MODE_HYP:
3952292SN/A                    intRegMap = IntRegHypMap;
3962348SN/A                    break;
3972292SN/A                  case MODE_UNDEFINED:
3982292SN/A                    intRegMap = IntRegUndMap;
3992348SN/A                    break;
4002292SN/A                  default:
4012292SN/A                    panic("Unrecognized mode setting in CPSR.\n");
4022292SN/A                }
4032292SN/A            }
4042292SN/A        }
4052292SN/A
4062292SN/A        BaseISADevice &getGenericTimer(ThreadContext *tc);
4072292SN/A        BaseISADevice &getGICv3CPUInterface(ThreadContext *tc);
4082727Sktlim@umich.edu
4092727Sktlim@umich.edu
4102307SN/A      private:
4113126Sktlim@umich.edu        inline void assert32(ThreadContext *tc) {
4123126Sktlim@umich.edu            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
4133126Sktlim@umich.edu            assert(cpsr.width);
4143126Sktlim@umich.edu        }
4153126Sktlim@umich.edu
4163126Sktlim@umich.edu        inline void assert64(ThreadContext *tc) {
4173126Sktlim@umich.edu            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
4183126Sktlim@umich.edu            assert(!cpsr.width);
4193126Sktlim@umich.edu        }
4203126Sktlim@umich.edu
4213126Sktlim@umich.edu      public:
4223126Sktlim@umich.edu        void clear();
4233126Sktlim@umich.edu
4242727Sktlim@umich.edu      protected:
4252727Sktlim@umich.edu        void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
4262727Sktlim@umich.edu        void clear64(const ArmISAParams *p);
4272727Sktlim@umich.edu        void initID32(const ArmISAParams *p);
4282727Sktlim@umich.edu        void initID64(const ArmISAParams *p);
4292727Sktlim@umich.edu
4302727Sktlim@umich.edu      public:
4312727Sktlim@umich.edu        MiscReg readMiscRegNoEffect(int misc_reg) const;
4322727Sktlim@umich.edu        MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
4332727Sktlim@umich.edu        void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
4342727Sktlim@umich.edu        void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
4352727Sktlim@umich.edu
4362727Sktlim@umich.edu        RegId
4372727Sktlim@umich.edu        flattenRegId(const RegId& regId) const
4382727Sktlim@umich.edu        {
4392292SN/A            switch (regId.classValue()) {
4402292SN/A              case IntRegClass:
4412292SN/A                return RegId(IntRegClass, flattenIntIndex(regId.index()));
4422669Sktlim@umich.edu              case FloatRegClass:
4432292SN/A                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
4442292SN/A              case VecRegClass:
4452292SN/A                return RegId(VecRegClass, flattenVecIndex(regId.index()));
4462669Sktlim@umich.edu              case VecElemClass:
4472292SN/A                return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
4482292SN/A                             regId.elemIndex());
4492292SN/A              case CCRegClass:
4502292SN/A                return RegId(CCRegClass, flattenCCIndex(regId.index()));
4512292SN/A              case MiscRegClass:
4522292SN/A                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
4532292SN/A            }
4542292SN/A            return RegId();
4552292SN/A        }
4562292SN/A
4572292SN/A        int
4582292SN/A        flattenIntIndex(int reg) const
4592292SN/A        {
4602292SN/A            assert(reg >= 0);
4612292SN/A            if (reg < NUM_ARCH_INTREGS) {
4622292SN/A                return intRegMap[reg];
4632292SN/A            } else if (reg < NUM_INTREGS) {
4642292SN/A                return reg;
4652292SN/A            } else if (reg == INTREG_SPX) {
4662292SN/A                CPSR cpsr = miscRegs[MISCREG_CPSR];
4672292SN/A                ExceptionLevel el = opModeToEL(
4682292SN/A                    (OperatingMode) (uint8_t) cpsr.mode);
4692292SN/A                if (!cpsr.sp && el != EL0)
4702292SN/A                    return INTREG_SP0;
4712292SN/A                switch (el) {
4722292SN/A                  case EL3:
4732292SN/A                    return INTREG_SP3;
4742292SN/A                  case EL2:
4752292SN/A                    return INTREG_SP2;
4762292SN/A                  case EL1:
4772292SN/A                    return INTREG_SP1;
4782292SN/A                  case EL0:
4792292SN/A                    return INTREG_SP0;
4802292SN/A                  default:
4812669Sktlim@umich.edu                    panic("Invalid exception level");
4822292SN/A                    return 0;  // Never happens.
4832669Sktlim@umich.edu                }
4842292SN/A            } else {
4852669Sktlim@umich.edu                return flattenIntRegModeIndex(reg);
4862669Sktlim@umich.edu            }
4872669Sktlim@umich.edu        }
4882292SN/A
4892292SN/A        int
4902292SN/A        flattenFloatIndex(int reg) const
4912292SN/A        {
4922292SN/A            assert(reg >= 0);
4933172Sstever@eecs.umich.edu            return reg;
4942731Sktlim@umich.edu        }
4952669Sktlim@umich.edu
4962727Sktlim@umich.edu        int
4974032Sktlim@umich.edu        flattenVecIndex(int reg) const
4984032Sktlim@umich.edu        {
4994032Sktlim@umich.edu            assert(reg >= 0);
5004032Sktlim@umich.edu            return reg;
5014032Sktlim@umich.edu        }
5022292SN/A
5032292SN/A        int
5042292SN/A        flattenVecElemIndex(int reg) const
5052292SN/A        {
5062669Sktlim@umich.edu            assert(reg >= 0);
5072292SN/A            return reg;
5082292SN/A        }
5092292SN/A
5102292SN/A        int
5112292SN/A        flattenCCIndex(int reg) const
5122669Sktlim@umich.edu        {
5132292SN/A            assert(reg >= 0);
5143172Sstever@eecs.umich.edu            return reg;
5153326Sktlim@umich.edu        }
5163326Sktlim@umich.edu
5173326Sktlim@umich.edu        int
5183326Sktlim@umich.edu        flattenMiscIndex(int reg) const
5193326Sktlim@umich.edu        {
5203326Sktlim@umich.edu            assert(reg >= 0);
5212292SN/A            int flat_idx = reg;
5222292SN/A
5232292SN/A            if (reg == MISCREG_SPSR) {
5242292SN/A                CPSR cpsr = miscRegs[MISCREG_CPSR];
5252292SN/A                switch (cpsr.mode) {
5262292SN/A                  case MODE_EL0T:
5272292SN/A                    warn("User mode does not have SPSR\n");
5282292SN/A                    flat_idx = MISCREG_SPSR;
5292292SN/A                    break;
5302292SN/A                  case MODE_EL1T:
5312292SN/A                  case MODE_EL1H:
5322292SN/A                    flat_idx = MISCREG_SPSR_EL1;
5332292SN/A                    break;
5342292SN/A                  case MODE_EL2T:
5352292SN/A                  case MODE_EL2H:
5362292SN/A                    flat_idx = MISCREG_SPSR_EL2;
5372292SN/A                    break;
5382292SN/A                  case MODE_EL3T:
5394032Sktlim@umich.edu                  case MODE_EL3H:
5404032Sktlim@umich.edu                    flat_idx = MISCREG_SPSR_EL3;
5414032Sktlim@umich.edu                    break;
5424032Sktlim@umich.edu                  case MODE_USER:
5432292SN/A                    warn("User mode does not have SPSR\n");
5442292SN/A                    flat_idx = MISCREG_SPSR;
5452292SN/A                    break;
5462292SN/A                  case MODE_FIQ:
5472669Sktlim@umich.edu                    flat_idx = MISCREG_SPSR_FIQ;
5482292SN/A                    break;
5492669Sktlim@umich.edu                  case MODE_IRQ:
5502669Sktlim@umich.edu                    flat_idx = MISCREG_SPSR_IRQ;
5512292SN/A                    break;
5522669Sktlim@umich.edu                  case MODE_SVC:
5532292SN/A                    flat_idx = MISCREG_SPSR_SVC;
5542292SN/A                    break;
5552669Sktlim@umich.edu                  case MODE_MON:
5562669Sktlim@umich.edu                    flat_idx = MISCREG_SPSR_MON;
5572292SN/A                    break;
5582292SN/A                  case MODE_ABORT:
5594032Sktlim@umich.edu                    flat_idx = MISCREG_SPSR_ABT;
5602329SN/A                    break;
5612669Sktlim@umich.edu                  case MODE_HYP:
5622292SN/A                    flat_idx = MISCREG_SPSR_HYP;
5634326Sgblack@eecs.umich.edu                    break;
5643803Sgblack@eecs.umich.edu                  case MODE_UNDEFINED:
5652669Sktlim@umich.edu                    flat_idx = MISCREG_SPSR_UND;
5662669Sktlim@umich.edu                    break;
5672292SN/A                  default:
5684326Sgblack@eecs.umich.edu                    warn("Trying to access SPSR in an invalid mode: %d\n",
5694326Sgblack@eecs.umich.edu                         cpsr.mode);
5702292SN/A                    flat_idx = MISCREG_SPSR;
5712292SN/A                    break;
5722292SN/A                }
5732693Sktlim@umich.edu            } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
5742678Sktlim@umich.edu                // Mutually exclusive CP15 register
5754022Sstever@eecs.umich.edu                switch (reg) {
5764022Sstever@eecs.umich.edu                  case MISCREG_PRRR_MAIR0:
5772678Sktlim@umich.edu                  case MISCREG_PRRR_MAIR0_NS:
5782678Sktlim@umich.edu                  case MISCREG_PRRR_MAIR0_S:
5792678Sktlim@umich.edu                    {
5802292SN/A                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
5812292SN/A                        // If the muxed reg has been flattened, work out the
5822292SN/A                        // offset and apply it to the unmuxed reg
5832292SN/A                        int idxOffset = reg - MISCREG_PRRR_MAIR0;
5842292SN/A                        if (ttbcr.eae)
5852678Sktlim@umich.edu                            flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
5862727Sktlim@umich.edu                                                        idxOffset);
5872292SN/A                        else
5882292SN/A                            flat_idx = flattenMiscIndex(MISCREG_PRRR +
5892292SN/A                                                        idxOffset);
5902292SN/A                    }
5912292SN/A                    break;
5922292SN/A                  case MISCREG_NMRR_MAIR1:
5932292SN/A                  case MISCREG_NMRR_MAIR1_NS:
5942292SN/A                  case MISCREG_NMRR_MAIR1_S:
5952292SN/A                    {
5962292SN/A                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
5974032Sktlim@umich.edu                        // If the muxed reg has been flattened, work out the
5982292SN/A                        // offset and apply it to the unmuxed reg
5992292SN/A                        int idxOffset = reg - MISCREG_NMRR_MAIR1;
6002292SN/A                        if (ttbcr.eae)
6012292SN/A                            flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
6022292SN/A                                                        idxOffset);
6032292SN/A                        else
6042292SN/A                            flat_idx = flattenMiscIndex(MISCREG_NMRR +
6052669Sktlim@umich.edu                                                        idxOffset);
6062292SN/A                    }
6072292SN/A                    break;
6082292SN/A                  case MISCREG_PMXEVTYPER_PMCCFILTR:
6092292SN/A                    {
6102292SN/A                        PMSELR pmselr = miscRegs[MISCREG_PMSELR];
6112292SN/A                        if (pmselr.sel == 31)
6122292SN/A                            flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
6132292SN/A                        else
6142669Sktlim@umich.edu                            flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
6152927Sktlim@umich.edu                    }
6164032Sktlim@umich.edu                    break;
6172727Sktlim@umich.edu                  default:
6182292SN/A                    panic("Unrecognized misc. register.\n");
6192292SN/A                    break;
6202292SN/A                }
6212292SN/A            } else {
6222292SN/A                if (miscRegInfo[reg][MISCREG_BANKED]) {
6232669Sktlim@umich.edu                    bool secureReg = haveSecurity && !highestELIs64 &&
6242292SN/A                                     inSecureState(miscRegs[MISCREG_SCR],
6254032Sktlim@umich.edu                                                   miscRegs[MISCREG_CPSR]);
6264032Sktlim@umich.edu                    flat_idx += secureReg ? 2 : 1;
6274032Sktlim@umich.edu                }
6284032Sktlim@umich.edu            }
6294032Sktlim@umich.edu            return flat_idx;
6302292SN/A        }
6312292SN/A
6322292SN/A        std::pair<int,int> getMiscIndices(int misc_reg) const
6332292SN/A        {
6342292SN/A            // Note: indexes of AArch64 registers are left unchanged
6352907Sktlim@umich.edu            int flat_idx = flattenMiscIndex(misc_reg);
6362669Sktlim@umich.edu
6372292SN/A            if (lookUpMiscReg[flat_idx].lower == 0) {
6382669Sktlim@umich.edu                return std::make_pair(flat_idx, 0);
6392669Sktlim@umich.edu            }
6402292SN/A
6412292SN/A            // do additional S/NS flattenings if mapped to NS while in S
6422292SN/A            bool S = haveSecurity && !highestELIs64 &&
6432907Sktlim@umich.edu                     inSecureState(miscRegs[MISCREG_SCR],
6442907Sktlim@umich.edu                                   miscRegs[MISCREG_CPSR]);
6453228Sktlim@umich.edu            int lower = lookUpMiscReg[flat_idx].lower;
6464022Sstever@eecs.umich.edu            int upper = lookUpMiscReg[flat_idx].upper;
6473228Sktlim@umich.edu            // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
6483228Sktlim@umich.edu            lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
6493228Sktlim@umich.edu            upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
6503228Sktlim@umich.edu            return std::make_pair(lower, upper);
6513228Sktlim@umich.edu        }
6523228Sktlim@umich.edu
6533228Sktlim@umich.edu        void serialize(CheckpointOut &cp) const
6543228Sktlim@umich.edu        {
6552907Sktlim@umich.edu            DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
6563228Sktlim@umich.edu            SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
6573228Sktlim@umich.edu
6583228Sktlim@umich.edu            SERIALIZE_SCALAR(highestELIs64);
6593228Sktlim@umich.edu            SERIALIZE_SCALAR(haveSecurity);
6603228Sktlim@umich.edu            SERIALIZE_SCALAR(haveLPAE);
6614032Sktlim@umich.edu            SERIALIZE_SCALAR(haveVirtualization);
6623228Sktlim@umich.edu            SERIALIZE_SCALAR(haveLargeAsid64);
6633228Sktlim@umich.edu            SERIALIZE_SCALAR(physAddrRange);
6644032Sktlim@umich.edu        }
6654032Sktlim@umich.edu        void unserialize(CheckpointIn &cp)
6663228Sktlim@umich.edu        {
6673221Sktlim@umich.edu            DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
6683221Sktlim@umich.edu            UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
6693221Sktlim@umich.edu            CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
6702907Sktlim@umich.edu            updateRegMap(tmp_cpsr);
6712907Sktlim@umich.edu
6722907Sktlim@umich.edu            UNSERIALIZE_SCALAR(highestELIs64);
6732907Sktlim@umich.edu            UNSERIALIZE_SCALAR(haveSecurity);
6742907Sktlim@umich.edu            UNSERIALIZE_SCALAR(haveLPAE);
6752907Sktlim@umich.edu            UNSERIALIZE_SCALAR(haveVirtualization);
6762907Sktlim@umich.edu            UNSERIALIZE_SCALAR(haveLargeAsid64);
6772907Sktlim@umich.edu            UNSERIALIZE_SCALAR(physAddrRange);
6782907Sktlim@umich.edu        }
6794032Sktlim@umich.edu
6804032Sktlim@umich.edu        void startup(ThreadContext *tc);
6814032Sktlim@umich.edu
6822727Sktlim@umich.edu        Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
6833014Srdreslin@umich.edu
6843014Srdreslin@umich.edu        Enums::VecRegRenameMode
6852669Sktlim@umich.edu        vecRegRenameMode() const
6862669Sktlim@umich.edu        {
6872669Sktlim@umich.edu            return _vecRegRenameMode;
6882292SN/A        }
6892669Sktlim@umich.edu
6902669Sktlim@umich.edu        /// Explicitly import the otherwise hidden startup
6912669Sktlim@umich.edu        using SimObject::startup;
6922669Sktlim@umich.edu
6932669Sktlim@umich.edu        typedef ArmISAParams Params;
6942669Sktlim@umich.edu
6952669Sktlim@umich.edu        const Params *params() const;
6962669Sktlim@umich.edu
6972292SN/A        ISA(Params *p);
6982292SN/A    };
6992669Sktlim@umich.edu}
7002292SN/A
7012292SN/Atemplate<>
7022292SN/Astruct initRenameMode<ArmISA::ISA>
7032292SN/A{
7042292SN/A    static Enums::VecRegRenameMode mode(const ArmISA::ISA* isa)
7052669Sktlim@umich.edu    {
7062292SN/A        return isa->vecRegRenameMode();
7072292SN/A    }
7082292SN/A    static bool equals(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
7092292SN/A    {
7102292SN/A        return mode(isa1) == mode(isa2);
7112669Sktlim@umich.edu    }
7122292SN/A};
7132329SN/A
7142292SN/A#endif
7152292SN/A