2 * Copyright (c) 2010, 2012-2016 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/registers.hh"
48 #include "arch/arm/system.hh"
49 #include "arch/arm/tlb.hh"
50 #include "arch/arm/types.hh"
51 #include "debug/Checkpoint.hh"
52 #include "sim/sim_object.hh"
53 #include "enums/DecoderFlavour.hh"
56 struct DummyArmISADeviceParams;
63 class ISA : public SimObject
70 const Enums::DecoderFlavour _decoderFlavour;
72 /** Dummy device for to handle non-existing ISA devices */
73 DummyISADevice dummyDevice;
75 // PMU belonging to this ISA
78 // Generic timer interface belonging to this ISA
79 std::unique_ptr<BaseISADevice> timer;
81 // Cached copies of system-level properties
85 bool haveVirtualization;
87 uint8_t physAddrRange64;
89 /** Register translation entry used in lookUpMiscReg */
90 struct MiscRegLUTEntry {
95 struct MiscRegInitializerEntry {
97 struct MiscRegLUTEntry entry;
100 /** Register table noting all translations */
101 static const struct MiscRegInitializerEntry MiscRegSwitch[];
103 /** Translation table accessible via the value of the register */
104 std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
106 MiscReg miscRegs[NumMiscRegs];
107 const IntRegIndex *intRegMap;
110 updateRegMap(CPSR cpsr)
112 if (cpsr.width == 0) {
113 intRegMap = IntReg64Map;
118 intRegMap = IntRegUsrMap;
121 intRegMap = IntRegFiqMap;
124 intRegMap = IntRegIrqMap;
127 intRegMap = IntRegSvcMap;
130 intRegMap = IntRegMonMap;
133 intRegMap = IntRegAbtMap;
136 intRegMap = IntRegHypMap;
139 intRegMap = IntRegUndMap;
142 panic("Unrecognized mode setting in CPSR.\n");
147 BaseISADevice &getGenericTimer(ThreadContext *tc);
151 inline void assert32(ThreadContext *tc) {
152 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
156 inline void assert64(ThreadContext *tc) {
157 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
161 void tlbiVA(ThreadContext *tc, MiscReg newVal, uint16_t asid,
162 bool secure_lookup, uint8_t target_el);
164 void tlbiALL(ThreadContext *tc, bool secure_lookup, uint8_t target_el);
166 void tlbiALLN(ThreadContext *tc, bool hyp, uint8_t target_el);
168 void tlbiMVA(ThreadContext *tc, MiscReg newVal, bool secure_lookup,
169 bool hyp, uint8_t target_el);
173 void clear64(const ArmISAParams *p);
175 MiscReg readMiscRegNoEffect(int misc_reg) const;
176 MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
177 void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
178 void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
181 flattenIntIndex(int reg) const
184 if (reg < NUM_ARCH_INTREGS) {
185 return intRegMap[reg];
186 } else if (reg < NUM_INTREGS) {
188 } else if (reg == INTREG_SPX) {
189 CPSR cpsr = miscRegs[MISCREG_CPSR];
190 ExceptionLevel el = opModeToEL(
191 (OperatingMode) (uint8_t) cpsr.mode);
192 if (!cpsr.sp && el != EL0)
204 panic("Invalid exception level");
208 return flattenIntRegModeIndex(reg);
213 flattenFloatIndex(int reg) const
220 flattenCCIndex(int reg) const
227 flattenMiscIndex(int reg) const
232 if (reg == MISCREG_SPSR) {
233 CPSR cpsr = miscRegs[MISCREG_CPSR];
236 warn("User mode does not have SPSR\n");
237 flat_idx = MISCREG_SPSR;
241 flat_idx = MISCREG_SPSR_EL1;
245 flat_idx = MISCREG_SPSR_EL2;
249 flat_idx = MISCREG_SPSR_EL3;
252 warn("User mode does not have SPSR\n");
253 flat_idx = MISCREG_SPSR;
256 flat_idx = MISCREG_SPSR_FIQ;
259 flat_idx = MISCREG_SPSR_IRQ;
262 flat_idx = MISCREG_SPSR_SVC;
265 flat_idx = MISCREG_SPSR_MON;
268 flat_idx = MISCREG_SPSR_ABT;
271 flat_idx = MISCREG_SPSR_HYP;
274 flat_idx = MISCREG_SPSR_UND;
277 warn("Trying to access SPSR in an invalid mode: %d\n",
279 flat_idx = MISCREG_SPSR;
282 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
283 // Mutually exclusive CP15 register
285 case MISCREG_PRRR_MAIR0:
286 case MISCREG_PRRR_MAIR0_NS:
287 case MISCREG_PRRR_MAIR0_S:
289 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
290 // If the muxed reg has been flattened, work out the
291 // offset and apply it to the unmuxed reg
292 int idxOffset = reg - MISCREG_PRRR_MAIR0;
294 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
297 flat_idx = flattenMiscIndex(MISCREG_PRRR +
301 case MISCREG_NMRR_MAIR1:
302 case MISCREG_NMRR_MAIR1_NS:
303 case MISCREG_NMRR_MAIR1_S:
305 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
306 // If the muxed reg has been flattened, work out the
307 // offset and apply it to the unmuxed reg
308 int idxOffset = reg - MISCREG_NMRR_MAIR1;
310 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
313 flat_idx = flattenMiscIndex(MISCREG_NMRR +
317 case MISCREG_PMXEVTYPER_PMCCFILTR:
319 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
320 if (pmselr.sel == 31)
321 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
323 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
327 panic("Unrecognized misc. register.\n");
331 if (miscRegInfo[reg][MISCREG_BANKED]) {
332 bool secureReg = haveSecurity && !highestELIs64 &&
333 inSecureState(miscRegs[MISCREG_SCR],
334 miscRegs[MISCREG_CPSR]);
335 flat_idx += secureReg ? 2 : 1;
341 std::pair<int,int> getMiscIndices(int misc_reg) const
343 // Note: indexes of AArch64 registers are left unchanged
344 int flat_idx = flattenMiscIndex(misc_reg);
346 if (lookUpMiscReg[flat_idx].lower == 0) {
347 return std::make_pair(flat_idx, 0);
350 // do additional S/NS flattenings if mapped to NS while in S
351 bool S = haveSecurity && !highestELIs64 &&
352 inSecureState(miscRegs[MISCREG_SCR],
353 miscRegs[MISCREG_CPSR]);
354 int lower = lookUpMiscReg[flat_idx].lower;
355 int upper = lookUpMiscReg[flat_idx].upper;
356 // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
357 lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
358 upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
359 return std::make_pair(lower, upper);
362 void serialize(CheckpointOut &cp) const
364 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
365 SERIALIZE_ARRAY(miscRegs, NumMiscRegs);
367 SERIALIZE_SCALAR(highestELIs64);
368 SERIALIZE_SCALAR(haveSecurity);
369 SERIALIZE_SCALAR(haveLPAE);
370 SERIALIZE_SCALAR(haveVirtualization);
371 SERIALIZE_SCALAR(haveLargeAsid64);
372 SERIALIZE_SCALAR(physAddrRange64);
374 void unserialize(CheckpointIn &cp)
376 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
377 UNSERIALIZE_ARRAY(miscRegs, NumMiscRegs);
378 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
379 updateRegMap(tmp_cpsr);
381 UNSERIALIZE_SCALAR(highestELIs64);
382 UNSERIALIZE_SCALAR(haveSecurity);
383 UNSERIALIZE_SCALAR(haveLPAE);
384 UNSERIALIZE_SCALAR(haveVirtualization);
385 UNSERIALIZE_SCALAR(haveLargeAsid64);
386 UNSERIALIZE_SCALAR(physAddrRange64);
389 void startup(ThreadContext *tc) {}
391 Enums::DecoderFlavour decoderFlavour() const { return _decoderFlavour; }
393 /// Explicitly import the otherwise hidden startup
394 using SimObject::startup;
396 typedef ArmISAParams Params;
398 const Params *params() const;