isa.hh (10844:8551af601f75) isa.hh (10905:a6ca6831e775)
1/*
2 * Copyright (c) 2010, 2012-2015 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/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
54struct ArmISAParams;
55struct DummyArmISADeviceParams;
56class ThreadContext;
57class Checkpoint;
58class EventManager;
59
60namespace ArmISA
61{
62
63 /**
64 * At the moment there are 57 registers which need to be aliased/
65 * translated with other registers in the ISA. This enum helps with that
66 * translation.
67 */
68 enum translateTable {
69 miscRegTranslateCSSELR_EL1,
70 miscRegTranslateSCTLR_EL1,
71 miscRegTranslateSCTLR_EL2,
72 miscRegTranslateACTLR_EL1,
73 miscRegTranslateACTLR_EL2,
74 miscRegTranslateCPACR_EL1,
75 miscRegTranslateCPTR_EL2,
76 miscRegTranslateHCR_EL2,
77 miscRegTranslateMDCR_EL2,
78 miscRegTranslateHSTR_EL2,
79 miscRegTranslateHACR_EL2,
80 miscRegTranslateTTBR0_EL1,
81 miscRegTranslateTTBR1_EL1,
82 miscRegTranslateTTBR0_EL2,
83 miscRegTranslateVTTBR_EL2,
84 miscRegTranslateTCR_EL1,
85 miscRegTranslateTCR_EL2,
86 miscRegTranslateVTCR_EL2,
87 miscRegTranslateAFSR0_EL1,
88 miscRegTranslateAFSR1_EL1,
89 miscRegTranslateAFSR0_EL2,
90 miscRegTranslateAFSR1_EL2,
91 miscRegTranslateESR_EL2,
92 miscRegTranslateFAR_EL1,
93 miscRegTranslateFAR_EL2,
94 miscRegTranslateHPFAR_EL2,
95 miscRegTranslatePAR_EL1,
96 miscRegTranslateMAIR_EL1,
97 miscRegTranslateMAIR_EL2,
98 miscRegTranslateAMAIR_EL1,
99 miscRegTranslateVBAR_EL1,
100 miscRegTranslateVBAR_EL2,
101 miscRegTranslateCONTEXTIDR_EL1,
102 miscRegTranslateTPIDR_EL0,
103 miscRegTranslateTPIDRRO_EL0,
104 miscRegTranslateTPIDR_EL1,
105 miscRegTranslateTPIDR_EL2,
106 miscRegTranslateTEECR32_EL1,
107 miscRegTranslateCNTFRQ_EL0,
108 miscRegTranslateCNTPCT_EL0,
109 miscRegTranslateCNTVCT_EL0,
110 miscRegTranslateCNTVOFF_EL2,
111 miscRegTranslateCNTKCTL_EL1,
112 miscRegTranslateCNTHCTL_EL2,
113 miscRegTranslateCNTP_TVAL_EL0,
114 miscRegTranslateCNTP_CTL_EL0,
115 miscRegTranslateCNTP_CVAL_EL0,
116 miscRegTranslateCNTV_TVAL_EL0,
117 miscRegTranslateCNTV_CTL_EL0,
118 miscRegTranslateCNTV_CVAL_EL0,
119 miscRegTranslateCNTHP_TVAL_EL2,
120 miscRegTranslateCNTHP_CTL_EL2,
121 miscRegTranslateCNTHP_CVAL_EL2,
122 miscRegTranslateDACR32_EL2,
123 miscRegTranslateIFSR32_EL2,
124 miscRegTranslateTEEHBR32_EL1,
125 miscRegTranslateSDER32_EL3,
126 miscRegTranslateMax
127 };
128
129 class ISA : public SimObject
130 {
131 protected:
132 // Parent system
133 ArmSystem *system;
134
135 /** Dummy device for to handle non-existing ISA devices */
136 DummyISADevice dummyDevice;
137
138 // PMU belonging to this ISA
139 BaseISADevice *pmu;
140
141 // Generic timer interface belonging to this ISA
142 std::unique_ptr<BaseISADevice> timer;
143
144 // Cached copies of system-level properties
145 bool haveSecurity;
146 bool haveLPAE;
147 bool haveVirtualization;
148 bool haveLargeAsid64;
149 uint8_t physAddrRange64;
150
151 /** Register translation entry used in lookUpMiscReg */
152 struct MiscRegLUTEntry {
153 uint32_t lower;
154 uint32_t upper;
155 };
156
157 struct MiscRegInitializerEntry {
158 uint32_t index;
159 struct MiscRegLUTEntry entry;
160 };
161
162 /** Register table noting all translations */
163 static const struct MiscRegInitializerEntry
164 MiscRegSwitch[miscRegTranslateMax];
165
166 /** Translation table accessible via the value of the register */
167 std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
168
169 MiscReg miscRegs[NumMiscRegs];
170 const IntRegIndex *intRegMap;
171
172 void
173 updateRegMap(CPSR cpsr)
174 {
175 if (cpsr.width == 0) {
176 intRegMap = IntReg64Map;
177 } else {
178 switch (cpsr.mode) {
179 case MODE_USER:
180 case MODE_SYSTEM:
181 intRegMap = IntRegUsrMap;
182 break;
183 case MODE_FIQ:
184 intRegMap = IntRegFiqMap;
185 break;
186 case MODE_IRQ:
187 intRegMap = IntRegIrqMap;
188 break;
189 case MODE_SVC:
190 intRegMap = IntRegSvcMap;
191 break;
192 case MODE_MON:
193 intRegMap = IntRegMonMap;
194 break;
195 case MODE_ABORT:
196 intRegMap = IntRegAbtMap;
197 break;
198 case MODE_HYP:
199 intRegMap = IntRegHypMap;
200 break;
201 case MODE_UNDEFINED:
202 intRegMap = IntRegUndMap;
203 break;
204 default:
205 panic("Unrecognized mode setting in CPSR.\n");
206 }
207 }
208 }
209
210 BaseISADevice &getGenericTimer(ThreadContext *tc);
211
212
213 private:
214 inline void assert32(ThreadContext *tc) {
215 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
216 assert(cpsr.width);
217 }
218
219 inline void assert64(ThreadContext *tc) {
220 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
221 assert(!cpsr.width);
222 }
223
224 void tlbiVA(ThreadContext *tc, MiscReg newVal, uint16_t asid,
225 bool secure_lookup, uint8_t target_el);
226
227 void tlbiALL(ThreadContext *tc, bool secure_lookup, uint8_t target_el);
228
229 void tlbiALLN(ThreadContext *tc, bool hyp, uint8_t target_el);
230
231 void tlbiMVA(ThreadContext *tc, MiscReg newVal, bool secure_lookup,
232 bool hyp, uint8_t target_el);
233
234 public:
235 void clear();
236 void clear64(const ArmISAParams *p);
237
238 MiscReg readMiscRegNoEffect(int misc_reg) const;
239 MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
240 void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
241 void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
242
243 int
244 flattenIntIndex(int reg) const
245 {
246 assert(reg >= 0);
247 if (reg < NUM_ARCH_INTREGS) {
248 return intRegMap[reg];
249 } else if (reg < NUM_INTREGS) {
250 return reg;
251 } else if (reg == INTREG_SPX) {
252 CPSR cpsr = miscRegs[MISCREG_CPSR];
253 ExceptionLevel el = opModeToEL(
254 (OperatingMode) (uint8_t) cpsr.mode);
255 if (!cpsr.sp && el != EL0)
256 return INTREG_SP0;
257 switch (el) {
258 case EL3:
259 return INTREG_SP3;
260 // @todo: uncomment this to enable Virtualization
261 // case EL2:
262 // return INTREG_SP2;
263 case EL1:
264 return INTREG_SP1;
265 case EL0:
266 return INTREG_SP0;
267 default:
268 panic("Invalid exception level");
269 break;
270 }
271 } else {
272 return flattenIntRegModeIndex(reg);
273 }
274 }
275
276 int
277 flattenFloatIndex(int reg) const
278 {
279 assert(reg >= 0);
280 return reg;
281 }
282
283 int
284 flattenCCIndex(int reg) const
285 {
286 assert(reg >= 0);
287 return reg;
288 }
289
290 int
291 flattenMiscIndex(int reg) const
292 {
293 assert(reg >= 0);
294 int flat_idx = reg;
295
296 if (reg == MISCREG_SPSR) {
297 CPSR cpsr = miscRegs[MISCREG_CPSR];
298 switch (cpsr.mode) {
299 case MODE_EL0T:
300 warn("User mode does not have SPSR\n");
301 flat_idx = MISCREG_SPSR;
302 break;
303 case MODE_EL1T:
304 case MODE_EL1H:
305 flat_idx = MISCREG_SPSR_EL1;
306 break;
307 case MODE_EL2T:
308 case MODE_EL2H:
309 flat_idx = MISCREG_SPSR_EL2;
310 break;
311 case MODE_EL3T:
312 case MODE_EL3H:
313 flat_idx = MISCREG_SPSR_EL3;
314 break;
315 case MODE_USER:
316 warn("User mode does not have SPSR\n");
317 flat_idx = MISCREG_SPSR;
318 break;
319 case MODE_FIQ:
320 flat_idx = MISCREG_SPSR_FIQ;
321 break;
322 case MODE_IRQ:
323 flat_idx = MISCREG_SPSR_IRQ;
324 break;
325 case MODE_SVC:
326 flat_idx = MISCREG_SPSR_SVC;
327 break;
328 case MODE_MON:
329 flat_idx = MISCREG_SPSR_MON;
330 break;
331 case MODE_ABORT:
332 flat_idx = MISCREG_SPSR_ABT;
333 break;
334 case MODE_HYP:
335 flat_idx = MISCREG_SPSR_HYP;
336 break;
337 case MODE_UNDEFINED:
338 flat_idx = MISCREG_SPSR_UND;
339 break;
340 default:
341 warn("Trying to access SPSR in an invalid mode: %d\n",
342 cpsr.mode);
343 flat_idx = MISCREG_SPSR;
344 break;
345 }
346 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
347 // Mutually exclusive CP15 register
348 switch (reg) {
349 case MISCREG_PRRR_MAIR0:
350 case MISCREG_PRRR_MAIR0_NS:
351 case MISCREG_PRRR_MAIR0_S:
352 {
353 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
354 // If the muxed reg has been flattened, work out the
355 // offset and apply it to the unmuxed reg
356 int idxOffset = reg - MISCREG_PRRR_MAIR0;
357 if (ttbcr.eae)
358 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
359 idxOffset);
360 else
361 flat_idx = flattenMiscIndex(MISCREG_PRRR +
362 idxOffset);
363 }
364 break;
365 case MISCREG_NMRR_MAIR1:
366 case MISCREG_NMRR_MAIR1_NS:
367 case MISCREG_NMRR_MAIR1_S:
368 {
369 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
370 // If the muxed reg has been flattened, work out the
371 // offset and apply it to the unmuxed reg
372 int idxOffset = reg - MISCREG_NMRR_MAIR1;
373 if (ttbcr.eae)
374 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
375 idxOffset);
376 else
377 flat_idx = flattenMiscIndex(MISCREG_NMRR +
378 idxOffset);
379 }
380 break;
381 case MISCREG_PMXEVTYPER_PMCCFILTR:
382 {
383 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
384 if (pmselr.sel == 31)
385 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
386 else
387 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
388 }
389 break;
390 default:
391 panic("Unrecognized misc. register.\n");
392 break;
393 }
394 } else {
395 if (miscRegInfo[reg][MISCREG_BANKED]) {
396 bool secureReg = haveSecurity &&
397 inSecureState(miscRegs[MISCREG_SCR],
398 miscRegs[MISCREG_CPSR]);
399 flat_idx += secureReg ? 2 : 1;
400 }
401 }
402 return flat_idx;
403 }
404
1/*
2 * Copyright (c) 2010, 2012-2015 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/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
54struct ArmISAParams;
55struct DummyArmISADeviceParams;
56class ThreadContext;
57class Checkpoint;
58class EventManager;
59
60namespace ArmISA
61{
62
63 /**
64 * At the moment there are 57 registers which need to be aliased/
65 * translated with other registers in the ISA. This enum helps with that
66 * translation.
67 */
68 enum translateTable {
69 miscRegTranslateCSSELR_EL1,
70 miscRegTranslateSCTLR_EL1,
71 miscRegTranslateSCTLR_EL2,
72 miscRegTranslateACTLR_EL1,
73 miscRegTranslateACTLR_EL2,
74 miscRegTranslateCPACR_EL1,
75 miscRegTranslateCPTR_EL2,
76 miscRegTranslateHCR_EL2,
77 miscRegTranslateMDCR_EL2,
78 miscRegTranslateHSTR_EL2,
79 miscRegTranslateHACR_EL2,
80 miscRegTranslateTTBR0_EL1,
81 miscRegTranslateTTBR1_EL1,
82 miscRegTranslateTTBR0_EL2,
83 miscRegTranslateVTTBR_EL2,
84 miscRegTranslateTCR_EL1,
85 miscRegTranslateTCR_EL2,
86 miscRegTranslateVTCR_EL2,
87 miscRegTranslateAFSR0_EL1,
88 miscRegTranslateAFSR1_EL1,
89 miscRegTranslateAFSR0_EL2,
90 miscRegTranslateAFSR1_EL2,
91 miscRegTranslateESR_EL2,
92 miscRegTranslateFAR_EL1,
93 miscRegTranslateFAR_EL2,
94 miscRegTranslateHPFAR_EL2,
95 miscRegTranslatePAR_EL1,
96 miscRegTranslateMAIR_EL1,
97 miscRegTranslateMAIR_EL2,
98 miscRegTranslateAMAIR_EL1,
99 miscRegTranslateVBAR_EL1,
100 miscRegTranslateVBAR_EL2,
101 miscRegTranslateCONTEXTIDR_EL1,
102 miscRegTranslateTPIDR_EL0,
103 miscRegTranslateTPIDRRO_EL0,
104 miscRegTranslateTPIDR_EL1,
105 miscRegTranslateTPIDR_EL2,
106 miscRegTranslateTEECR32_EL1,
107 miscRegTranslateCNTFRQ_EL0,
108 miscRegTranslateCNTPCT_EL0,
109 miscRegTranslateCNTVCT_EL0,
110 miscRegTranslateCNTVOFF_EL2,
111 miscRegTranslateCNTKCTL_EL1,
112 miscRegTranslateCNTHCTL_EL2,
113 miscRegTranslateCNTP_TVAL_EL0,
114 miscRegTranslateCNTP_CTL_EL0,
115 miscRegTranslateCNTP_CVAL_EL0,
116 miscRegTranslateCNTV_TVAL_EL0,
117 miscRegTranslateCNTV_CTL_EL0,
118 miscRegTranslateCNTV_CVAL_EL0,
119 miscRegTranslateCNTHP_TVAL_EL2,
120 miscRegTranslateCNTHP_CTL_EL2,
121 miscRegTranslateCNTHP_CVAL_EL2,
122 miscRegTranslateDACR32_EL2,
123 miscRegTranslateIFSR32_EL2,
124 miscRegTranslateTEEHBR32_EL1,
125 miscRegTranslateSDER32_EL3,
126 miscRegTranslateMax
127 };
128
129 class ISA : public SimObject
130 {
131 protected:
132 // Parent system
133 ArmSystem *system;
134
135 /** Dummy device for to handle non-existing ISA devices */
136 DummyISADevice dummyDevice;
137
138 // PMU belonging to this ISA
139 BaseISADevice *pmu;
140
141 // Generic timer interface belonging to this ISA
142 std::unique_ptr<BaseISADevice> timer;
143
144 // Cached copies of system-level properties
145 bool haveSecurity;
146 bool haveLPAE;
147 bool haveVirtualization;
148 bool haveLargeAsid64;
149 uint8_t physAddrRange64;
150
151 /** Register translation entry used in lookUpMiscReg */
152 struct MiscRegLUTEntry {
153 uint32_t lower;
154 uint32_t upper;
155 };
156
157 struct MiscRegInitializerEntry {
158 uint32_t index;
159 struct MiscRegLUTEntry entry;
160 };
161
162 /** Register table noting all translations */
163 static const struct MiscRegInitializerEntry
164 MiscRegSwitch[miscRegTranslateMax];
165
166 /** Translation table accessible via the value of the register */
167 std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
168
169 MiscReg miscRegs[NumMiscRegs];
170 const IntRegIndex *intRegMap;
171
172 void
173 updateRegMap(CPSR cpsr)
174 {
175 if (cpsr.width == 0) {
176 intRegMap = IntReg64Map;
177 } else {
178 switch (cpsr.mode) {
179 case MODE_USER:
180 case MODE_SYSTEM:
181 intRegMap = IntRegUsrMap;
182 break;
183 case MODE_FIQ:
184 intRegMap = IntRegFiqMap;
185 break;
186 case MODE_IRQ:
187 intRegMap = IntRegIrqMap;
188 break;
189 case MODE_SVC:
190 intRegMap = IntRegSvcMap;
191 break;
192 case MODE_MON:
193 intRegMap = IntRegMonMap;
194 break;
195 case MODE_ABORT:
196 intRegMap = IntRegAbtMap;
197 break;
198 case MODE_HYP:
199 intRegMap = IntRegHypMap;
200 break;
201 case MODE_UNDEFINED:
202 intRegMap = IntRegUndMap;
203 break;
204 default:
205 panic("Unrecognized mode setting in CPSR.\n");
206 }
207 }
208 }
209
210 BaseISADevice &getGenericTimer(ThreadContext *tc);
211
212
213 private:
214 inline void assert32(ThreadContext *tc) {
215 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
216 assert(cpsr.width);
217 }
218
219 inline void assert64(ThreadContext *tc) {
220 CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
221 assert(!cpsr.width);
222 }
223
224 void tlbiVA(ThreadContext *tc, MiscReg newVal, uint16_t asid,
225 bool secure_lookup, uint8_t target_el);
226
227 void tlbiALL(ThreadContext *tc, bool secure_lookup, uint8_t target_el);
228
229 void tlbiALLN(ThreadContext *tc, bool hyp, uint8_t target_el);
230
231 void tlbiMVA(ThreadContext *tc, MiscReg newVal, bool secure_lookup,
232 bool hyp, uint8_t target_el);
233
234 public:
235 void clear();
236 void clear64(const ArmISAParams *p);
237
238 MiscReg readMiscRegNoEffect(int misc_reg) const;
239 MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
240 void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
241 void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
242
243 int
244 flattenIntIndex(int reg) const
245 {
246 assert(reg >= 0);
247 if (reg < NUM_ARCH_INTREGS) {
248 return intRegMap[reg];
249 } else if (reg < NUM_INTREGS) {
250 return reg;
251 } else if (reg == INTREG_SPX) {
252 CPSR cpsr = miscRegs[MISCREG_CPSR];
253 ExceptionLevel el = opModeToEL(
254 (OperatingMode) (uint8_t) cpsr.mode);
255 if (!cpsr.sp && el != EL0)
256 return INTREG_SP0;
257 switch (el) {
258 case EL3:
259 return INTREG_SP3;
260 // @todo: uncomment this to enable Virtualization
261 // case EL2:
262 // return INTREG_SP2;
263 case EL1:
264 return INTREG_SP1;
265 case EL0:
266 return INTREG_SP0;
267 default:
268 panic("Invalid exception level");
269 break;
270 }
271 } else {
272 return flattenIntRegModeIndex(reg);
273 }
274 }
275
276 int
277 flattenFloatIndex(int reg) const
278 {
279 assert(reg >= 0);
280 return reg;
281 }
282
283 int
284 flattenCCIndex(int reg) const
285 {
286 assert(reg >= 0);
287 return reg;
288 }
289
290 int
291 flattenMiscIndex(int reg) const
292 {
293 assert(reg >= 0);
294 int flat_idx = reg;
295
296 if (reg == MISCREG_SPSR) {
297 CPSR cpsr = miscRegs[MISCREG_CPSR];
298 switch (cpsr.mode) {
299 case MODE_EL0T:
300 warn("User mode does not have SPSR\n");
301 flat_idx = MISCREG_SPSR;
302 break;
303 case MODE_EL1T:
304 case MODE_EL1H:
305 flat_idx = MISCREG_SPSR_EL1;
306 break;
307 case MODE_EL2T:
308 case MODE_EL2H:
309 flat_idx = MISCREG_SPSR_EL2;
310 break;
311 case MODE_EL3T:
312 case MODE_EL3H:
313 flat_idx = MISCREG_SPSR_EL3;
314 break;
315 case MODE_USER:
316 warn("User mode does not have SPSR\n");
317 flat_idx = MISCREG_SPSR;
318 break;
319 case MODE_FIQ:
320 flat_idx = MISCREG_SPSR_FIQ;
321 break;
322 case MODE_IRQ:
323 flat_idx = MISCREG_SPSR_IRQ;
324 break;
325 case MODE_SVC:
326 flat_idx = MISCREG_SPSR_SVC;
327 break;
328 case MODE_MON:
329 flat_idx = MISCREG_SPSR_MON;
330 break;
331 case MODE_ABORT:
332 flat_idx = MISCREG_SPSR_ABT;
333 break;
334 case MODE_HYP:
335 flat_idx = MISCREG_SPSR_HYP;
336 break;
337 case MODE_UNDEFINED:
338 flat_idx = MISCREG_SPSR_UND;
339 break;
340 default:
341 warn("Trying to access SPSR in an invalid mode: %d\n",
342 cpsr.mode);
343 flat_idx = MISCREG_SPSR;
344 break;
345 }
346 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
347 // Mutually exclusive CP15 register
348 switch (reg) {
349 case MISCREG_PRRR_MAIR0:
350 case MISCREG_PRRR_MAIR0_NS:
351 case MISCREG_PRRR_MAIR0_S:
352 {
353 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
354 // If the muxed reg has been flattened, work out the
355 // offset and apply it to the unmuxed reg
356 int idxOffset = reg - MISCREG_PRRR_MAIR0;
357 if (ttbcr.eae)
358 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
359 idxOffset);
360 else
361 flat_idx = flattenMiscIndex(MISCREG_PRRR +
362 idxOffset);
363 }
364 break;
365 case MISCREG_NMRR_MAIR1:
366 case MISCREG_NMRR_MAIR1_NS:
367 case MISCREG_NMRR_MAIR1_S:
368 {
369 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
370 // If the muxed reg has been flattened, work out the
371 // offset and apply it to the unmuxed reg
372 int idxOffset = reg - MISCREG_NMRR_MAIR1;
373 if (ttbcr.eae)
374 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
375 idxOffset);
376 else
377 flat_idx = flattenMiscIndex(MISCREG_NMRR +
378 idxOffset);
379 }
380 break;
381 case MISCREG_PMXEVTYPER_PMCCFILTR:
382 {
383 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
384 if (pmselr.sel == 31)
385 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
386 else
387 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
388 }
389 break;
390 default:
391 panic("Unrecognized misc. register.\n");
392 break;
393 }
394 } else {
395 if (miscRegInfo[reg][MISCREG_BANKED]) {
396 bool secureReg = haveSecurity &&
397 inSecureState(miscRegs[MISCREG_SCR],
398 miscRegs[MISCREG_CPSR]);
399 flat_idx += secureReg ? 2 : 1;
400 }
401 }
402 return flat_idx;
403 }
404
405 void serialize(std::ostream &os)
405 void serialize(CheckpointOut &cp) const
406 {
407 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
408 SERIALIZE_ARRAY(miscRegs, NumMiscRegs);
409
410 SERIALIZE_SCALAR(haveSecurity);
411 SERIALIZE_SCALAR(haveLPAE);
412 SERIALIZE_SCALAR(haveVirtualization);
413 SERIALIZE_SCALAR(haveLargeAsid64);
414 SERIALIZE_SCALAR(physAddrRange64);
415 }
406 {
407 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
408 SERIALIZE_ARRAY(miscRegs, NumMiscRegs);
409
410 SERIALIZE_SCALAR(haveSecurity);
411 SERIALIZE_SCALAR(haveLPAE);
412 SERIALIZE_SCALAR(haveVirtualization);
413 SERIALIZE_SCALAR(haveLargeAsid64);
414 SERIALIZE_SCALAR(physAddrRange64);
415 }
416 void unserialize(Checkpoint *cp, const std::string &section)
416 void unserialize(CheckpointIn &cp)
417 {
418 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
419 UNSERIALIZE_ARRAY(miscRegs, NumMiscRegs);
420 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
421 updateRegMap(tmp_cpsr);
422
423 UNSERIALIZE_SCALAR(haveSecurity);
424 UNSERIALIZE_SCALAR(haveLPAE);
425 UNSERIALIZE_SCALAR(haveVirtualization);
426 UNSERIALIZE_SCALAR(haveLargeAsid64);
427 UNSERIALIZE_SCALAR(physAddrRange64);
428 }
429
430 void startup(ThreadContext *tc) {}
431
432 /// Explicitly import the otherwise hidden startup
433 using SimObject::startup;
434
435 typedef ArmISAParams Params;
436
437 const Params *params() const;
438
439 ISA(Params *p);
440 };
441}
442
443#endif
417 {
418 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
419 UNSERIALIZE_ARRAY(miscRegs, NumMiscRegs);
420 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
421 updateRegMap(tmp_cpsr);
422
423 UNSERIALIZE_SCALAR(haveSecurity);
424 UNSERIALIZE_SCALAR(haveLPAE);
425 UNSERIALIZE_SCALAR(haveVirtualization);
426 UNSERIALIZE_SCALAR(haveLargeAsid64);
427 UNSERIALIZE_SCALAR(physAddrRange64);
428 }
429
430 void startup(ThreadContext *tc) {}
431
432 /// Explicitly import the otherwise hidden startup
433 using SimObject::startup;
434
435 typedef ArmISAParams Params;
436
437 const Params *params() const;
438
439 ISA(Params *p);
440 };
441}
442
443#endif