isa.hh revision 14133:f3e7e7c3803d
1/*
2 * Copyright (c) 2010, 2012-2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2009 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Gabe Black
41 */
42
43#ifndef __ARCH_ARM_ISA_HH__
44#define __ARCH_ARM_ISA_HH__
45
46#include "arch/arm/isa_device.hh"
47#include "arch/arm/miscregs.hh"
48#include "arch/arm/registers.hh"
49#include "arch/arm/system.hh"
50#include "arch/arm/tlb.hh"
51#include "arch/arm/types.hh"
52#include "arch/generic/traits.hh"
53#include "debug/Checkpoint.hh"
54#include "enums/VecRegRenameMode.hh"
55#include "sim/sim_object.hh"
56#include "enums/DecoderFlavour.hh"
57
58struct ArmISAParams;
59struct DummyArmISADeviceParams;
60class ThreadContext;
61class Checkpoint;
62class EventManager;
63
64namespace ArmISA
65{
66    class ISA : public SimObject
67    {
68      protected:
69        // Parent system
70        ArmSystem *system;
71
72        // Micro Architecture
73        const Enums::DecoderFlavour _decoderFlavour;
74        const Enums::VecRegRenameMode _vecRegRenameMode;
75
76        /** Dummy device for to handle non-existing ISA devices */
77        DummyISADevice dummyDevice;
78
79        // PMU belonging to this ISA
80        BaseISADevice *pmu;
81
82        // Generic timer interface belonging to this ISA
83        std::unique_ptr<BaseISADevice> timer;
84
85        // GICv3 CPU interface belonging to this ISA
86        std::unique_ptr<BaseISADevice> gicv3CpuInterface;
87
88        // Cached copies of system-level properties
89        bool highestELIs64;
90        bool haveSecurity;
91        bool haveLPAE;
92        bool haveVirtualization;
93        bool haveCrypto;
94        bool haveLargeAsid64;
95        bool haveGICv3CPUInterface;
96        uint8_t physAddrRange;
97        bool haveSVE;
98        bool haveLSE;
99        bool havePAN;
100
101        /** SVE vector length in quadwords */
102        unsigned sveVL;
103
104        /**
105         * If true, accesses to IMPLEMENTATION DEFINED registers are treated
106         * as NOP hence not causing UNDEFINED INSTRUCTION.
107         */
108        bool impdefAsNop;
109
110        bool afterStartup;
111
112        /** MiscReg metadata **/
113        struct MiscRegLUTEntry {
114            uint32_t lower;  // Lower half mapped to this register
115            uint32_t upper;  // Upper half mapped to this register
116            uint64_t _reset; // value taken on reset (i.e. initialization)
117            uint64_t _res0;  // reserved
118            uint64_t _res1;  // reserved
119            uint64_t _raz;   // read as zero (fixed at 0)
120            uint64_t _rao;   // read as one (fixed at 1)
121          public:
122            MiscRegLUTEntry() :
123              lower(0), upper(0),
124              _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
125            uint64_t reset() const { return _reset; }
126            uint64_t res0()  const { return _res0; }
127            uint64_t res1()  const { return _res1; }
128            uint64_t raz()   const { return _raz; }
129            uint64_t rao()   const { return _rao; }
130            // raz/rao implies writes ignored
131            uint64_t wi()    const { return _raz | _rao; }
132        };
133
134        /** Metadata table accessible via the value of the register */
135        static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
136
137        class MiscRegLUTEntryInitializer {
138            struct MiscRegLUTEntry &entry;
139            std::bitset<NUM_MISCREG_INFOS> &info;
140            typedef const MiscRegLUTEntryInitializer& chain;
141          public:
142            chain mapsTo(uint32_t l, uint32_t u = 0) const {
143                entry.lower = l;
144                entry.upper = u;
145                return *this;
146            }
147            chain res0(uint64_t mask) const {
148                entry._res0 = mask;
149                return *this;
150            }
151            chain res1(uint64_t mask) const {
152                entry._res1 = mask;
153                return *this;
154            }
155            chain raz(uint64_t mask) const {
156                entry._raz  = mask;
157                return *this;
158            }
159            chain rao(uint64_t mask) const {
160                entry._rao  = mask;
161                return *this;
162            }
163            chain implemented(bool v = true) const {
164                info[MISCREG_IMPLEMENTED] = v;
165                return *this;
166            }
167            chain unimplemented() const {
168                return implemented(false);
169            }
170            chain unverifiable(bool v = true) const {
171                info[MISCREG_UNVERIFIABLE] = v;
172                return *this;
173            }
174            chain warnNotFail(bool v = true) const {
175                info[MISCREG_WARN_NOT_FAIL] = v;
176                return *this;
177            }
178            chain mutex(bool v = true) const {
179                info[MISCREG_MUTEX] = v;
180                return *this;
181            }
182            chain banked(bool v = true) const {
183                info[MISCREG_BANKED] = v;
184                return *this;
185            }
186            chain bankedChild(bool v = true) const {
187                info[MISCREG_BANKED_CHILD] = v;
188                return *this;
189            }
190            chain userNonSecureRead(bool v = true) const {
191                info[MISCREG_USR_NS_RD] = v;
192                return *this;
193            }
194            chain userNonSecureWrite(bool v = true) const {
195                info[MISCREG_USR_NS_WR] = v;
196                return *this;
197            }
198            chain userSecureRead(bool v = true) const {
199                info[MISCREG_USR_S_RD] = v;
200                return *this;
201            }
202            chain userSecureWrite(bool v = true) const {
203                info[MISCREG_USR_S_WR] = v;
204                return *this;
205            }
206            chain user(bool v = true) const {
207                userNonSecureRead(v);
208                userNonSecureWrite(v);
209                userSecureRead(v);
210                userSecureWrite(v);
211                return *this;
212            }
213            chain privNonSecureRead(bool v = true) const {
214                info[MISCREG_PRI_NS_RD] = v;
215                return *this;
216            }
217            chain privNonSecureWrite(bool v = true) const {
218                info[MISCREG_PRI_NS_WR] = v;
219                return *this;
220            }
221            chain privNonSecure(bool v = true) const {
222                privNonSecureRead(v);
223                privNonSecureWrite(v);
224                return *this;
225            }
226            chain privSecureRead(bool v = true) const {
227                info[MISCREG_PRI_S_RD] = v;
228                return *this;
229            }
230            chain privSecureWrite(bool v = true) const {
231                info[MISCREG_PRI_S_WR] = v;
232                return *this;
233            }
234            chain privSecure(bool v = true) const {
235                privSecureRead(v);
236                privSecureWrite(v);
237                return *this;
238            }
239            chain priv(bool v = true) const {
240                privSecure(v);
241                privNonSecure(v);
242                return *this;
243            }
244            chain privRead(bool v = true) const {
245                privSecureRead(v);
246                privNonSecureRead(v);
247                return *this;
248            }
249            chain hypRead(bool v = true) const {
250                info[MISCREG_HYP_RD] = v;
251                return *this;
252            }
253            chain hypWrite(bool v = true) const {
254                info[MISCREG_HYP_WR] = v;
255                return *this;
256            }
257            chain hyp(bool v = true) const {
258                hypRead(v);
259                hypWrite(v);
260                return *this;
261            }
262            chain monSecureRead(bool v = true) const {
263                info[MISCREG_MON_NS0_RD] = v;
264                return *this;
265            }
266            chain monSecureWrite(bool v = true) const {
267                info[MISCREG_MON_NS0_WR] = v;
268                return *this;
269            }
270            chain monNonSecureRead(bool v = true) const {
271                info[MISCREG_MON_NS1_RD] = v;
272                return *this;
273            }
274            chain monNonSecureWrite(bool v = true) const {
275                info[MISCREG_MON_NS1_WR] = v;
276                return *this;
277            }
278            chain mon(bool v = true) const {
279                monSecureRead(v);
280                monSecureWrite(v);
281                monNonSecureRead(v);
282                monNonSecureWrite(v);
283                return *this;
284            }
285            chain monSecure(bool v = true) const {
286                monSecureRead(v);
287                monSecureWrite(v);
288                return *this;
289            }
290            chain monNonSecure(bool v = true) const {
291                monNonSecureRead(v);
292                monNonSecureWrite(v);
293                return *this;
294            }
295            chain allPrivileges(bool v = true) const {
296                userNonSecureRead(v);
297                userNonSecureWrite(v);
298                userSecureRead(v);
299                userSecureWrite(v);
300                privNonSecureRead(v);
301                privNonSecureWrite(v);
302                privSecureRead(v);
303                privSecureWrite(v);
304                hypRead(v);
305                hypWrite(v);
306                monSecureRead(v);
307                monSecureWrite(v);
308                monNonSecureRead(v);
309                monNonSecureWrite(v);
310                return *this;
311            }
312            chain nonSecure(bool v = true) const {
313                userNonSecureRead(v);
314                userNonSecureWrite(v);
315                privNonSecureRead(v);
316                privNonSecureWrite(v);
317                hypRead(v);
318                hypWrite(v);
319                monNonSecureRead(v);
320                monNonSecureWrite(v);
321                return *this;
322            }
323            chain secure(bool v = true) const {
324                userSecureRead(v);
325                userSecureWrite(v);
326                privSecureRead(v);
327                privSecureWrite(v);
328                monSecureRead(v);
329                monSecureWrite(v);
330                return *this;
331            }
332            chain reads(bool v) const {
333                userNonSecureRead(v);
334                userSecureRead(v);
335                privNonSecureRead(v);
336                privSecureRead(v);
337                hypRead(v);
338                monSecureRead(v);
339                monNonSecureRead(v);
340                return *this;
341            }
342            chain writes(bool v) const {
343                userNonSecureWrite(v);
344                userSecureWrite(v);
345                privNonSecureWrite(v);
346                privSecureWrite(v);
347                hypWrite(v);
348                monSecureWrite(v);
349                monNonSecureWrite(v);
350                return *this;
351            }
352            chain exceptUserMode() const {
353                user(0);
354                return *this;
355            }
356            MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
357                                       std::bitset<NUM_MISCREG_INFOS> &i)
358              : entry(e),
359                info(i)
360            {
361                // force unimplemented registers to be thusly declared
362                implemented(1);
363            }
364        };
365
366        const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
367            return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
368                                              miscRegInfo[reg]);
369        }
370
371        void initializeMiscRegMetadata();
372
373        RegVal miscRegs[NumMiscRegs];
374        const IntRegIndex *intRegMap;
375
376        void
377        updateRegMap(CPSR cpsr)
378        {
379            if (cpsr.width == 0) {
380                intRegMap = IntReg64Map;
381            } else {
382                switch (cpsr.mode) {
383                  case MODE_USER:
384                  case MODE_SYSTEM:
385                    intRegMap = IntRegUsrMap;
386                    break;
387                  case MODE_FIQ:
388                    intRegMap = IntRegFiqMap;
389                    break;
390                  case MODE_IRQ:
391                    intRegMap = IntRegIrqMap;
392                    break;
393                  case MODE_SVC:
394                    intRegMap = IntRegSvcMap;
395                    break;
396                  case MODE_MON:
397                    intRegMap = IntRegMonMap;
398                    break;
399                  case MODE_ABORT:
400                    intRegMap = IntRegAbtMap;
401                    break;
402                  case MODE_HYP:
403                    intRegMap = IntRegHypMap;
404                    break;
405                  case MODE_UNDEFINED:
406                    intRegMap = IntRegUndMap;
407                    break;
408                  default:
409                    panic("Unrecognized mode setting in CPSR.\n");
410                }
411            }
412        }
413
414        BaseISADevice &getGenericTimer(ThreadContext *tc);
415        BaseISADevice &getGICv3CPUInterface(ThreadContext *tc);
416
417
418      private:
419        inline void assert32(ThreadContext *tc) {
420            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
421            assert(cpsr.width);
422        }
423
424        inline void assert64(ThreadContext *tc) {
425            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
426            assert(!cpsr.width);
427        }
428
429      public:
430        void clear();
431
432      protected:
433        void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
434        void clear64(const ArmISAParams *p);
435        void initID32(const ArmISAParams *p);
436        void initID64(const ArmISAParams *p);
437
438      public:
439        RegVal readMiscRegNoEffect(int misc_reg) const;
440        RegVal readMiscReg(int misc_reg, ThreadContext *tc);
441        void setMiscRegNoEffect(int misc_reg, RegVal val);
442        void setMiscReg(int misc_reg, RegVal val, ThreadContext *tc);
443
444        RegId
445        flattenRegId(const RegId& regId) const
446        {
447            switch (regId.classValue()) {
448              case IntRegClass:
449                return RegId(IntRegClass, flattenIntIndex(regId.index()));
450              case FloatRegClass:
451                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
452              case VecRegClass:
453                return RegId(VecRegClass, flattenVecIndex(regId.index()));
454              case VecElemClass:
455                return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
456                             regId.elemIndex());
457              case VecPredRegClass:
458                return RegId(VecPredRegClass,
459                             flattenVecPredIndex(regId.index()));
460              case CCRegClass:
461                return RegId(CCRegClass, flattenCCIndex(regId.index()));
462              case MiscRegClass:
463                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
464            }
465            return RegId();
466        }
467
468        int
469        flattenIntIndex(int reg) const
470        {
471            assert(reg >= 0);
472            if (reg < NUM_ARCH_INTREGS) {
473                return intRegMap[reg];
474            } else if (reg < NUM_INTREGS) {
475                return reg;
476            } else if (reg == INTREG_SPX) {
477                CPSR cpsr = miscRegs[MISCREG_CPSR];
478                ExceptionLevel el = opModeToEL(
479                    (OperatingMode) (uint8_t) cpsr.mode);
480                if (!cpsr.sp && el != EL0)
481                    return INTREG_SP0;
482                switch (el) {
483                  case EL3:
484                    return INTREG_SP3;
485                  case EL2:
486                    return INTREG_SP2;
487                  case EL1:
488                    return INTREG_SP1;
489                  case EL0:
490                    return INTREG_SP0;
491                  default:
492                    panic("Invalid exception level");
493                    return 0;  // Never happens.
494                }
495            } else {
496                return flattenIntRegModeIndex(reg);
497            }
498        }
499
500        int
501        flattenFloatIndex(int reg) const
502        {
503            assert(reg >= 0);
504            return reg;
505        }
506
507        int
508        flattenVecIndex(int reg) const
509        {
510            assert(reg >= 0);
511            return reg;
512        }
513
514        int
515        flattenVecElemIndex(int reg) const
516        {
517            assert(reg >= 0);
518            return reg;
519        }
520
521        int
522        flattenVecPredIndex(int reg) const
523        {
524            assert(reg >= 0);
525            return reg;
526        }
527
528        int
529        flattenCCIndex(int reg) const
530        {
531            assert(reg >= 0);
532            return reg;
533        }
534
535        int
536        flattenMiscIndex(int reg) const
537        {
538            assert(reg >= 0);
539            int flat_idx = reg;
540
541            if (reg == MISCREG_SPSR) {
542                CPSR cpsr = miscRegs[MISCREG_CPSR];
543                switch (cpsr.mode) {
544                  case MODE_EL0T:
545                    warn("User mode does not have SPSR\n");
546                    flat_idx = MISCREG_SPSR;
547                    break;
548                  case MODE_EL1T:
549                  case MODE_EL1H:
550                    flat_idx = MISCREG_SPSR_EL1;
551                    break;
552                  case MODE_EL2T:
553                  case MODE_EL2H:
554                    flat_idx = MISCREG_SPSR_EL2;
555                    break;
556                  case MODE_EL3T:
557                  case MODE_EL3H:
558                    flat_idx = MISCREG_SPSR_EL3;
559                    break;
560                  case MODE_USER:
561                    warn("User mode does not have SPSR\n");
562                    flat_idx = MISCREG_SPSR;
563                    break;
564                  case MODE_FIQ:
565                    flat_idx = MISCREG_SPSR_FIQ;
566                    break;
567                  case MODE_IRQ:
568                    flat_idx = MISCREG_SPSR_IRQ;
569                    break;
570                  case MODE_SVC:
571                    flat_idx = MISCREG_SPSR_SVC;
572                    break;
573                  case MODE_MON:
574                    flat_idx = MISCREG_SPSR_MON;
575                    break;
576                  case MODE_ABORT:
577                    flat_idx = MISCREG_SPSR_ABT;
578                    break;
579                  case MODE_HYP:
580                    flat_idx = MISCREG_SPSR_HYP;
581                    break;
582                  case MODE_UNDEFINED:
583                    flat_idx = MISCREG_SPSR_UND;
584                    break;
585                  default:
586                    warn("Trying to access SPSR in an invalid mode: %d\n",
587                         cpsr.mode);
588                    flat_idx = MISCREG_SPSR;
589                    break;
590                }
591            } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
592                // Mutually exclusive CP15 register
593                switch (reg) {
594                  case MISCREG_PRRR_MAIR0:
595                  case MISCREG_PRRR_MAIR0_NS:
596                  case MISCREG_PRRR_MAIR0_S:
597                    {
598                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
599                        // If the muxed reg has been flattened, work out the
600                        // offset and apply it to the unmuxed reg
601                        int idxOffset = reg - MISCREG_PRRR_MAIR0;
602                        if (ttbcr.eae)
603                            flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
604                                                        idxOffset);
605                        else
606                            flat_idx = flattenMiscIndex(MISCREG_PRRR +
607                                                        idxOffset);
608                    }
609                    break;
610                  case MISCREG_NMRR_MAIR1:
611                  case MISCREG_NMRR_MAIR1_NS:
612                  case MISCREG_NMRR_MAIR1_S:
613                    {
614                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
615                        // If the muxed reg has been flattened, work out the
616                        // offset and apply it to the unmuxed reg
617                        int idxOffset = reg - MISCREG_NMRR_MAIR1;
618                        if (ttbcr.eae)
619                            flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
620                                                        idxOffset);
621                        else
622                            flat_idx = flattenMiscIndex(MISCREG_NMRR +
623                                                        idxOffset);
624                    }
625                    break;
626                  case MISCREG_PMXEVTYPER_PMCCFILTR:
627                    {
628                        PMSELR pmselr = miscRegs[MISCREG_PMSELR];
629                        if (pmselr.sel == 31)
630                            flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
631                        else
632                            flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
633                    }
634                    break;
635                  default:
636                    panic("Unrecognized misc. register.\n");
637                    break;
638                }
639            } else {
640                if (miscRegInfo[reg][MISCREG_BANKED]) {
641                    bool secureReg = haveSecurity && !highestELIs64 &&
642                                     inSecureState(miscRegs[MISCREG_SCR],
643                                                   miscRegs[MISCREG_CPSR]);
644                    flat_idx += secureReg ? 2 : 1;
645                }
646            }
647            return flat_idx;
648        }
649
650        std::pair<int,int> getMiscIndices(int misc_reg) const
651        {
652            // Note: indexes of AArch64 registers are left unchanged
653            int flat_idx = flattenMiscIndex(misc_reg);
654
655            if (lookUpMiscReg[flat_idx].lower == 0) {
656                return std::make_pair(flat_idx, 0);
657            }
658
659            // do additional S/NS flattenings if mapped to NS while in S
660            bool S = haveSecurity && !highestELIs64 &&
661                     inSecureState(miscRegs[MISCREG_SCR],
662                                   miscRegs[MISCREG_CPSR]);
663            int lower = lookUpMiscReg[flat_idx].lower;
664            int upper = lookUpMiscReg[flat_idx].upper;
665            // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
666            lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
667            upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
668            return std::make_pair(lower, upper);
669        }
670
671        unsigned getCurSveVecLenInBits(ThreadContext *tc) const;
672
673        unsigned getCurSveVecLenInBitsAtReset() const { return sveVL * 128; }
674
675        static void zeroSveVecRegUpperPart(VecRegContainer &vc,
676                                           unsigned eCount);
677
678        void serialize(CheckpointOut &cp) const
679        {
680            DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
681            SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
682
683            SERIALIZE_SCALAR(highestELIs64);
684            SERIALIZE_SCALAR(haveSecurity);
685            SERIALIZE_SCALAR(haveLPAE);
686            SERIALIZE_SCALAR(haveVirtualization);
687            SERIALIZE_SCALAR(haveLargeAsid64);
688            SERIALIZE_SCALAR(physAddrRange);
689            SERIALIZE_SCALAR(haveSVE);
690            SERIALIZE_SCALAR(sveVL);
691            SERIALIZE_SCALAR(haveLSE);
692            SERIALIZE_SCALAR(havePAN);
693        }
694        void unserialize(CheckpointIn &cp)
695        {
696            DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
697            UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
698            CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
699            updateRegMap(tmp_cpsr);
700
701            UNSERIALIZE_SCALAR(highestELIs64);
702            UNSERIALIZE_SCALAR(haveSecurity);
703            UNSERIALIZE_SCALAR(haveLPAE);
704            UNSERIALIZE_SCALAR(haveVirtualization);
705            UNSERIALIZE_SCALAR(haveLargeAsid64);
706            UNSERIALIZE_SCALAR(physAddrRange);
707            UNSERIALIZE_SCALAR(haveSVE);
708            UNSERIALIZE_SCALAR(sveVL);
709            UNSERIALIZE_SCALAR(haveLSE);
710            UNSERIALIZE_SCALAR(havePAN);
711        }
712
713        void startup(ThreadContext *tc);
714
715        Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
716
717        /** Getter for haveGICv3CPUInterface */
718        bool haveGICv3CpuIfc() const
719        {
720            // haveGICv3CPUInterface is initialized at startup time, hence
721            // trying to read its value before the startup stage will lead
722            // to an error
723            assert(afterStartup);
724            return haveGICv3CPUInterface;
725        }
726
727        Enums::VecRegRenameMode
728        vecRegRenameMode() const
729        {
730            return _vecRegRenameMode;
731        }
732
733        /// Explicitly import the otherwise hidden startup
734        using SimObject::startup;
735
736        typedef ArmISAParams Params;
737
738        const Params *params() const;
739
740        ISA(Params *p);
741    };
742}
743
744template<>
745struct RenameMode<ArmISA::ISA>
746{
747    static Enums::VecRegRenameMode
748    init(const ArmISA::ISA* isa)
749    {
750        return isa->vecRegRenameMode();
751    }
752
753    static Enums::VecRegRenameMode
754    mode(const ArmISA::PCState& pc)
755    {
756        if (pc.aarch64()) {
757            return Enums::Full;
758        } else {
759            return Enums::Elem;
760        }
761    }
762
763    static bool
764    equalsInit(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
765    {
766        return init(isa1) == init(isa2);
767    }
768};
769
770#endif
771