Deleted Added
sdiff udiff text old ( 14133:f3e7e7c3803d ) new ( 14242:076b215de8d4 )
full compact
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