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