Deleted Added
sdiff udiff text old ( 10338:8bee5f4edb92 ) new ( 10461:afeb5cdb3907 )
full compact
1/*
2 * Copyright (c) 2010, 2012-2014 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/registers.hh"
47#include "arch/arm/system.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"
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
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
159 MiscReg miscRegs[NumMiscRegs];
160 const IntRegIndex *intRegMap;
161
162 void
163 updateRegMap(CPSR cpsr)
164 {
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 }
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
226 public:
227 void clear();
228 void clear64(const ArmISAParams *p);
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;
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;
259 default:
260 panic("Invalid exception level");
261 break;
262 }
263 } else {
264 return flattenIntRegModeIndex(reg);
265 }
266 }
267
268 int
269 flattenFloatIndex(int reg) const
270 {
271 assert(reg >= 0);
272 return reg;
273 }
274
275 int
276 flattenCCIndex(int reg) const
277 {
278 assert(reg >= 0);
279 return reg;
280 }
281
282 int
283 flattenMiscIndex(int reg) const
284 {
285 assert(reg >= 0);
286 int flat_idx = reg;
287
288 if (reg == MISCREG_SPSR) {
289 CPSR cpsr = miscRegs[MISCREG_CPSR];
290 switch (cpsr.mode) {
291 case MODE_EL0T:
292 warn("User mode does not have SPSR\n");
293 flat_idx = MISCREG_SPSR;
294 break;
295 case MODE_EL1T:
296 case MODE_EL1H:
297 flat_idx = MISCREG_SPSR_EL1;
298 break;
299 case MODE_EL2T:
300 case MODE_EL2H:
301 flat_idx = MISCREG_SPSR_EL2;
302 break;
303 case MODE_EL3T:
304 case MODE_EL3H:
305 flat_idx = MISCREG_SPSR_EL3;
306 break;
307 case MODE_USER:
308 warn("User mode does not have SPSR\n");
309 flat_idx = MISCREG_SPSR;
310 break;
311 case MODE_FIQ:
312 flat_idx = MISCREG_SPSR_FIQ;
313 break;
314 case MODE_IRQ:
315 flat_idx = MISCREG_SPSR_IRQ;
316 break;
317 case MODE_SVC:
318 flat_idx = MISCREG_SPSR_SVC;
319 break;
320 case MODE_MON:
321 flat_idx = MISCREG_SPSR_MON;
322 break;
323 case MODE_ABORT:
324 flat_idx = MISCREG_SPSR_ABT;
325 break;
326 case MODE_HYP:
327 flat_idx = MISCREG_SPSR_HYP;
328 break;
329 case MODE_UNDEFINED:
330 flat_idx = MISCREG_SPSR_UND;
331 break;
332 default:
333 warn("Trying to access SPSR in an invalid mode: %d\n",
334 cpsr.mode);
335 flat_idx = MISCREG_SPSR;
336 break;
337 }
338 } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
339 // Mutually exclusive CP15 register
340 switch (reg) {
341 case MISCREG_PRRR_MAIR0:
342 case MISCREG_PRRR_MAIR0_NS:
343 case MISCREG_PRRR_MAIR0_S:
344 {
345 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
346 // If the muxed reg has been flattened, work out the
347 // offset and apply it to the unmuxed reg
348 int idxOffset = reg - MISCREG_PRRR_MAIR0;
349 if (ttbcr.eae)
350 flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
351 idxOffset);
352 else
353 flat_idx = flattenMiscIndex(MISCREG_PRRR +
354 idxOffset);
355 }
356 break;
357 case MISCREG_NMRR_MAIR1:
358 case MISCREG_NMRR_MAIR1_NS:
359 case MISCREG_NMRR_MAIR1_S:
360 {
361 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
362 // If the muxed reg has been flattened, work out the
363 // offset and apply it to the unmuxed reg
364 int idxOffset = reg - MISCREG_NMRR_MAIR1;
365 if (ttbcr.eae)
366 flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
367 idxOffset);
368 else
369 flat_idx = flattenMiscIndex(MISCREG_NMRR +
370 idxOffset);
371 }
372 break;
373 case MISCREG_PMXEVTYPER_PMCCFILTR:
374 {
375 PMSELR pmselr = miscRegs[MISCREG_PMSELR];
376 if (pmselr.sel == 31)
377 flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
378 else
379 flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
380 }
381 break;
382 default:
383 panic("Unrecognized misc. register.\n");
384 break;
385 }
386 } else {
387 if (miscRegInfo[reg][MISCREG_BANKED]) {
388 bool secureReg = haveSecurity &&
389 inSecureState(miscRegs[MISCREG_SCR],
390 miscRegs[MISCREG_CPSR]);
391 flat_idx += secureReg ? 2 : 1;
392 }
393 }
394 return flat_idx;
395 }
396
397 void serialize(std::ostream &os)
398 {
399 DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
400 SERIALIZE_ARRAY(miscRegs, NumMiscRegs);
401
402 SERIALIZE_SCALAR(haveSecurity);
403 SERIALIZE_SCALAR(haveLPAE);
404 SERIALIZE_SCALAR(haveVirtualization);
405 SERIALIZE_SCALAR(haveLargeAsid64);
406 SERIALIZE_SCALAR(physAddrRange64);
407 }
408 void unserialize(Checkpoint *cp, const std::string &section)
409 {
410 DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
411 UNSERIALIZE_ARRAY(miscRegs, NumMiscRegs);
412 CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
413 updateRegMap(tmp_cpsr);
414
415 UNSERIALIZE_SCALAR(haveSecurity);
416 UNSERIALIZE_SCALAR(haveLPAE);
417 UNSERIALIZE_SCALAR(haveVirtualization);
418 UNSERIALIZE_SCALAR(haveLargeAsid64);
419 UNSERIALIZE_SCALAR(physAddrRange64);
420 }
421
422 void startup(ThreadContext *tc) {}
423
424 /// Explicitly import the otherwise hidden startup
425 using SimObject::startup;
426
427 typedef ArmISAParams Params;
428
429 const Params *params() const;
430
431 ISA(Params *p);
432 };
433}
434
435#endif