arch-arm: Implement ARM8.1-VHE feature
[gem5.git] / src / arch / arm / isa.hh
1 /*
2 * Copyright (c) 2010, 2012-2020 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 havePAN;
98
99 /** SVE vector length in quadwords */
100 unsigned sveVL;
101
102 /**
103 * If true, accesses to IMPLEMENTATION DEFINED registers are treated
104 * as NOP hence not causing UNDEFINED INSTRUCTION.
105 */
106 bool impdefAsNop;
107
108 bool afterStartup;
109
110 SelfDebug * selfDebug;
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 hypE2HRead(bool v = true) const {
254 info[MISCREG_HYP_E2H_RD] = v;
255 return *this;
256 }
257 chain hypE2HWrite(bool v = true) const {
258 info[MISCREG_HYP_E2H_WR] = v;
259 return *this;
260 }
261 chain hypE2H(bool v = true) const {
262 hypE2HRead(v);
263 hypE2HWrite(v);
264 return *this;
265 }
266 chain hypRead(bool v = true) const {
267 hypE2HRead(v);
268 info[MISCREG_HYP_RD] = v;
269 return *this;
270 }
271 chain hypWrite(bool v = true) const {
272 hypE2HWrite(v);
273 info[MISCREG_HYP_WR] = v;
274 return *this;
275 }
276 chain hyp(bool v = true) const {
277 hypRead(v);
278 hypWrite(v);
279 return *this;
280 }
281 chain monE2HRead(bool v = true) const {
282 info[MISCREG_MON_E2H_RD] = v;
283 return *this;
284 }
285 chain monE2HWrite(bool v = true) const {
286 info[MISCREG_MON_E2H_WR] = v;
287 return *this;
288 }
289 chain monE2H(bool v = true) const {
290 monE2HRead(v);
291 monE2HWrite(v);
292 return *this;
293 }
294 chain monSecureRead(bool v = true) const {
295 monE2HRead(v);
296 info[MISCREG_MON_NS0_RD] = v;
297 return *this;
298 }
299 chain monSecureWrite(bool v = true) const {
300 monE2HWrite(v);
301 info[MISCREG_MON_NS0_WR] = v;
302 return *this;
303 }
304 chain monNonSecureRead(bool v = true) const {
305 monE2HRead(v);
306 info[MISCREG_MON_NS1_RD] = v;
307 return *this;
308 }
309 chain monNonSecureWrite(bool v = true) const {
310 monE2HWrite(v);
311 info[MISCREG_MON_NS1_WR] = v;
312 return *this;
313 }
314 chain mon(bool v = true) const {
315 monSecureRead(v);
316 monSecureWrite(v);
317 monNonSecureRead(v);
318 monNonSecureWrite(v);
319 return *this;
320 }
321 chain monSecure(bool v = true) const {
322 monSecureRead(v);
323 monSecureWrite(v);
324 return *this;
325 }
326 chain monNonSecure(bool v = true) const {
327 monNonSecureRead(v);
328 monNonSecureWrite(v);
329 return *this;
330 }
331 chain allPrivileges(bool v = true) const {
332 userNonSecureRead(v);
333 userNonSecureWrite(v);
334 userSecureRead(v);
335 userSecureWrite(v);
336 privNonSecureRead(v);
337 privNonSecureWrite(v);
338 privSecureRead(v);
339 privSecureWrite(v);
340 hypRead(v);
341 hypWrite(v);
342 monSecureRead(v);
343 monSecureWrite(v);
344 monNonSecureRead(v);
345 monNonSecureWrite(v);
346 return *this;
347 }
348 chain nonSecure(bool v = true) const {
349 userNonSecureRead(v);
350 userNonSecureWrite(v);
351 privNonSecureRead(v);
352 privNonSecureWrite(v);
353 hypRead(v);
354 hypWrite(v);
355 monNonSecureRead(v);
356 monNonSecureWrite(v);
357 return *this;
358 }
359 chain secure(bool v = true) const {
360 userSecureRead(v);
361 userSecureWrite(v);
362 privSecureRead(v);
363 privSecureWrite(v);
364 monSecureRead(v);
365 monSecureWrite(v);
366 return *this;
367 }
368 chain reads(bool v) const {
369 userNonSecureRead(v);
370 userSecureRead(v);
371 privNonSecureRead(v);
372 privSecureRead(v);
373 hypRead(v);
374 monSecureRead(v);
375 monNonSecureRead(v);
376 return *this;
377 }
378 chain writes(bool v) const {
379 userNonSecureWrite(v);
380 userSecureWrite(v);
381 privNonSecureWrite(v);
382 privSecureWrite(v);
383 hypWrite(v);
384 monSecureWrite(v);
385 monNonSecureWrite(v);
386 return *this;
387 }
388 chain exceptUserMode() const {
389 user(0);
390 return *this;
391 }
392 chain highest(ArmSystem *const sys) const;
393 MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
394 std::bitset<NUM_MISCREG_INFOS> &i)
395 : entry(e),
396 info(i)
397 {
398 // force unimplemented registers to be thusly declared
399 implemented(1);
400 }
401 };
402
403 const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
404 return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
405 miscRegInfo[reg]);
406 }
407
408 void initializeMiscRegMetadata();
409
410 RegVal miscRegs[NumMiscRegs];
411 const IntRegIndex *intRegMap;
412
413 void
414 updateRegMap(CPSR cpsr)
415 {
416 if (cpsr.width == 0) {
417 intRegMap = IntReg64Map;
418 } else {
419 switch (cpsr.mode) {
420 case MODE_USER:
421 case MODE_SYSTEM:
422 intRegMap = IntRegUsrMap;
423 break;
424 case MODE_FIQ:
425 intRegMap = IntRegFiqMap;
426 break;
427 case MODE_IRQ:
428 intRegMap = IntRegIrqMap;
429 break;
430 case MODE_SVC:
431 intRegMap = IntRegSvcMap;
432 break;
433 case MODE_MON:
434 intRegMap = IntRegMonMap;
435 break;
436 case MODE_ABORT:
437 intRegMap = IntRegAbtMap;
438 break;
439 case MODE_HYP:
440 intRegMap = IntRegHypMap;
441 break;
442 case MODE_UNDEFINED:
443 intRegMap = IntRegUndMap;
444 break;
445 default:
446 panic("Unrecognized mode setting in CPSR.\n");
447 }
448 }
449 }
450
451 BaseISADevice &getGenericTimer();
452 BaseISADevice &getGICv3CPUInterface();
453
454 private:
455 void assert32() { assert(((CPSR)readMiscReg(MISCREG_CPSR)).width); }
456 void assert64() { assert(!((CPSR)readMiscReg(MISCREG_CPSR)).width); }
457
458 public:
459 void clear();
460
461 protected:
462 void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
463 void clear64(const ArmISAParams *p);
464 void initID32(const ArmISAParams *p);
465 void initID64(const ArmISAParams *p);
466
467 public:
468 SelfDebug * getSelfDebug()
469 {
470 return selfDebug;
471 }
472 RegVal readMiscRegNoEffect(int misc_reg) const;
473 RegVal readMiscReg(int misc_reg);
474 void setMiscRegNoEffect(int misc_reg, RegVal val);
475 void setMiscReg(int misc_reg, RegVal val);
476
477 RegId
478 flattenRegId(const RegId& regId) const
479 {
480 switch (regId.classValue()) {
481 case IntRegClass:
482 return RegId(IntRegClass, flattenIntIndex(regId.index()));
483 case FloatRegClass:
484 return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
485 case VecRegClass:
486 return RegId(VecRegClass, flattenVecIndex(regId.index()));
487 case VecElemClass:
488 return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
489 regId.elemIndex());
490 case VecPredRegClass:
491 return RegId(VecPredRegClass,
492 flattenVecPredIndex(regId.index()));
493 case CCRegClass:
494 return RegId(CCRegClass, flattenCCIndex(regId.index()));
495 case MiscRegClass:
496 return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
497 }
498 return RegId();
499 }
500
501 int
502 flattenIntIndex(int reg) const
503 {
504 assert(reg >= 0);
505 if (reg < NUM_ARCH_INTREGS) {
506 return intRegMap[reg];
507 } else if (reg < NUM_INTREGS) {
508 return reg;
509 } else if (reg == INTREG_SPX) {
510 CPSR cpsr = miscRegs[MISCREG_CPSR];
511 ExceptionLevel el = opModeToEL(
512 (OperatingMode) (uint8_t) cpsr.mode);
513 if (!cpsr.sp && el != EL0)
514 return INTREG_SP0;
515 switch (el) {
516 case EL3:
517 return INTREG_SP3;
518 case EL2:
519 return INTREG_SP2;
520 case EL1:
521 return INTREG_SP1;
522 case EL0:
523 return INTREG_SP0;
524 default:
525 panic("Invalid exception level");
526 return 0; // Never happens.
527 }
528 } else {
529 return flattenIntRegModeIndex(reg);
530 }
531 }
532
533 int
534 flattenFloatIndex(int reg) const
535 {
536 assert(reg >= 0);
537 return reg;
538 }
539
540 int
541 flattenVecIndex(int reg) const
542 {
543 assert(reg >= 0);
544 return reg;
545 }
546
547 int
548 flattenVecElemIndex(int reg) const
549 {
550 assert(reg >= 0);
551 return reg;
552 }
553
554 int
555 flattenVecPredIndex(int reg) const
556 {
557 assert(reg >= 0);
558 return reg;
559 }
560
561 int
562 flattenCCIndex(int reg) const
563 {
564 assert(reg >= 0);
565 return reg;
566 }
567
568 int
569 flattenMiscIndex(int reg) const
570 {
571 assert(reg >= 0);
572 int flat_idx = reg;
573
574 if (reg == MISCREG_SPSR) {
575 CPSR cpsr = miscRegs[MISCREG_CPSR];
576 switch (cpsr.mode) {
577 case MODE_EL0T:
578 warn("User mode does not have SPSR\n");
579 flat_idx = MISCREG_SPSR;
580 break;
581 case MODE_EL1T:
582 case MODE_EL1H:
583 flat_idx = MISCREG_SPSR_EL1;
584 break;
585 case MODE_EL2T:
586 case MODE_EL2H:
587 flat_idx = MISCREG_SPSR_EL2;
588 break;
589 case MODE_EL3T:
590 case MODE_EL3H:
591 flat_idx = MISCREG_SPSR_EL3;
592 break;
593 case MODE_USER:
594 warn("User mode does not have SPSR\n");
595 flat_idx = MISCREG_SPSR;
596 break;
597 case MODE_FIQ:
598 flat_idx = MISCREG_SPSR_FIQ;
599 break;
600 case MODE_IRQ:
601 flat_idx = MISCREG_SPSR_IRQ;
602 break;
603 case MODE_SVC:
604 flat_idx = MISCREG_SPSR_SVC;
605 break;
606 case MODE_MON:
607 flat_idx = MISCREG_SPSR_MON;
608 break;
609 case MODE_ABORT:
610 flat_idx = MISCREG_SPSR_ABT;
611 break;
612 case MODE_HYP:
613 flat_idx = MISCREG_SPSR_HYP;
614 break;
615 case MODE_UNDEFINED:
616 flat_idx = MISCREG_SPSR_UND;
617 break;
618 default:
619 warn("Trying to access SPSR in an invalid mode: %d\n",
620 cpsr.mode);
621 flat_idx = MISCREG_SPSR;
622 break;
623 }
624 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
625 // Mutually exclusive CP15 register
626 switch (reg) {
627 case MISCREG_PRRR_MAIR0:
628 case MISCREG_PRRR_MAIR0_NS:
629 case MISCREG_PRRR_MAIR0_S:
630 {
631 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
632 // If the muxed reg has been flattened, work out the
633 // offset and apply it to the unmuxed reg
634 int idxOffset = reg - MISCREG_PRRR_MAIR0;
635 if (ttbcr.eae)
636 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
637 idxOffset);
638 else
639 flat_idx = flattenMiscIndex(MISCREG_PRRR +
640 idxOffset);
641 }
642 break;
643 case MISCREG_NMRR_MAIR1:
644 case MISCREG_NMRR_MAIR1_NS:
645 case MISCREG_NMRR_MAIR1_S:
646 {
647 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
648 // If the muxed reg has been flattened, work out the
649 // offset and apply it to the unmuxed reg
650 int idxOffset = reg - MISCREG_NMRR_MAIR1;
651 if (ttbcr.eae)
652 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
653 idxOffset);
654 else
655 flat_idx = flattenMiscIndex(MISCREG_NMRR +
656 idxOffset);
657 }
658 break;
659 case MISCREG_PMXEVTYPER_PMCCFILTR:
660 {
661 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
662 if (pmselr.sel == 31)
663 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
664 else
665 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
666 }
667 break;
668 default:
669 panic("Unrecognized misc. register.\n");
670 break;
671 }
672 } else {
673 if (miscRegInfo[reg][MISCREG_BANKED]) {
674 bool secureReg = haveSecurity && !highestELIs64 &&
675 inSecureState(miscRegs[MISCREG_SCR],
676 miscRegs[MISCREG_CPSR]);
677 flat_idx += secureReg ? 2 : 1;
678 } else {
679 flat_idx = snsBankedIndex64((MiscRegIndex)reg,
680 !inSecureState(miscRegs[MISCREG_SCR],
681 miscRegs[MISCREG_CPSR]));
682 }
683 }
684 return flat_idx;
685 }
686
687 /**
688 * Returns the enconcing equivalent when VHE is implemented and
689 * HCR_EL2.E2H is enabled and executing at EL2
690 */
691 int
692 redirectRegVHE(ThreadContext * tc, int misc_reg)
693 {
694 const HCR hcr = readMiscRegNoEffect(MISCREG_HCR_EL2);
695 if (hcr.e2h == 0x0 || currEL(tc) != EL2)
696 return misc_reg;
697 SCR scr = readMiscRegNoEffect(MISCREG_SCR_EL3);
698 bool sec_el2 = scr.eel2 && false;
699 switch(misc_reg) {
700 case MISCREG_SPSR_EL1:
701 return MISCREG_SPSR_EL2;
702 case MISCREG_ELR_EL1:
703 return MISCREG_ELR_EL2;
704 case MISCREG_SCTLR_EL1:
705 return MISCREG_SCTLR_EL2;
706 case MISCREG_CPACR_EL1:
707 return MISCREG_CPTR_EL2;
708 // case :
709 // return MISCREG_TRFCR_EL2;
710 case MISCREG_TTBR0_EL1:
711 return MISCREG_TTBR0_EL2;
712 case MISCREG_TTBR1_EL1:
713 return MISCREG_TTBR1_EL2;
714 case MISCREG_TCR_EL1:
715 return MISCREG_TCR_EL2;
716 case MISCREG_AFSR0_EL1:
717 return MISCREG_AFSR0_EL2;
718 case MISCREG_AFSR1_EL1:
719 return MISCREG_AFSR1_EL2;
720 case MISCREG_ESR_EL1:
721 return MISCREG_ESR_EL2;
722 case MISCREG_FAR_EL1:
723 return MISCREG_FAR_EL2;
724 case MISCREG_MAIR_EL1:
725 return MISCREG_MAIR_EL2;
726 case MISCREG_AMAIR_EL1:
727 return MISCREG_AMAIR_EL2;
728 case MISCREG_VBAR_EL1:
729 return MISCREG_VBAR_EL2;
730 case MISCREG_CONTEXTIDR_EL1:
731 return MISCREG_CONTEXTIDR_EL2;
732 case MISCREG_CNTKCTL_EL1:
733 return MISCREG_CNTHCTL_EL2;
734 case MISCREG_CNTP_TVAL_EL0:
735 return sec_el2? MISCREG_CNTHPS_TVAL_EL2:
736 MISCREG_CNTHP_TVAL_EL2;
737 case MISCREG_CNTP_CTL_EL0:
738 return sec_el2? MISCREG_CNTHPS_CTL_EL2:
739 MISCREG_CNTHP_CTL_EL2;
740 case MISCREG_CNTP_CVAL_EL0:
741 return sec_el2? MISCREG_CNTHPS_CVAL_EL2:
742 MISCREG_CNTHP_CVAL_EL2;
743 case MISCREG_CNTV_TVAL_EL0:
744 return sec_el2? MISCREG_CNTHVS_TVAL_EL2:
745 MISCREG_CNTHV_TVAL_EL2;
746 case MISCREG_CNTV_CTL_EL0:
747 return sec_el2? MISCREG_CNTHVS_CTL_EL2:
748 MISCREG_CNTHV_CTL_EL2;
749 case MISCREG_CNTV_CVAL_EL0:
750 return sec_el2? MISCREG_CNTHVS_CVAL_EL2:
751 MISCREG_CNTHV_CVAL_EL2;
752 default:
753 return misc_reg;
754 }
755 /*should not be accessible */
756 return misc_reg;
757 }
758
759 int
760 snsBankedIndex64(MiscRegIndex reg, bool ns) const
761 {
762 int reg_as_int = static_cast<int>(reg);
763 if (miscRegInfo[reg][MISCREG_BANKED64]) {
764 reg_as_int += (haveSecurity && !ns) ? 2 : 1;
765 }
766 return reg_as_int;
767 }
768
769 std::pair<int,int> getMiscIndices(int misc_reg) const
770 {
771 // Note: indexes of AArch64 registers are left unchanged
772 int flat_idx = flattenMiscIndex(misc_reg);
773
774 if (lookUpMiscReg[flat_idx].lower == 0) {
775 return std::make_pair(flat_idx, 0);
776 }
777
778 // do additional S/NS flattenings if mapped to NS while in S
779 bool S = haveSecurity && !highestELIs64 &&
780 inSecureState(miscRegs[MISCREG_SCR],
781 miscRegs[MISCREG_CPSR]);
782 int lower = lookUpMiscReg[flat_idx].lower;
783 int upper = lookUpMiscReg[flat_idx].upper;
784 // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
785 lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
786 upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
787 return std::make_pair(lower, upper);
788 }
789
790 unsigned getCurSveVecLenInBits() const;
791
792 unsigned getCurSveVecLenInBitsAtReset() const { return sveVL * 128; }
793
794 static void zeroSveVecRegUpperPart(VecRegContainer &vc,
795 unsigned eCount);
796
797 void
798 serialize(CheckpointOut &cp) const override
799 {
800 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
801 SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
802 }
803
804 void
805 unserialize(CheckpointIn &cp) override
806 {
807 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
808 UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
809 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
810 updateRegMap(tmp_cpsr);
811 }
812
813 void startup() override;
814
815 void setupThreadContext();
816
817 void takeOverFrom(ThreadContext *new_tc,
818 ThreadContext *old_tc) override;
819
820 Enums::DecoderFlavor decoderFlavor() const { return _decoderFlavor; }
821
822 /** Returns true if the ISA has a GICv3 cpu interface */
823 bool haveGICv3CpuIfc() const
824 {
825 // gicv3CpuInterface is initialized at startup time, hence
826 // trying to read its value before the startup stage will lead
827 // to an error
828 assert(afterStartup);
829 return gicv3CpuInterface != nullptr;
830 }
831
832 Enums::VecRegRenameMode
833 vecRegRenameMode() const
834 {
835 return _vecRegRenameMode;
836 }
837
838 typedef ArmISAParams Params;
839
840 const Params *params() const;
841
842 ISA(Params *p);
843 };
844 }
845
846 template<>
847 struct RenameMode<ArmISA::ISA>
848 {
849 static Enums::VecRegRenameMode
850 init(const BaseISA* isa)
851 {
852 auto arm_isa = dynamic_cast<const ArmISA::ISA *>(isa);
853 assert(arm_isa);
854 return arm_isa->vecRegRenameMode();
855 }
856
857 static Enums::VecRegRenameMode
858 mode(const ArmISA::PCState& pc)
859 {
860 if (pc.aarch64()) {
861 return Enums::Full;
862 } else {
863 return Enums::Elem;
864 }
865 }
866
867 static bool
868 equalsInit(const BaseISA* isa1, const BaseISA* isa2)
869 {
870 return init(isa1) == init(isa2);
871 }
872 };
873
874 #endif