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 §ion) 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 §ion) 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 |