2 * Copyright (c) 2010, 2012-2019 ARM Limited
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.
14 * Copyright (c) 2009 The Regents of The University of Michigan
15 * All rights reserved.
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.
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.
43 #ifndef __ARCH_ARM_ISA_HH__
44 #define __ARCH_ARM_ISA_HH__
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"
59 struct DummyArmISADeviceParams;
66 class ISA : public SimObject
73 const Enums::DecoderFlavour _decoderFlavour;
74 const Enums::VecRegRenameMode _vecRegRenameMode;
76 /** Dummy device for to handle non-existing ISA devices */
77 DummyISADevice dummyDevice;
79 // PMU belonging to this ISA
82 // Generic timer interface belonging to this ISA
83 std::unique_ptr<BaseISADevice> timer;
85 // GICv3 CPU interface belonging to this ISA
86 std::unique_ptr<BaseISADevice> gicv3CpuInterface;
88 // Cached copies of system-level properties
92 bool haveVirtualization;
95 bool haveGICv3CPUInterface;
96 uint8_t physAddrRange;
101 /** SVE vector length in quadwords */
105 * If true, accesses to IMPLEMENTATION DEFINED registers are treated
106 * as NOP hence not causing UNDEFINED INSTRUCTION.
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)
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; }
134 /** Metadata table accessible via the value of the register */
135 static std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
137 class MiscRegLUTEntryInitializer {
138 struct MiscRegLUTEntry &entry;
139 std::bitset<NUM_MISCREG_INFOS> &info;
140 typedef const MiscRegLUTEntryInitializer& chain;
142 chain mapsTo(uint32_t l, uint32_t u = 0) const {
147 chain res0(uint64_t mask) const {
151 chain res1(uint64_t mask) const {
155 chain raz(uint64_t mask) const {
159 chain rao(uint64_t mask) const {
163 chain implemented(bool v = true) const {
164 info[MISCREG_IMPLEMENTED] = v;
167 chain unimplemented() const {
168 return implemented(false);
170 chain unverifiable(bool v = true) const {
171 info[MISCREG_UNVERIFIABLE] = v;
174 chain warnNotFail(bool v = true) const {
175 info[MISCREG_WARN_NOT_FAIL] = v;
178 chain mutex(bool v = true) const {
179 info[MISCREG_MUTEX] = v;
182 chain banked(bool v = true) const {
183 info[MISCREG_BANKED] = v;
186 chain banked64(bool v = true) const {
187 info[MISCREG_BANKED64] = v;
190 chain bankedChild(bool v = true) const {
191 info[MISCREG_BANKED_CHILD] = v;
194 chain userNonSecureRead(bool v = true) const {
195 info[MISCREG_USR_NS_RD] = v;
198 chain userNonSecureWrite(bool v = true) const {
199 info[MISCREG_USR_NS_WR] = v;
202 chain userSecureRead(bool v = true) const {
203 info[MISCREG_USR_S_RD] = v;
206 chain userSecureWrite(bool v = true) const {
207 info[MISCREG_USR_S_WR] = v;
210 chain user(bool v = true) const {
211 userNonSecureRead(v);
212 userNonSecureWrite(v);
217 chain privNonSecureRead(bool v = true) const {
218 info[MISCREG_PRI_NS_RD] = v;
221 chain privNonSecureWrite(bool v = true) const {
222 info[MISCREG_PRI_NS_WR] = v;
225 chain privNonSecure(bool v = true) const {
226 privNonSecureRead(v);
227 privNonSecureWrite(v);
230 chain privSecureRead(bool v = true) const {
231 info[MISCREG_PRI_S_RD] = v;
234 chain privSecureWrite(bool v = true) const {
235 info[MISCREG_PRI_S_WR] = v;
238 chain privSecure(bool v = true) const {
243 chain priv(bool v = true) const {
248 chain privRead(bool v = true) const {
250 privNonSecureRead(v);
253 chain hypRead(bool v = true) const {
254 info[MISCREG_HYP_RD] = v;
257 chain hypWrite(bool v = true) const {
258 info[MISCREG_HYP_WR] = v;
261 chain hyp(bool v = true) const {
266 chain monSecureRead(bool v = true) const {
267 info[MISCREG_MON_NS0_RD] = v;
270 chain monSecureWrite(bool v = true) const {
271 info[MISCREG_MON_NS0_WR] = v;
274 chain monNonSecureRead(bool v = true) const {
275 info[MISCREG_MON_NS1_RD] = v;
278 chain monNonSecureWrite(bool v = true) const {
279 info[MISCREG_MON_NS1_WR] = v;
282 chain mon(bool v = true) const {
286 monNonSecureWrite(v);
289 chain monSecure(bool v = true) const {
294 chain monNonSecure(bool v = true) const {
296 monNonSecureWrite(v);
299 chain allPrivileges(bool v = true) const {
300 userNonSecureRead(v);
301 userNonSecureWrite(v);
304 privNonSecureRead(v);
305 privNonSecureWrite(v);
313 monNonSecureWrite(v);
316 chain nonSecure(bool v = true) const {
317 userNonSecureRead(v);
318 userNonSecureWrite(v);
319 privNonSecureRead(v);
320 privNonSecureWrite(v);
324 monNonSecureWrite(v);
327 chain secure(bool v = true) const {
336 chain reads(bool v) const {
337 userNonSecureRead(v);
339 privNonSecureRead(v);
346 chain writes(bool v) const {
347 userNonSecureWrite(v);
349 privNonSecureWrite(v);
353 monNonSecureWrite(v);
356 chain exceptUserMode() const {
360 MiscRegLUTEntryInitializer(struct MiscRegLUTEntry &e,
361 std::bitset<NUM_MISCREG_INFOS> &i)
365 // force unimplemented registers to be thusly declared
370 const MiscRegLUTEntryInitializer InitReg(uint32_t reg) {
371 return MiscRegLUTEntryInitializer(lookUpMiscReg[reg],
375 void initializeMiscRegMetadata();
377 RegVal miscRegs[NumMiscRegs];
378 const IntRegIndex *intRegMap;
381 updateRegMap(CPSR cpsr)
383 if (cpsr.width == 0) {
384 intRegMap = IntReg64Map;
389 intRegMap = IntRegUsrMap;
392 intRegMap = IntRegFiqMap;
395 intRegMap = IntRegIrqMap;
398 intRegMap = IntRegSvcMap;
401 intRegMap = IntRegMonMap;
404 intRegMap = IntRegAbtMap;
407 intRegMap = IntRegHypMap;
410 intRegMap = IntRegUndMap;
413 panic("Unrecognized mode setting in CPSR.\n");
418 BaseISADevice &getGenericTimer(ThreadContext *tc);
419 BaseISADevice &getGICv3CPUInterface(ThreadContext *tc);
423 inline void assert32(ThreadContext *tc) {
424 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
428 inline void assert64(ThreadContext *tc) {
429 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
437 void clear32(const ArmISAParams *p, const SCTLR &sctlr_rst);
438 void clear64(const ArmISAParams *p);
439 void initID32(const ArmISAParams *p);
440 void initID64(const ArmISAParams *p);
443 RegVal readMiscRegNoEffect(int misc_reg) const;
444 RegVal readMiscReg(int misc_reg, ThreadContext *tc);
445 void setMiscRegNoEffect(int misc_reg, RegVal val);
446 void setMiscReg(int misc_reg, RegVal val, ThreadContext *tc);
449 flattenRegId(const RegId& regId) const
451 switch (regId.classValue()) {
453 return RegId(IntRegClass, flattenIntIndex(regId.index()));
455 return RegId(FloatRegClass, flattenFloatIndex(regId.index()));
457 return RegId(VecRegClass, flattenVecIndex(regId.index()));
459 return RegId(VecElemClass, flattenVecElemIndex(regId.index()),
461 case VecPredRegClass:
462 return RegId(VecPredRegClass,
463 flattenVecPredIndex(regId.index()));
465 return RegId(CCRegClass, flattenCCIndex(regId.index()));
467 return RegId(MiscRegClass, flattenMiscIndex(regId.index()));
473 flattenIntIndex(int reg) const
476 if (reg < NUM_ARCH_INTREGS) {
477 return intRegMap[reg];
478 } else if (reg < NUM_INTREGS) {
480 } else if (reg == INTREG_SPX) {
481 CPSR cpsr = miscRegs[MISCREG_CPSR];
482 ExceptionLevel el = opModeToEL(
483 (OperatingMode) (uint8_t) cpsr.mode);
484 if (!cpsr.sp && el != EL0)
496 panic("Invalid exception level");
497 return 0; // Never happens.
500 return flattenIntRegModeIndex(reg);
505 flattenFloatIndex(int reg) const
512 flattenVecIndex(int reg) const
519 flattenVecElemIndex(int reg) const
526 flattenVecPredIndex(int reg) const
533 flattenCCIndex(int reg) const
540 flattenMiscIndex(int reg) const
545 if (reg == MISCREG_SPSR) {
546 CPSR cpsr = miscRegs[MISCREG_CPSR];
549 warn("User mode does not have SPSR\n");
550 flat_idx = MISCREG_SPSR;
554 flat_idx = MISCREG_SPSR_EL1;
558 flat_idx = MISCREG_SPSR_EL2;
562 flat_idx = MISCREG_SPSR_EL3;
565 warn("User mode does not have SPSR\n");
566 flat_idx = MISCREG_SPSR;
569 flat_idx = MISCREG_SPSR_FIQ;
572 flat_idx = MISCREG_SPSR_IRQ;
575 flat_idx = MISCREG_SPSR_SVC;
578 flat_idx = MISCREG_SPSR_MON;
581 flat_idx = MISCREG_SPSR_ABT;
584 flat_idx = MISCREG_SPSR_HYP;
587 flat_idx = MISCREG_SPSR_UND;
590 warn("Trying to access SPSR in an invalid mode: %d\n",
592 flat_idx = MISCREG_SPSR;
595 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
596 // Mutually exclusive CP15 register
598 case MISCREG_PRRR_MAIR0:
599 case MISCREG_PRRR_MAIR0_NS:
600 case MISCREG_PRRR_MAIR0_S:
602 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
603 // If the muxed reg has been flattened, work out the
604 // offset and apply it to the unmuxed reg
605 int idxOffset = reg - MISCREG_PRRR_MAIR0;
607 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
610 flat_idx = flattenMiscIndex(MISCREG_PRRR +
614 case MISCREG_NMRR_MAIR1:
615 case MISCREG_NMRR_MAIR1_NS:
616 case MISCREG_NMRR_MAIR1_S:
618 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
619 // If the muxed reg has been flattened, work out the
620 // offset and apply it to the unmuxed reg
621 int idxOffset = reg - MISCREG_NMRR_MAIR1;
623 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
626 flat_idx = flattenMiscIndex(MISCREG_NMRR +
630 case MISCREG_PMXEVTYPER_PMCCFILTR:
632 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
633 if (pmselr.sel == 31)
634 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
636 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
640 panic("Unrecognized misc. register.\n");
644 if (miscRegInfo[reg][MISCREG_BANKED]) {
645 bool secureReg = haveSecurity && !highestELIs64 &&
646 inSecureState(miscRegs[MISCREG_SCR],
647 miscRegs[MISCREG_CPSR]);
648 flat_idx += secureReg ? 2 : 1;
650 flat_idx = snsBankedIndex64((MiscRegIndex)reg,
651 !inSecureState(miscRegs[MISCREG_SCR],
652 miscRegs[MISCREG_CPSR]));
659 snsBankedIndex64(MiscRegIndex reg, bool ns) const
661 int reg_as_int = static_cast<int>(reg);
662 if (miscRegInfo[reg][MISCREG_BANKED64]) {
663 reg_as_int += (haveSecurity && !ns) ? 2 : 1;
668 std::pair<int,int> getMiscIndices(int misc_reg) const
670 // Note: indexes of AArch64 registers are left unchanged
671 int flat_idx = flattenMiscIndex(misc_reg);
673 if (lookUpMiscReg[flat_idx].lower == 0) {
674 return std::make_pair(flat_idx, 0);
677 // do additional S/NS flattenings if mapped to NS while in S
678 bool S = haveSecurity && !highestELIs64 &&
679 inSecureState(miscRegs[MISCREG_SCR],
680 miscRegs[MISCREG_CPSR]);
681 int lower = lookUpMiscReg[flat_idx].lower;
682 int upper = lookUpMiscReg[flat_idx].upper;
683 // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
684 lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
685 upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
686 return std::make_pair(lower, upper);
689 unsigned getCurSveVecLenInBits(ThreadContext *tc) const;
691 unsigned getCurSveVecLenInBitsAtReset() const { return sveVL * 128; }
693 static void zeroSveVecRegUpperPart(VecRegContainer &vc,
697 serialize(CheckpointOut &cp) const
699 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
700 SERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
704 unserialize(CheckpointIn &cp)
706 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
707 UNSERIALIZE_ARRAY(miscRegs, NUM_PHYS_MISCREGS);
708 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
709 updateRegMap(tmp_cpsr);
712 void startup(ThreadContext *tc);
714 Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
716 /** Getter for haveGICv3CPUInterface */
717 bool haveGICv3CpuIfc() const
719 // haveGICv3CPUInterface is initialized at startup time, hence
720 // trying to read its value before the startup stage will lead
722 assert(afterStartup);
723 return haveGICv3CPUInterface;
726 Enums::VecRegRenameMode
727 vecRegRenameMode() const
729 return _vecRegRenameMode;
732 /// Explicitly import the otherwise hidden startup
733 using SimObject::startup;
735 typedef ArmISAParams Params;
737 const Params *params() const;
744 struct RenameMode<ArmISA::ISA>
746 static Enums::VecRegRenameMode
747 init(const ArmISA::ISA* isa)
749 return isa->vecRegRenameMode();
752 static Enums::VecRegRenameMode
753 mode(const ArmISA::PCState& pc)
763 equalsInit(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
765 return init(isa1) == init(isa2);