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