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