isa.hh revision 12605:16476b32138d
12SN/A/*
29448SAndreas.Sandberg@ARM.com * Copyright (c) 2010, 2012-2018 ARM Limited
39920Syasuko.eckert@amd.com * All rights reserved
48733Sgeoffrey.blake@arm.com *
58733Sgeoffrey.blake@arm.com * The license below extends only to copyright in the software and shall
68733Sgeoffrey.blake@arm.com * not be construed as granting a license to any other intellectual
78733Sgeoffrey.blake@arm.com * property including but not limited to intellectual property relating
88733Sgeoffrey.blake@arm.com * to a hardware implementation of the functionality of the software
98733Sgeoffrey.blake@arm.com * licensed hereunder.  You may use the software subject to the license
108733Sgeoffrey.blake@arm.com * terms below provided that you ensure that this notice is replicated
118733Sgeoffrey.blake@arm.com * unmodified and in its entirety in all distributions of the software,
128733Sgeoffrey.blake@arm.com * modified or unmodified, in source code or in binary form.
138733Sgeoffrey.blake@arm.com *
148733Sgeoffrey.blake@arm.com * Copyright (c) 2009 The Regents of The University of Michigan
151762SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272SN/A *
282SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392SN/A *
402665Ssaidi@eecs.umich.edu * Authors: Gabe Black
412665Ssaidi@eecs.umich.edu */
422665Ssaidi@eecs.umich.edu
432665Ssaidi@eecs.umich.edu#ifndef __ARCH_ARM_ISA_HH__
442SN/A#define __ARCH_ARM_ISA_HH__
452SN/A
462623SN/A#include "arch/arm/isa_device.hh"
472623SN/A#include "arch/arm/miscregs.hh"
482SN/A#include "arch/arm/registers.hh"
491354SN/A#include "arch/arm/system.hh"
506658Snate@binkert.org#include "arch/arm/tlb.hh"
511717SN/A#include "arch/arm/types.hh"
528887Sgeoffrey.blake@arm.com#include "arch/generic/traits.hh"
538229Snate@binkert.org#include "debug/Checkpoint.hh"
542683Sktlim@umich.edu#include "enums/VecRegRenameMode.hh"
551354SN/A#include "sim/sim_object.hh"
562387SN/A#include "enums/DecoderFlavour.hh"
572387SN/A
582387SN/Astruct ArmISAParams;
5956SN/Astruct DummyArmISADeviceParams;
608779Sgblack@eecs.umich.educlass ThreadContext;
615348Ssaidi@eecs.umich.educlass Checkpoint;
622SN/Aclass EventManager;
632SN/A
648779Sgblack@eecs.umich.edunamespace ArmISA
658779Sgblack@eecs.umich.edu{
662SN/A    class ISA : public SimObject
678779Sgblack@eecs.umich.edu    {
682SN/A      protected:
694182Sgblack@eecs.umich.edu        // Parent system
704182Sgblack@eecs.umich.edu        ArmSystem *system;
718779Sgblack@eecs.umich.edu
728779Sgblack@eecs.umich.edu        // Micro Architecture
734182Sgblack@eecs.umich.edu        const Enums::DecoderFlavour _decoderFlavour;
742SN/A        const Enums::VecRegRenameMode _vecRegRenameMode;
752SN/A
762SN/A        /** Dummy device for to handle non-existing ISA devices */
772SN/A        DummyISADevice dummyDevice;
782SN/A
798737Skoansin.tan@gmail.com        // PMU belonging to this ISA
805529Snate@binkert.org        BaseISADevice *pmu;
812420SN/A
822623SN/A        // Generic timer interface belonging to this ISA
832SN/A        std::unique_ptr<BaseISADevice> timer;
842107SN/A
852159SN/A        // Cached copies of system-level properties
862455SN/A        bool highestELIs64;
872455SN/A        bool haveSecurity;
889920Syasuko.eckert@amd.com        bool haveLPAE;
892386SN/A        bool haveVirtualization;
902623SN/A        bool haveLargeAsid64;
912SN/A        uint8_t physAddrRange64;
921371SN/A
935348Ssaidi@eecs.umich.edu        /** MiscReg metadata **/
947720Sgblack@eecs.umich.edu        struct MiscRegLUTEntry {
955348Ssaidi@eecs.umich.edu            uint32_t lower;  // Lower half mapped to this register
967720Sgblack@eecs.umich.edu            uint32_t upper;  // Upper half mapped to this register
975348Ssaidi@eecs.umich.edu            uint64_t _reset; // value taken on reset (i.e. initialization)
987720Sgblack@eecs.umich.edu            uint64_t _res0;  // reserved
997720Sgblack@eecs.umich.edu            uint64_t _res1;  // reserved
1005348Ssaidi@eecs.umich.edu            uint64_t _raz;   // read as zero (fixed at 0)
1015348Ssaidi@eecs.umich.edu            uint64_t _rao;   // read as one (fixed at 1)
1022SN/A          public:
1035807Snate@binkert.org            MiscRegLUTEntry() :
1042SN/A              lower(0), upper(0),
1052SN/A              _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
1062SN/A            uint64_t reset() const { return _reset; }
1072SN/A            uint64_t res0()  const { return _res0; }
1082SN/A            uint64_t res1()  const { return _res1; }
1092SN/A            uint64_t raz()   const { return _raz; }
1102SN/A            uint64_t rao()   const { return _rao; }
1112SN/A            // raz/rao implies writes ignored
1122SN/A            uint64_t wi()    const { return _raz | _rao; }
1131400SN/A        };
1145529Snate@binkert.org
1152623SN/A        /** Metadata table accessible via the value of the register */
1162SN/A        static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
1171400SN/A
1182683Sktlim@umich.edu        class MiscRegLUTEntryInitializer {
1192683Sktlim@umich.edu            struct MiscRegLUTEntry &entry;
1202190SN/A            std::bitset<NUM_MISCREG_INFOS> &info;
1212683Sktlim@umich.edu            typedef const MiscRegLUTEntryInitializer& chain;
1222683Sktlim@umich.edu          public:
1232683Sktlim@umich.edu            chain mapsTo(uint32_t l, uint32_t u = 0) const {
1242680Sktlim@umich.edu                entry.lower = l;
1258733Sgeoffrey.blake@arm.com                entry.upper = u;
1268733Sgeoffrey.blake@arm.com                return *this;
1278887Sgeoffrey.blake@arm.com            }
1285169Ssaidi@eecs.umich.edu            chain res0(uint64_t mask) const {
1295169Ssaidi@eecs.umich.edu                entry._res0 = mask;
1305496Ssaidi@eecs.umich.edu                return *this;
1315496Ssaidi@eecs.umich.edu            }
1325496Ssaidi@eecs.umich.edu            chain res1(uint64_t mask) const {
1338276SAli.Saidi@ARM.com                entry._res1 = mask;
1345894Sgblack@eecs.umich.edu                return *this;
1355496Ssaidi@eecs.umich.edu            }
1365496Ssaidi@eecs.umich.edu            chain raz(uint64_t mask) const {
1375496Ssaidi@eecs.umich.edu                entry._raz  = mask;
1385894Sgblack@eecs.umich.edu                return *this;
1395496Ssaidi@eecs.umich.edu            }
1405496Ssaidi@eecs.umich.edu            chain rao(uint64_t mask) const {
1415496Ssaidi@eecs.umich.edu                entry._rao  = mask;
1425496Ssaidi@eecs.umich.edu                return *this;
1435496Ssaidi@eecs.umich.edu            }
1445496Ssaidi@eecs.umich.edu            chain implemented(bool v = true) const {
1455496Ssaidi@eecs.umich.edu                info[MISCREG_IMPLEMENTED] = v;
1465169Ssaidi@eecs.umich.edu                return *this;
1472SN/A            }
1482SN/A            chain unimplemented() const {
1492SN/A                return implemented(false);
1502SN/A            }
1512SN/A            chain unverifiable(bool v = true) const {
1522SN/A                info[MISCREG_UNVERIFIABLE] = v;
1534181Sgblack@eecs.umich.edu                return *this;
1544181Sgblack@eecs.umich.edu            }
1552107SN/A            chain warnNotFail(bool v = true) const {
1563276Sgblack@eecs.umich.edu                info[MISCREG_WARN_NOT_FAIL] = v;
1571469SN/A                return *this;
1584377Sgblack@eecs.umich.edu            }
1594377Sgblack@eecs.umich.edu            chain mutex(bool v = true) const {
1604377Sgblack@eecs.umich.edu                info[MISCREG_MUTEX] = v;
1614377Sgblack@eecs.umich.edu                return *this;
1624377Sgblack@eecs.umich.edu            }
1634377Sgblack@eecs.umich.edu            chain banked(bool v = true) const {
1642623SN/A                info[MISCREG_BANKED] = v;
1655894Sgblack@eecs.umich.edu                return *this;
1662623SN/A            }
1672623SN/A            chain bankedChild(bool v = true) const {
1682623SN/A                info[MISCREG_BANKED_CHILD] = v;
169180SN/A                return *this;
1708737Skoansin.tan@gmail.com            }
1718737Skoansin.tan@gmail.com            chain userNonSecureRead(bool v = true) const {
1722SN/A                info[MISCREG_USR_NS_RD] = v;
1732SN/A                return *this;
174334SN/A            }
175334SN/A            chain userNonSecureWrite(bool v = true) const {
1762SN/A                info[MISCREG_USR_NS_WR] = v;
1779461Snilay@cs.wisc.edu                return *this;
1789461Snilay@cs.wisc.edu            }
1792SN/A            chain userSecureRead(bool v = true) const {
1802SN/A                info[MISCREG_USR_S_RD] = v;
181334SN/A                return *this;
1825999Snate@binkert.org            }
1838834Satgutier@umich.edu            chain userSecureWrite(bool v = true) const {
1848834Satgutier@umich.edu                info[MISCREG_USR_S_WR] = v;
1858834Satgutier@umich.edu                return *this;
186707SN/A            }
1874998Sgblack@eecs.umich.edu            chain user(bool v = true) const {
1884998Sgblack@eecs.umich.edu                userNonSecureRead(v);
1898834Satgutier@umich.edu                userNonSecureWrite(v);
1908834Satgutier@umich.edu                userSecureRead(v);
1918834Satgutier@umich.edu                userSecureWrite(v);
1928834Satgutier@umich.edu                return *this;
1938834Satgutier@umich.edu            }
1948834Satgutier@umich.edu            chain privNonSecureRead(bool v = true) const {
1958834Satgutier@umich.edu                info[MISCREG_PRI_NS_RD] = v;
1967897Shestness@cs.utexas.edu                return *this;
1974998Sgblack@eecs.umich.edu            }
1984998Sgblack@eecs.umich.edu            chain privNonSecureWrite(bool v = true) const {
1994998Sgblack@eecs.umich.edu                info[MISCREG_PRI_NS_WR] = v;
2008834Satgutier@umich.edu                return *this;
201707SN/A            }
202707SN/A            chain privSecureRead(bool v = true) const {
203707SN/A                info[MISCREG_PRI_S_RD] = v;
2042SN/A                return *this;
2058834Satgutier@umich.edu            }
2068834Satgutier@umich.edu            chain privSecureWrite(bool v = true) const {
2078834Satgutier@umich.edu                info[MISCREG_PRI_S_WR] = v;
2088834Satgutier@umich.edu                return *this;
2098834Satgutier@umich.edu            }
2107897Shestness@cs.utexas.edu            chain privSecure(bool v = true) const {
2117897Shestness@cs.utexas.edu                privSecureRead(v);
2127897Shestness@cs.utexas.edu                privSecureWrite(v);
2137897Shestness@cs.utexas.edu                return *this;
2147897Shestness@cs.utexas.edu            }
2157897Shestness@cs.utexas.edu            chain hypRead(bool v = true) const {
2167897Shestness@cs.utexas.edu                info[MISCREG_HYP_RD] = v;
2177897Shestness@cs.utexas.edu                return *this;
2187897Shestness@cs.utexas.edu            }
2197897Shestness@cs.utexas.edu            chain hypWrite(bool v = true) const {
2207897Shestness@cs.utexas.edu                info[MISCREG_HYP_WR] = v;
2217897Shestness@cs.utexas.edu                return *this;
2227897Shestness@cs.utexas.edu            }
2237897Shestness@cs.utexas.edu            chain hyp(bool v = true) const {
2247897Shestness@cs.utexas.edu                hypRead(v);
2257897Shestness@cs.utexas.edu                hypWrite(v);
2267897Shestness@cs.utexas.edu                return *this;
2277897Shestness@cs.utexas.edu            }
2287897Shestness@cs.utexas.edu            chain monSecureRead(bool v = true) const {
2297897Shestness@cs.utexas.edu                info[MISCREG_MON_NS0_RD] = v;
2307897Shestness@cs.utexas.edu                return *this;
2317897Shestness@cs.utexas.edu            }
2327897Shestness@cs.utexas.edu            chain monSecureWrite(bool v = true) const {
2337897Shestness@cs.utexas.edu                info[MISCREG_MON_NS0_WR] = v;
2347897Shestness@cs.utexas.edu                return *this;
2357897Shestness@cs.utexas.edu            }
2369920Syasuko.eckert@amd.com            chain monNonSecureRead(bool v = true) const {
2379920Syasuko.eckert@amd.com                info[MISCREG_MON_NS1_RD] = v;
2389920Syasuko.eckert@amd.com                return *this;
2399920Syasuko.eckert@amd.com            }
2402SN/A            chain monNonSecureWrite(bool v = true) const {
2415999Snate@binkert.org                info[MISCREG_MON_NS1_WR] = v;
2427897Shestness@cs.utexas.edu                return *this;
2437897Shestness@cs.utexas.edu            }
2447897Shestness@cs.utexas.edu            chain mon(bool v = true) const {
2457897Shestness@cs.utexas.edu                monSecureRead(v);
2467897Shestness@cs.utexas.edu                monSecureWrite(v);
2477897Shestness@cs.utexas.edu                monNonSecureRead(v);
2487897Shestness@cs.utexas.edu                monNonSecureWrite(v);
2497897Shestness@cs.utexas.edu                return *this;
2502SN/A            }
251124SN/A            chain monSecure(bool v = true) const {
252124SN/A                monSecureRead(v);
253334SN/A                monSecureWrite(v);
254124SN/A                return *this;
2552SN/A            }
2565999Snate@binkert.org            chain monNonSecure(bool v = true) const {
257729SN/A                monNonSecureRead(v);
2582SN/A                monNonSecureWrite(v);
2592390SN/A                return *this;
2605999Snate@binkert.org            }
2612SN/A            chain allPrivileges(bool v = true) const {
2622SN/A                userNonSecureRead(v);
2632390SN/A                userNonSecureWrite(v);
2645999Snate@binkert.org                userSecureRead(v);
2652390SN/A                userSecureWrite(v);
2662390SN/A                privNonSecureRead(v);
2672390SN/A                privNonSecureWrite(v);
2685999Snate@binkert.org                privSecureRead(v);
2692SN/A                privSecureWrite(v);
2702SN/A                hypRead(v);
2712390SN/A                hypWrite(v);
2725999Snate@binkert.org                monSecureRead(v);
2732390SN/A                monSecureWrite(v);
2742390SN/A                monNonSecureRead(v);
2759448SAndreas.Sandberg@ARM.com                monNonSecureWrite(v);
2769448SAndreas.Sandberg@ARM.com                return *this;
2779448SAndreas.Sandberg@ARM.com            }
2782SN/A            chain nonSecure(bool v = true) const {
2791371SN/A                userNonSecureRead(v);
2801371SN/A                userNonSecureWrite(v);
2812623SN/A                privNonSecureRead(v);
2825543Ssaidi@eecs.umich.edu                privNonSecureWrite(v);
2833918Ssaidi@eecs.umich.edu                hypRead(v);
2841371SN/A                hypWrite(v);
285726SN/A                monNonSecureRead(v);
286726SN/A                monNonSecureWrite(v);
287726SN/A                return *this;
288726SN/A            }
289726SN/A            chain secure(bool v = true) const {
290726SN/A                userSecureRead(v);
291726SN/A                userSecureWrite(v);
292726SN/A                privSecureRead(v);
293726SN/A                privSecureWrite(v);
294726SN/A                monSecureRead(v);
295705SN/A                monSecureWrite(v);
2963735Sstever@eecs.umich.edu                return *this;
297726SN/A            }
2987897Shestness@cs.utexas.edu            chain reads(bool v) const {
2992683Sktlim@umich.edu                userNonSecureRead(v);
300726SN/A                userSecureRead(v);
301705SN/A                privNonSecureRead(v);
3023735Sstever@eecs.umich.edu                privSecureRead(v);
303726SN/A                hypRead(v);
3047897Shestness@cs.utexas.edu                monSecureRead(v);
3059918Ssteve.reinhardt@amd.com                monNonSecureRead(v);
3062683Sktlim@umich.edu                return *this;
307726SN/A            }
308705SN/A            chain writes(bool v) const {
3093735Sstever@eecs.umich.edu                userNonSecureWrite(v);
3102455SN/A                userSecureWrite(v);
3117897Shestness@cs.utexas.edu                privNonSecureWrite(v);
3129918Ssteve.reinhardt@amd.com                privSecureWrite(v);
3132683Sktlim@umich.edu                hypWrite(v);
314726SN/A                monSecureWrite(v);
315705SN/A                monNonSecureWrite(v);
3169920Syasuko.eckert@amd.com                return *this;
3179920Syasuko.eckert@amd.com            }
3189920Syasuko.eckert@amd.com            chain exceptUserMode() const {
3199920Syasuko.eckert@amd.com                user(0);
3209920Syasuko.eckert@amd.com                return *this;
3219920Syasuko.eckert@amd.com            }
3229920Syasuko.eckert@amd.com            MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
3233735Sstever@eecs.umich.edu                                       std::bitset<NUM_MISCREG_INFOS> &i)
324726SN/A              : entry(e),
3257897Shestness@cs.utexas.edu                info(i)
3262683Sktlim@umich.edu            {
327726SN/A                // force unimplemented registers to be thusly declared
328705SN/A                implemented(1);
3293735Sstever@eecs.umich.edu            }
330726SN/A        };
3317897Shestness@cs.utexas.edu
3329918Ssteve.reinhardt@amd.com        const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
3332683Sktlim@umich.edu            return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
334726SN/A                                              miscRegInfo[reg]);
335726SN/A        }
3363735Sstever@eecs.umich.edu
3373735Sstever@eecs.umich.edu        void initializeMiscRegMetadata();
3382455SN/A
3397897Shestness@cs.utexas.edu        MiscReg miscRegs[NumMiscRegs];
3409918Ssteve.reinhardt@amd.com        const IntRegIndex *intRegMap;
3412683Sktlim@umich.edu
342726SN/A        void
343705SN/A        updateRegMap(CPSR cpsr)
3449920Syasuko.eckert@amd.com        {
3459920Syasuko.eckert@amd.com            if (cpsr.width == 0) {
3469920Syasuko.eckert@amd.com                intRegMap = IntReg64Map;
3479920Syasuko.eckert@amd.com            } else {
3489920Syasuko.eckert@amd.com                switch (cpsr.mode) {
3499920Syasuko.eckert@amd.com                  case MODE_USER:
3509920Syasuko.eckert@amd.com                  case MODE_SYSTEM:
3517597Sminkyu.jeong@arm.com                    intRegMap = IntRegUsrMap;
3527597Sminkyu.jeong@arm.com                    break;
3537600Sminkyu.jeong@arm.com                  case MODE_FIQ:
3547600Sminkyu.jeong@arm.com                    intRegMap = IntRegFiqMap;
3557600Sminkyu.jeong@arm.com                    break;
3567600Sminkyu.jeong@arm.com                  case MODE_IRQ:
3577600Sminkyu.jeong@arm.com                    intRegMap = IntRegIrqMap;
3587600Sminkyu.jeong@arm.com                    break;
3597720Sgblack@eecs.umich.edu                  case MODE_SVC:
3607720Sgblack@eecs.umich.edu                    intRegMap = IntRegSvcMap;
3617720Sgblack@eecs.umich.edu                    break;
3627720Sgblack@eecs.umich.edu                  case MODE_MON:
3637720Sgblack@eecs.umich.edu                    intRegMap = IntRegMonMap;
364705SN/A                    break;
3654172Ssaidi@eecs.umich.edu                  case MODE_ABORT:
3664172Ssaidi@eecs.umich.edu                    intRegMap = IntRegAbtMap;
3674172Ssaidi@eecs.umich.edu                    break;
3684172Ssaidi@eecs.umich.edu                  case MODE_HYP:
3694172Ssaidi@eecs.umich.edu                    intRegMap = IntRegHypMap;
3702159SN/A                    break;
3712159SN/A                  case MODE_UNDEFINED:
3727897Shestness@cs.utexas.edu                    intRegMap = IntRegUndMap;
3732683Sktlim@umich.edu                    break;
3742159SN/A                  default:
375705SN/A                    panic("Unrecognized mode setting in CPSR.\n");
3763468Sgblack@eecs.umich.edu                }
3772159SN/A            }
3787897Shestness@cs.utexas.edu        }
3792683Sktlim@umich.edu
3802159SN/A        BaseISADevice &getGenericTimer(ThreadContext *tc);
3812159SN/A
3824185Ssaidi@eecs.umich.edu
3833792Sgblack@eecs.umich.edu      private:
3847897Shestness@cs.utexas.edu        inline void assert32(ThreadContext *tc) {
3859918Ssteve.reinhardt@amd.com            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
3863792Sgblack@eecs.umich.edu            assert(cpsr.width);
3873792Sgblack@eecs.umich.edu        }
3883792Sgblack@eecs.umich.edu
3894185Ssaidi@eecs.umich.edu        inline void assert64(ThreadContext *tc) {
3903792Sgblack@eecs.umich.edu            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
3913792Sgblack@eecs.umich.edu            assert(!cpsr.width);
3927897Shestness@cs.utexas.edu        }
3939918Ssteve.reinhardt@amd.com
3944172Ssaidi@eecs.umich.edu      public:
3953792Sgblack@eecs.umich.edu        void clear();
3963792Sgblack@eecs.umich.edu        void clear64(const ArmISAParams *p);
3975358Sgblack@eecs.umich.edu
3985358Sgblack@eecs.umich.edu        MiscReg readMiscRegNoEffect(int misc_reg) const;
3995358Sgblack@eecs.umich.edu        MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
4005358Sgblack@eecs.umich.edu        void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
4015358Sgblack@eecs.umich.edu        void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
4025358Sgblack@eecs.umich.edu
4035358Sgblack@eecs.umich.edu        RegId
4045358Sgblack@eecs.umich.edu        flattenRegId(const RegId& regId) const
4055358Sgblack@eecs.umich.edu        {
4065358Sgblack@eecs.umich.edu            switch (regId.classValue()) {
4075358Sgblack@eecs.umich.edu              case IntRegClass:
4085358Sgblack@eecs.umich.edu                return RegId(IntRegClass, flattenIntIndex(regId.index()));
4095358Sgblack@eecs.umich.edu              case FloatRegClass:
4105358Sgblack@eecs.umich.edu                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
4115358Sgblack@eecs.umich.edu              case VecRegClass:
4124027Sstever@eecs.umich.edu                return RegId(VecRegClass, flattenVecIndex(regId.index()));
4134027Sstever@eecs.umich.edu              case VecElemClass:
4144027Sstever@eecs.umich.edu                return RegId(VecElemClass, flattenVecElemIndex(regId.index()));
4154027Sstever@eecs.umich.edu              case CCRegClass:
4164027Sstever@eecs.umich.edu                return RegId(CCRegClass, flattenCCIndex(regId.index()));
4174027Sstever@eecs.umich.edu              case MiscRegClass:
4184027Sstever@eecs.umich.edu                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
4194027Sstever@eecs.umich.edu            }
4206221Snate@binkert.org            return RegId();
4214661Sksewell@umich.edu        }
4224661Sksewell@umich.edu
4234661Sksewell@umich.edu        int
4244661Sksewell@umich.edu        flattenIntIndex(int reg) const
4254661Sksewell@umich.edu        {
4266221Snate@binkert.org            assert(reg >= 0);
4276221Snate@binkert.org            if (reg < NUM_ARCH_INTREGS) {
4284661Sksewell@umich.edu                return intRegMap[reg];
4294661Sksewell@umich.edu            } else if (reg < NUM_INTREGS) {
4304661Sksewell@umich.edu                return reg;
4314661Sksewell@umich.edu            } else if (reg == INTREG_SPX) {
4324661Sksewell@umich.edu                CPSR cpsr = miscRegs[MISCREG_CPSR];
4335250Sksewell@umich.edu                ExceptionLevel el = opModeToEL(
4345222Sksewell@umich.edu                    (OperatingMode) (uint8_t) cpsr.mode);
4355702Ssaidi@eecs.umich.edu                if (!cpsr.sp && el != EL0)
4365702Ssaidi@eecs.umich.edu                    return INTREG_SP0;
4378557Sgblack@eecs.umich.edu                switch (el) {
4388557Sgblack@eecs.umich.edu                  case EL3:
4398557Sgblack@eecs.umich.edu                    return INTREG_SP3;
4408557Sgblack@eecs.umich.edu                  case EL2:
4418779Sgblack@eecs.umich.edu                    return INTREG_SP2;
4428779Sgblack@eecs.umich.edu                  case EL1:
4438806Sgblack@eecs.umich.edu                    return INTREG_SP1;
4448557Sgblack@eecs.umich.edu                  case EL0:
4458557Sgblack@eecs.umich.edu                    return INTREG_SP0;
446705SN/A                  default:
4472683Sktlim@umich.edu                    panic("Invalid exception level");
4482680Sktlim@umich.edu                    break;
4492SN/A                }
4502SN/A            } else {
4512623SN/A                return flattenIntRegModeIndex(reg);
452            }
453        }
454
455        int
456        flattenFloatIndex(int reg) const
457        {
458            assert(reg >= 0);
459            return reg;
460        }
461
462        int
463        flattenVecIndex(int reg) const
464        {
465            assert(reg >= 0);
466            return reg;
467        }
468
469        int
470        flattenVecElemIndex(int reg) const
471        {
472            assert(reg >= 0);
473            return reg;
474        }
475
476        int
477        flattenCCIndex(int reg) const
478        {
479            assert(reg >= 0);
480            return reg;
481        }
482
483        int
484        flattenMiscIndex(int reg) const
485        {
486            assert(reg >= 0);
487            int flat_idx = reg;
488
489            if (reg == MISCREG_SPSR) {
490                CPSR cpsr = miscRegs[MISCREG_CPSR];
491                switch (cpsr.mode) {
492                  case MODE_EL0T:
493                    warn("User mode does not have SPSR\n");
494                    flat_idx = MISCREG_SPSR;
495                    break;
496                  case MODE_EL1T:
497                  case MODE_EL1H:
498                    flat_idx = MISCREG_SPSR_EL1;
499                    break;
500                  case MODE_EL2T:
501                  case MODE_EL2H:
502                    flat_idx = MISCREG_SPSR_EL2;
503                    break;
504                  case MODE_EL3T:
505                  case MODE_EL3H:
506                    flat_idx = MISCREG_SPSR_EL3;
507                    break;
508                  case MODE_USER:
509                    warn("User mode does not have SPSR\n");
510                    flat_idx = MISCREG_SPSR;
511                    break;
512                  case MODE_FIQ:
513                    flat_idx = MISCREG_SPSR_FIQ;
514                    break;
515                  case MODE_IRQ:
516                    flat_idx = MISCREG_SPSR_IRQ;
517                    break;
518                  case MODE_SVC:
519                    flat_idx = MISCREG_SPSR_SVC;
520                    break;
521                  case MODE_MON:
522                    flat_idx = MISCREG_SPSR_MON;
523                    break;
524                  case MODE_ABORT:
525                    flat_idx = MISCREG_SPSR_ABT;
526                    break;
527                  case MODE_HYP:
528                    flat_idx = MISCREG_SPSR_HYP;
529                    break;
530                  case MODE_UNDEFINED:
531                    flat_idx = MISCREG_SPSR_UND;
532                    break;
533                  default:
534                    warn("Trying to access SPSR in an invalid mode: %d\n",
535                         cpsr.mode);
536                    flat_idx = MISCREG_SPSR;
537                    break;
538                }
539            } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
540                // Mutually exclusive CP15 register
541                switch (reg) {
542                  case MISCREG_PRRR_MAIR0:
543                  case MISCREG_PRRR_MAIR0_NS:
544                  case MISCREG_PRRR_MAIR0_S:
545                    {
546                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
547                        // If the muxed reg has been flattened, work out the
548                        // offset and apply it to the unmuxed reg
549                        int idxOffset = reg - MISCREG_PRRR_MAIR0;
550                        if (ttbcr.eae)
551                            flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
552                                                        idxOffset);
553                        else
554                            flat_idx = flattenMiscIndex(MISCREG_PRRR +
555                                                        idxOffset);
556                    }
557                    break;
558                  case MISCREG_NMRR_MAIR1:
559                  case MISCREG_NMRR_MAIR1_NS:
560                  case MISCREG_NMRR_MAIR1_S:
561                    {
562                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
563                        // If the muxed reg has been flattened, work out the
564                        // offset and apply it to the unmuxed reg
565                        int idxOffset = reg - MISCREG_NMRR_MAIR1;
566                        if (ttbcr.eae)
567                            flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
568                                                        idxOffset);
569                        else
570                            flat_idx = flattenMiscIndex(MISCREG_NMRR +
571                                                        idxOffset);
572                    }
573                    break;
574                  case MISCREG_PMXEVTYPER_PMCCFILTR:
575                    {
576                        PMSELR pmselr = miscRegs[MISCREG_PMSELR];
577                        if (pmselr.sel == 31)
578                            flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
579                        else
580                            flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
581                    }
582                    break;
583                  default:
584                    panic("Unrecognized misc. register.\n");
585                    break;
586                }
587            } else {
588                if (miscRegInfo[reg][MISCREG_BANKED]) {
589                    bool secureReg = haveSecurity && !highestELIs64 &&
590                                     inSecureState(miscRegs[MISCREG_SCR],
591                                                   miscRegs[MISCREG_CPSR]);
592                    flat_idx += secureReg ? 2 : 1;
593                }
594            }
595            return flat_idx;
596        }
597
598        std::pair<int,int> getMiscIndices(int misc_reg) const
599        {
600            // Note: indexes of AArch64 registers are left unchanged
601            int flat_idx = flattenMiscIndex(misc_reg);
602
603            if (lookUpMiscReg[flat_idx].lower == 0) {
604                return std::make_pair(flat_idx, 0);
605            }
606
607            // do additional S/NS flattenings if mapped to NS while in S
608            bool S = haveSecurity && !highestELIs64 &&
609                     inSecureState(miscRegs[MISCREG_SCR],
610                                   miscRegs[MISCREG_CPSR]);
611            int lower = lookUpMiscReg[flat_idx].lower;
612            int upper = lookUpMiscReg[flat_idx].upper;
613            // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
614            lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
615            upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
616            return std::make_pair(lower, upper);
617        }
618
619        void serialize(CheckpointOut &cp) const
620        {
621            DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
622            SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
623
624            SERIALIZE_SCALAR(highestELIs64);
625            SERIALIZE_SCALAR(haveSecurity);
626            SERIALIZE_SCALAR(haveLPAE);
627            SERIALIZE_SCALAR(haveVirtualization);
628            SERIALIZE_SCALAR(haveLargeAsid64);
629            SERIALIZE_SCALAR(physAddrRange64);
630        }
631        void unserialize(CheckpointIn &cp)
632        {
633            DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
634            UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
635            CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
636            updateRegMap(tmp_cpsr);
637
638            UNSERIALIZE_SCALAR(highestELIs64);
639            UNSERIALIZE_SCALAR(haveSecurity);
640            UNSERIALIZE_SCALAR(haveLPAE);
641            UNSERIALIZE_SCALAR(haveVirtualization);
642            UNSERIALIZE_SCALAR(haveLargeAsid64);
643            UNSERIALIZE_SCALAR(physAddrRange64);
644        }
645
646        void startup(ThreadContext *tc) {}
647
648        Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
649
650        Enums::VecRegRenameMode
651        vecRegRenameMode() const
652        {
653            return _vecRegRenameMode;
654        }
655
656        /// Explicitly import the otherwise hidden startup
657        using SimObject::startup;
658
659        typedef ArmISAParams Params;
660
661        const Params *params() const;
662
663        ISA(Params *p);
664    };
665}
666
667template<>
668struct initRenameMode<ArmISA::ISA>
669{
670    static Enums::VecRegRenameMode mode(const ArmISA::ISA* isa)
671    {
672        return isa->vecRegRenameMode();
673    }
674    static bool equals(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
675    {
676        return mode(isa1) == mode(isa2);
677    }
678};
679
680#endif
681