misc: Merge branch v20.1.0.3 hotfix into develop
[gem5.git] / src / arch / arm / isa.hh
1 /*
2 * Copyright (c) 2010, 2012-2021 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
41 #ifndef __ARCH_ARM_ISA_HH__
42 #define __ARCH_ARM_ISA_HH__
43
44 #include "arch/arm/isa_device.hh"
45 #include "arch/arm/miscregs.hh"
46 #include "arch/arm/registers.hh"
47 #include "arch/arm/self_debug.hh"
48 #include "arch/arm/system.hh"
49 #include "arch/arm/tlb.hh"
50 #include "arch/arm/types.hh"
51 #include "arch/generic/isa.hh"
52 #include "arch/generic/traits.hh"
53 #include "debug/Checkpoint.hh"
54 #include "enums/DecoderFlavor.hh"
55 #include "enums/VecRegRenameMode.hh"
56 #include "sim/sim_object.hh"
57
58 struct ArmISAParams;
59 struct DummyArmISADeviceParams;
60 class Checkpoint;
61 class EventManager;
62
63 namespace ArmISA
64 {
65 class ISA : public BaseISA
66 {
67 protected:
68 // Parent system
69 ArmSystem *system;
70
71 // Micro Architecture
72 const Enums::DecoderFlavor _decoderFlavor;
73 const Enums::VecRegRenameMode _vecRegRenameMode;
74
75 /** Dummy device for to handle non-existing ISA devices */
76 DummyISADevice dummyDevice;
77
78 // PMU belonging to this ISA
79 BaseISADevice *pmu;
80
81 // Generic timer interface belonging to this ISA
82 std::unique_ptr<BaseISADevice> timer;
83
84 // GICv3 CPU interface belonging to this ISA
85 std::unique_ptr<BaseISADevice> gicv3CpuInterface;
86
87 // Cached copies of system-level properties
88 bool highestELIs64;
89 bool haveSecurity;
90 bool haveLPAE;
91 bool haveVirtualization;
92 bool haveCrypto;
93 bool haveLargeAsid64;
94 uint8_t physAddrRange;
95 bool haveSVE;
96 bool haveLSE;
97 bool haveVHE;
98 bool havePAN;
99 bool haveSecEL2;
100 bool haveTME;
101
102 /** SVE vector length in quadwords */
103 unsigned sveVL;
104
105 /**
106 * If true, accesses to IMPLEMENTATION DEFINED registers are treated
107 * as NOP hence not causing UNDEFINED INSTRUCTION.
108 */
109 bool impdefAsNop;
110
111 bool afterStartup;
112
113 SelfDebug * selfDebug;
114
115 /** MiscReg metadata **/
116 struct MiscRegLUTEntry {
117 uint32_t lower; // Lower half mapped to this register
118 uint32_t upper; // Upper half mapped to this register
119 uint64_t _reset; // value taken on reset (i.e. initialization)
120 uint64_t _res0; // reserved
121 uint64_t _res1; // reserved
122 uint64_t _raz; // read as zero (fixed at 0)
123 uint64_t _rao; // read as one (fixed at 1)
124 public:
125 MiscRegLUTEntry() :
126 lower(0), upper(0),
127 _reset(0), _res0(0), _res1(0), _raz(0), _rao(0) {}
128 uint64_t reset() const { return _reset; }
129 uint64_t res0() const { return _res0; }
130 uint64_t res1() const { return _res1; }
131 uint64_t raz() const { return _raz; }
132 uint64_t rao() const { return _rao; }
133 // raz/rao implies writes ignored
134 uint64_t wi() const { return _raz | _rao; }
135 };
136
137 /** Metadata table accessible via the value of the register */
138 static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
139
140 class MiscRegLUTEntryInitializer {
141 struct MiscRegLUTEntry &entry;
142 std::bitset<NUM_MISCREG_INFOS> &info;
143 typedef const MiscRegLUTEntryInitializer& chain;
144 public:
145 chain mapsTo(uint32_t l, uint32_t u = 0) const {
146 entry.lower = l;
147 entry.upper = u;
148 return *this;
149 }
150 chain res0(uint64_t mask) const {
151 entry._res0 = mask;
152 return *this;
153 }
154 chain res1(uint64_t mask) const {
155 entry._res1 = mask;
156 return *this;
157 }
158 chain raz(uint64_t mask) const {
159 entry._raz = mask;
160 return *this;
161 }
162 chain rao(uint64_t mask) const {
163 entry._rao = mask;
164 return *this;
165 }
166 chain implemented(bool v = true) const {
167 info[MISCREG_IMPLEMENTED] = v;
168 return *this;
169 }
170 chain unimplemented() const {
171 return implemented(false);
172 }
173 chain unverifiable(bool v = true) const {
174 info[MISCREG_UNVERIFIABLE] = v;
175 return *this;
176 }
177 chain warnNotFail(bool v = true) const {
178 info[MISCREG_WARN_NOT_FAIL] = v;
179 return *this;
180 }
181 chain mutex(bool v = true) const {
182 info[MISCREG_MUTEX] = v;
183 return *this;
184 }
185 chain banked(bool v = true) const {
186 info[MISCREG_BANKED] = v;
187 return *this;
188 }
189 chain banked64(bool v = true) const {
190 info[MISCREG_BANKED64] = v;
191 return *this;
192 }
193 chain bankedChild(bool v = true) const {
194 info[MISCREG_BANKED_CHILD] = v;
195 return *this;
196 }
197 chain userNonSecureRead(bool v = true) const {
198 info[MISCREG_USR_NS_RD] = v;
199 return *this;
200 }
201 chain userNonSecureWrite(bool v = true) const {
202 info[MISCREG_USR_NS_WR] = v;
203 return *this;
204 }
205 chain userSecureRead(bool v = true) const {
206 info[MISCREG_USR_S_RD] = v;
207 return *this;
208 }
209 chain userSecureWrite(bool v = true) const {
210 info[MISCREG_USR_S_WR] = v;
211 return *this;
212 }
213 chain user(bool v = true) const {
214 userNonSecureRead(v);
215 userNonSecureWrite(v);
216 userSecureRead(v);
217 userSecureWrite(v);
218 return *this;
219 }
220 chain privNonSecureRead(bool v = true) const {
221 info[MISCREG_PRI_NS_RD] = v;
222 return *this;
223 }
224 chain privNonSecureWrite(bool v = true) const {
225 info[MISCREG_PRI_NS_WR] = v;
226 return *this;
227 }
228 chain privNonSecure(bool v = true) const {
229 privNonSecureRead(v);
230 privNonSecureWrite(v);
231 return *this;
232 }
233 chain privSecureRead(bool v = true) const {
234 info[MISCREG_PRI_S_RD] = v;
235 return *this;
236 }
237 chain privSecureWrite(bool v = true) const {
238 info[MISCREG_PRI_S_WR] = v;
239 return *this;
240 }
241 chain privSecure(bool v = true) const {
242 privSecureRead(v);
243 privSecureWrite(v);
244 return *this;
245 }
246 chain priv(bool v = true) const {
247 privSecure(v);
248 privNonSecure(v);
249 return *this;
250 }
251 chain privRead(bool v = true) const {
252 privSecureRead(v);
253 privNonSecureRead(v);
254 return *this;
255 }
256 chain hypE2HSecureRead(bool v = true) const {
257 info[MISCREG_HYP_E2H_S_RD] = v;
258 return *this;
259 }
260 chain hypE2HNonSecureRead(bool v = true) const {
261 info[MISCREG_HYP_E2H_NS_RD] = v;
262 return *this;
263 }
264 chain hypE2HRead(bool v = true) const {
265 hypE2HSecureRead(v);
266 hypE2HNonSecureRead(v);
267 return *this;
268 }
269 chain hypE2HSecureWrite(bool v = true) const {
270 info[MISCREG_HYP_E2H_S_WR] = v;
271 return *this;
272 }
273 chain hypE2HNonSecureWrite(bool v = true) const {
274 info[MISCREG_HYP_E2H_NS_WR] = v;
275 return *this;
276 }
277 chain hypE2HWrite(bool v = true) const {
278 hypE2HSecureWrite(v);
279 hypE2HNonSecureWrite(v);
280 return *this;
281 }
282 chain hypE2H(bool v = true) const {
283 hypE2HRead(v);
284 hypE2HWrite(v);
285 return *this;
286 }
287 chain hypSecureRead(bool v = true) const {
288 info[MISCREG_HYP_S_RD] = v;
289 return *this;
290 }
291 chain hypNonSecureRead(bool v = true) const {
292 info[MISCREG_HYP_NS_RD] = v;
293 return *this;
294 }
295 chain hypRead(bool v = true) const {
296 hypE2HRead(v);
297 hypSecureRead(v);
298 hypNonSecureRead(v);
299 return *this;
300 }
301 chain hypSecureWrite(bool v = true) const {
302 info[MISCREG_HYP_S_WR] = v;
303 return *this;
304 }
305 chain hypNonSecureWrite(bool v = true) const {
306 info[MISCREG_HYP_NS_WR] = v;
307 return *this;
308 }
309 chain hypWrite(bool v = true) const {
310 hypE2HWrite(v);
311 hypSecureWrite(v);
312 hypNonSecureWrite(v);
313 return *this;
314 }
315 chain hypSecure(bool v = true) const {
316 hypE2HSecureRead(v);
317 hypE2HSecureWrite(v);
318 hypSecureRead(v);
319 hypSecureWrite(v);
320 return *this;
321 }
322 chain hyp(bool v = true) const {
323 hypRead(v);
324 hypWrite(v);
325 return *this;
326 }
327 chain monE2HRead(bool v = true) const {
328 info[MISCREG_MON_E2H_RD] = v;
329 return *this;
330 }
331 chain monE2HWrite(bool v = true) const {
332 info[MISCREG_MON_E2H_WR] = v;
333 return *this;
334 }
335 chain monE2H(bool v = true) const {
336 monE2HRead(v);
337 monE2HWrite(v);
338 return *this;
339 }
340 chain monSecureRead(bool v = true) const {
341 monE2HRead(v);
342 info[MISCREG_MON_NS0_RD] = v;
343 return *this;
344 }
345 chain monSecureWrite(bool v = true) const {
346 monE2HWrite(v);
347 info[MISCREG_MON_NS0_WR] = v;
348 return *this;
349 }
350 chain monNonSecureRead(bool v = true) const {
351 monE2HRead(v);
352 info[MISCREG_MON_NS1_RD] = v;
353 return *this;
354 }
355 chain monNonSecureWrite(bool v = true) const {
356 monE2HWrite(v);
357 info[MISCREG_MON_NS1_WR] = v;
358 return *this;
359 }
360 chain mon(bool v = true) const {
361 monSecureRead(v);
362 monSecureWrite(v);
363 monNonSecureRead(v);
364 monNonSecureWrite(v);
365 return *this;
366 }
367 chain monSecure(bool v = true) const {
368 monSecureRead(v);
369 monSecureWrite(v);
370 return *this;
371 }
372 chain monNonSecure(bool v = true) const {
373 monNonSecureRead(v);
374 monNonSecureWrite(v);
375 return *this;
376 }
377 chain allPrivileges(bool v = true) const {
378 userNonSecureRead(v);
379 userNonSecureWrite(v);
380 userSecureRead(v);
381 userSecureWrite(v);
382 privNonSecureRead(v);
383 privNonSecureWrite(v);
384 privSecureRead(v);
385 privSecureWrite(v);
386 hypRead(v);
387 hypWrite(v);
388 monSecureRead(v);
389 monSecureWrite(v);
390 monNonSecureRead(v);
391 monNonSecureWrite(v);
392 return *this;
393 }
394 chain nonSecure(bool v = true) const {
395 userNonSecureRead(v);
396 userNonSecureWrite(v);
397 privNonSecureRead(v);
398 privNonSecureWrite(v);
399 hypRead(v);
400 hypWrite(v);
401 monNonSecureRead(v);
402 monNonSecureWrite(v);
403 return *this;
404 }
405 chain secure(bool v = true) const {
406 userSecureRead(v);
407 userSecureWrite(v);
408 privSecureRead(v);
409 privSecureWrite(v);
410 monSecureRead(v);
411 monSecureWrite(v);
412 return *this;
413 }
414 chain reads(bool v) const {
415 userNonSecureRead(v);
416 userSecureRead(v);
417 privNonSecureRead(v);
418 privSecureRead(v);
419 hypRead(v);
420 monSecureRead(v);
421 monNonSecureRead(v);
422 return *this;
423 }
424 chain writes(bool v) const {
425 userNonSecureWrite(v);
426 userSecureWrite(v);
427 privNonSecureWrite(v);
428 privSecureWrite(v);
429 hypWrite(v);
430 monSecureWrite(v);
431 monNonSecureWrite(v);
432 return *this;
433 }
434 chain exceptUserMode() const {
435 user(0);
436 return *this;
437 }
438 chain highest(ArmSystem *const sys) const;
439 MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
440 std::bitset<NUM_MISCREG_INFOS> &i)
441 : entry(e),
442 info(i)
443 {
444 // force unimplemented registers to be thusly declared
445 implemented(1);
446 }
447 };
448
449 const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
450 return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
451 miscRegInfo[reg]);
452 }
453
454 void initializeMiscRegMetadata();
455
456 RegVal miscRegs[NumMiscRegs];
457 const IntRegIndex *intRegMap;
458
459 void
460 updateRegMap(CPSR cpsr)
461 {
462 if (cpsr.width == 0) {
463 intRegMap = IntReg64Map;
464 } else {
465 switch (cpsr.mode) {
466 case MODE_USER:
467 case MODE_SYSTEM:
468 intRegMap = IntRegUsrMap;
469 break;
470 case MODE_FIQ:
471 intRegMap = IntRegFiqMap;
472 break;
473 case MODE_IRQ:
474 intRegMap = IntRegIrqMap;
475 break;
476 case MODE_SVC:
477 intRegMap = IntRegSvcMap;
478 break;
479 case MODE_MON:
480 intRegMap = IntRegMonMap;
481 break;
482 case MODE_ABORT:
483 intRegMap = IntRegAbtMap;
484 break;
485 case MODE_HYP:
486 intRegMap = IntRegHypMap;
487 break;
488 case MODE_UNDEFINED:
489 intRegMap = IntRegUndMap;
490 break;
491 default:
492 panic("Unrecognized mode setting in CPSR.\n");
493 }
494 }
495 }
496
497 BaseISADevice &getGenericTimer();
498 BaseISADevice &getGICv3CPUInterface();
499
500 private:
501 void assert32() { assert(((CPSR)readMiscReg(MISCREG_CPSR)).width); }
502 void assert64() { assert(!((CPSR)readMiscReg(MISCREG_CPSR)).width); }
503
504 public:
505 void clear();
506
507 protected:
508 void clear32(const ArmISAParams &p, const SCTLR &sctlr_rst);
509 void clear64(const ArmISAParams &p);
510 void initID32(const ArmISAParams &p);
511 void initID64(const ArmISAParams &p);
512
513 void addressTranslation(TLB::ArmTranslationType tran_type,
514 BaseTLB::Mode mode, Request::Flags flags, RegVal val);
515 void addressTranslation64(TLB::ArmTranslationType tran_type,
516 BaseTLB::Mode mode, Request::Flags flags, RegVal val);
517
518 public:
519 SelfDebug*
520 getSelfDebug() const
521 {
522 return selfDebug;
523 }
524
525 static SelfDebug*
526 getSelfDebug(ThreadContext *tc)
527 {
528 auto *arm_isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
529 return arm_isa->getSelfDebug();
530 }
531
532 RegVal readMiscRegNoEffect(int misc_reg) const;
533 RegVal readMiscReg(int misc_reg);
534 void setMiscRegNoEffect(int misc_reg, RegVal val);
535 void setMiscReg(int misc_reg, RegVal val);
536
537 RegId
538 flattenRegId(const RegId& regId) const
539 {
540 switch (regId.classValue()) {
541 case IntRegClass:
542 return RegId(IntRegClass, flattenIntIndex(regId.index()));
543 case FloatRegClass:
544 return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
545 case VecRegClass:
546 return RegId(VecRegClass, flattenVecIndex(regId.index()));
547 case VecElemClass:
548 return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
549 regId.elemIndex());
550 case VecPredRegClass:
551 return RegId(VecPredRegClass,
552 flattenVecPredIndex(regId.index()));
553 case CCRegClass:
554 return RegId(CCRegClass, flattenCCIndex(regId.index()));
555 case MiscRegClass:
556 return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
557 }
558 return RegId();
559 }
560
561 int
562 flattenIntIndex(int reg) const
563 {
564 assert(reg >= 0);
565 if (reg < NUM_ARCH_INTREGS) {
566 return intRegMap[reg];
567 } else if (reg < NUM_INTREGS) {
568 return reg;
569 } else if (reg == INTREG_SPX) {
570 CPSR cpsr = miscRegs[MISCREG_CPSR];
571 ExceptionLevel el = opModeToEL(
572 (OperatingMode) (uint8_t) cpsr.mode);
573 if (!cpsr.sp && el != EL0)
574 return INTREG_SP0;
575 switch (el) {
576 case EL3:
577 return INTREG_SP3;
578 case EL2:
579 return INTREG_SP2;
580 case EL1:
581 return INTREG_SP1;
582 case EL0:
583 return INTREG_SP0;
584 default:
585 panic("Invalid exception level");
586 return 0; // Never happens.
587 }
588 } else {
589 return flattenIntRegModeIndex(reg);
590 }
591 }
592
593 int
594 flattenFloatIndex(int reg) const
595 {
596 assert(reg >= 0);
597 return reg;
598 }
599
600 int
601 flattenVecIndex(int reg) const
602 {
603 assert(reg >= 0);
604 return reg;
605 }
606
607 int
608 flattenVecElemIndex(int reg) const
609 {
610 assert(reg >= 0);
611 return reg;
612 }
613
614 int
615 flattenVecPredIndex(int reg) const
616 {
617 assert(reg >= 0);
618 return reg;
619 }
620
621 int
622 flattenCCIndex(int reg) const
623 {
624 assert(reg >= 0);
625 return reg;
626 }
627
628 int
629 flattenMiscIndex(int reg) const
630 {
631 assert(reg >= 0);
632 int flat_idx = reg;
633
634 if (reg == MISCREG_SPSR) {
635 CPSR cpsr = miscRegs[MISCREG_CPSR];
636 switch (cpsr.mode) {
637 case MODE_EL0T:
638 warn("User mode does not have SPSR\n");
639 flat_idx = MISCREG_SPSR;
640 break;
641 case MODE_EL1T:
642 case MODE_EL1H:
643 flat_idx = MISCREG_SPSR_EL1;
644 break;
645 case MODE_EL2T:
646 case MODE_EL2H:
647 flat_idx = MISCREG_SPSR_EL2;
648 break;
649 case MODE_EL3T:
650 case MODE_EL3H:
651 flat_idx = MISCREG_SPSR_EL3;
652 break;
653 case MODE_USER:
654 warn("User mode does not have SPSR\n");
655 flat_idx = MISCREG_SPSR;
656 break;
657 case MODE_FIQ:
658 flat_idx = MISCREG_SPSR_FIQ;
659 break;
660 case MODE_IRQ:
661 flat_idx = MISCREG_SPSR_IRQ;
662 break;
663 case MODE_SVC:
664 flat_idx = MISCREG_SPSR_SVC;
665 break;
666 case MODE_MON:
667 flat_idx = MISCREG_SPSR_MON;
668 break;
669 case MODE_ABORT:
670 flat_idx = MISCREG_SPSR_ABT;
671 break;
672 case MODE_HYP:
673 flat_idx = MISCREG_SPSR_HYP;
674 break;
675 case MODE_UNDEFINED:
676 flat_idx = MISCREG_SPSR_UND;
677 break;
678 default:
679 warn("Trying to access SPSR in an invalid mode: %d\n",
680 cpsr.mode);
681 flat_idx = MISCREG_SPSR;
682 break;
683 }
684 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
685 // Mutually exclusive CP15 register
686 switch (reg) {
687 case MISCREG_PRRR_MAIR0:
688 case MISCREG_PRRR_MAIR0_NS:
689 case MISCREG_PRRR_MAIR0_S:
690 {
691 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
692 // If the muxed reg has been flattened, work out the
693 // offset and apply it to the unmuxed reg
694 int idxOffset = reg - MISCREG_PRRR_MAIR0;
695 if (ttbcr.eae)
696 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
697 idxOffset);
698 else
699 flat_idx = flattenMiscIndex(MISCREG_PRRR +
700 idxOffset);
701 }
702 break;
703 case MISCREG_NMRR_MAIR1:
704 case MISCREG_NMRR_MAIR1_NS:
705 case MISCREG_NMRR_MAIR1_S:
706 {
707 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
708 // If the muxed reg has been flattened, work out the
709 // offset and apply it to the unmuxed reg
710 int idxOffset = reg - MISCREG_NMRR_MAIR1;
711 if (ttbcr.eae)
712 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
713 idxOffset);
714 else
715 flat_idx = flattenMiscIndex(MISCREG_NMRR +
716 idxOffset);
717 }
718 break;
719 case MISCREG_PMXEVTYPER_PMCCFILTR:
720 {
721 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
722 if (pmselr.sel == 31)
723 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
724 else
725 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
726 }
727 break;
728 default:
729 panic("Unrecognized misc. register.\n");
730 break;
731 }
732 } else {
733 if (miscRegInfo[reg][MISCREG_BANKED]) {
734 bool secureReg = haveSecurity && !highestELIs64 &&
735 inSecureState(miscRegs[MISCREG_SCR],
736 miscRegs[MISCREG_CPSR]);
737 flat_idx += secureReg ? 2 : 1;
738 } else {
739 flat_idx = snsBankedIndex64((MiscRegIndex)reg,
740 !inSecureState(miscRegs[MISCREG_SCR],
741 miscRegs[MISCREG_CPSR]));
742 }
743 }
744 return flat_idx;
745 }
746
747 /**
748 * Returns the enconcing equivalent when VHE is implemented and
749 * HCR_EL2.E2H is enabled and executing at EL2
750 */
751 int
752 redirectRegVHE(ThreadContext * tc, int misc_reg)
753 {
754 const HCR hcr = readMiscRegNoEffect(MISCREG_HCR_EL2);
755 if (hcr.e2h == 0x0 || currEL(tc) != EL2)
756 return misc_reg;
757 SCR scr = readMiscRegNoEffect(MISCREG_SCR_EL3);
758 bool sec_el2 = scr.eel2 && haveSecEL2;
759 switch(misc_reg) {
760 case MISCREG_SPSR_EL1:
761 return MISCREG_SPSR_EL2;
762 case MISCREG_ELR_EL1:
763 return MISCREG_ELR_EL2;
764 case MISCREG_SCTLR_EL1:
765 return MISCREG_SCTLR_EL2;
766 case MISCREG_CPACR_EL1:
767 return MISCREG_CPTR_EL2;
768 // case :
769 // return MISCREG_TRFCR_EL2;
770 case MISCREG_TTBR0_EL1:
771 return MISCREG_TTBR0_EL2;
772 case MISCREG_TTBR1_EL1:
773 return MISCREG_TTBR1_EL2;
774 case MISCREG_TCR_EL1:
775 return MISCREG_TCR_EL2;
776 case MISCREG_AFSR0_EL1:
777 return MISCREG_AFSR0_EL2;
778 case MISCREG_AFSR1_EL1:
779 return MISCREG_AFSR1_EL2;
780 case MISCREG_ESR_EL1:
781 return MISCREG_ESR_EL2;
782 case MISCREG_FAR_EL1:
783 return MISCREG_FAR_EL2;
784 case MISCREG_MAIR_EL1:
785 return MISCREG_MAIR_EL2;
786 case MISCREG_AMAIR_EL1:
787 return MISCREG_AMAIR_EL2;
788 case MISCREG_VBAR_EL1:
789 return MISCREG_VBAR_EL2;
790 case MISCREG_CONTEXTIDR_EL1:
791 return MISCREG_CONTEXTIDR_EL2;
792 case MISCREG_CNTKCTL_EL1:
793 return MISCREG_CNTHCTL_EL2;
794 case MISCREG_CNTP_TVAL_EL0:
795 return sec_el2? MISCREG_CNTHPS_TVAL_EL2:
796 MISCREG_CNTHP_TVAL_EL2;
797 case MISCREG_CNTP_CTL_EL0:
798 return sec_el2? MISCREG_CNTHPS_CTL_EL2:
799 MISCREG_CNTHP_CTL_EL2;
800 case MISCREG_CNTP_CVAL_EL0:
801 return sec_el2? MISCREG_CNTHPS_CVAL_EL2:
802 MISCREG_CNTHP_CVAL_EL2;
803 case MISCREG_CNTV_TVAL_EL0:
804 return sec_el2? MISCREG_CNTHVS_TVAL_EL2:
805 MISCREG_CNTHV_TVAL_EL2;
806 case MISCREG_CNTV_CTL_EL0:
807 return sec_el2? MISCREG_CNTHVS_CTL_EL2:
808 MISCREG_CNTHV_CTL_EL2;
809 case MISCREG_CNTV_CVAL_EL0:
810 return sec_el2? MISCREG_CNTHVS_CVAL_EL2:
811 MISCREG_CNTHV_CVAL_EL2;
812 default:
813 return misc_reg;
814 }
815 /*should not be accessible */
816 return misc_reg;
817 }
818
819 int
820 snsBankedIndex64(MiscRegIndex reg, bool ns) const
821 {
822 int reg_as_int = static_cast<int>(reg);
823 if (miscRegInfo[reg][MISCREG_BANKED64]) {
824 reg_as_int += (haveSecurity && !ns) ? 2 : 1;
825 }
826 return reg_as_int;
827 }
828
829 std::pair<int,int> getMiscIndices(int misc_reg) const
830 {
831 // Note: indexes of AArch64 registers are left unchanged
832 int flat_idx = flattenMiscIndex(misc_reg);
833
834 if (lookUpMiscReg[flat_idx].lower == 0) {
835 return std::make_pair(flat_idx, 0);
836 }
837
838 // do additional S/NS flattenings if mapped to NS while in S
839 bool S = haveSecurity && !highestELIs64 &&
840 inSecureState(miscRegs[MISCREG_SCR],
841 miscRegs[MISCREG_CPSR]);
842 int lower = lookUpMiscReg[flat_idx].lower;
843 int upper = lookUpMiscReg[flat_idx].upper;
844 // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
845 lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
846 upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
847 return std::make_pair(lower, upper);
848 }
849
850 unsigned getCurSveVecLenInBits() const;
851
852 unsigned getCurSveVecLenInBitsAtReset() const { return sveVL * 128; }
853
854 static void zeroSveVecRegUpperPart(VecRegContainer &vc,
855 unsigned eCount);
856
857 void serialize(CheckpointOut &cp) const override;
858 void unserialize(CheckpointIn &cp) override;
859
860 void startup() override;
861
862 void setupThreadContext();
863
864 void takeOverFrom(ThreadContext *new_tc,
865 ThreadContext *old_tc) override;
866
867 Enums::DecoderFlavor decoderFlavor() const { return _decoderFlavor; }
868
869 /** Returns true if the ISA has a GICv3 cpu interface */
870 bool haveGICv3CpuIfc() const
871 {
872 // gicv3CpuInterface is initialized at startup time, hence
873 // trying to read its value before the startup stage will lead
874 // to an error
875 assert(afterStartup);
876 return gicv3CpuInterface != nullptr;
877 }
878
879 Enums::VecRegRenameMode
880 vecRegRenameMode() const
881 {
882 return _vecRegRenameMode;
883 }
884
885 typedef ArmISAParams Params;
886
887 const Params &params() const;
888
889 ISA(const Params &p);
890 };
891 }
892
893 template<>
894 struct RenameMode<ArmISA::ISA>
895 {
896 static Enums::VecRegRenameMode
897 init(const BaseISA* isa)
898 {
899 auto arm_isa = dynamic_cast<const ArmISA::ISA *>(isa);
900 assert(arm_isa);
901 return arm_isa->vecRegRenameMode();
902 }
903
904 static Enums::VecRegRenameMode
905 mode(const ArmISA::PCState& pc)
906 {
907 if (pc.aarch64()) {
908 return Enums::Full;
909 } else {
910 return Enums::Elem;
911 }
912 }
913
914 static bool
915 equalsInit(const BaseISA* isa1, const BaseISA* isa2)
916 {
917 return init(isa1) == init(isa2);
918 }
919 };
920
921 #endif