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