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