isa.hh revision 14000
1/*
2 * Copyright (c) 2010, 2012-2018 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
99        /** SVE vector length in quadwords */
100        unsigned sveVL;
101
102        /**
103         * If true, accesses to IMPLEMENTATION DEFINED registers are treated
104         * as NOP hence not causing UNDEFINED INSTRUCTION.
105         */
106        bool impdefAsNop;
107
108        bool afterStartup;
109
110        /** MiscReg metadata **/
111        struct MiscRegLUTEntry {
112            uint32_t lower;  // Lower half mapped to this register
113            uint32_t upper;  // Upper half mapped to this register
114            uint64_t _reset; // value taken on reset (i.e. initialization)
115            uint64_t _res0;  // reserved
116            uint64_t _res1;  // reserved
117            uint64_t _raz;   // read as zero (fixed at 0)
118            uint64_t _rao;   // read as one (fixed at 1)
119          public:
120            MiscRegLUTEntry() :
121              lower(0), upper(0),
122              _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
123            uint64_t reset() const { return _reset; }
124            uint64_t res0()  const { return _res0; }
125            uint64_t res1()  const { return _res1; }
126            uint64_t raz()   const { return _raz; }
127            uint64_t rao()   const { return _rao; }
128            // raz/rao implies writes ignored
129            uint64_t wi()    const { return _raz | _rao; }
130        };
131
132        /** Metadata table accessible via the value of the register */
133        static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
134
135        class MiscRegLUTEntryInitializer {
136            struct MiscRegLUTEntry &entry;
137            std::bitset<NUM_MISCREG_INFOS> &info;
138            typedef const MiscRegLUTEntryInitializer& chain;
139          public:
140            chain mapsTo(uint32_t l, uint32_t u = 0) const {
141                entry.lower = l;
142                entry.upper = u;
143                return *this;
144            }
145            chain res0(uint64_t mask) const {
146                entry._res0 = mask;
147                return *this;
148            }
149            chain res1(uint64_t mask) const {
150                entry._res1 = mask;
151                return *this;
152            }
153            chain raz(uint64_t mask) const {
154                entry._raz  = mask;
155                return *this;
156            }
157            chain rao(uint64_t mask) const {
158                entry._rao  = mask;
159                return *this;
160            }
161            chain implemented(bool v = true) const {
162                info[MISCREG_IMPLEMENTED] = v;
163                return *this;
164            }
165            chain unimplemented() const {
166                return implemented(false);
167            }
168            chain unverifiable(bool v = true) const {
169                info[MISCREG_UNVERIFIABLE] = v;
170                return *this;
171            }
172            chain warnNotFail(bool v = true) const {
173                info[MISCREG_WARN_NOT_FAIL] = v;
174                return *this;
175            }
176            chain mutex(bool v = true) const {
177                info[MISCREG_MUTEX] = v;
178                return *this;
179            }
180            chain banked(bool v = true) const {
181                info[MISCREG_BANKED] = v;
182                return *this;
183            }
184            chain bankedChild(bool v = true) const {
185                info[MISCREG_BANKED_CHILD] = v;
186                return *this;
187            }
188            chain userNonSecureRead(bool v = true) const {
189                info[MISCREG_USR_NS_RD] = v;
190                return *this;
191            }
192            chain userNonSecureWrite(bool v = true) const {
193                info[MISCREG_USR_NS_WR] = v;
194                return *this;
195            }
196            chain userSecureRead(bool v = true) const {
197                info[MISCREG_USR_S_RD] = v;
198                return *this;
199            }
200            chain userSecureWrite(bool v = true) const {
201                info[MISCREG_USR_S_WR] = v;
202                return *this;
203            }
204            chain user(bool v = true) const {
205                userNonSecureRead(v);
206                userNonSecureWrite(v);
207                userSecureRead(v);
208                userSecureWrite(v);
209                return *this;
210            }
211            chain privNonSecureRead(bool v = true) const {
212                info[MISCREG_PRI_NS_RD] = v;
213                return *this;
214            }
215            chain privNonSecureWrite(bool v = true) const {
216                info[MISCREG_PRI_NS_WR] = v;
217                return *this;
218            }
219            chain privNonSecure(bool v = true) const {
220                privNonSecureRead(v);
221                privNonSecureWrite(v);
222                return *this;
223            }
224            chain privSecureRead(bool v = true) const {
225                info[MISCREG_PRI_S_RD] = v;
226                return *this;
227            }
228            chain privSecureWrite(bool v = true) const {
229                info[MISCREG_PRI_S_WR] = v;
230                return *this;
231            }
232            chain privSecure(bool v = true) const {
233                privSecureRead(v);
234                privSecureWrite(v);
235                return *this;
236            }
237            chain priv(bool v = true) const {
238                privSecure(v);
239                privNonSecure(v);
240                return *this;
241            }
242            chain privRead(bool v = true) const {
243                privSecureRead(v);
244                privNonSecureRead(v);
245                return *this;
246            }
247            chain hypRead(bool v = true) const {
248                info[MISCREG_HYP_RD] = v;
249                return *this;
250            }
251            chain hypWrite(bool v = true) const {
252                info[MISCREG_HYP_WR] = v;
253                return *this;
254            }
255            chain hyp(bool v = true) const {
256                hypRead(v);
257                hypWrite(v);
258                return *this;
259            }
260            chain monSecureRead(bool v = true) const {
261                info[MISCREG_MON_NS0_RD] = v;
262                return *this;
263            }
264            chain monSecureWrite(bool v = true) const {
265                info[MISCREG_MON_NS0_WR] = v;
266                return *this;
267            }
268            chain monNonSecureRead(bool v = true) const {
269                info[MISCREG_MON_NS1_RD] = v;
270                return *this;
271            }
272            chain monNonSecureWrite(bool v = true) const {
273                info[MISCREG_MON_NS1_WR] = v;
274                return *this;
275            }
276            chain mon(bool v = true) const {
277                monSecureRead(v);
278                monSecureWrite(v);
279                monNonSecureRead(v);
280                monNonSecureWrite(v);
281                return *this;
282            }
283            chain monSecure(bool v = true) const {
284                monSecureRead(v);
285                monSecureWrite(v);
286                return *this;
287            }
288            chain monNonSecure(bool v = true) const {
289                monNonSecureRead(v);
290                monNonSecureWrite(v);
291                return *this;
292            }
293            chain allPrivileges(bool v = true) const {
294                userNonSecureRead(v);
295                userNonSecureWrite(v);
296                userSecureRead(v);
297                userSecureWrite(v);
298                privNonSecureRead(v);
299                privNonSecureWrite(v);
300                privSecureRead(v);
301                privSecureWrite(v);
302                hypRead(v);
303                hypWrite(v);
304                monSecureRead(v);
305                monSecureWrite(v);
306                monNonSecureRead(v);
307                monNonSecureWrite(v);
308                return *this;
309            }
310            chain nonSecure(bool v = true) const {
311                userNonSecureRead(v);
312                userNonSecureWrite(v);
313                privNonSecureRead(v);
314                privNonSecureWrite(v);
315                hypRead(v);
316                hypWrite(v);
317                monNonSecureRead(v);
318                monNonSecureWrite(v);
319                return *this;
320            }
321            chain secure(bool v = true) const {
322                userSecureRead(v);
323                userSecureWrite(v);
324                privSecureRead(v);
325                privSecureWrite(v);
326                monSecureRead(v);
327                monSecureWrite(v);
328                return *this;
329            }
330            chain reads(bool v) const {
331                userNonSecureRead(v);
332                userSecureRead(v);
333                privNonSecureRead(v);
334                privSecureRead(v);
335                hypRead(v);
336                monSecureRead(v);
337                monNonSecureRead(v);
338                return *this;
339            }
340            chain writes(bool v) const {
341                userNonSecureWrite(v);
342                userSecureWrite(v);
343                privNonSecureWrite(v);
344                privSecureWrite(v);
345                hypWrite(v);
346                monSecureWrite(v);
347                monNonSecureWrite(v);
348                return *this;
349            }
350            chain exceptUserMode() const {
351                user(0);
352                return *this;
353            }
354            MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
355                                       std::bitset<NUM_MISCREG_INFOS> &i)
356              : entry(e),
357                info(i)
358            {
359                // force unimplemented registers to be thusly declared
360                implemented(1);
361            }
362        };
363
364        const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
365            return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
366                                              miscRegInfo[reg]);
367        }
368
369        void initializeMiscRegMetadata();
370
371        RegVal miscRegs[NumMiscRegs];
372        const IntRegIndex *intRegMap;
373
374        void
375        updateRegMap(CPSR cpsr)
376        {
377            if (cpsr.width == 0) {
378                intRegMap = IntReg64Map;
379            } else {
380                switch (cpsr.mode) {
381                  case MODE_USER:
382                  case MODE_SYSTEM:
383                    intRegMap = IntRegUsrMap;
384                    break;
385                  case MODE_FIQ:
386                    intRegMap = IntRegFiqMap;
387                    break;
388                  case MODE_IRQ:
389                    intRegMap = IntRegIrqMap;
390                    break;
391                  case MODE_SVC:
392                    intRegMap = IntRegSvcMap;
393                    break;
394                  case MODE_MON:
395                    intRegMap = IntRegMonMap;
396                    break;
397                  case MODE_ABORT:
398                    intRegMap = IntRegAbtMap;
399                    break;
400                  case MODE_HYP:
401                    intRegMap = IntRegHypMap;
402                    break;
403                  case MODE_UNDEFINED:
404                    intRegMap = IntRegUndMap;
405                    break;
406                  default:
407                    panic("Unrecognized mode setting in CPSR.\n");
408                }
409            }
410        }
411
412        BaseISADevice &getGenericTimer(ThreadContext *tc);
413        BaseISADevice &getGICv3CPUInterface(ThreadContext *tc);
414
415
416      private:
417        inline void assert32(ThreadContext *tc) {
418            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
419            assert(cpsr.width);
420        }
421
422        inline void assert64(ThreadContext *tc) {
423            CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
424            assert(!cpsr.width);
425        }
426
427      public:
428        void clear();
429
430      protected:
431        void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
432        void clear64(const ArmISAParams *p);
433        void initID32(const ArmISAParams *p);
434        void initID64(const ArmISAParams *p);
435
436      public:
437        RegVal readMiscRegNoEffect(int misc_reg) const;
438        RegVal readMiscReg(int misc_reg, ThreadContext *tc);
439        void setMiscRegNoEffect(int misc_reg, RegVal val);
440        void setMiscReg(int misc_reg, RegVal val, ThreadContext *tc);
441
442        RegId
443        flattenRegId(const RegId& regId) const
444        {
445            switch (regId.classValue()) {
446              case IntRegClass:
447                return RegId(IntRegClass, flattenIntIndex(regId.index()));
448              case FloatRegClass:
449                return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
450              case VecRegClass:
451                return RegId(VecRegClass, flattenVecIndex(regId.index()));
452              case VecElemClass:
453                return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
454                             regId.elemIndex());
455              case VecPredRegClass:
456                return RegId(VecPredRegClass,
457                             flattenVecPredIndex(regId.index()));
458              case CCRegClass:
459                return RegId(CCRegClass, flattenCCIndex(regId.index()));
460              case MiscRegClass:
461                return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
462            }
463            return RegId();
464        }
465
466        int
467        flattenIntIndex(int reg) const
468        {
469            assert(reg >= 0);
470            if (reg < NUM_ARCH_INTREGS) {
471                return intRegMap[reg];
472            } else if (reg < NUM_INTREGS) {
473                return reg;
474            } else if (reg == INTREG_SPX) {
475                CPSR cpsr = miscRegs[MISCREG_CPSR];
476                ExceptionLevel el = opModeToEL(
477                    (OperatingMode) (uint8_t) cpsr.mode);
478                if (!cpsr.sp && el != EL0)
479                    return INTREG_SP0;
480                switch (el) {
481                  case EL3:
482                    return INTREG_SP3;
483                  case EL2:
484                    return INTREG_SP2;
485                  case EL1:
486                    return INTREG_SP1;
487                  case EL0:
488                    return INTREG_SP0;
489                  default:
490                    panic("Invalid exception level");
491                    return 0;  // Never happens.
492                }
493            } else {
494                return flattenIntRegModeIndex(reg);
495            }
496        }
497
498        int
499        flattenFloatIndex(int reg) const
500        {
501            assert(reg >= 0);
502            return reg;
503        }
504
505        int
506        flattenVecIndex(int reg) const
507        {
508            assert(reg >= 0);
509            return reg;
510        }
511
512        int
513        flattenVecElemIndex(int reg) const
514        {
515            assert(reg >= 0);
516            return reg;
517        }
518
519        int
520        flattenVecPredIndex(int reg) const
521        {
522            assert(reg >= 0);
523            return reg;
524        }
525
526        int
527        flattenCCIndex(int reg) const
528        {
529            assert(reg >= 0);
530            return reg;
531        }
532
533        int
534        flattenMiscIndex(int reg) const
535        {
536            assert(reg >= 0);
537            int flat_idx = reg;
538
539            if (reg == MISCREG_SPSR) {
540                CPSR cpsr = miscRegs[MISCREG_CPSR];
541                switch (cpsr.mode) {
542                  case MODE_EL0T:
543                    warn("User mode does not have SPSR\n");
544                    flat_idx = MISCREG_SPSR;
545                    break;
546                  case MODE_EL1T:
547                  case MODE_EL1H:
548                    flat_idx = MISCREG_SPSR_EL1;
549                    break;
550                  case MODE_EL2T:
551                  case MODE_EL2H:
552                    flat_idx = MISCREG_SPSR_EL2;
553                    break;
554                  case MODE_EL3T:
555                  case MODE_EL3H:
556                    flat_idx = MISCREG_SPSR_EL3;
557                    break;
558                  case MODE_USER:
559                    warn("User mode does not have SPSR\n");
560                    flat_idx = MISCREG_SPSR;
561                    break;
562                  case MODE_FIQ:
563                    flat_idx = MISCREG_SPSR_FIQ;
564                    break;
565                  case MODE_IRQ:
566                    flat_idx = MISCREG_SPSR_IRQ;
567                    break;
568                  case MODE_SVC:
569                    flat_idx = MISCREG_SPSR_SVC;
570                    break;
571                  case MODE_MON:
572                    flat_idx = MISCREG_SPSR_MON;
573                    break;
574                  case MODE_ABORT:
575                    flat_idx = MISCREG_SPSR_ABT;
576                    break;
577                  case MODE_HYP:
578                    flat_idx = MISCREG_SPSR_HYP;
579                    break;
580                  case MODE_UNDEFINED:
581                    flat_idx = MISCREG_SPSR_UND;
582                    break;
583                  default:
584                    warn("Trying to access SPSR in an invalid mode: %d\n",
585                         cpsr.mode);
586                    flat_idx = MISCREG_SPSR;
587                    break;
588                }
589            } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
590                // Mutually exclusive CP15 register
591                switch (reg) {
592                  case MISCREG_PRRR_MAIR0:
593                  case MISCREG_PRRR_MAIR0_NS:
594                  case MISCREG_PRRR_MAIR0_S:
595                    {
596                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
597                        // If the muxed reg has been flattened, work out the
598                        // offset and apply it to the unmuxed reg
599                        int idxOffset = reg - MISCREG_PRRR_MAIR0;
600                        if (ttbcr.eae)
601                            flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
602                                                        idxOffset);
603                        else
604                            flat_idx = flattenMiscIndex(MISCREG_PRRR +
605                                                        idxOffset);
606                    }
607                    break;
608                  case MISCREG_NMRR_MAIR1:
609                  case MISCREG_NMRR_MAIR1_NS:
610                  case MISCREG_NMRR_MAIR1_S:
611                    {
612                        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
613                        // If the muxed reg has been flattened, work out the
614                        // offset and apply it to the unmuxed reg
615                        int idxOffset = reg - MISCREG_NMRR_MAIR1;
616                        if (ttbcr.eae)
617                            flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
618                                                        idxOffset);
619                        else
620                            flat_idx = flattenMiscIndex(MISCREG_NMRR +
621                                                        idxOffset);
622                    }
623                    break;
624                  case MISCREG_PMXEVTYPER_PMCCFILTR:
625                    {
626                        PMSELR pmselr = miscRegs[MISCREG_PMSELR];
627                        if (pmselr.sel == 31)
628                            flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
629                        else
630                            flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
631                    }
632                    break;
633                  default:
634                    panic("Unrecognized misc. register.\n");
635                    break;
636                }
637            } else {
638                if (miscRegInfo[reg][MISCREG_BANKED]) {
639                    bool secureReg = haveSecurity && !highestELIs64 &&
640                                     inSecureState(miscRegs[MISCREG_SCR],
641                                                   miscRegs[MISCREG_CPSR]);
642                    flat_idx += secureReg ? 2 : 1;
643                }
644            }
645            return flat_idx;
646        }
647
648        std::pair<int,int> getMiscIndices(int misc_reg) const
649        {
650            // Note: indexes of AArch64 registers are left unchanged
651            int flat_idx = flattenMiscIndex(misc_reg);
652
653            if (lookUpMiscReg[flat_idx].lower == 0) {
654                return std::make_pair(flat_idx, 0);
655            }
656
657            // do additional S/NS flattenings if mapped to NS while in S
658            bool S = haveSecurity && !highestELIs64 &&
659                     inSecureState(miscRegs[MISCREG_SCR],
660                                   miscRegs[MISCREG_CPSR]);
661            int lower = lookUpMiscReg[flat_idx].lower;
662            int upper = lookUpMiscReg[flat_idx].upper;
663            // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
664            lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
665            upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
666            return std::make_pair(lower, upper);
667        }
668
669        unsigned getCurSveVecLenInBits(ThreadContext *tc) const;
670
671        unsigned getCurSveVecLenInBitsAtReset() const { return sveVL * 128; }
672
673        static void zeroSveVecRegUpperPart(VecRegContainer &vc,
674                                           unsigned eCount);
675
676        void serialize(CheckpointOut &cp) const
677        {
678            DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
679            SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
680
681            SERIALIZE_SCALAR(highestELIs64);
682            SERIALIZE_SCALAR(haveSecurity);
683            SERIALIZE_SCALAR(haveLPAE);
684            SERIALIZE_SCALAR(haveVirtualization);
685            SERIALIZE_SCALAR(haveLargeAsid64);
686            SERIALIZE_SCALAR(physAddrRange);
687            SERIALIZE_SCALAR(haveSVE);
688            SERIALIZE_SCALAR(sveVL);
689        }
690        void unserialize(CheckpointIn &cp)
691        {
692            DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
693            UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
694            CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
695            updateRegMap(tmp_cpsr);
696
697            UNSERIALIZE_SCALAR(highestELIs64);
698            UNSERIALIZE_SCALAR(haveSecurity);
699            UNSERIALIZE_SCALAR(haveLPAE);
700            UNSERIALIZE_SCALAR(haveVirtualization);
701            UNSERIALIZE_SCALAR(haveLargeAsid64);
702            UNSERIALIZE_SCALAR(physAddrRange);
703            UNSERIALIZE_SCALAR(haveSVE);
704            UNSERIALIZE_SCALAR(sveVL);
705        }
706
707        void startup(ThreadContext *tc);
708
709        Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
710
711        /** Getter for haveGICv3CPUInterface */
712        bool haveGICv3CpuIfc() const
713        {
714            // haveGICv3CPUInterface is initialized at startup time, hence
715            // trying to read its value before the startup stage will lead
716            // to an error
717            assert(afterStartup);
718            return haveGICv3CPUInterface;
719        }
720
721        Enums::VecRegRenameMode
722        vecRegRenameMode() const
723        {
724            return _vecRegRenameMode;
725        }
726
727        /// Explicitly import the otherwise hidden startup
728        using SimObject::startup;
729
730        typedef ArmISAParams Params;
731
732        const Params *params() const;
733
734        ISA(Params *p);
735    };
736}
737
738template<>
739struct RenameMode<ArmISA::ISA>
740{
741    static Enums::VecRegRenameMode
742    init(const ArmISA::ISA* isa)
743    {
744        return isa->vecRegRenameMode();
745    }
746
747    static Enums::VecRegRenameMode
748    mode(const ArmISA::PCState& pc)
749    {
750        if (pc.aarch64()) {
751            return Enums::Full;
752        } else {
753            return Enums::Elem;
754        }
755    }
756
757    static bool
758    equalsInit(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
759    {
760        return init(isa1) == init(isa2);
761    }
762};
763
764#endif
765