isa.cc revision 7427
1/* 2 * Copyright (c) 2010 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 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Gabe Black 38 * Ali Saidi 39 */ 40 41#include "arch/arm/isa.hh" 42 43namespace ArmISA 44{ 45 46void 47ISA::clear() 48{ 49 SCTLR sctlr_rst = miscRegs[MISCREG_SCTLR_RST]; 50 51 memset(miscRegs, 0, sizeof(miscRegs)); 52 CPSR cpsr = 0; 53 cpsr.mode = MODE_USER; 54 miscRegs[MISCREG_CPSR] = cpsr; 55 updateRegMap(cpsr); 56 57 SCTLR sctlr = 0; 58 sctlr.nmfi = (bool)sctlr_rst.nmfi; 59 sctlr.v = (bool)sctlr_rst.v; 60 sctlr.u = 1; 61 sctlr.xp = 1; 62 sctlr.rao2 = 1; 63 sctlr.rao3 = 1; 64 sctlr.rao4 = 1; 65 miscRegs[MISCREG_SCTLR] = sctlr; 66 miscRegs[MISCREG_SCTLR_RST] = sctlr_rst; 67 68 69 /* 70 * Technically this should be 0, but we don't support those 71 * settings. 72 */ 73 CPACR cpacr = 0; 74 // Enable CP 10, 11 75 cpacr.cp10 = 0x3; 76 cpacr.cp11 = 0x3; 77 miscRegs[MISCREG_CPACR] = cpacr; 78 79 /* Start with an event in the mailbox */ 80 miscRegs[MISCREG_SEV_MAILBOX] = 1; 81 82 /* 83 * Implemented = '5' from "M5", 84 * Variant = 0, 85 */ 86 miscRegs[MISCREG_MIDR] = 87 (0x35 << 24) | //Implementor is '5' from "M5" 88 (0 << 20) | //Variant 89 (0xf << 16) | //Architecture from CPUID scheme 90 (0 << 4) | //Primary part number 91 (0 << 0) | //Revision 92 0; 93 94 // Separate Instruction and Data TLBs. 95 miscRegs[MISCREG_TLBTR] = 1; 96 97 MVFR0 mvfr0 = 0; 98 mvfr0.advSimdRegisters = 2; 99 mvfr0.singlePrecision = 2; 100 mvfr0.doublePrecision = 2; 101 mvfr0.vfpExceptionTrapping = 0; 102 mvfr0.divide = 1; 103 mvfr0.squareRoot = 1; 104 mvfr0.shortVectors = 1; 105 mvfr0.roundingModes = 1; 106 miscRegs[MISCREG_MVFR0] = mvfr0; 107 108 MVFR1 mvfr1 = 0; 109 mvfr1.flushToZero = 1; 110 mvfr1.defaultNaN = 1; 111 mvfr1.advSimdLoadStore = 1; 112 mvfr1.advSimdInteger = 1; 113 mvfr1.advSimdSinglePrecision = 1; 114 mvfr1.advSimdHalfPrecision = 1; 115 mvfr1.vfpHalfPrecision = 1; 116 miscRegs[MISCREG_MVFR1] = mvfr1; 117 118 miscRegs[MISCREG_MPIDR] = 0; 119 120 //XXX We need to initialize the rest of the state. 121} 122 123MiscReg 124ISA::readMiscRegNoEffect(int misc_reg) 125{ 126 assert(misc_reg < NumMiscRegs); 127 if (misc_reg == MISCREG_SPSR) { 128 CPSR cpsr = miscRegs[MISCREG_CPSR]; 129 switch (cpsr.mode) { 130 case MODE_USER: 131 return miscRegs[MISCREG_SPSR]; 132 case MODE_FIQ: 133 return miscRegs[MISCREG_SPSR_FIQ]; 134 case MODE_IRQ: 135 return miscRegs[MISCREG_SPSR_IRQ]; 136 case MODE_SVC: 137 return miscRegs[MISCREG_SPSR_SVC]; 138 case MODE_MON: 139 return miscRegs[MISCREG_SPSR_MON]; 140 case MODE_ABORT: 141 return miscRegs[MISCREG_SPSR_ABT]; 142 case MODE_UNDEFINED: 143 return miscRegs[MISCREG_SPSR_UND]; 144 default: 145 return miscRegs[MISCREG_SPSR]; 146 } 147 } 148 return miscRegs[misc_reg]; 149} 150 151 152MiscReg 153ISA::readMiscReg(int misc_reg, ThreadContext *tc) 154{ 155 if (misc_reg == MISCREG_CPSR) { 156 CPSR cpsr = miscRegs[misc_reg]; 157 Addr pc = tc->readPC(); 158 if (pc & (ULL(1) << PcJBitShift)) 159 cpsr.j = 1; 160 else 161 cpsr.j = 0; 162 if (pc & (ULL(1) << PcTBitShift)) 163 cpsr.t = 1; 164 else 165 cpsr.t = 0; 166 return cpsr; 167 } 168 if (misc_reg >= MISCREG_CP15_UNIMP_START && 169 misc_reg < MISCREG_CP15_END) { 170 panic("Unimplemented CP15 register %s read.\n", 171 miscRegName[misc_reg]); 172 } 173 switch (misc_reg) { 174 case MISCREG_CLIDR: 175 warn("The clidr register always reports 0 caches.\n"); 176 break; 177 case MISCREG_CCSIDR: 178 warn("The ccsidr register isn't implemented and " 179 "always reads as 0.\n"); 180 break; 181 case MISCREG_ID_PFR0: 182 return 0x1031; // ThumbEE | !Jazelle | Thumb | ARM 183 } 184 return readMiscRegNoEffect(misc_reg); 185} 186 187void 188ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val) 189{ 190 assert(misc_reg < NumMiscRegs); 191 if (misc_reg == MISCREG_SPSR) { 192 CPSR cpsr = miscRegs[MISCREG_CPSR]; 193 switch (cpsr.mode) { 194 case MODE_USER: 195 miscRegs[MISCREG_SPSR] = val; 196 return; 197 case MODE_FIQ: 198 miscRegs[MISCREG_SPSR_FIQ] = val; 199 return; 200 case MODE_IRQ: 201 miscRegs[MISCREG_SPSR_IRQ] = val; 202 return; 203 case MODE_SVC: 204 miscRegs[MISCREG_SPSR_SVC] = val; 205 return; 206 case MODE_MON: 207 miscRegs[MISCREG_SPSR_MON] = val; 208 return; 209 case MODE_ABORT: 210 miscRegs[MISCREG_SPSR_ABT] = val; 211 return; 212 case MODE_UNDEFINED: 213 miscRegs[MISCREG_SPSR_UND] = val; 214 return; 215 default: 216 miscRegs[MISCREG_SPSR] = val; 217 return; 218 } 219 } 220 miscRegs[misc_reg] = val; 221} 222 223void 224ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) 225{ 226 MiscReg newVal = val; 227 if (misc_reg == MISCREG_CPSR) { 228 updateRegMap(val); 229 CPSR cpsr = val; 230 DPRINTF(Arm, "Updating CPSR to %#x f:%d i:%d a:%d mode:%#x\n", 231 cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode); 232 Addr npc = tc->readNextPC() & ~PcModeMask; 233 if (cpsr.j) 234 npc = npc | (ULL(1) << PcJBitShift); 235 if (cpsr.t) 236 npc = npc | (ULL(1) << PcTBitShift); 237 238 tc->setNextPC(npc); 239 } else if (misc_reg >= MISCREG_CP15_UNIMP_START && 240 misc_reg < MISCREG_CP15_END) { 241 panic("Unimplemented CP15 register %s wrote with %#x.\n", 242 miscRegName[misc_reg], val); 243 } else { 244 switch (misc_reg) { 245 case MISCREG_ITSTATE: 246 { 247 ITSTATE itstate = newVal; 248 CPSR cpsr = miscRegs[MISCREG_CPSR]; 249 cpsr.it1 = itstate.bottom2; 250 cpsr.it2 = itstate.top6; 251 miscRegs[MISCREG_CPSR] = cpsr; 252 DPRINTF(MiscRegs, 253 "Updating ITSTATE -> %#x in CPSR -> %#x.\n", 254 (uint8_t)itstate, (uint32_t)cpsr); 255 } 256 break; 257 case MISCREG_CPACR: 258 { 259 CPACR newCpacr = 0; 260 CPACR valCpacr = val; 261 newCpacr.cp10 = valCpacr.cp10; 262 newCpacr.cp11 = valCpacr.cp11; 263 if (newCpacr.cp10 != 0x3 || newCpacr.cp11 != 3) { 264 panic("Disabling coprocessors isn't implemented.\n"); 265 } 266 newVal = newCpacr; 267 } 268 break; 269 case MISCREG_CSSELR: 270 warn("The csselr register isn't implemented.\n"); 271 break; 272 case MISCREG_FPSCR: 273 { 274 const uint32_t ones = (uint32_t)(-1); 275 FPSCR fpscrMask = 0; 276 fpscrMask.ioc = ones; 277 fpscrMask.dzc = ones; 278 fpscrMask.ofc = ones; 279 fpscrMask.ufc = ones; 280 fpscrMask.ixc = ones; 281 fpscrMask.idc = ones; 282 fpscrMask.len = ones; 283 fpscrMask.stride = ones; 284 fpscrMask.rMode = ones; 285 fpscrMask.fz = ones; 286 fpscrMask.dn = ones; 287 fpscrMask.ahp = ones; 288 fpscrMask.qc = ones; 289 fpscrMask.v = ones; 290 fpscrMask.c = ones; 291 fpscrMask.z = ones; 292 fpscrMask.n = ones; 293 newVal = (newVal & (uint32_t)fpscrMask) | 294 (miscRegs[MISCREG_FPSCR] & ~(uint32_t)fpscrMask); 295 } 296 break; 297 case MISCREG_FPEXC: 298 { 299 const uint32_t fpexcMask = 0x60000000; 300 newVal = (newVal & fpexcMask) | 301 (miscRegs[MISCREG_FPEXC] & ~fpexcMask); 302 } 303 break; 304 case MISCREG_SCTLR: 305 { 306 DPRINTF(MiscRegs, "Writing SCTLR: %#x\n", newVal); 307 SCTLR sctlr = miscRegs[MISCREG_SCTLR]; 308 SCTLR new_sctlr = newVal; 309 new_sctlr.nmfi = (bool)sctlr.nmfi; 310 miscRegs[MISCREG_SCTLR] = (MiscReg)new_sctlr; 311 return; 312 } 313 case MISCREG_TLBTR: 314 case MISCREG_MVFR0: 315 case MISCREG_MVFR1: 316 case MISCREG_MPIDR: 317 case MISCREG_FPSID: 318 return; 319 case MISCREG_TLBIALLIS: 320 case MISCREG_TLBIALL: 321 warn("Need to flush all TLBs in MP\n"); 322 tc->getITBPtr()->flushAll(); 323 tc->getDTBPtr()->flushAll(); 324 return; 325 case MISCREG_ITLBIALL: 326 tc->getITBPtr()->flushAll(); 327 return; 328 case MISCREG_DTLBIALL: 329 tc->getDTBPtr()->flushAll(); 330 return; 331 case MISCREG_TLBIMVAIS: 332 case MISCREG_TLBIMVA: 333 warn("Need to flush all TLBs in MP\n"); 334 tc->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12), 335 bits(newVal, 7,0)); 336 tc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12), 337 bits(newVal, 7,0)); 338 return; 339 case MISCREG_TLBIASIDIS: 340 case MISCREG_TLBIASID: 341 warn("Need to flush all TLBs in MP\n"); 342 tc->getITBPtr()->flushAsid(bits(newVal, 7,0)); 343 tc->getDTBPtr()->flushAsid(bits(newVal, 7,0)); 344 return; 345 case MISCREG_TLBIMVAAIS: 346 case MISCREG_TLBIMVAA: 347 warn("Need to flush all TLBs in MP\n"); 348 tc->getITBPtr()->flushMva(mbits(newVal, 31,12)); 349 tc->getDTBPtr()->flushMva(mbits(newVal, 31,12)); 350 return; 351 case MISCREG_ITLBIMVA: 352 tc->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12), 353 bits(newVal, 7,0)); 354 return; 355 case MISCREG_DTLBIMVA: 356 tc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12), 357 bits(newVal, 7,0)); 358 return; 359 case MISCREG_ITLBIASID: 360 tc->getITBPtr()->flushAsid(bits(newVal, 7,0)); 361 return; 362 case MISCREG_DTLBIASID: 363 tc->getDTBPtr()->flushAsid(bits(newVal, 7,0)); 364 return; 365 } 366 } 367 setMiscRegNoEffect(misc_reg, newVal); 368} 369 370} 371