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