isa.hh (10035:2a0fbecfeb14) isa.hh (10037:5cac77888310)
1/*
1/*
2 * Copyright (c) 2010 ARM Limited
2 * Copyright (c) 2010, 2012-2013 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

--- 28 unchanged lines hidden (view full) ---

39 *
40 * Authors: Gabe Black
41 */
42
43#ifndef __ARCH_ARM_ISA_HH__
44#define __ARCH_ARM_ISA_HH__
45
46#include "arch/arm/registers.hh"
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

--- 28 unchanged lines hidden (view full) ---

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