Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1 | /* |
| 2 | * QEMU ARM CPU |
| 3 | * |
| 4 | * Copyright (c) 2012 SUSE LINUX Products GmbH |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License |
| 8 | * as published by the Free Software Foundation; either version 2 |
| 9 | * of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program; if not, see |
| 18 | * <http://www.gnu.org/licenses/gpl-2.0.html> |
| 19 | */ |
| 20 | |
Peter Maydell | 74c21bd | 2015-12-07 16:23:44 +0000 | [diff] [blame] | 21 | #include "qemu/osdep.h" |
Peter Maydell | 181962f | 2018-03-02 10:45:36 +0000 | [diff] [blame] | 22 | #include "target/arm/idau.h" |
Wei Huang | 929e754 | 2016-10-28 14:12:31 +0100 | [diff] [blame] | 23 | #include "qemu/error-report.h" |
Markus Armbruster | da34e65 | 2016-03-14 09:01:28 +0100 | [diff] [blame] | 24 | #include "qapi/error.h" |
Andreas Färber | 778c3a0 | 2012-04-20 07:39:14 +0000 | [diff] [blame] | 25 | #include "cpu.h" |
Peter Maydell | ccd3808 | 2014-04-15 19:18:37 +0100 | [diff] [blame] | 26 | #include "internals.h" |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 27 | #include "qemu-common.h" |
Paolo Bonzini | 63c9155 | 2016-03-15 13:18:37 +0100 | [diff] [blame] | 28 | #include "exec/exec-all.h" |
Peter Maydell | 5de1643 | 2013-11-22 17:17:13 +0000 | [diff] [blame] | 29 | #include "hw/qdev-properties.h" |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 30 | #if !defined(CONFIG_USER_ONLY) |
| 31 | #include "hw/loader.h" |
| 32 | #endif |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 33 | #include "hw/arm/arm.h" |
Paolo Bonzini | 9c17d61 | 2012-12-17 18:20:04 +0100 | [diff] [blame] | 34 | #include "sysemu/sysemu.h" |
Vincent Palatin | b394662 | 2017-01-10 11:59:55 +0100 | [diff] [blame] | 35 | #include "sysemu/hw_accel.h" |
Paolo Bonzini | 50a2c6e | 2013-03-20 13:11:56 +0100 | [diff] [blame] | 36 | #include "kvm_arm.h" |
Richard Henderson | 110f6c7 | 2017-09-14 09:51:06 -0700 | [diff] [blame] | 37 | #include "disas/capstone.h" |
Alex Bennée | 24f91e8 | 2018-01-19 18:24:22 +0000 | [diff] [blame] | 38 | #include "fpu/softfloat.h" |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 39 | |
Andreas Färber | f45748f | 2013-06-21 19:09:18 +0200 | [diff] [blame] | 40 | static void arm_cpu_set_pc(CPUState *cs, vaddr value) |
| 41 | { |
| 42 | ARMCPU *cpu = ARM_CPU(cs); |
| 43 | |
| 44 | cpu->env.regs[15] = value; |
| 45 | } |
| 46 | |
Andreas Färber | 8c2e1b0 | 2013-08-25 18:53:55 +0200 | [diff] [blame] | 47 | static bool arm_cpu_has_work(CPUState *cs) |
| 48 | { |
Rob Herring | 543486d | 2014-10-24 12:19:12 +0100 | [diff] [blame] | 49 | ARMCPU *cpu = ARM_CPU(cs); |
| 50 | |
Alex Bennée | 062ba09 | 2017-02-23 18:29:23 +0000 | [diff] [blame] | 51 | return (cpu->power_state != PSCI_OFF) |
Rob Herring | 543486d | 2014-10-24 12:19:12 +0100 | [diff] [blame] | 52 | && cs->interrupt_request & |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 53 | (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD |
| 54 | | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ |
| 55 | | CPU_INTERRUPT_EXITTB); |
Andreas Färber | 8c2e1b0 | 2013-08-25 18:53:55 +0200 | [diff] [blame] | 56 | } |
| 57 | |
Aaron Lindsay | b5c53d1 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 58 | void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, |
| 59 | void *opaque) |
| 60 | { |
| 61 | ARMELChangeHook *entry = g_new0(ARMELChangeHook, 1); |
| 62 | |
| 63 | entry->hook = hook; |
| 64 | entry->opaque = opaque; |
| 65 | |
| 66 | QLIST_INSERT_HEAD(&cpu->pre_el_change_hooks, entry, node); |
| 67 | } |
| 68 | |
Aaron Lindsay | 0826748 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 69 | void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, |
Peter Maydell | bd7d00f | 2016-06-17 15:23:46 +0100 | [diff] [blame] | 70 | void *opaque) |
| 71 | { |
Aaron Lindsay | 0826748 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 72 | ARMELChangeHook *entry = g_new0(ARMELChangeHook, 1); |
| 73 | |
| 74 | entry->hook = hook; |
| 75 | entry->opaque = opaque; |
| 76 | |
| 77 | QLIST_INSERT_HEAD(&cpu->el_change_hooks, entry, node); |
Peter Maydell | bd7d00f | 2016-06-17 15:23:46 +0100 | [diff] [blame] | 78 | } |
| 79 | |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 80 | static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) |
| 81 | { |
| 82 | /* Reset a single ARMCPRegInfo register */ |
| 83 | ARMCPRegInfo *ri = value; |
| 84 | ARMCPU *cpu = opaque; |
| 85 | |
Sergey Fedorov | b061a82 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 86 | if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS)) { |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 87 | return; |
| 88 | } |
| 89 | |
| 90 | if (ri->resetfn) { |
| 91 | ri->resetfn(&cpu->env, ri); |
| 92 | return; |
| 93 | } |
| 94 | |
| 95 | /* A zero offset is never possible as it would be regs[0] |
| 96 | * so we use it to indicate that reset is being handled elsewhere. |
| 97 | * This is basically only used for fields in non-core coprocessors |
| 98 | * (like the pxa2xx ones). |
| 99 | */ |
| 100 | if (!ri->fieldoffset) { |
| 101 | return; |
| 102 | } |
| 103 | |
Peter Maydell | 67ed771 | 2014-02-26 17:20:01 +0000 | [diff] [blame] | 104 | if (cpreg_field_is_64bit(ri)) { |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 105 | CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue; |
| 106 | } else { |
| 107 | CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue; |
| 108 | } |
| 109 | } |
| 110 | |
Peter Maydell | 49a6619 | 2015-08-13 11:26:21 +0100 | [diff] [blame] | 111 | static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque) |
| 112 | { |
| 113 | /* Purely an assertion check: we've already done reset once, |
| 114 | * so now check that running the reset for the cpreg doesn't |
| 115 | * change its value. This traps bugs where two different cpregs |
| 116 | * both try to reset the same state field but to different values. |
| 117 | */ |
| 118 | ARMCPRegInfo *ri = value; |
| 119 | ARMCPU *cpu = opaque; |
| 120 | uint64_t oldvalue, newvalue; |
| 121 | |
| 122 | if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) { |
| 123 | return; |
| 124 | } |
| 125 | |
| 126 | oldvalue = read_raw_cp_reg(&cpu->env, ri); |
| 127 | cp_reg_reset(key, value, opaque); |
| 128 | newvalue = read_raw_cp_reg(&cpu->env, ri); |
| 129 | assert(oldvalue == newvalue); |
| 130 | } |
| 131 | |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 132 | /* CPUClass::reset() */ |
| 133 | static void arm_cpu_reset(CPUState *s) |
| 134 | { |
| 135 | ARMCPU *cpu = ARM_CPU(s); |
| 136 | ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 137 | CPUARMState *env = &cpu->env; |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 138 | |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 139 | acc->parent_reset(s); |
| 140 | |
Alex Bennée | 1f5c00c | 2016-11-14 14:19:17 +0000 | [diff] [blame] | 141 | memset(env, 0, offsetof(CPUARMState, end_reset_fields)); |
| 142 | |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 143 | g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu); |
Peter Maydell | 49a6619 | 2015-08-13 11:26:21 +0100 | [diff] [blame] | 144 | g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu); |
| 145 | |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 146 | env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; |
| 147 | env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; |
| 148 | env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; |
Peter Maydell | a50c0f5 | 2014-04-15 19:18:44 +0100 | [diff] [blame] | 149 | env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2; |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 150 | |
Alex Bennée | 062ba09 | 2017-02-23 18:29:23 +0000 | [diff] [blame] | 151 | cpu->power_state = cpu->start_powered_off ? PSCI_OFF : PSCI_ON; |
Rob Herring | 543486d | 2014-10-24 12:19:12 +0100 | [diff] [blame] | 152 | s->halted = cpu->start_powered_off; |
| 153 | |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 154 | if (arm_feature(env, ARM_FEATURE_IWMMXT)) { |
| 155 | env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; |
| 156 | } |
| 157 | |
Alexander Graf | 3926cc8 | 2013-09-03 20:12:09 +0100 | [diff] [blame] | 158 | if (arm_feature(env, ARM_FEATURE_AARCH64)) { |
| 159 | /* 64 bit CPUs always start in 64 bit mode */ |
| 160 | env->aarch64 = 1; |
Peter Maydell | d356312 | 2013-12-17 19:42:30 +0000 | [diff] [blame] | 161 | #if defined(CONFIG_USER_ONLY) |
| 162 | env->pstate = PSTATE_MODE_EL0t; |
Peter Maydell | 14e5f10 | 2014-10-24 12:19:13 +0100 | [diff] [blame] | 163 | /* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */ |
Fabian Aggeler | 137feaa | 2014-12-11 12:07:50 +0000 | [diff] [blame] | 164 | env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE; |
Peter Maydell | 8c6afa6 | 2014-04-15 19:18:39 +0100 | [diff] [blame] | 165 | /* and to the FP/Neon instructions */ |
Sergey Fedorov | 7ebd5f2 | 2015-04-26 16:49:25 +0100 | [diff] [blame] | 166 | env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3); |
Peter Maydell | d356312 | 2013-12-17 19:42:30 +0000 | [diff] [blame] | 167 | #else |
Greg Bellows | 5097227 | 2015-02-05 13:37:22 +0000 | [diff] [blame] | 168 | /* Reset into the highest available EL */ |
| 169 | if (arm_feature(env, ARM_FEATURE_EL3)) { |
| 170 | env->pstate = PSTATE_MODE_EL3h; |
| 171 | } else if (arm_feature(env, ARM_FEATURE_EL2)) { |
| 172 | env->pstate = PSTATE_MODE_EL2h; |
| 173 | } else { |
| 174 | env->pstate = PSTATE_MODE_EL1h; |
| 175 | } |
Peter Maydell | 3933443 | 2014-04-15 19:18:48 +0100 | [diff] [blame] | 176 | env->pc = cpu->rvbar; |
Peter Maydell | d356312 | 2013-12-17 19:42:30 +0000 | [diff] [blame] | 177 | #endif |
Peter Maydell | 8c6afa6 | 2014-04-15 19:18:39 +0100 | [diff] [blame] | 178 | } else { |
| 179 | #if defined(CONFIG_USER_ONLY) |
| 180 | /* Userspace expects access to cp10 and cp11 for FP/Neon */ |
Sergey Fedorov | 7ebd5f2 | 2015-04-26 16:49:25 +0100 | [diff] [blame] | 181 | env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 4, 0xf); |
Peter Maydell | 8c6afa6 | 2014-04-15 19:18:39 +0100 | [diff] [blame] | 182 | #endif |
Alexander Graf | 3926cc8 | 2013-09-03 20:12:09 +0100 | [diff] [blame] | 183 | } |
| 184 | |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 185 | #if defined(CONFIG_USER_ONLY) |
| 186 | env->uncached_cpsr = ARM_CPU_MODE_USR; |
| 187 | /* For user mode we must enable access to coprocessors */ |
| 188 | env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; |
| 189 | if (arm_feature(env, ARM_FEATURE_IWMMXT)) { |
| 190 | env->cp15.c15_cpar = 3; |
| 191 | } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { |
| 192 | env->cp15.c15_cpar = 1; |
| 193 | } |
| 194 | #else |
| 195 | /* SVC mode with interrupts disabled. */ |
Peter Maydell | 4cc3561 | 2014-02-26 17:20:06 +0000 | [diff] [blame] | 196 | env->uncached_cpsr = ARM_CPU_MODE_SVC; |
| 197 | env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F; |
Michael Davidsaver | dc7abe4 | 2017-01-27 15:20:24 +0000 | [diff] [blame] | 198 | |
Peter Maydell | 531c60a | 2017-01-27 15:20:22 +0000 | [diff] [blame] | 199 | if (arm_feature(env, ARM_FEATURE_M)) { |
Martin Galvan | 6e3cf5d | 2014-09-12 14:06:48 +0100 | [diff] [blame] | 200 | uint32_t initial_msp; /* Loaded from 0x0 */ |
| 201 | uint32_t initial_pc; /* Loaded from 0x4 */ |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 202 | uint8_t *rom; |
Peter Maydell | 38e2a77 | 2018-03-02 10:45:37 +0000 | [diff] [blame] | 203 | uint32_t vecbase; |
Martin Galvan | 6e3cf5d | 2014-09-12 14:06:48 +0100 | [diff] [blame] | 204 | |
Peter Maydell | 1e577cc | 2017-09-07 13:54:52 +0100 | [diff] [blame] | 205 | if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { |
| 206 | env->v7m.secure = true; |
Peter Maydell | 3b2e934 | 2017-09-12 19:13:52 +0100 | [diff] [blame] | 207 | } else { |
| 208 | /* This bit resets to 0 if security is supported, but 1 if |
| 209 | * it is not. The bit is not present in v7M, but we set it |
| 210 | * here so we can avoid having to make checks on it conditional |
| 211 | * on ARM_FEATURE_V8 (we don't let the guest see the bit). |
| 212 | */ |
| 213 | env->v7m.aircr = R_V7M_AIRCR_BFHFNMINS_MASK; |
Peter Maydell | 1e577cc | 2017-09-07 13:54:52 +0100 | [diff] [blame] | 214 | } |
| 215 | |
Peter Maydell | 9d40cd8 | 2017-09-07 13:54:54 +0100 | [diff] [blame] | 216 | /* In v7M the reset value of this bit is IMPDEF, but ARM recommends |
Peter Maydell | 2c4da50 | 2017-01-27 15:20:23 +0000 | [diff] [blame] | 217 | * that it resets to 1, so QEMU always does that rather than making |
Peter Maydell | 9d40cd8 | 2017-09-07 13:54:54 +0100 | [diff] [blame] | 218 | * it dependent on CPU model. In v8M it is RES1. |
Peter Maydell | 2c4da50 | 2017-01-27 15:20:23 +0000 | [diff] [blame] | 219 | */ |
Peter Maydell | 9d40cd8 | 2017-09-07 13:54:54 +0100 | [diff] [blame] | 220 | env->v7m.ccr[M_REG_NS] = R_V7M_CCR_STKALIGN_MASK; |
| 221 | env->v7m.ccr[M_REG_S] = R_V7M_CCR_STKALIGN_MASK; |
| 222 | if (arm_feature(env, ARM_FEATURE_V8)) { |
| 223 | /* in v8M the NONBASETHRDENA bit [0] is RES1 */ |
| 224 | env->v7m.ccr[M_REG_NS] |= R_V7M_CCR_NONBASETHRDENA_MASK; |
| 225 | env->v7m.ccr[M_REG_S] |= R_V7M_CCR_NONBASETHRDENA_MASK; |
| 226 | } |
Peter Maydell | 2c4da50 | 2017-01-27 15:20:23 +0000 | [diff] [blame] | 227 | |
Peter Maydell | 056f43d | 2017-01-27 15:20:24 +0000 | [diff] [blame] | 228 | /* Unlike A/R profile, M profile defines the reset LR value */ |
| 229 | env->regs[14] = 0xffffffff; |
| 230 | |
Peter Maydell | 38e2a77 | 2018-03-02 10:45:37 +0000 | [diff] [blame] | 231 | env->v7m.vecbase[M_REG_S] = cpu->init_svtor & 0xffffff80; |
| 232 | |
| 233 | /* Load the initial SP and PC from offset 0 and 4 in the vector table */ |
| 234 | vecbase = env->v7m.vecbase[env->v7m.secure]; |
| 235 | rom = rom_ptr(vecbase); |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 236 | if (rom) { |
Martin Galvan | 6e3cf5d | 2014-09-12 14:06:48 +0100 | [diff] [blame] | 237 | /* Address zero is covered by ROM which hasn't yet been |
| 238 | * copied into physical memory. |
| 239 | */ |
| 240 | initial_msp = ldl_p(rom); |
| 241 | initial_pc = ldl_p(rom + 4); |
| 242 | } else { |
| 243 | /* Address zero not covered by a ROM blob, or the ROM blob |
| 244 | * is in non-modifiable memory and this is a second reset after |
| 245 | * it got copied into memory. In the latter case, rom_ptr |
| 246 | * will return a NULL pointer and we should use ldl_phys instead. |
| 247 | */ |
Peter Maydell | 38e2a77 | 2018-03-02 10:45:37 +0000 | [diff] [blame] | 248 | initial_msp = ldl_phys(s->as, vecbase); |
| 249 | initial_pc = ldl_phys(s->as, vecbase + 4); |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 250 | } |
Martin Galvan | 6e3cf5d | 2014-09-12 14:06:48 +0100 | [diff] [blame] | 251 | |
| 252 | env->regs[13] = initial_msp & 0xFFFFFFFC; |
| 253 | env->regs[15] = initial_pc & ~1; |
| 254 | env->thumb = initial_pc & 1; |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 255 | } |
Antony Pavlov | 387f980 | 2013-12-17 19:42:29 +0000 | [diff] [blame] | 256 | |
Fabian Aggeler | 137feaa | 2014-12-11 12:07:50 +0000 | [diff] [blame] | 257 | /* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently |
| 258 | * executing as AArch32 then check if highvecs are enabled and |
| 259 | * adjust the PC accordingly. |
| 260 | */ |
| 261 | if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) { |
Martin Galvan | 34bf774 | 2014-09-12 14:06:48 +0100 | [diff] [blame] | 262 | env->regs[15] = 0xFFFF0000; |
Antony Pavlov | 387f980 | 2013-12-17 19:42:29 +0000 | [diff] [blame] | 263 | } |
| 264 | |
Peter Maydell | dc3c4c1 | 2017-09-14 18:43:16 +0100 | [diff] [blame] | 265 | /* M profile requires that reset clears the exclusive monitor; |
| 266 | * A profile does not, but clearing it makes more sense than having it |
| 267 | * set with an exclusive access on address zero. |
| 268 | */ |
| 269 | arm_clear_exclusive(env); |
| 270 | |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 271 | env->vfp.xregs[ARM_VFP_FPEXC] = 0; |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 272 | #endif |
Peter Maydell | 69ceea6 | 2017-07-27 11:59:09 +0100 | [diff] [blame] | 273 | |
Peter Maydell | 0e1a46b | 2017-09-07 13:54:51 +0100 | [diff] [blame] | 274 | if (arm_feature(env, ARM_FEATURE_PMSA)) { |
Peter Maydell | 69ceea6 | 2017-07-27 11:59:09 +0100 | [diff] [blame] | 275 | if (cpu->pmsav7_dregion > 0) { |
Peter Maydell | 0e1a46b | 2017-09-07 13:54:51 +0100 | [diff] [blame] | 276 | if (arm_feature(env, ARM_FEATURE_V8)) { |
Peter Maydell | 62c58ee | 2017-09-07 13:54:53 +0100 | [diff] [blame] | 277 | memset(env->pmsav8.rbar[M_REG_NS], 0, |
| 278 | sizeof(*env->pmsav8.rbar[M_REG_NS]) |
| 279 | * cpu->pmsav7_dregion); |
| 280 | memset(env->pmsav8.rlar[M_REG_NS], 0, |
| 281 | sizeof(*env->pmsav8.rlar[M_REG_NS]) |
| 282 | * cpu->pmsav7_dregion); |
| 283 | if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { |
| 284 | memset(env->pmsav8.rbar[M_REG_S], 0, |
| 285 | sizeof(*env->pmsav8.rbar[M_REG_S]) |
| 286 | * cpu->pmsav7_dregion); |
| 287 | memset(env->pmsav8.rlar[M_REG_S], 0, |
| 288 | sizeof(*env->pmsav8.rlar[M_REG_S]) |
| 289 | * cpu->pmsav7_dregion); |
| 290 | } |
Peter Maydell | 0e1a46b | 2017-09-07 13:54:51 +0100 | [diff] [blame] | 291 | } else if (arm_feature(env, ARM_FEATURE_V7)) { |
| 292 | memset(env->pmsav7.drbar, 0, |
| 293 | sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); |
| 294 | memset(env->pmsav7.drsr, 0, |
| 295 | sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion); |
| 296 | memset(env->pmsav7.dracr, 0, |
| 297 | sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion); |
| 298 | } |
Peter Maydell | 69ceea6 | 2017-07-27 11:59:09 +0100 | [diff] [blame] | 299 | } |
Peter Maydell | 1bc04a8 | 2017-09-07 13:54:53 +0100 | [diff] [blame] | 300 | env->pmsav7.rnr[M_REG_NS] = 0; |
| 301 | env->pmsav7.rnr[M_REG_S] = 0; |
Peter Maydell | 4125e6f | 2017-09-07 13:54:53 +0100 | [diff] [blame] | 302 | env->pmsav8.mair0[M_REG_NS] = 0; |
| 303 | env->pmsav8.mair0[M_REG_S] = 0; |
| 304 | env->pmsav8.mair1[M_REG_NS] = 0; |
| 305 | env->pmsav8.mair1[M_REG_S] = 0; |
Peter Maydell | 69ceea6 | 2017-07-27 11:59:09 +0100 | [diff] [blame] | 306 | } |
| 307 | |
Peter Maydell | 9901c57 | 2017-10-06 16:46:49 +0100 | [diff] [blame] | 308 | if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { |
| 309 | if (cpu->sau_sregion > 0) { |
| 310 | memset(env->sau.rbar, 0, sizeof(*env->sau.rbar) * cpu->sau_sregion); |
| 311 | memset(env->sau.rlar, 0, sizeof(*env->sau.rlar) * cpu->sau_sregion); |
| 312 | } |
| 313 | env->sau.rnr = 0; |
| 314 | /* SAU_CTRL reset value is IMPDEF; we choose 0, which is what |
| 315 | * the Cortex-M33 does. |
| 316 | */ |
| 317 | env->sau.ctrl = 0; |
| 318 | } |
| 319 | |
Peter Maydell | 3c30dd5 | 2012-04-20 17:58:36 +0000 | [diff] [blame] | 320 | set_flush_to_zero(1, &env->vfp.standard_fp_status); |
| 321 | set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); |
| 322 | set_default_nan_mode(1, &env->vfp.standard_fp_status); |
| 323 | set_float_detect_tininess(float_tininess_before_rounding, |
| 324 | &env->vfp.fp_status); |
| 325 | set_float_detect_tininess(float_tininess_before_rounding, |
| 326 | &env->vfp.standard_fp_status); |
Paolo Bonzini | 50a2c6e | 2013-03-20 13:11:56 +0100 | [diff] [blame] | 327 | #ifndef CONFIG_USER_ONLY |
| 328 | if (kvm_enabled()) { |
| 329 | kvm_arm_reset_vcpu(cpu); |
| 330 | } |
| 331 | #endif |
Peter Maydell | 9ee98ce | 2014-09-12 14:06:49 +0100 | [diff] [blame] | 332 | |
Peter Maydell | 46747d1 | 2014-09-29 18:48:46 +0100 | [diff] [blame] | 333 | hw_breakpoint_update_all(cpu); |
Peter Maydell | 9ee98ce | 2014-09-12 14:06:49 +0100 | [diff] [blame] | 334 | hw_watchpoint_update_all(cpu); |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 335 | } |
| 336 | |
Richard Henderson | e892571 | 2014-09-13 09:45:25 -0700 | [diff] [blame] | 337 | bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) |
| 338 | { |
| 339 | CPUClass *cc = CPU_GET_CLASS(cs); |
Greg Bellows | 012a906 | 2015-05-29 11:28:51 +0100 | [diff] [blame] | 340 | CPUARMState *env = cs->env_ptr; |
| 341 | uint32_t cur_el = arm_current_el(env); |
| 342 | bool secure = arm_is_secure(env); |
| 343 | uint32_t target_el; |
| 344 | uint32_t excp_idx; |
Richard Henderson | e892571 | 2014-09-13 09:45:25 -0700 | [diff] [blame] | 345 | bool ret = false; |
| 346 | |
Greg Bellows | 012a906 | 2015-05-29 11:28:51 +0100 | [diff] [blame] | 347 | if (interrupt_request & CPU_INTERRUPT_FIQ) { |
| 348 | excp_idx = EXCP_FIQ; |
| 349 | target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure); |
| 350 | if (arm_excp_unmasked(cs, excp_idx, target_el)) { |
| 351 | cs->exception_index = excp_idx; |
| 352 | env->exception.target_el = target_el; |
| 353 | cc->do_interrupt(cs); |
| 354 | ret = true; |
| 355 | } |
Richard Henderson | e892571 | 2014-09-13 09:45:25 -0700 | [diff] [blame] | 356 | } |
Greg Bellows | 012a906 | 2015-05-29 11:28:51 +0100 | [diff] [blame] | 357 | if (interrupt_request & CPU_INTERRUPT_HARD) { |
| 358 | excp_idx = EXCP_IRQ; |
| 359 | target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure); |
| 360 | if (arm_excp_unmasked(cs, excp_idx, target_el)) { |
| 361 | cs->exception_index = excp_idx; |
| 362 | env->exception.target_el = target_el; |
| 363 | cc->do_interrupt(cs); |
| 364 | ret = true; |
| 365 | } |
Richard Henderson | e892571 | 2014-09-13 09:45:25 -0700 | [diff] [blame] | 366 | } |
Greg Bellows | 012a906 | 2015-05-29 11:28:51 +0100 | [diff] [blame] | 367 | if (interrupt_request & CPU_INTERRUPT_VIRQ) { |
| 368 | excp_idx = EXCP_VIRQ; |
| 369 | target_el = 1; |
| 370 | if (arm_excp_unmasked(cs, excp_idx, target_el)) { |
| 371 | cs->exception_index = excp_idx; |
| 372 | env->exception.target_el = target_el; |
| 373 | cc->do_interrupt(cs); |
| 374 | ret = true; |
| 375 | } |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 376 | } |
Greg Bellows | 012a906 | 2015-05-29 11:28:51 +0100 | [diff] [blame] | 377 | if (interrupt_request & CPU_INTERRUPT_VFIQ) { |
| 378 | excp_idx = EXCP_VFIQ; |
| 379 | target_el = 1; |
| 380 | if (arm_excp_unmasked(cs, excp_idx, target_el)) { |
| 381 | cs->exception_index = excp_idx; |
| 382 | env->exception.target_el = target_el; |
| 383 | cc->do_interrupt(cs); |
| 384 | ret = true; |
| 385 | } |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 386 | } |
Richard Henderson | e892571 | 2014-09-13 09:45:25 -0700 | [diff] [blame] | 387 | |
| 388 | return ret; |
| 389 | } |
| 390 | |
Peter Maydell | b5c633c | 2014-10-30 15:48:51 +0000 | [diff] [blame] | 391 | #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) |
| 392 | static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) |
| 393 | { |
| 394 | CPUClass *cc = CPU_GET_CLASS(cs); |
| 395 | ARMCPU *cpu = ARM_CPU(cs); |
| 396 | CPUARMState *env = &cpu->env; |
| 397 | bool ret = false; |
| 398 | |
Peter Maydell | f4e8e4e | 2017-04-20 17:32:31 +0100 | [diff] [blame] | 399 | /* ARMv7-M interrupt masking works differently than -A or -R. |
Peter Maydell | 7ecdaa4 | 2017-02-28 12:08:17 +0000 | [diff] [blame] | 400 | * There is no FIQ/IRQ distinction. Instead of I and F bits |
| 401 | * masking FIQ and IRQ interrupts, an exception is taken only |
| 402 | * if it is higher priority than the current execution priority |
| 403 | * (which depends on state like BASEPRI, FAULTMASK and the |
| 404 | * currently active exception). |
Peter Maydell | b5c633c | 2014-10-30 15:48:51 +0000 | [diff] [blame] | 405 | */ |
| 406 | if (interrupt_request & CPU_INTERRUPT_HARD |
Peter Maydell | f4e8e4e | 2017-04-20 17:32:31 +0100 | [diff] [blame] | 407 | && (armv7m_nvic_can_take_pending_exception(env->nvic))) { |
Peter Maydell | b5c633c | 2014-10-30 15:48:51 +0000 | [diff] [blame] | 408 | cs->exception_index = EXCP_IRQ; |
| 409 | cc->do_interrupt(cs); |
| 410 | ret = true; |
| 411 | } |
| 412 | return ret; |
| 413 | } |
| 414 | #endif |
| 415 | |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 416 | #ifndef CONFIG_USER_ONLY |
| 417 | static void arm_cpu_set_irq(void *opaque, int irq, int level) |
| 418 | { |
| 419 | ARMCPU *cpu = opaque; |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 420 | CPUARMState *env = &cpu->env; |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 421 | CPUState *cs = CPU(cpu); |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 422 | static const int mask[] = { |
| 423 | [ARM_CPU_IRQ] = CPU_INTERRUPT_HARD, |
| 424 | [ARM_CPU_FIQ] = CPU_INTERRUPT_FIQ, |
| 425 | [ARM_CPU_VIRQ] = CPU_INTERRUPT_VIRQ, |
| 426 | [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ |
| 427 | }; |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 428 | |
| 429 | switch (irq) { |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 430 | case ARM_CPU_VIRQ: |
| 431 | case ARM_CPU_VFIQ: |
Peter Crosthwaite | f128bf2 | 2015-09-07 10:39:29 +0100 | [diff] [blame] | 432 | assert(arm_feature(env, ARM_FEATURE_EL2)); |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 433 | /* fall through */ |
| 434 | case ARM_CPU_IRQ: |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 435 | case ARM_CPU_FIQ: |
| 436 | if (level) { |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 437 | cpu_interrupt(cs, mask[irq]); |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 438 | } else { |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 439 | cpu_reset_interrupt(cs, mask[irq]); |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 440 | } |
| 441 | break; |
| 442 | default: |
Peter Crosthwaite | 8f6fd32 | 2015-09-07 10:39:29 +0100 | [diff] [blame] | 443 | g_assert_not_reached(); |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 444 | } |
| 445 | } |
| 446 | |
| 447 | static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level) |
| 448 | { |
| 449 | #ifdef CONFIG_KVM |
| 450 | ARMCPU *cpu = opaque; |
| 451 | CPUState *cs = CPU(cpu); |
| 452 | int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT; |
| 453 | |
| 454 | switch (irq) { |
| 455 | case ARM_CPU_IRQ: |
| 456 | kvm_irq |= KVM_ARM_IRQ_CPU_IRQ; |
| 457 | break; |
| 458 | case ARM_CPU_FIQ: |
| 459 | kvm_irq |= KVM_ARM_IRQ_CPU_FIQ; |
| 460 | break; |
| 461 | default: |
Peter Crosthwaite | 8f6fd32 | 2015-09-07 10:39:29 +0100 | [diff] [blame] | 462 | g_assert_not_reached(); |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 463 | } |
| 464 | kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT; |
| 465 | kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0); |
| 466 | #endif |
| 467 | } |
Pranavkumar Sawargaonkar | 84f2bed | 2015-02-05 13:37:25 +0000 | [diff] [blame] | 468 | |
Peter Crosthwaite | ed50ff7 | 2016-03-04 11:30:19 +0000 | [diff] [blame] | 469 | static bool arm_cpu_virtio_is_big_endian(CPUState *cs) |
Pranavkumar Sawargaonkar | 84f2bed | 2015-02-05 13:37:25 +0000 | [diff] [blame] | 470 | { |
| 471 | ARMCPU *cpu = ARM_CPU(cs); |
| 472 | CPUARMState *env = &cpu->env; |
Pranavkumar Sawargaonkar | 84f2bed | 2015-02-05 13:37:25 +0000 | [diff] [blame] | 473 | |
| 474 | cpu_synchronize_state(cs); |
Peter Crosthwaite | ed50ff7 | 2016-03-04 11:30:19 +0000 | [diff] [blame] | 475 | return arm_cpu_data_is_big_endian(env); |
Pranavkumar Sawargaonkar | 84f2bed | 2015-02-05 13:37:25 +0000 | [diff] [blame] | 476 | } |
| 477 | |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 478 | #endif |
| 479 | |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 480 | static inline void set_feature(CPUARMState *env, int feature) |
| 481 | { |
Peter Maydell | 918f5dc | 2012-07-12 10:59:06 +0000 | [diff] [blame] | 482 | env->features |= 1ULL << feature; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 483 | } |
| 484 | |
Greg Bellows | 0882848 | 2014-12-15 17:09:45 -0600 | [diff] [blame] | 485 | static inline void unset_feature(CPUARMState *env, int feature) |
| 486 | { |
| 487 | env->features &= ~(1ULL << feature); |
| 488 | } |
| 489 | |
Peter Crosthwaite | 4844062 | 2015-06-23 20:57:35 -0700 | [diff] [blame] | 490 | static int |
| 491 | print_insn_thumb1(bfd_vma pc, disassemble_info *info) |
| 492 | { |
| 493 | return print_insn_arm(pc | 1, info); |
| 494 | } |
| 495 | |
| 496 | static void arm_disas_set_info(CPUState *cpu, disassemble_info *info) |
| 497 | { |
| 498 | ARMCPU *ac = ARM_CPU(cpu); |
| 499 | CPUARMState *env = &ac->env; |
Richard Henderson | 7bcdbf5 | 2017-10-19 14:13:02 -0700 | [diff] [blame] | 500 | bool sctlr_b; |
Peter Crosthwaite | 4844062 | 2015-06-23 20:57:35 -0700 | [diff] [blame] | 501 | |
| 502 | if (is_a64(env)) { |
| 503 | /* We might not be compiled with the A64 disassembler |
| 504 | * because it needs a C++ compiler. Leave print_insn |
| 505 | * unset in this case to use the caller default behaviour. |
| 506 | */ |
| 507 | #if defined(CONFIG_ARM_A64_DIS) |
| 508 | info->print_insn = print_insn_arm_a64; |
| 509 | #endif |
Richard Henderson | 110f6c7 | 2017-09-14 09:51:06 -0700 | [diff] [blame] | 510 | info->cap_arch = CS_ARCH_ARM64; |
Richard Henderson | 15fa1a0 | 2017-11-07 13:19:18 +0100 | [diff] [blame] | 511 | info->cap_insn_unit = 4; |
| 512 | info->cap_insn_split = 4; |
Peter Crosthwaite | 4844062 | 2015-06-23 20:57:35 -0700 | [diff] [blame] | 513 | } else { |
Richard Henderson | 110f6c7 | 2017-09-14 09:51:06 -0700 | [diff] [blame] | 514 | int cap_mode; |
| 515 | if (env->thumb) { |
| 516 | info->print_insn = print_insn_thumb1; |
Richard Henderson | 15fa1a0 | 2017-11-07 13:19:18 +0100 | [diff] [blame] | 517 | info->cap_insn_unit = 2; |
| 518 | info->cap_insn_split = 4; |
Richard Henderson | 110f6c7 | 2017-09-14 09:51:06 -0700 | [diff] [blame] | 519 | cap_mode = CS_MODE_THUMB; |
| 520 | } else { |
| 521 | info->print_insn = print_insn_arm; |
Richard Henderson | 15fa1a0 | 2017-11-07 13:19:18 +0100 | [diff] [blame] | 522 | info->cap_insn_unit = 4; |
| 523 | info->cap_insn_split = 4; |
Richard Henderson | 110f6c7 | 2017-09-14 09:51:06 -0700 | [diff] [blame] | 524 | cap_mode = CS_MODE_ARM; |
| 525 | } |
| 526 | if (arm_feature(env, ARM_FEATURE_V8)) { |
| 527 | cap_mode |= CS_MODE_V8; |
| 528 | } |
| 529 | if (arm_feature(env, ARM_FEATURE_M)) { |
| 530 | cap_mode |= CS_MODE_MCLASS; |
| 531 | } |
| 532 | info->cap_arch = CS_ARCH_ARM; |
| 533 | info->cap_mode = cap_mode; |
Peter Crosthwaite | 4844062 | 2015-06-23 20:57:35 -0700 | [diff] [blame] | 534 | } |
Richard Henderson | 7bcdbf5 | 2017-10-19 14:13:02 -0700 | [diff] [blame] | 535 | |
| 536 | sctlr_b = arm_sctlr_b(env); |
| 537 | if (bswap_code(sctlr_b)) { |
Peter Crosthwaite | 4844062 | 2015-06-23 20:57:35 -0700 | [diff] [blame] | 538 | #ifdef TARGET_WORDS_BIGENDIAN |
| 539 | info->endian = BFD_ENDIAN_LITTLE; |
| 540 | #else |
| 541 | info->endian = BFD_ENDIAN_BIG; |
| 542 | #endif |
| 543 | } |
Julian Brown | f7478a9 | 2017-02-07 18:29:59 +0000 | [diff] [blame] | 544 | info->flags &= ~INSN_ARM_BE32; |
Richard Henderson | 7bcdbf5 | 2017-10-19 14:13:02 -0700 | [diff] [blame] | 545 | #ifndef CONFIG_USER_ONLY |
| 546 | if (sctlr_b) { |
Julian Brown | f7478a9 | 2017-02-07 18:29:59 +0000 | [diff] [blame] | 547 | info->flags |= INSN_ARM_BE32; |
| 548 | } |
Richard Henderson | 7bcdbf5 | 2017-10-19 14:13:02 -0700 | [diff] [blame] | 549 | #endif |
Peter Crosthwaite | 4844062 | 2015-06-23 20:57:35 -0700 | [diff] [blame] | 550 | } |
| 551 | |
Igor Mammedov | 46de591 | 2017-05-03 14:56:56 +0200 | [diff] [blame] | 552 | uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz) |
| 553 | { |
| 554 | uint32_t Aff1 = idx / clustersz; |
| 555 | uint32_t Aff0 = idx % clustersz; |
| 556 | return (Aff1 << ARM_AFF1_SHIFT) | Aff0; |
| 557 | } |
| 558 | |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 559 | static void arm_cpu_initfn(Object *obj) |
| 560 | { |
Andreas Färber | c05efcb | 2013-01-17 12:13:41 +0100 | [diff] [blame] | 561 | CPUState *cs = CPU(obj); |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 562 | ARMCPU *cpu = ARM_CPU(obj); |
| 563 | |
Andreas Färber | c05efcb | 2013-01-17 12:13:41 +0100 | [diff] [blame] | 564 | cs->env_ptr = &cpu->env; |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 565 | cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, |
| 566 | g_free, g_free); |
Andreas Färber | 79614b7 | 2013-01-19 07:37:45 +0100 | [diff] [blame] | 567 | |
Aaron Lindsay | b5c53d1 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 568 | QLIST_INIT(&cpu->pre_el_change_hooks); |
Aaron Lindsay | 0826748 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 569 | QLIST_INIT(&cpu->el_change_hooks); |
| 570 | |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 571 | #ifndef CONFIG_USER_ONLY |
| 572 | /* Our inbound IRQ and FIQ lines */ |
| 573 | if (kvm_enabled()) { |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 574 | /* VIRQ and VFIQ are unused with KVM but we add them to maintain |
| 575 | * the same interface as non-KVM CPUs. |
| 576 | */ |
| 577 | qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 4); |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 578 | } else { |
Edgar E. Iglesias | 136e67e | 2014-09-29 18:48:51 +0100 | [diff] [blame] | 579 | qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 4); |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 580 | } |
Peter Maydell | 55d284a | 2013-08-20 14:54:31 +0100 | [diff] [blame] | 581 | |
Alex Bligh | bc72ad6 | 2013-08-21 16:03:08 +0100 | [diff] [blame] | 582 | cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, |
Peter Maydell | 55d284a | 2013-08-20 14:54:31 +0100 | [diff] [blame] | 583 | arm_gt_ptimer_cb, cpu); |
Alex Bligh | bc72ad6 | 2013-08-21 16:03:08 +0100 | [diff] [blame] | 584 | cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, |
Peter Maydell | 55d284a | 2013-08-20 14:54:31 +0100 | [diff] [blame] | 585 | arm_gt_vtimer_cb, cpu); |
Edgar E. Iglesias | b0e66d9 | 2015-08-13 11:26:18 +0100 | [diff] [blame] | 586 | cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, |
| 587 | arm_gt_htimer_cb, cpu); |
Peter Maydell | b4d3978 | 2015-08-13 11:26:22 +0100 | [diff] [blame] | 588 | cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE, |
| 589 | arm_gt_stimer_cb, cpu); |
Peter Maydell | 55d284a | 2013-08-20 14:54:31 +0100 | [diff] [blame] | 590 | qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs, |
| 591 | ARRAY_SIZE(cpu->gt_timer_outputs)); |
Peter Maydell | aa1b311 | 2017-01-20 11:15:09 +0000 | [diff] [blame] | 592 | |
| 593 | qdev_init_gpio_out_named(DEVICE(cpu), &cpu->gicv3_maintenance_interrupt, |
| 594 | "gicv3-maintenance-interrupt", 1); |
Andrew Jones | 07f4873 | 2017-09-04 15:21:53 +0100 | [diff] [blame] | 595 | qdev_init_gpio_out_named(DEVICE(cpu), &cpu->pmu_interrupt, |
| 596 | "pmu-interrupt", 1); |
Peter Maydell | 7c1840b | 2013-08-20 14:54:28 +0100 | [diff] [blame] | 597 | #endif |
| 598 | |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 599 | /* DTB consumers generally don't in fact care what the 'compatible' |
| 600 | * string is, so always provide some string and trust that a hypothetical |
| 601 | * picky DTB consumer will also provide a helpful error message. |
| 602 | */ |
| 603 | cpu->dtb_compatible = "qemu,unknown"; |
Pranavkumar Sawargaonkar | dd032e3 | 2014-06-19 18:06:26 +0100 | [diff] [blame] | 604 | cpu->psci_version = 1; /* By default assume PSCI v0.1 */ |
Peter Maydell | 3541add | 2013-11-22 17:17:16 +0000 | [diff] [blame] | 605 | cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE; |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 606 | |
Rob Herring | 9812860 | 2014-10-24 12:19:13 +0100 | [diff] [blame] | 607 | if (tcg_enabled()) { |
| 608 | cpu->psci_version = 2; /* TCG implements PSCI 0.2 */ |
Andreas Färber | 79614b7 | 2013-01-19 07:37:45 +0100 | [diff] [blame] | 609 | } |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 610 | } |
| 611 | |
Peter Crosthwaite | 07a5b0d | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 612 | static Property arm_cpu_reset_cbar_property = |
Peter Maydell | f318cec | 2014-04-15 19:18:49 +0100 | [diff] [blame] | 613 | DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0); |
Peter Crosthwaite | 07a5b0d | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 614 | |
Antony Pavlov | 68e0a40 | 2013-12-17 19:42:29 +0000 | [diff] [blame] | 615 | static Property arm_cpu_reset_hivecs_property = |
| 616 | DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false); |
| 617 | |
Peter Maydell | 3933443 | 2014-04-15 19:18:48 +0100 | [diff] [blame] | 618 | static Property arm_cpu_rvbar_property = |
| 619 | DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0); |
| 620 | |
Peter Maydell | c25bd18 | 2017-01-20 11:15:10 +0000 | [diff] [blame] | 621 | static Property arm_cpu_has_el2_property = |
| 622 | DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true); |
| 623 | |
Greg Bellows | 51942ae | 2014-12-15 17:09:46 -0600 | [diff] [blame] | 624 | static Property arm_cpu_has_el3_property = |
| 625 | DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true); |
| 626 | |
Julian Brown | 3a062d5 | 2017-02-07 18:29:59 +0000 | [diff] [blame] | 627 | static Property arm_cpu_cfgend_property = |
| 628 | DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false); |
| 629 | |
Wei Huang | 929e754 | 2016-10-28 14:12:31 +0100 | [diff] [blame] | 630 | /* use property name "pmu" to match other archs and virt tools */ |
| 631 | static Property arm_cpu_has_pmu_property = |
| 632 | DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true); |
| 633 | |
Peter Crosthwaite | 8f325f5 | 2015-06-15 18:06:10 +0100 | [diff] [blame] | 634 | static Property arm_cpu_has_mpu_property = |
| 635 | DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true); |
| 636 | |
Peter Maydell | 8d92e26 | 2017-07-17 13:36:07 +0100 | [diff] [blame] | 637 | /* This is like DEFINE_PROP_UINT32 but it doesn't set the default value, |
| 638 | * because the CPU initfn will have already set cpu->pmsav7_dregion to |
| 639 | * the right value for that particular CPU type, and we don't want |
| 640 | * to override that with an incorrect constant value. |
| 641 | */ |
Peter Crosthwaite | 3281af8 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 642 | static Property arm_cpu_pmsav7_dregion_property = |
Peter Maydell | 8d92e26 | 2017-07-17 13:36:07 +0100 | [diff] [blame] | 643 | DEFINE_PROP_UNSIGNED_NODEFAULT("pmsav7-dregion", ARMCPU, |
| 644 | pmsav7_dregion, |
| 645 | qdev_prop_uint32, uint32_t); |
Peter Crosthwaite | 3281af8 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 646 | |
Peter Maydell | 38e2a77 | 2018-03-02 10:45:37 +0000 | [diff] [blame] | 647 | /* M profile: initial value of the Secure VTOR */ |
| 648 | static Property arm_cpu_initsvtor_property = |
| 649 | DEFINE_PROP_UINT32("init-svtor", ARMCPU, init_svtor, 0); |
| 650 | |
Peter Crosthwaite | 07a5b0d | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 651 | static void arm_cpu_post_init(Object *obj) |
| 652 | { |
| 653 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Crosthwaite | 07a5b0d | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 654 | |
Peter Maydell | 790a115 | 2017-06-02 11:51:48 +0100 | [diff] [blame] | 655 | /* M profile implies PMSA. We have to do this here rather than |
| 656 | * in realize with the other feature-implication checks because |
| 657 | * we look at the PMSA bit to see if we should add some properties. |
| 658 | */ |
| 659 | if (arm_feature(&cpu->env, ARM_FEATURE_M)) { |
| 660 | set_feature(&cpu->env, ARM_FEATURE_PMSA); |
| 661 | } |
| 662 | |
Peter Maydell | f318cec | 2014-04-15 19:18:49 +0100 | [diff] [blame] | 663 | if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) || |
| 664 | arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) { |
Peter Crosthwaite | 07a5b0d | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 665 | qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property, |
Peter Crosthwaite | 5433a0a | 2014-01-01 18:48:08 -0800 | [diff] [blame] | 666 | &error_abort); |
Peter Crosthwaite | 07a5b0d | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 667 | } |
Antony Pavlov | 68e0a40 | 2013-12-17 19:42:29 +0000 | [diff] [blame] | 668 | |
| 669 | if (!arm_feature(&cpu->env, ARM_FEATURE_M)) { |
| 670 | qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property, |
Peter Crosthwaite | 5433a0a | 2014-01-01 18:48:08 -0800 | [diff] [blame] | 671 | &error_abort); |
Antony Pavlov | 68e0a40 | 2013-12-17 19:42:29 +0000 | [diff] [blame] | 672 | } |
Peter Maydell | 3933443 | 2014-04-15 19:18:48 +0100 | [diff] [blame] | 673 | |
| 674 | if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { |
| 675 | qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property, |
| 676 | &error_abort); |
| 677 | } |
Greg Bellows | 51942ae | 2014-12-15 17:09:46 -0600 | [diff] [blame] | 678 | |
| 679 | if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) { |
| 680 | /* Add the has_el3 state CPU property only if EL3 is allowed. This will |
| 681 | * prevent "has_el3" from existing on CPUs which cannot support EL3. |
| 682 | */ |
| 683 | qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el3_property, |
| 684 | &error_abort); |
Peter Maydell | 9e273ef | 2016-01-21 14:15:06 +0000 | [diff] [blame] | 685 | |
| 686 | #ifndef CONFIG_USER_ONLY |
| 687 | object_property_add_link(obj, "secure-memory", |
| 688 | TYPE_MEMORY_REGION, |
| 689 | (Object **)&cpu->secure_memory, |
| 690 | qdev_prop_allow_set_link_before_realize, |
| 691 | OBJ_PROP_LINK_UNREF_ON_RELEASE, |
| 692 | &error_abort); |
| 693 | #endif |
Greg Bellows | 51942ae | 2014-12-15 17:09:46 -0600 | [diff] [blame] | 694 | } |
Peter Crosthwaite | 8f325f5 | 2015-06-15 18:06:10 +0100 | [diff] [blame] | 695 | |
Peter Maydell | c25bd18 | 2017-01-20 11:15:10 +0000 | [diff] [blame] | 696 | if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) { |
| 697 | qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el2_property, |
| 698 | &error_abort); |
| 699 | } |
| 700 | |
Wei Huang | 929e754 | 2016-10-28 14:12:31 +0100 | [diff] [blame] | 701 | if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) { |
| 702 | qdev_property_add_static(DEVICE(obj), &arm_cpu_has_pmu_property, |
| 703 | &error_abort); |
| 704 | } |
| 705 | |
Peter Maydell | 452a095 | 2017-06-02 11:51:47 +0100 | [diff] [blame] | 706 | if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) { |
Peter Crosthwaite | 8f325f5 | 2015-06-15 18:06:10 +0100 | [diff] [blame] | 707 | qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property, |
| 708 | &error_abort); |
Peter Crosthwaite | 3281af8 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 709 | if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { |
| 710 | qdev_property_add_static(DEVICE(obj), |
| 711 | &arm_cpu_pmsav7_dregion_property, |
| 712 | &error_abort); |
| 713 | } |
Peter Crosthwaite | 8f325f5 | 2015-06-15 18:06:10 +0100 | [diff] [blame] | 714 | } |
| 715 | |
Peter Maydell | 181962f | 2018-03-02 10:45:36 +0000 | [diff] [blame] | 716 | if (arm_feature(&cpu->env, ARM_FEATURE_M_SECURITY)) { |
| 717 | object_property_add_link(obj, "idau", TYPE_IDAU_INTERFACE, &cpu->idau, |
| 718 | qdev_prop_allow_set_link_before_realize, |
| 719 | OBJ_PROP_LINK_UNREF_ON_RELEASE, |
| 720 | &error_abort); |
Peter Maydell | 38e2a77 | 2018-03-02 10:45:37 +0000 | [diff] [blame] | 721 | qdev_property_add_static(DEVICE(obj), &arm_cpu_initsvtor_property, |
| 722 | &error_abort); |
Peter Maydell | 181962f | 2018-03-02 10:45:36 +0000 | [diff] [blame] | 723 | } |
| 724 | |
Julian Brown | 3a062d5 | 2017-02-07 18:29:59 +0000 | [diff] [blame] | 725 | qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property, |
| 726 | &error_abort); |
Peter Crosthwaite | 07a5b0d | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 727 | } |
| 728 | |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 729 | static void arm_cpu_finalizefn(Object *obj) |
| 730 | { |
| 731 | ARMCPU *cpu = ARM_CPU(obj); |
Aaron Lindsay | 0826748 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 732 | ARMELChangeHook *hook, *next; |
| 733 | |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 734 | g_hash_table_destroy(cpu->cp_regs); |
Aaron Lindsay | 0826748 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 735 | |
Aaron Lindsay | b5c53d1 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 736 | QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) { |
| 737 | QLIST_REMOVE(hook, node); |
| 738 | g_free(hook); |
| 739 | } |
Aaron Lindsay | 0826748 | 2018-04-26 11:04:39 +0100 | [diff] [blame] | 740 | QLIST_FOREACH_SAFE(hook, &cpu->el_change_hooks, node, next) { |
| 741 | QLIST_REMOVE(hook, node); |
| 742 | g_free(hook); |
| 743 | } |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 744 | } |
| 745 | |
Andreas Färber | 1496926 | 2013-01-05 10:18:18 +0100 | [diff] [blame] | 746 | static void arm_cpu_realizefn(DeviceState *dev, Error **errp) |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 747 | { |
Andreas Färber | 14a10fc | 2013-07-27 02:53:25 +0200 | [diff] [blame] | 748 | CPUState *cs = CPU(dev); |
Andreas Färber | 1496926 | 2013-01-05 10:18:18 +0100 | [diff] [blame] | 749 | ARMCPU *cpu = ARM_CPU(dev); |
| 750 | ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 751 | CPUARMState *env = &cpu->env; |
Peter Maydell | e97da98 | 2016-10-24 16:26:50 +0100 | [diff] [blame] | 752 | int pagebits; |
Laurent Vivier | ce5b1bb | 2016-10-20 13:26:03 +0200 | [diff] [blame] | 753 | Error *local_err = NULL; |
| 754 | |
Peter Maydell | c4487d7 | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 755 | /* If we needed to query the host kernel for the CPU features |
| 756 | * then it's possible that might have failed in the initfn, but |
| 757 | * this is the first point where we can report it. |
| 758 | */ |
| 759 | if (cpu->host_cpu_probe_failed) { |
| 760 | if (!kvm_enabled()) { |
| 761 | error_setg(errp, "The 'host' CPU type can only be used with KVM"); |
| 762 | } else { |
| 763 | error_setg(errp, "Failed to retrieve host CPU features"); |
| 764 | } |
| 765 | return; |
| 766 | } |
| 767 | |
Laurent Vivier | ce5b1bb | 2016-10-20 13:26:03 +0200 | [diff] [blame] | 768 | cpu_exec_realizefn(cs, &local_err); |
| 769 | if (local_err != NULL) { |
| 770 | error_propagate(errp, local_err); |
| 771 | return; |
| 772 | } |
Andreas Färber | 1496926 | 2013-01-05 10:18:18 +0100 | [diff] [blame] | 773 | |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 774 | /* Some features automatically imply others: */ |
Mans Rullgard | 81e69fb | 2013-07-15 14:35:25 +0100 | [diff] [blame] | 775 | if (arm_feature(env, ARM_FEATURE_V8)) { |
| 776 | set_feature(env, ARM_FEATURE_V7); |
| 777 | set_feature(env, ARM_FEATURE_ARM_DIV); |
| 778 | set_feature(env, ARM_FEATURE_LPAE); |
| 779 | } |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 780 | if (arm_feature(env, ARM_FEATURE_V7)) { |
| 781 | set_feature(env, ARM_FEATURE_VAPA); |
| 782 | set_feature(env, ARM_FEATURE_THUMB2); |
Peter Maydell | 81bdde9 | 2012-06-20 11:57:20 +0000 | [diff] [blame] | 783 | set_feature(env, ARM_FEATURE_MPIDR); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 784 | if (!arm_feature(env, ARM_FEATURE_M)) { |
| 785 | set_feature(env, ARM_FEATURE_V6K); |
| 786 | } else { |
| 787 | set_feature(env, ARM_FEATURE_V6); |
| 788 | } |
Cédric Le Goater | 91db464 | 2016-12-27 14:59:30 +0000 | [diff] [blame] | 789 | |
| 790 | /* Always define VBAR for V7 CPUs even if it doesn't exist in |
| 791 | * non-EL3 configs. This is needed by some legacy boards. |
| 792 | */ |
| 793 | set_feature(env, ARM_FEATURE_VBAR); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 794 | } |
| 795 | if (arm_feature(env, ARM_FEATURE_V6K)) { |
| 796 | set_feature(env, ARM_FEATURE_V6); |
| 797 | set_feature(env, ARM_FEATURE_MVFR); |
| 798 | } |
| 799 | if (arm_feature(env, ARM_FEATURE_V6)) { |
| 800 | set_feature(env, ARM_FEATURE_V5); |
Portia Stephens | c99a55d | 2017-09-07 13:54:55 +0100 | [diff] [blame] | 801 | set_feature(env, ARM_FEATURE_JAZELLE); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 802 | if (!arm_feature(env, ARM_FEATURE_M)) { |
| 803 | set_feature(env, ARM_FEATURE_AUXCR); |
| 804 | } |
| 805 | } |
| 806 | if (arm_feature(env, ARM_FEATURE_V5)) { |
| 807 | set_feature(env, ARM_FEATURE_V4T); |
| 808 | } |
| 809 | if (arm_feature(env, ARM_FEATURE_M)) { |
| 810 | set_feature(env, ARM_FEATURE_THUMB_DIV); |
| 811 | } |
| 812 | if (arm_feature(env, ARM_FEATURE_ARM_DIV)) { |
| 813 | set_feature(env, ARM_FEATURE_THUMB_DIV); |
| 814 | } |
| 815 | if (arm_feature(env, ARM_FEATURE_VFP4)) { |
| 816 | set_feature(env, ARM_FEATURE_VFP3); |
Peter Maydell | da5141f | 2014-06-09 15:43:25 +0100 | [diff] [blame] | 817 | set_feature(env, ARM_FEATURE_VFP_FP16); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 818 | } |
| 819 | if (arm_feature(env, ARM_FEATURE_VFP3)) { |
| 820 | set_feature(env, ARM_FEATURE_VFP); |
| 821 | } |
Peter Maydell | de9b05b | 2012-07-12 10:59:05 +0000 | [diff] [blame] | 822 | if (arm_feature(env, ARM_FEATURE_LPAE)) { |
Peter Maydell | bdcc150 | 2013-06-25 18:16:08 +0100 | [diff] [blame] | 823 | set_feature(env, ARM_FEATURE_V7MP); |
Peter Maydell | de9b05b | 2012-07-12 10:59:05 +0000 | [diff] [blame] | 824 | set_feature(env, ARM_FEATURE_PXN); |
| 825 | } |
Peter Maydell | f318cec | 2014-04-15 19:18:49 +0100 | [diff] [blame] | 826 | if (arm_feature(env, ARM_FEATURE_CBAR_RO)) { |
| 827 | set_feature(env, ARM_FEATURE_CBAR); |
| 828 | } |
Aurelio C. Remonda | 62b44f0 | 2015-06-15 18:06:09 +0100 | [diff] [blame] | 829 | if (arm_feature(env, ARM_FEATURE_THUMB2) && |
| 830 | !arm_feature(env, ARM_FEATURE_M)) { |
| 831 | set_feature(env, ARM_FEATURE_THUMB_DSP); |
| 832 | } |
Peter Maydell | 2ceb98c | 2012-06-20 11:57:09 +0000 | [diff] [blame] | 833 | |
Peter Maydell | e97da98 | 2016-10-24 16:26:50 +0100 | [diff] [blame] | 834 | if (arm_feature(env, ARM_FEATURE_V7) && |
| 835 | !arm_feature(env, ARM_FEATURE_M) && |
Peter Maydell | 452a095 | 2017-06-02 11:51:47 +0100 | [diff] [blame] | 836 | !arm_feature(env, ARM_FEATURE_PMSA)) { |
Peter Maydell | e97da98 | 2016-10-24 16:26:50 +0100 | [diff] [blame] | 837 | /* v7VMSA drops support for the old ARMv5 tiny pages, so we |
| 838 | * can use 4K pages. |
| 839 | */ |
| 840 | pagebits = 12; |
| 841 | } else { |
| 842 | /* For CPUs which might have tiny 1K pages, or which have an |
| 843 | * MPU and might have small region sizes, stick with 1K pages. |
| 844 | */ |
| 845 | pagebits = 10; |
| 846 | } |
| 847 | if (!set_preferred_target_page_bits(pagebits)) { |
| 848 | /* This can only ever happen for hotplugging a CPU, or if |
| 849 | * the board code incorrectly creates a CPU which it has |
| 850 | * promised via minimum_page_size that it will not. |
| 851 | */ |
| 852 | error_setg(errp, "This CPU requires a smaller page size than the " |
| 853 | "system is using"); |
| 854 | return; |
| 855 | } |
| 856 | |
Laurent Vivier | ce5b1bb | 2016-10-20 13:26:03 +0200 | [diff] [blame] | 857 | /* This cpu-id-to-MPIDR affinity is used only for TCG; KVM will override it. |
| 858 | * We don't support setting cluster ID ([16..23]) (known as Aff2 |
| 859 | * in later ARM ARM versions), or any of the higher affinity level fields, |
| 860 | * so these bits always RAZ. |
| 861 | */ |
| 862 | if (cpu->mp_affinity == ARM64_AFFINITY_INVALID) { |
Igor Mammedov | 46de591 | 2017-05-03 14:56:56 +0200 | [diff] [blame] | 863 | cpu->mp_affinity = arm_cpu_mp_affinity(cs->cpu_index, |
| 864 | ARM_DEFAULT_CPUS_PER_CLUSTER); |
Laurent Vivier | ce5b1bb | 2016-10-20 13:26:03 +0200 | [diff] [blame] | 865 | } |
| 866 | |
Antony Pavlov | 68e0a40 | 2013-12-17 19:42:29 +0000 | [diff] [blame] | 867 | if (cpu->reset_hivecs) { |
| 868 | cpu->reset_sctlr |= (1 << 13); |
| 869 | } |
| 870 | |
Julian Brown | 3a062d5 | 2017-02-07 18:29:59 +0000 | [diff] [blame] | 871 | if (cpu->cfgend) { |
| 872 | if (arm_feature(&cpu->env, ARM_FEATURE_V7)) { |
| 873 | cpu->reset_sctlr |= SCTLR_EE; |
| 874 | } else { |
| 875 | cpu->reset_sctlr |= SCTLR_B; |
| 876 | } |
| 877 | } |
| 878 | |
Greg Bellows | 51942ae | 2014-12-15 17:09:46 -0600 | [diff] [blame] | 879 | if (!cpu->has_el3) { |
| 880 | /* If the has_el3 CPU property is disabled then we need to disable the |
| 881 | * feature. |
| 882 | */ |
| 883 | unset_feature(env, ARM_FEATURE_EL3); |
| 884 | |
| 885 | /* Disable the security extension feature bits in the processor feature |
Sergey Fedorov | 3d5c84f | 2015-04-26 16:49:26 +0100 | [diff] [blame] | 886 | * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12]. |
Greg Bellows | 51942ae | 2014-12-15 17:09:46 -0600 | [diff] [blame] | 887 | */ |
| 888 | cpu->id_pfr1 &= ~0xf0; |
Sergey Fedorov | 3d5c84f | 2015-04-26 16:49:26 +0100 | [diff] [blame] | 889 | cpu->id_aa64pfr0 &= ~0xf000; |
Greg Bellows | 51942ae | 2014-12-15 17:09:46 -0600 | [diff] [blame] | 890 | } |
| 891 | |
Peter Maydell | c25bd18 | 2017-01-20 11:15:10 +0000 | [diff] [blame] | 892 | if (!cpu->has_el2) { |
| 893 | unset_feature(env, ARM_FEATURE_EL2); |
| 894 | } |
| 895 | |
Wei Huang | d6f02ce | 2017-02-10 17:40:28 +0000 | [diff] [blame] | 896 | if (!cpu->has_pmu) { |
Wei Huang | 929e754 | 2016-10-28 14:12:31 +0100 | [diff] [blame] | 897 | unset_feature(env, ARM_FEATURE_PMU); |
Wei Huang | 2b3ffa9 | 2017-06-02 11:51:47 +0100 | [diff] [blame] | 898 | cpu->id_aa64dfr0 &= ~0xf00; |
Wei Huang | 929e754 | 2016-10-28 14:12:31 +0100 | [diff] [blame] | 899 | } |
| 900 | |
Peter Maydell | 3c2f7bb | 2016-02-02 18:20:42 +0000 | [diff] [blame] | 901 | if (!arm_feature(env, ARM_FEATURE_EL2)) { |
| 902 | /* Disable the hypervisor feature bits in the processor feature |
| 903 | * registers if we don't have EL2. These are id_pfr1[15:12] and |
| 904 | * id_aa64pfr0_el1[11:8]. |
| 905 | */ |
| 906 | cpu->id_aa64pfr0 &= ~0xf00; |
| 907 | cpu->id_pfr1 &= ~0xf000; |
| 908 | } |
| 909 | |
Peter Maydell | f50cd31 | 2017-06-02 11:51:47 +0100 | [diff] [blame] | 910 | /* MPU can be configured out of a PMSA CPU either by setting has-mpu |
| 911 | * to false or by setting pmsav7-dregion to 0. |
| 912 | */ |
Peter Crosthwaite | 8f325f5 | 2015-06-15 18:06:10 +0100 | [diff] [blame] | 913 | if (!cpu->has_mpu) { |
Peter Maydell | f50cd31 | 2017-06-02 11:51:47 +0100 | [diff] [blame] | 914 | cpu->pmsav7_dregion = 0; |
| 915 | } |
| 916 | if (cpu->pmsav7_dregion == 0) { |
| 917 | cpu->has_mpu = false; |
Peter Crosthwaite | 8f325f5 | 2015-06-15 18:06:10 +0100 | [diff] [blame] | 918 | } |
| 919 | |
Peter Maydell | 452a095 | 2017-06-02 11:51:47 +0100 | [diff] [blame] | 920 | if (arm_feature(env, ARM_FEATURE_PMSA) && |
Peter Crosthwaite | 3281af8 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 921 | arm_feature(env, ARM_FEATURE_V7)) { |
| 922 | uint32_t nr = cpu->pmsav7_dregion; |
| 923 | |
| 924 | if (nr > 0xff) { |
Markus Armbruster | 9af9e0f | 2015-12-18 16:35:19 +0100 | [diff] [blame] | 925 | error_setg(errp, "PMSAv7 MPU #regions invalid %" PRIu32, nr); |
Peter Crosthwaite | 3281af8 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 926 | return; |
| 927 | } |
Peter Crosthwaite | 6cb0b01 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 928 | |
| 929 | if (nr) { |
Peter Maydell | 0e1a46b | 2017-09-07 13:54:51 +0100 | [diff] [blame] | 930 | if (arm_feature(env, ARM_FEATURE_V8)) { |
| 931 | /* PMSAv8 */ |
Peter Maydell | 62c58ee | 2017-09-07 13:54:53 +0100 | [diff] [blame] | 932 | env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr); |
| 933 | env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr); |
| 934 | if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { |
| 935 | env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr); |
| 936 | env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr); |
| 937 | } |
Peter Maydell | 0e1a46b | 2017-09-07 13:54:51 +0100 | [diff] [blame] | 938 | } else { |
| 939 | env->pmsav7.drbar = g_new0(uint32_t, nr); |
| 940 | env->pmsav7.drsr = g_new0(uint32_t, nr); |
| 941 | env->pmsav7.dracr = g_new0(uint32_t, nr); |
| 942 | } |
Peter Crosthwaite | 6cb0b01 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 943 | } |
Peter Crosthwaite | 3281af8 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 944 | } |
| 945 | |
Peter Maydell | 9901c57 | 2017-10-06 16:46:49 +0100 | [diff] [blame] | 946 | if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { |
| 947 | uint32_t nr = cpu->sau_sregion; |
| 948 | |
| 949 | if (nr > 0xff) { |
| 950 | error_setg(errp, "v8M SAU #regions invalid %" PRIu32, nr); |
| 951 | return; |
| 952 | } |
| 953 | |
| 954 | if (nr) { |
| 955 | env->sau.rbar = g_new0(uint32_t, nr); |
| 956 | env->sau.rlar = g_new0(uint32_t, nr); |
| 957 | } |
| 958 | } |
| 959 | |
Cédric Le Goater | 91db464 | 2016-12-27 14:59:30 +0000 | [diff] [blame] | 960 | if (arm_feature(env, ARM_FEATURE_EL3)) { |
| 961 | set_feature(env, ARM_FEATURE_VBAR); |
| 962 | } |
| 963 | |
Peter Maydell | 2ceb98c | 2012-06-20 11:57:09 +0000 | [diff] [blame] | 964 | register_cp_regs_for_features(cpu); |
Andreas Färber | 1496926 | 2013-01-05 10:18:18 +0100 | [diff] [blame] | 965 | arm_cpu_register_gdb_regs_for_features(cpu); |
| 966 | |
Peter Maydell | 721fae1 | 2013-06-25 18:16:07 +0100 | [diff] [blame] | 967 | init_cpreg_list(cpu); |
| 968 | |
Peter Maydell | 9e273ef | 2016-01-21 14:15:06 +0000 | [diff] [blame] | 969 | #ifndef CONFIG_USER_ONLY |
Peter Maydell | 1d2091b | 2017-09-07 13:54:52 +0100 | [diff] [blame] | 970 | if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) { |
Peter Maydell | 1d2091b | 2017-09-07 13:54:52 +0100 | [diff] [blame] | 971 | cs->num_ases = 2; |
| 972 | |
Peter Maydell | 9e273ef | 2016-01-21 14:15:06 +0000 | [diff] [blame] | 973 | if (!cpu->secure_memory) { |
| 974 | cpu->secure_memory = cs->memory; |
| 975 | } |
Peter Xu | 80ceb07 | 2017-11-23 17:23:32 +0800 | [diff] [blame] | 976 | cpu_address_space_init(cs, ARMASIdx_S, "cpu-secure-memory", |
| 977 | cpu->secure_memory); |
Peter Maydell | 1d2091b | 2017-09-07 13:54:52 +0100 | [diff] [blame] | 978 | } else { |
| 979 | cs->num_ases = 1; |
Peter Maydell | 9e273ef | 2016-01-21 14:15:06 +0000 | [diff] [blame] | 980 | } |
Peter Xu | 80ceb07 | 2017-11-23 17:23:32 +0800 | [diff] [blame] | 981 | cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory); |
Alistair Francis | f9a6971 | 2018-03-09 17:09:43 +0000 | [diff] [blame] | 982 | |
| 983 | /* No core_count specified, default to smp_cpus. */ |
| 984 | if (cpu->core_count == -1) { |
| 985 | cpu->core_count = smp_cpus; |
| 986 | } |
Peter Maydell | 9e273ef | 2016-01-21 14:15:06 +0000 | [diff] [blame] | 987 | #endif |
| 988 | |
Andreas Färber | 14a10fc | 2013-07-27 02:53:25 +0200 | [diff] [blame] | 989 | qemu_init_vcpu(cs); |
Christoffer Dall | 00d0f7c | 2014-05-27 14:37:43 +0200 | [diff] [blame] | 990 | cpu_reset(cs); |
Andreas Färber | 1496926 | 2013-01-05 10:18:18 +0100 | [diff] [blame] | 991 | |
| 992 | acc->parent_realize(dev, errp); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 993 | } |
| 994 | |
Andreas Färber | 5900d6b | 2013-01-21 16:11:43 +0100 | [diff] [blame] | 995 | static ObjectClass *arm_cpu_class_by_name(const char *cpu_model) |
| 996 | { |
| 997 | ObjectClass *oc; |
Andreas Färber | 51492fd | 2013-01-27 17:30:10 +0100 | [diff] [blame] | 998 | char *typename; |
Greg Bellows | fb8d6c2 | 2015-02-13 05:46:08 +0000 | [diff] [blame] | 999 | char **cpuname; |
Peter Maydell | a0032cc | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 1000 | const char *cpunamestr; |
Andreas Färber | 5900d6b | 2013-01-21 16:11:43 +0100 | [diff] [blame] | 1001 | |
Greg Bellows | fb8d6c2 | 2015-02-13 05:46:08 +0000 | [diff] [blame] | 1002 | cpuname = g_strsplit(cpu_model, ",", 1); |
Peter Maydell | a0032cc | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 1003 | cpunamestr = cpuname[0]; |
| 1004 | #ifdef CONFIG_USER_ONLY |
| 1005 | /* For backwards compatibility usermode emulation allows "-cpu any", |
| 1006 | * which has the same semantics as "-cpu max". |
| 1007 | */ |
| 1008 | if (!strcmp(cpunamestr, "any")) { |
| 1009 | cpunamestr = "max"; |
| 1010 | } |
| 1011 | #endif |
| 1012 | typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpunamestr); |
Andreas Färber | 51492fd | 2013-01-27 17:30:10 +0100 | [diff] [blame] | 1013 | oc = object_class_by_name(typename); |
Greg Bellows | fb8d6c2 | 2015-02-13 05:46:08 +0000 | [diff] [blame] | 1014 | g_strfreev(cpuname); |
Andreas Färber | 51492fd | 2013-01-27 17:30:10 +0100 | [diff] [blame] | 1015 | g_free(typename); |
Andreas Färber | 245fb54 | 2013-01-23 12:32:49 +0100 | [diff] [blame] | 1016 | if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU) || |
| 1017 | object_class_is_abstract(oc)) { |
Andreas Färber | 5900d6b | 2013-01-21 16:11:43 +0100 | [diff] [blame] | 1018 | return NULL; |
| 1019 | } |
| 1020 | return oc; |
| 1021 | } |
| 1022 | |
Peter Maydell | 15ee776 | 2013-09-03 20:12:08 +0100 | [diff] [blame] | 1023 | /* CPU models. These are not needed for the AArch64 linux-user build. */ |
| 1024 | #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) |
| 1025 | |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1026 | static void arm926_initfn(Object *obj) |
| 1027 | { |
| 1028 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1029 | |
| 1030 | cpu->dtb_compatible = "arm,arm926"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1031 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1032 | set_feature(&cpu->env, ARM_FEATURE_VFP); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1033 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 1034 | set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); |
Portia Stephens | c99a55d | 2017-09-07 13:54:55 +0100 | [diff] [blame] | 1035 | set_feature(&cpu->env, ARM_FEATURE_JAZELLE); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1036 | cpu->midr = 0x41069265; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1037 | cpu->reset_fpsid = 0x41011090; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1038 | cpu->ctr = 0x1dd20d2; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1039 | cpu->reset_sctlr = 0x00090078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1040 | } |
| 1041 | |
| 1042 | static void arm946_initfn(Object *obj) |
| 1043 | { |
| 1044 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1045 | |
| 1046 | cpu->dtb_compatible = "arm,arm946"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1047 | set_feature(&cpu->env, ARM_FEATURE_V5); |
Peter Maydell | 452a095 | 2017-06-02 11:51:47 +0100 | [diff] [blame] | 1048 | set_feature(&cpu->env, ARM_FEATURE_PMSA); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1049 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1050 | cpu->midr = 0x41059461; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1051 | cpu->ctr = 0x0f004006; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1052 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1053 | } |
| 1054 | |
| 1055 | static void arm1026_initfn(Object *obj) |
| 1056 | { |
| 1057 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1058 | |
| 1059 | cpu->dtb_compatible = "arm,arm1026"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1060 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1061 | set_feature(&cpu->env, ARM_FEATURE_VFP); |
| 1062 | set_feature(&cpu->env, ARM_FEATURE_AUXCR); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1063 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 1064 | set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); |
Portia Stephens | c99a55d | 2017-09-07 13:54:55 +0100 | [diff] [blame] | 1065 | set_feature(&cpu->env, ARM_FEATURE_JAZELLE); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1066 | cpu->midr = 0x4106a262; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1067 | cpu->reset_fpsid = 0x410110a0; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1068 | cpu->ctr = 0x1dd20d2; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1069 | cpu->reset_sctlr = 0x00090078; |
Peter Maydell | 2771db2 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1070 | cpu->reset_auxcr = 1; |
Peter Maydell | 06d76f3 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1071 | { |
| 1072 | /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */ |
| 1073 | ARMCPRegInfo ifar = { |
| 1074 | .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1, |
| 1075 | .access = PL1_RW, |
Fabian Aggeler | b848ce2 | 2014-12-11 12:07:51 +0000 | [diff] [blame] | 1076 | .fieldoffset = offsetof(CPUARMState, cp15.ifar_ns), |
Peter Maydell | 06d76f3 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1077 | .resetvalue = 0 |
| 1078 | }; |
| 1079 | define_one_arm_cp_reg(cpu, &ifar); |
| 1080 | } |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1081 | } |
| 1082 | |
| 1083 | static void arm1136_r2_initfn(Object *obj) |
| 1084 | { |
| 1085 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1086 | /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an |
| 1087 | * older core than plain "arm1136". In particular this does not |
| 1088 | * have the v6K features. |
| 1089 | * These ID register values are correct for 1136 but may be wrong |
| 1090 | * for 1136_r2 (in particular r0p2 does not actually implement most |
| 1091 | * of the ID registers). |
| 1092 | */ |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1093 | |
| 1094 | cpu->dtb_compatible = "arm,arm1136"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1095 | set_feature(&cpu->env, ARM_FEATURE_V6); |
| 1096 | set_feature(&cpu->env, ARM_FEATURE_VFP); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1097 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 1098 | set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); |
| 1099 | set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1100 | cpu->midr = 0x4107b362; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1101 | cpu->reset_fpsid = 0x410120b4; |
Peter Maydell | bd35c35 | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1102 | cpu->mvfr0 = 0x11111111; |
| 1103 | cpu->mvfr1 = 0x00000000; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1104 | cpu->ctr = 0x1dd20d2; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1105 | cpu->reset_sctlr = 0x00050078; |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1106 | cpu->id_pfr0 = 0x111; |
| 1107 | cpu->id_pfr1 = 0x1; |
| 1108 | cpu->id_dfr0 = 0x2; |
| 1109 | cpu->id_afr0 = 0x3; |
| 1110 | cpu->id_mmfr0 = 0x01130003; |
| 1111 | cpu->id_mmfr1 = 0x10030302; |
| 1112 | cpu->id_mmfr2 = 0x01222110; |
| 1113 | cpu->id_isar0 = 0x00140011; |
| 1114 | cpu->id_isar1 = 0x12002111; |
| 1115 | cpu->id_isar2 = 0x11231111; |
| 1116 | cpu->id_isar3 = 0x01102131; |
| 1117 | cpu->id_isar4 = 0x141; |
Peter Maydell | 2771db2 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1118 | cpu->reset_auxcr = 7; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1119 | } |
| 1120 | |
| 1121 | static void arm1136_initfn(Object *obj) |
| 1122 | { |
| 1123 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1124 | |
| 1125 | cpu->dtb_compatible = "arm,arm1136"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1126 | set_feature(&cpu->env, ARM_FEATURE_V6K); |
| 1127 | set_feature(&cpu->env, ARM_FEATURE_V6); |
| 1128 | set_feature(&cpu->env, ARM_FEATURE_VFP); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1129 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 1130 | set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); |
| 1131 | set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1132 | cpu->midr = 0x4117b363; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1133 | cpu->reset_fpsid = 0x410120b4; |
Peter Maydell | bd35c35 | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1134 | cpu->mvfr0 = 0x11111111; |
| 1135 | cpu->mvfr1 = 0x00000000; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1136 | cpu->ctr = 0x1dd20d2; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1137 | cpu->reset_sctlr = 0x00050078; |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1138 | cpu->id_pfr0 = 0x111; |
| 1139 | cpu->id_pfr1 = 0x1; |
| 1140 | cpu->id_dfr0 = 0x2; |
| 1141 | cpu->id_afr0 = 0x3; |
| 1142 | cpu->id_mmfr0 = 0x01130003; |
| 1143 | cpu->id_mmfr1 = 0x10030302; |
| 1144 | cpu->id_mmfr2 = 0x01222110; |
| 1145 | cpu->id_isar0 = 0x00140011; |
| 1146 | cpu->id_isar1 = 0x12002111; |
| 1147 | cpu->id_isar2 = 0x11231111; |
| 1148 | cpu->id_isar3 = 0x01102131; |
| 1149 | cpu->id_isar4 = 0x141; |
Peter Maydell | 2771db2 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1150 | cpu->reset_auxcr = 7; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1151 | } |
| 1152 | |
| 1153 | static void arm1176_initfn(Object *obj) |
| 1154 | { |
| 1155 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1156 | |
| 1157 | cpu->dtb_compatible = "arm,arm1176"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1158 | set_feature(&cpu->env, ARM_FEATURE_V6K); |
| 1159 | set_feature(&cpu->env, ARM_FEATURE_VFP); |
| 1160 | set_feature(&cpu->env, ARM_FEATURE_VAPA); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1161 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 1162 | set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); |
| 1163 | set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); |
Fabian Aggeler | c0ccb02 | 2014-12-15 17:09:52 -0600 | [diff] [blame] | 1164 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1165 | cpu->midr = 0x410fb767; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1166 | cpu->reset_fpsid = 0x410120b5; |
Peter Maydell | bd35c35 | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1167 | cpu->mvfr0 = 0x11111111; |
| 1168 | cpu->mvfr1 = 0x00000000; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1169 | cpu->ctr = 0x1dd20d2; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1170 | cpu->reset_sctlr = 0x00050078; |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1171 | cpu->id_pfr0 = 0x111; |
| 1172 | cpu->id_pfr1 = 0x11; |
| 1173 | cpu->id_dfr0 = 0x33; |
| 1174 | cpu->id_afr0 = 0; |
| 1175 | cpu->id_mmfr0 = 0x01130003; |
| 1176 | cpu->id_mmfr1 = 0x10030302; |
| 1177 | cpu->id_mmfr2 = 0x01222100; |
| 1178 | cpu->id_isar0 = 0x0140011; |
| 1179 | cpu->id_isar1 = 0x12002111; |
| 1180 | cpu->id_isar2 = 0x11231121; |
| 1181 | cpu->id_isar3 = 0x01102131; |
| 1182 | cpu->id_isar4 = 0x01141; |
Peter Maydell | 2771db2 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1183 | cpu->reset_auxcr = 7; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1184 | } |
| 1185 | |
| 1186 | static void arm11mpcore_initfn(Object *obj) |
| 1187 | { |
| 1188 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1189 | |
| 1190 | cpu->dtb_compatible = "arm,arm11mpcore"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1191 | set_feature(&cpu->env, ARM_FEATURE_V6K); |
| 1192 | set_feature(&cpu->env, ARM_FEATURE_VFP); |
| 1193 | set_feature(&cpu->env, ARM_FEATURE_VAPA); |
Peter Maydell | 81bdde9 | 2012-06-20 11:57:20 +0000 | [diff] [blame] | 1194 | set_feature(&cpu->env, ARM_FEATURE_MPIDR); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1195 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1196 | cpu->midr = 0x410fb022; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1197 | cpu->reset_fpsid = 0x410120b4; |
Peter Maydell | bd35c35 | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1198 | cpu->mvfr0 = 0x11111111; |
| 1199 | cpu->mvfr1 = 0x00000000; |
Peter Maydell | 200bf59 | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 1200 | cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1201 | cpu->id_pfr0 = 0x111; |
| 1202 | cpu->id_pfr1 = 0x1; |
| 1203 | cpu->id_dfr0 = 0; |
| 1204 | cpu->id_afr0 = 0x2; |
| 1205 | cpu->id_mmfr0 = 0x01100103; |
| 1206 | cpu->id_mmfr1 = 0x10020302; |
| 1207 | cpu->id_mmfr2 = 0x01222000; |
| 1208 | cpu->id_isar0 = 0x00100011; |
| 1209 | cpu->id_isar1 = 0x12002111; |
| 1210 | cpu->id_isar2 = 0x11221011; |
| 1211 | cpu->id_isar3 = 0x01102131; |
| 1212 | cpu->id_isar4 = 0x141; |
Peter Maydell | 2771db2 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1213 | cpu->reset_auxcr = 1; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1214 | } |
| 1215 | |
| 1216 | static void cortex_m3_initfn(Object *obj) |
| 1217 | { |
| 1218 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1219 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 1220 | set_feature(&cpu->env, ARM_FEATURE_M); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1221 | cpu->midr = 0x410fc231; |
Peter Maydell | 8d92e26 | 2017-07-17 13:36:07 +0100 | [diff] [blame] | 1222 | cpu->pmsav7_dregion = 8; |
Peter Maydell | 5a53e2c | 2018-02-15 18:29:37 +0000 | [diff] [blame] | 1223 | cpu->id_pfr0 = 0x00000030; |
| 1224 | cpu->id_pfr1 = 0x00000200; |
| 1225 | cpu->id_dfr0 = 0x00100000; |
| 1226 | cpu->id_afr0 = 0x00000000; |
| 1227 | cpu->id_mmfr0 = 0x00000030; |
| 1228 | cpu->id_mmfr1 = 0x00000000; |
| 1229 | cpu->id_mmfr2 = 0x00000000; |
| 1230 | cpu->id_mmfr3 = 0x00000000; |
| 1231 | cpu->id_isar0 = 0x01141110; |
| 1232 | cpu->id_isar1 = 0x02111000; |
| 1233 | cpu->id_isar2 = 0x21112231; |
| 1234 | cpu->id_isar3 = 0x01111110; |
| 1235 | cpu->id_isar4 = 0x01310102; |
| 1236 | cpu->id_isar5 = 0x00000000; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1237 | } |
| 1238 | |
Aurelio C. Remonda | ba890a9 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 1239 | static void cortex_m4_initfn(Object *obj) |
| 1240 | { |
| 1241 | ARMCPU *cpu = ARM_CPU(obj); |
| 1242 | |
| 1243 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 1244 | set_feature(&cpu->env, ARM_FEATURE_M); |
| 1245 | set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); |
| 1246 | cpu->midr = 0x410fc240; /* r0p0 */ |
Peter Maydell | 8d92e26 | 2017-07-17 13:36:07 +0100 | [diff] [blame] | 1247 | cpu->pmsav7_dregion = 8; |
Peter Maydell | 5a53e2c | 2018-02-15 18:29:37 +0000 | [diff] [blame] | 1248 | cpu->id_pfr0 = 0x00000030; |
| 1249 | cpu->id_pfr1 = 0x00000200; |
| 1250 | cpu->id_dfr0 = 0x00100000; |
| 1251 | cpu->id_afr0 = 0x00000000; |
| 1252 | cpu->id_mmfr0 = 0x00000030; |
| 1253 | cpu->id_mmfr1 = 0x00000000; |
| 1254 | cpu->id_mmfr2 = 0x00000000; |
| 1255 | cpu->id_mmfr3 = 0x00000000; |
| 1256 | cpu->id_isar0 = 0x01141110; |
| 1257 | cpu->id_isar1 = 0x02111000; |
| 1258 | cpu->id_isar2 = 0x21112231; |
| 1259 | cpu->id_isar3 = 0x01111110; |
| 1260 | cpu->id_isar4 = 0x01310102; |
| 1261 | cpu->id_isar5 = 0x00000000; |
Aurelio C. Remonda | ba890a9 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 1262 | } |
Peter Maydell | 9901c57 | 2017-10-06 16:46:49 +0100 | [diff] [blame] | 1263 | |
Peter Maydell | c7b2638 | 2018-03-02 10:45:37 +0000 | [diff] [blame] | 1264 | static void cortex_m33_initfn(Object *obj) |
| 1265 | { |
| 1266 | ARMCPU *cpu = ARM_CPU(obj); |
| 1267 | |
| 1268 | set_feature(&cpu->env, ARM_FEATURE_V8); |
| 1269 | set_feature(&cpu->env, ARM_FEATURE_M); |
| 1270 | set_feature(&cpu->env, ARM_FEATURE_M_SECURITY); |
| 1271 | set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); |
| 1272 | cpu->midr = 0x410fd213; /* r0p3 */ |
| 1273 | cpu->pmsav7_dregion = 16; |
| 1274 | cpu->sau_sregion = 8; |
| 1275 | cpu->id_pfr0 = 0x00000030; |
| 1276 | cpu->id_pfr1 = 0x00000210; |
| 1277 | cpu->id_dfr0 = 0x00200000; |
| 1278 | cpu->id_afr0 = 0x00000000; |
| 1279 | cpu->id_mmfr0 = 0x00101F40; |
| 1280 | cpu->id_mmfr1 = 0x00000000; |
| 1281 | cpu->id_mmfr2 = 0x01000000; |
| 1282 | cpu->id_mmfr3 = 0x00000000; |
| 1283 | cpu->id_isar0 = 0x01101110; |
| 1284 | cpu->id_isar1 = 0x02212000; |
| 1285 | cpu->id_isar2 = 0x20232232; |
| 1286 | cpu->id_isar3 = 0x01111131; |
| 1287 | cpu->id_isar4 = 0x01310132; |
| 1288 | cpu->id_isar5 = 0x00000000; |
| 1289 | cpu->clidr = 0x00000000; |
| 1290 | cpu->ctr = 0x8000c000; |
| 1291 | } |
| 1292 | |
Andreas Färber | e6f010c | 2013-02-02 12:33:14 +0100 | [diff] [blame] | 1293 | static void arm_v7m_class_init(ObjectClass *oc, void *data) |
| 1294 | { |
Andreas Färber | e6f010c | 2013-02-02 12:33:14 +0100 | [diff] [blame] | 1295 | CPUClass *cc = CPU_CLASS(oc); |
| 1296 | |
Peter Maydell | b5c633c | 2014-10-30 15:48:51 +0000 | [diff] [blame] | 1297 | #ifndef CONFIG_USER_ONLY |
Andreas Färber | e6f010c | 2013-02-02 12:33:14 +0100 | [diff] [blame] | 1298 | cc->do_interrupt = arm_v7m_cpu_do_interrupt; |
| 1299 | #endif |
Peter Maydell | b5c633c | 2014-10-30 15:48:51 +0000 | [diff] [blame] | 1300 | |
| 1301 | cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; |
Andreas Färber | e6f010c | 2013-02-02 12:33:14 +0100 | [diff] [blame] | 1302 | } |
| 1303 | |
Peter Crosthwaite | d6a6b13 | 2015-06-19 14:17:45 +0100 | [diff] [blame] | 1304 | static const ARMCPRegInfo cortexr5_cp_reginfo[] = { |
| 1305 | /* Dummy the TCM region regs for the moment */ |
| 1306 | { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, |
| 1307 | .access = PL1_RW, .type = ARM_CP_CONST }, |
| 1308 | { .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, |
| 1309 | .access = PL1_RW, .type = ARM_CP_CONST }, |
Luc MICHEL | 95e9a24 | 2017-04-28 14:56:32 +0200 | [diff] [blame] | 1310 | { .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5, |
| 1311 | .opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP }, |
Peter Crosthwaite | d6a6b13 | 2015-06-19 14:17:45 +0100 | [diff] [blame] | 1312 | REGINFO_SENTINEL |
| 1313 | }; |
| 1314 | |
| 1315 | static void cortex_r5_initfn(Object *obj) |
| 1316 | { |
| 1317 | ARMCPU *cpu = ARM_CPU(obj); |
| 1318 | |
| 1319 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 1320 | set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV); |
| 1321 | set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); |
| 1322 | set_feature(&cpu->env, ARM_FEATURE_V7MP); |
Peter Maydell | 452a095 | 2017-06-02 11:51:47 +0100 | [diff] [blame] | 1323 | set_feature(&cpu->env, ARM_FEATURE_PMSA); |
Peter Crosthwaite | d6a6b13 | 2015-06-19 14:17:45 +0100 | [diff] [blame] | 1324 | cpu->midr = 0x411fc153; /* r1p3 */ |
| 1325 | cpu->id_pfr0 = 0x0131; |
| 1326 | cpu->id_pfr1 = 0x001; |
| 1327 | cpu->id_dfr0 = 0x010400; |
| 1328 | cpu->id_afr0 = 0x0; |
| 1329 | cpu->id_mmfr0 = 0x0210030; |
| 1330 | cpu->id_mmfr1 = 0x00000000; |
| 1331 | cpu->id_mmfr2 = 0x01200000; |
| 1332 | cpu->id_mmfr3 = 0x0211; |
| 1333 | cpu->id_isar0 = 0x2101111; |
| 1334 | cpu->id_isar1 = 0x13112111; |
| 1335 | cpu->id_isar2 = 0x21232141; |
| 1336 | cpu->id_isar3 = 0x01112131; |
| 1337 | cpu->id_isar4 = 0x0010142; |
| 1338 | cpu->id_isar5 = 0x0; |
| 1339 | cpu->mp_is_up = true; |
Peter Maydell | 8d92e26 | 2017-07-17 13:36:07 +0100 | [diff] [blame] | 1340 | cpu->pmsav7_dregion = 16; |
Peter Crosthwaite | d6a6b13 | 2015-06-19 14:17:45 +0100 | [diff] [blame] | 1341 | define_arm_cp_regs(cpu, cortexr5_cp_reginfo); |
| 1342 | } |
| 1343 | |
Peter Maydell | 34f9052 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1344 | static const ARMCPRegInfo cortexa8_cp_reginfo[] = { |
| 1345 | { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0, |
| 1346 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 1347 | { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2, |
| 1348 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 1349 | REGINFO_SENTINEL |
| 1350 | }; |
| 1351 | |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1352 | static void cortex_a8_initfn(Object *obj) |
| 1353 | { |
| 1354 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1355 | |
| 1356 | cpu->dtb_compatible = "arm,cortex-a8"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1357 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 1358 | set_feature(&cpu->env, ARM_FEATURE_VFP3); |
| 1359 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 1360 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1361 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
Fabian Aggeler | c0ccb02 | 2014-12-15 17:09:52 -0600 | [diff] [blame] | 1362 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1363 | cpu->midr = 0x410fc080; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1364 | cpu->reset_fpsid = 0x410330c0; |
Peter Maydell | bd35c35 | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1365 | cpu->mvfr0 = 0x11110222; |
Julian Brown | 0f19447 | 2016-12-27 14:59:23 +0000 | [diff] [blame] | 1366 | cpu->mvfr1 = 0x00011111; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1367 | cpu->ctr = 0x82048004; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1368 | cpu->reset_sctlr = 0x00c50078; |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1369 | cpu->id_pfr0 = 0x1031; |
| 1370 | cpu->id_pfr1 = 0x11; |
| 1371 | cpu->id_dfr0 = 0x400; |
| 1372 | cpu->id_afr0 = 0; |
| 1373 | cpu->id_mmfr0 = 0x31100003; |
| 1374 | cpu->id_mmfr1 = 0x20000000; |
| 1375 | cpu->id_mmfr2 = 0x01202000; |
| 1376 | cpu->id_mmfr3 = 0x11; |
| 1377 | cpu->id_isar0 = 0x00101111; |
| 1378 | cpu->id_isar1 = 0x12112111; |
| 1379 | cpu->id_isar2 = 0x21232031; |
| 1380 | cpu->id_isar3 = 0x11112131; |
| 1381 | cpu->id_isar4 = 0x00111142; |
Peter Maydell | 48eb3ae | 2014-08-19 18:56:25 +0100 | [diff] [blame] | 1382 | cpu->dbgdidr = 0x15141000; |
Peter Maydell | 85df378 | 2012-04-20 17:58:35 +0000 | [diff] [blame] | 1383 | cpu->clidr = (1 << 27) | (2 << 24) | 3; |
| 1384 | cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ |
| 1385 | cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ |
| 1386 | cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */ |
Peter Maydell | 2771db2 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1387 | cpu->reset_auxcr = 2; |
Peter Maydell | 34f9052 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1388 | define_arm_cp_regs(cpu, cortexa8_cp_reginfo); |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1389 | } |
| 1390 | |
Peter Maydell | 1047b9d | 2012-06-20 11:57:15 +0000 | [diff] [blame] | 1391 | static const ARMCPRegInfo cortexa9_cp_reginfo[] = { |
| 1392 | /* power_control should be set to maximum latency. Again, |
| 1393 | * default to 0 and set by private hook |
| 1394 | */ |
| 1395 | { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0, |
| 1396 | .access = PL1_RW, .resetvalue = 0, |
| 1397 | .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) }, |
| 1398 | { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1, |
| 1399 | .access = PL1_RW, .resetvalue = 0, |
| 1400 | .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) }, |
| 1401 | { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2, |
| 1402 | .access = PL1_RW, .resetvalue = 0, |
| 1403 | .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) }, |
| 1404 | { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, |
| 1405 | .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, |
| 1406 | /* TLB lockdown control */ |
| 1407 | { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2, |
| 1408 | .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP }, |
| 1409 | { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4, |
| 1410 | .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP }, |
| 1411 | { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2, |
| 1412 | .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, |
| 1413 | { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2, |
| 1414 | .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, |
| 1415 | { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2, |
| 1416 | .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, |
| 1417 | REGINFO_SENTINEL |
| 1418 | }; |
| 1419 | |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1420 | static void cortex_a9_initfn(Object *obj) |
| 1421 | { |
| 1422 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1423 | |
| 1424 | cpu->dtb_compatible = "arm,cortex-a9"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1425 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 1426 | set_feature(&cpu->env, ARM_FEATURE_VFP3); |
| 1427 | set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); |
| 1428 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 1429 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
Fabian Aggeler | c0ccb02 | 2014-12-15 17:09:52 -0600 | [diff] [blame] | 1430 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1431 | /* Note that A9 supports the MP extensions even for |
| 1432 | * A9UP and single-core A9MP (which are both different |
| 1433 | * and valid configurations; we don't model A9UP). |
| 1434 | */ |
| 1435 | set_feature(&cpu->env, ARM_FEATURE_V7MP); |
Peter Crosthwaite | d8ba780 | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 1436 | set_feature(&cpu->env, ARM_FEATURE_CBAR); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1437 | cpu->midr = 0x410fc090; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1438 | cpu->reset_fpsid = 0x41033090; |
Peter Maydell | bd35c35 | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1439 | cpu->mvfr0 = 0x11110222; |
| 1440 | cpu->mvfr1 = 0x01111111; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1441 | cpu->ctr = 0x80038003; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1442 | cpu->reset_sctlr = 0x00c50078; |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1443 | cpu->id_pfr0 = 0x1031; |
| 1444 | cpu->id_pfr1 = 0x11; |
| 1445 | cpu->id_dfr0 = 0x000; |
| 1446 | cpu->id_afr0 = 0; |
| 1447 | cpu->id_mmfr0 = 0x00100103; |
| 1448 | cpu->id_mmfr1 = 0x20000000; |
| 1449 | cpu->id_mmfr2 = 0x01230000; |
| 1450 | cpu->id_mmfr3 = 0x00002111; |
| 1451 | cpu->id_isar0 = 0x00101111; |
| 1452 | cpu->id_isar1 = 0x13112111; |
| 1453 | cpu->id_isar2 = 0x21232041; |
| 1454 | cpu->id_isar3 = 0x11112131; |
| 1455 | cpu->id_isar4 = 0x00111142; |
Peter Maydell | 48eb3ae | 2014-08-19 18:56:25 +0100 | [diff] [blame] | 1456 | cpu->dbgdidr = 0x35141000; |
Peter Maydell | 85df378 | 2012-04-20 17:58:35 +0000 | [diff] [blame] | 1457 | cpu->clidr = (1 << 27) | (1 << 24) | 3; |
Peter Crosthwaite | f7838b5 | 2014-08-19 18:56:27 +0100 | [diff] [blame] | 1458 | cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */ |
| 1459 | cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */ |
Peter Crosthwaite | d8ba780 | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 1460 | define_arm_cp_regs(cpu, cortexa9_cp_reginfo); |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1461 | } |
| 1462 | |
Peter Maydell | 34f9052 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1463 | #ifndef CONFIG_USER_ONLY |
Peter Maydell | c4241c7 | 2014-02-20 10:35:54 +0000 | [diff] [blame] | 1464 | static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) |
Peter Maydell | 34f9052 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1465 | { |
| 1466 | /* Linux wants the number of processors from here. |
| 1467 | * Might as well set the interrupt-controller bit too. |
| 1468 | */ |
Peter Maydell | c4241c7 | 2014-02-20 10:35:54 +0000 | [diff] [blame] | 1469 | return ((smp_cpus - 1) << 24) | (1 << 23); |
Peter Maydell | 34f9052 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1470 | } |
| 1471 | #endif |
| 1472 | |
| 1473 | static const ARMCPRegInfo cortexa15_cp_reginfo[] = { |
| 1474 | #ifndef CONFIG_USER_ONLY |
| 1475 | { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2, |
| 1476 | .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read, |
| 1477 | .writefn = arm_cp_write_ignore, }, |
| 1478 | #endif |
| 1479 | { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3, |
| 1480 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 1481 | REGINFO_SENTINEL |
| 1482 | }; |
| 1483 | |
Andrey Yurovsky | dcf578e | 2016-09-22 18:13:05 +0100 | [diff] [blame] | 1484 | static void cortex_a7_initfn(Object *obj) |
| 1485 | { |
| 1486 | ARMCPU *cpu = ARM_CPU(obj); |
| 1487 | |
| 1488 | cpu->dtb_compatible = "arm,cortex-a7"; |
| 1489 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 1490 | set_feature(&cpu->env, ARM_FEATURE_VFP4); |
| 1491 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 1492 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
| 1493 | set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); |
| 1494 | set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); |
| 1495 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 1496 | set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); |
| 1497 | set_feature(&cpu->env, ARM_FEATURE_LPAE); |
| 1498 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
| 1499 | cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7; |
| 1500 | cpu->midr = 0x410fc075; |
| 1501 | cpu->reset_fpsid = 0x41023075; |
| 1502 | cpu->mvfr0 = 0x10110222; |
| 1503 | cpu->mvfr1 = 0x11111111; |
| 1504 | cpu->ctr = 0x84448003; |
| 1505 | cpu->reset_sctlr = 0x00c50078; |
| 1506 | cpu->id_pfr0 = 0x00001131; |
| 1507 | cpu->id_pfr1 = 0x00011011; |
| 1508 | cpu->id_dfr0 = 0x02010555; |
| 1509 | cpu->pmceid0 = 0x00000000; |
| 1510 | cpu->pmceid1 = 0x00000000; |
| 1511 | cpu->id_afr0 = 0x00000000; |
| 1512 | cpu->id_mmfr0 = 0x10101105; |
| 1513 | cpu->id_mmfr1 = 0x40000000; |
| 1514 | cpu->id_mmfr2 = 0x01240000; |
| 1515 | cpu->id_mmfr3 = 0x02102211; |
| 1516 | cpu->id_isar0 = 0x01101110; |
| 1517 | cpu->id_isar1 = 0x13112111; |
| 1518 | cpu->id_isar2 = 0x21232041; |
| 1519 | cpu->id_isar3 = 0x11112131; |
| 1520 | cpu->id_isar4 = 0x10011142; |
| 1521 | cpu->dbgdidr = 0x3515f005; |
| 1522 | cpu->clidr = 0x0a200023; |
| 1523 | cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ |
| 1524 | cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ |
| 1525 | cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ |
| 1526 | define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */ |
| 1527 | } |
| 1528 | |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1529 | static void cortex_a15_initfn(Object *obj) |
| 1530 | { |
| 1531 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1532 | |
| 1533 | cpu->dtb_compatible = "arm,cortex-a15"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1534 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 1535 | set_feature(&cpu->env, ARM_FEATURE_VFP4); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1536 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 1537 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
| 1538 | set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1539 | set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1540 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
Peter Maydell | c29f9a0 | 2014-04-15 19:18:49 +0100 | [diff] [blame] | 1541 | set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); |
Peter Maydell | de9b05b | 2012-07-12 10:59:05 +0000 | [diff] [blame] | 1542 | set_feature(&cpu->env, ARM_FEATURE_LPAE); |
Fabian Aggeler | c0ccb02 | 2014-12-15 17:09:52 -0600 | [diff] [blame] | 1543 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
Peter Maydell | 3541add | 2013-11-22 17:17:16 +0000 | [diff] [blame] | 1544 | cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15; |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1545 | cpu->midr = 0x412fc0f1; |
Peter Maydell | 325b3ce | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1546 | cpu->reset_fpsid = 0x410430f0; |
Peter Maydell | bd35c35 | 2012-04-20 17:58:32 +0000 | [diff] [blame] | 1547 | cpu->mvfr0 = 0x10110222; |
| 1548 | cpu->mvfr1 = 0x11111111; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1549 | cpu->ctr = 0x8444c004; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1550 | cpu->reset_sctlr = 0x00c50078; |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1551 | cpu->id_pfr0 = 0x00001131; |
| 1552 | cpu->id_pfr1 = 0x00011011; |
| 1553 | cpu->id_dfr0 = 0x02010555; |
Alistair Francis | 4054bfa | 2016-02-18 14:16:17 +0000 | [diff] [blame] | 1554 | cpu->pmceid0 = 0x0000000; |
| 1555 | cpu->pmceid1 = 0x00000000; |
Peter Maydell | 2e4d7e3 | 2012-04-20 17:58:34 +0000 | [diff] [blame] | 1556 | cpu->id_afr0 = 0x00000000; |
| 1557 | cpu->id_mmfr0 = 0x10201105; |
| 1558 | cpu->id_mmfr1 = 0x20000000; |
| 1559 | cpu->id_mmfr2 = 0x01240000; |
| 1560 | cpu->id_mmfr3 = 0x02102211; |
| 1561 | cpu->id_isar0 = 0x02101110; |
| 1562 | cpu->id_isar1 = 0x13112111; |
| 1563 | cpu->id_isar2 = 0x21232041; |
| 1564 | cpu->id_isar3 = 0x11112131; |
| 1565 | cpu->id_isar4 = 0x10011142; |
Peter Maydell | 48eb3ae | 2014-08-19 18:56:25 +0100 | [diff] [blame] | 1566 | cpu->dbgdidr = 0x3515f021; |
Peter Maydell | 85df378 | 2012-04-20 17:58:35 +0000 | [diff] [blame] | 1567 | cpu->clidr = 0x0a200023; |
| 1568 | cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ |
| 1569 | cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ |
| 1570 | cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ |
Peter Maydell | 34f9052 | 2012-06-20 11:57:18 +0000 | [diff] [blame] | 1571 | define_arm_cp_regs(cpu, cortexa15_cp_reginfo); |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1572 | } |
| 1573 | |
| 1574 | static void ti925t_initfn(Object *obj) |
| 1575 | { |
| 1576 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1577 | set_feature(&cpu->env, ARM_FEATURE_V4T); |
| 1578 | set_feature(&cpu->env, ARM_FEATURE_OMAPCP); |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1579 | cpu->midr = ARM_CPUID_TI925T; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1580 | cpu->ctr = 0x5109149; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1581 | cpu->reset_sctlr = 0x00000070; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1582 | } |
| 1583 | |
| 1584 | static void sa1100_initfn(Object *obj) |
| 1585 | { |
| 1586 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1587 | |
| 1588 | cpu->dtb_compatible = "intel,sa1100"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1589 | set_feature(&cpu->env, ARM_FEATURE_STRONGARM); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1590 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1591 | cpu->midr = 0x4401A11B; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1592 | cpu->reset_sctlr = 0x00000070; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1593 | } |
| 1594 | |
| 1595 | static void sa1110_initfn(Object *obj) |
| 1596 | { |
| 1597 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1598 | set_feature(&cpu->env, ARM_FEATURE_STRONGARM); |
Peter Maydell | c480421 | 2012-06-20 11:57:17 +0000 | [diff] [blame] | 1599 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1600 | cpu->midr = 0x6901B119; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1601 | cpu->reset_sctlr = 0x00000070; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1602 | } |
| 1603 | |
| 1604 | static void pxa250_initfn(Object *obj) |
| 1605 | { |
| 1606 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1607 | |
| 1608 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1609 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1610 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1611 | cpu->midr = 0x69052100; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1612 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1613 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1614 | } |
| 1615 | |
| 1616 | static void pxa255_initfn(Object *obj) |
| 1617 | { |
| 1618 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1619 | |
| 1620 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1621 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1622 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1623 | cpu->midr = 0x69052d00; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1624 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1625 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1626 | } |
| 1627 | |
| 1628 | static void pxa260_initfn(Object *obj) |
| 1629 | { |
| 1630 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1631 | |
| 1632 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1633 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1634 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1635 | cpu->midr = 0x69052903; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1636 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1637 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1638 | } |
| 1639 | |
| 1640 | static void pxa261_initfn(Object *obj) |
| 1641 | { |
| 1642 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1643 | |
| 1644 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1645 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1646 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1647 | cpu->midr = 0x69052d05; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1648 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1649 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1650 | } |
| 1651 | |
| 1652 | static void pxa262_initfn(Object *obj) |
| 1653 | { |
| 1654 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1655 | |
| 1656 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1657 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1658 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1659 | cpu->midr = 0x69052d06; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1660 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1661 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1662 | } |
| 1663 | |
| 1664 | static void pxa270a0_initfn(Object *obj) |
| 1665 | { |
| 1666 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1667 | |
| 1668 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1669 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1670 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
| 1671 | set_feature(&cpu->env, ARM_FEATURE_IWMMXT); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1672 | cpu->midr = 0x69054110; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1673 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1674 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1675 | } |
| 1676 | |
| 1677 | static void pxa270a1_initfn(Object *obj) |
| 1678 | { |
| 1679 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1680 | |
| 1681 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1682 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1683 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
| 1684 | set_feature(&cpu->env, ARM_FEATURE_IWMMXT); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1685 | cpu->midr = 0x69054111; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1686 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1687 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1688 | } |
| 1689 | |
| 1690 | static void pxa270b0_initfn(Object *obj) |
| 1691 | { |
| 1692 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1693 | |
| 1694 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1695 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1696 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
| 1697 | set_feature(&cpu->env, ARM_FEATURE_IWMMXT); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1698 | cpu->midr = 0x69054112; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1699 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1700 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1701 | } |
| 1702 | |
| 1703 | static void pxa270b1_initfn(Object *obj) |
| 1704 | { |
| 1705 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1706 | |
| 1707 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1708 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1709 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
| 1710 | set_feature(&cpu->env, ARM_FEATURE_IWMMXT); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1711 | cpu->midr = 0x69054113; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1712 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1713 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1714 | } |
| 1715 | |
| 1716 | static void pxa270c0_initfn(Object *obj) |
| 1717 | { |
| 1718 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1719 | |
| 1720 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1721 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1722 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
| 1723 | set_feature(&cpu->env, ARM_FEATURE_IWMMXT); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1724 | cpu->midr = 0x69054114; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1725 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1726 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1727 | } |
| 1728 | |
| 1729 | static void pxa270c5_initfn(Object *obj) |
| 1730 | { |
| 1731 | ARMCPU *cpu = ARM_CPU(obj); |
Peter Maydell | 54d3e3f | 2013-11-22 17:17:12 +0000 | [diff] [blame] | 1732 | |
| 1733 | cpu->dtb_compatible = "marvell,xscale"; |
Peter Maydell | 581be09 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1734 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 1735 | set_feature(&cpu->env, ARM_FEATURE_XSCALE); |
| 1736 | set_feature(&cpu->env, ARM_FEATURE_IWMMXT); |
Peter Maydell | b2d06f9 | 2012-06-20 11:57:23 +0000 | [diff] [blame] | 1737 | cpu->midr = 0x69054117; |
Peter Maydell | 64e1671 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1738 | cpu->ctr = 0xd172172; |
Peter Maydell | 0ca7e01 | 2012-04-20 17:58:33 +0000 | [diff] [blame] | 1739 | cpu->reset_sctlr = 0x00000078; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1740 | } |
| 1741 | |
Peter Maydell | bab52d4 | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 1742 | #ifndef TARGET_AARCH64 |
| 1743 | /* -cpu max: if KVM is enabled, like -cpu host (best possible with this host); |
| 1744 | * otherwise, a CPU with as many features enabled as our emulation supports. |
| 1745 | * The version of '-cpu max' for qemu-system-aarch64 is defined in cpu64.c; |
| 1746 | * this only needs to handle 32 bits. |
| 1747 | */ |
| 1748 | static void arm_max_initfn(Object *obj) |
| 1749 | { |
| 1750 | ARMCPU *cpu = ARM_CPU(obj); |
| 1751 | |
| 1752 | if (kvm_enabled()) { |
| 1753 | kvm_arm_set_cpu_features_from_host(cpu); |
| 1754 | } else { |
| 1755 | cortex_a15_initfn(obj); |
Peter Maydell | f5f6d38 | 2013-09-10 19:09:32 +0100 | [diff] [blame] | 1756 | #ifdef CONFIG_USER_ONLY |
Peter Maydell | a0032cc | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 1757 | /* We don't set these in system emulation mode for the moment, |
| 1758 | * since we don't correctly set the ID registers to advertise them, |
| 1759 | */ |
| 1760 | set_feature(&cpu->env, ARM_FEATURE_V8); |
| 1761 | set_feature(&cpu->env, ARM_FEATURE_VFP4); |
| 1762 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 1763 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
| 1764 | set_feature(&cpu->env, ARM_FEATURE_V8_AES); |
| 1765 | set_feature(&cpu->env, ARM_FEATURE_V8_SHA1); |
| 1766 | set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); |
| 1767 | set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); |
| 1768 | set_feature(&cpu->env, ARM_FEATURE_CRC); |
| 1769 | set_feature(&cpu->env, ARM_FEATURE_V8_RDM); |
| 1770 | set_feature(&cpu->env, ARM_FEATURE_V8_FCMA); |
| 1771 | #endif |
| 1772 | } |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1773 | } |
Peter Maydell | f5f6d38 | 2013-09-10 19:09:32 +0100 | [diff] [blame] | 1774 | #endif |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1775 | |
Peter Maydell | 15ee776 | 2013-09-03 20:12:08 +0100 | [diff] [blame] | 1776 | #endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */ |
| 1777 | |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1778 | typedef struct ARMCPUInfo { |
| 1779 | const char *name; |
| 1780 | void (*initfn)(Object *obj); |
Andreas Färber | e6f010c | 2013-02-02 12:33:14 +0100 | [diff] [blame] | 1781 | void (*class_init)(ObjectClass *oc, void *data); |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1782 | } ARMCPUInfo; |
| 1783 | |
| 1784 | static const ARMCPUInfo arm_cpus[] = { |
Peter Maydell | 15ee776 | 2013-09-03 20:12:08 +0100 | [diff] [blame] | 1785 | #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1786 | { .name = "arm926", .initfn = arm926_initfn }, |
| 1787 | { .name = "arm946", .initfn = arm946_initfn }, |
| 1788 | { .name = "arm1026", .initfn = arm1026_initfn }, |
| 1789 | /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an |
| 1790 | * older core than plain "arm1136". In particular this does not |
| 1791 | * have the v6K features. |
| 1792 | */ |
| 1793 | { .name = "arm1136-r2", .initfn = arm1136_r2_initfn }, |
| 1794 | { .name = "arm1136", .initfn = arm1136_initfn }, |
| 1795 | { .name = "arm1176", .initfn = arm1176_initfn }, |
| 1796 | { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, |
Andreas Färber | e6f010c | 2013-02-02 12:33:14 +0100 | [diff] [blame] | 1797 | { .name = "cortex-m3", .initfn = cortex_m3_initfn, |
| 1798 | .class_init = arm_v7m_class_init }, |
Aurelio C. Remonda | ba890a9 | 2015-06-19 14:17:44 +0100 | [diff] [blame] | 1799 | { .name = "cortex-m4", .initfn = cortex_m4_initfn, |
| 1800 | .class_init = arm_v7m_class_init }, |
Peter Maydell | c7b2638 | 2018-03-02 10:45:37 +0000 | [diff] [blame] | 1801 | { .name = "cortex-m33", .initfn = cortex_m33_initfn, |
| 1802 | .class_init = arm_v7m_class_init }, |
Peter Crosthwaite | d6a6b13 | 2015-06-19 14:17:45 +0100 | [diff] [blame] | 1803 | { .name = "cortex-r5", .initfn = cortex_r5_initfn }, |
Andrey Yurovsky | dcf578e | 2016-09-22 18:13:05 +0100 | [diff] [blame] | 1804 | { .name = "cortex-a7", .initfn = cortex_a7_initfn }, |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1805 | { .name = "cortex-a8", .initfn = cortex_a8_initfn }, |
| 1806 | { .name = "cortex-a9", .initfn = cortex_a9_initfn }, |
| 1807 | { .name = "cortex-a15", .initfn = cortex_a15_initfn }, |
| 1808 | { .name = "ti925t", .initfn = ti925t_initfn }, |
| 1809 | { .name = "sa1100", .initfn = sa1100_initfn }, |
| 1810 | { .name = "sa1110", .initfn = sa1110_initfn }, |
| 1811 | { .name = "pxa250", .initfn = pxa250_initfn }, |
| 1812 | { .name = "pxa255", .initfn = pxa255_initfn }, |
| 1813 | { .name = "pxa260", .initfn = pxa260_initfn }, |
| 1814 | { .name = "pxa261", .initfn = pxa261_initfn }, |
| 1815 | { .name = "pxa262", .initfn = pxa262_initfn }, |
| 1816 | /* "pxa270" is an alias for "pxa270-a0" */ |
| 1817 | { .name = "pxa270", .initfn = pxa270a0_initfn }, |
| 1818 | { .name = "pxa270-a0", .initfn = pxa270a0_initfn }, |
| 1819 | { .name = "pxa270-a1", .initfn = pxa270a1_initfn }, |
| 1820 | { .name = "pxa270-b0", .initfn = pxa270b0_initfn }, |
| 1821 | { .name = "pxa270-b1", .initfn = pxa270b1_initfn }, |
| 1822 | { .name = "pxa270-c0", .initfn = pxa270c0_initfn }, |
| 1823 | { .name = "pxa270-c5", .initfn = pxa270c5_initfn }, |
Peter Maydell | bab52d4 | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 1824 | #ifndef TARGET_AARCH64 |
| 1825 | { .name = "max", .initfn = arm_max_initfn }, |
| 1826 | #endif |
Peter Maydell | f5f6d38 | 2013-09-10 19:09:32 +0100 | [diff] [blame] | 1827 | #ifdef CONFIG_USER_ONLY |
Peter Maydell | a0032cc | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 1828 | { .name = "any", .initfn = arm_max_initfn }, |
Peter Maydell | f5f6d38 | 2013-09-10 19:09:32 +0100 | [diff] [blame] | 1829 | #endif |
Peter Maydell | 15ee776 | 2013-09-03 20:12:08 +0100 | [diff] [blame] | 1830 | #endif |
Peter Maydell | 83e6813 | 2014-01-13 10:26:16 +0000 | [diff] [blame] | 1831 | { .name = NULL } |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1832 | }; |
| 1833 | |
Peter Maydell | 5de1643 | 2013-11-22 17:17:13 +0000 | [diff] [blame] | 1834 | static Property arm_cpu_properties[] = { |
| 1835 | DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false), |
Rob Herring | 9812860 | 2014-10-24 12:19:13 +0100 | [diff] [blame] | 1836 | DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0), |
Alistair Francis | 51a9b04 | 2014-01-31 14:47:32 +0000 | [diff] [blame] | 1837 | DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0), |
Laurent Vivier | ce5b1bb | 2016-10-20 13:26:03 +0200 | [diff] [blame] | 1838 | DEFINE_PROP_UINT64("mp-affinity", ARMCPU, |
| 1839 | mp_affinity, ARM64_AFFINITY_INVALID), |
Igor Mammedov | 15f8b14 | 2017-05-30 18:24:00 +0200 | [diff] [blame] | 1840 | DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID), |
Alistair Francis | f9a6971 | 2018-03-09 17:09:43 +0000 | [diff] [blame] | 1841 | DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1), |
Peter Maydell | 5de1643 | 2013-11-22 17:17:13 +0000 | [diff] [blame] | 1842 | DEFINE_PROP_END_OF_LIST() |
| 1843 | }; |
| 1844 | |
Peter Maydell | 8c6084b | 2015-05-29 11:28:51 +0100 | [diff] [blame] | 1845 | #ifdef CONFIG_USER_ONLY |
Laurent Vivier | 98670d4 | 2018-01-18 20:38:40 +0100 | [diff] [blame] | 1846 | static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, |
| 1847 | int rw, int mmu_idx) |
Peter Maydell | 8c6084b | 2015-05-29 11:28:51 +0100 | [diff] [blame] | 1848 | { |
| 1849 | ARMCPU *cpu = ARM_CPU(cs); |
| 1850 | CPUARMState *env = &cpu->env; |
| 1851 | |
| 1852 | env->exception.vaddress = address; |
| 1853 | if (rw == 2) { |
| 1854 | cs->exception_index = EXCP_PREFETCH_ABORT; |
| 1855 | } else { |
| 1856 | cs->exception_index = EXCP_DATA_ABORT; |
| 1857 | } |
| 1858 | return 1; |
| 1859 | } |
| 1860 | #endif |
| 1861 | |
David Hildenbrand | b3820e6 | 2015-12-03 13:14:41 +0100 | [diff] [blame] | 1862 | static gchar *arm_gdb_arch_name(CPUState *cs) |
| 1863 | { |
| 1864 | ARMCPU *cpu = ARM_CPU(cs); |
| 1865 | CPUARMState *env = &cpu->env; |
| 1866 | |
| 1867 | if (arm_feature(env, ARM_FEATURE_IWMMXT)) { |
| 1868 | return g_strdup("iwmmxt"); |
| 1869 | } |
| 1870 | return g_strdup("arm"); |
| 1871 | } |
| 1872 | |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1873 | static void arm_cpu_class_init(ObjectClass *oc, void *data) |
| 1874 | { |
| 1875 | ARMCPUClass *acc = ARM_CPU_CLASS(oc); |
| 1876 | CPUClass *cc = CPU_CLASS(acc); |
Andreas Färber | 1496926 | 2013-01-05 10:18:18 +0100 | [diff] [blame] | 1877 | DeviceClass *dc = DEVICE_CLASS(oc); |
| 1878 | |
Philippe Mathieu-Daudé | bf85388 | 2018-01-13 23:04:12 -0300 | [diff] [blame] | 1879 | device_class_set_parent_realize(dc, arm_cpu_realizefn, |
| 1880 | &acc->parent_realize); |
Peter Maydell | 5de1643 | 2013-11-22 17:17:13 +0000 | [diff] [blame] | 1881 | dc->props = arm_cpu_properties; |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1882 | |
| 1883 | acc->parent_reset = cc->reset; |
| 1884 | cc->reset = arm_cpu_reset; |
Andreas Färber | 5900d6b | 2013-01-21 16:11:43 +0100 | [diff] [blame] | 1885 | |
| 1886 | cc->class_by_name = arm_cpu_class_by_name; |
Andreas Färber | 8c2e1b0 | 2013-08-25 18:53:55 +0200 | [diff] [blame] | 1887 | cc->has_work = arm_cpu_has_work; |
Richard Henderson | e892571 | 2014-09-13 09:45:25 -0700 | [diff] [blame] | 1888 | cc->cpu_exec_interrupt = arm_cpu_exec_interrupt; |
Andreas Färber | 878096e | 2013-05-27 01:33:50 +0200 | [diff] [blame] | 1889 | cc->dump_state = arm_cpu_dump_state; |
Andreas Färber | f45748f | 2013-06-21 19:09:18 +0200 | [diff] [blame] | 1890 | cc->set_pc = arm_cpu_set_pc; |
Andreas Färber | 5b50e79 | 2013-06-29 04:18:45 +0200 | [diff] [blame] | 1891 | cc->gdb_read_register = arm_cpu_gdb_read_register; |
| 1892 | cc->gdb_write_register = arm_cpu_gdb_write_register; |
Andreas Färber | 7510454 | 2013-08-26 03:01:33 +0200 | [diff] [blame] | 1893 | #ifdef CONFIG_USER_ONLY |
| 1894 | cc->handle_mmu_fault = arm_cpu_handle_mmu_fault; |
| 1895 | #else |
Rob Herring | 0adf7d3 | 2014-10-24 12:19:12 +0100 | [diff] [blame] | 1896 | cc->do_interrupt = arm_cpu_do_interrupt; |
Andrew Baumann | 3090147 | 2015-12-17 13:37:13 +0000 | [diff] [blame] | 1897 | cc->do_unaligned_access = arm_cpu_do_unaligned_access; |
Peter Maydell | c79c0a3 | 2017-09-07 13:54:55 +0100 | [diff] [blame] | 1898 | cc->do_transaction_failed = arm_cpu_do_transaction_failed; |
Peter Maydell | 0faea0c | 2016-01-21 14:15:07 +0000 | [diff] [blame] | 1899 | cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug; |
Peter Maydell | 017518c | 2016-01-21 14:15:06 +0000 | [diff] [blame] | 1900 | cc->asidx_from_attrs = arm_asidx_from_attrs; |
Andreas Färber | 00b941e | 2013-06-29 18:55:54 +0200 | [diff] [blame] | 1901 | cc->vmsd = &vmstate_arm_cpu; |
Peter Crosthwaite | ed50ff7 | 2016-03-04 11:30:19 +0000 | [diff] [blame] | 1902 | cc->virtio_is_big_endian = arm_cpu_virtio_is_big_endian; |
Andrew Jones | da2b914 | 2016-01-11 20:56:22 +0100 | [diff] [blame] | 1903 | cc->write_elf64_note = arm_cpu_write_elf64_note; |
| 1904 | cc->write_elf32_note = arm_cpu_write_elf32_note; |
Andreas Färber | 00b941e | 2013-06-29 18:55:54 +0200 | [diff] [blame] | 1905 | #endif |
Andreas Färber | a0e372f | 2013-06-28 23:18:47 +0200 | [diff] [blame] | 1906 | cc->gdb_num_core_regs = 26; |
Andreas Färber | 5b24c64 | 2013-07-07 15:08:22 +0200 | [diff] [blame] | 1907 | cc->gdb_core_xml_file = "arm-core.xml"; |
David Hildenbrand | b3820e6 | 2015-12-03 13:14:41 +0100 | [diff] [blame] | 1908 | cc->gdb_arch_name = arm_gdb_arch_name; |
Peter Maydell | 2472b6c | 2014-09-12 19:04:17 +0100 | [diff] [blame] | 1909 | cc->gdb_stop_before_watchpoint = true; |
Peter Maydell | 3ff6fc9 | 2014-09-12 14:06:49 +0100 | [diff] [blame] | 1910 | cc->debug_excp_handler = arm_debug_excp_handler; |
Sergey Fedorov | 3826121 | 2016-02-11 11:17:32 +0000 | [diff] [blame] | 1911 | cc->debug_check_watchpoint = arm_debug_check_watchpoint; |
Julian Brown | 4061200 | 2017-02-07 18:29:59 +0000 | [diff] [blame] | 1912 | #if !defined(CONFIG_USER_ONLY) |
| 1913 | cc->adjust_watchpoint_address = arm_adjust_watchpoint_address; |
| 1914 | #endif |
Peter Crosthwaite | 4844062 | 2015-06-23 20:57:35 -0700 | [diff] [blame] | 1915 | |
| 1916 | cc->disas_set_info = arm_disas_set_info; |
Richard Henderson | 74d7fc7 | 2017-10-26 15:58:14 +0200 | [diff] [blame] | 1917 | #ifdef CONFIG_TCG |
Richard Henderson | 55c3cee | 2017-10-15 19:02:42 -0700 | [diff] [blame] | 1918 | cc->tcg_initialize = arm_translate_init; |
Richard Henderson | 74d7fc7 | 2017-10-26 15:58:14 +0200 | [diff] [blame] | 1919 | #endif |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1920 | } |
| 1921 | |
Peter Maydell | 86f0a18 | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 1922 | #ifdef CONFIG_KVM |
| 1923 | static void arm_host_initfn(Object *obj) |
| 1924 | { |
| 1925 | ARMCPU *cpu = ARM_CPU(obj); |
| 1926 | |
| 1927 | kvm_arm_set_cpu_features_from_host(cpu); |
| 1928 | } |
| 1929 | |
| 1930 | static const TypeInfo host_arm_cpu_type_info = { |
| 1931 | .name = TYPE_ARM_HOST_CPU, |
| 1932 | #ifdef TARGET_AARCH64 |
| 1933 | .parent = TYPE_AARCH64_CPU, |
| 1934 | #else |
| 1935 | .parent = TYPE_ARM_CPU, |
| 1936 | #endif |
| 1937 | .instance_init = arm_host_initfn, |
| 1938 | }; |
| 1939 | |
| 1940 | #endif |
| 1941 | |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1942 | static void cpu_register(const ARMCPUInfo *info) |
| 1943 | { |
| 1944 | TypeInfo type_info = { |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1945 | .parent = TYPE_ARM_CPU, |
| 1946 | .instance_size = sizeof(ARMCPU), |
| 1947 | .instance_init = info->initfn, |
| 1948 | .class_size = sizeof(ARMCPUClass), |
Andreas Färber | e6f010c | 2013-02-02 12:33:14 +0100 | [diff] [blame] | 1949 | .class_init = info->class_init, |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1950 | }; |
| 1951 | |
Andreas Färber | 51492fd | 2013-01-27 17:30:10 +0100 | [diff] [blame] | 1952 | type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name); |
Eduardo Habkost | 918fd08 | 2013-01-11 15:21:22 +0000 | [diff] [blame] | 1953 | type_register(&type_info); |
Andreas Färber | 51492fd | 2013-01-27 17:30:10 +0100 | [diff] [blame] | 1954 | g_free((void *)type_info.name); |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1955 | } |
| 1956 | |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1957 | static const TypeInfo arm_cpu_type_info = { |
| 1958 | .name = TYPE_ARM_CPU, |
| 1959 | .parent = TYPE_CPU, |
| 1960 | .instance_size = sizeof(ARMCPU), |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1961 | .instance_init = arm_cpu_initfn, |
Peter Crosthwaite | 07a5b0d | 2013-12-17 19:42:28 +0000 | [diff] [blame] | 1962 | .instance_post_init = arm_cpu_post_init, |
Peter Maydell | 4b6a83f | 2012-06-20 11:57:06 +0000 | [diff] [blame] | 1963 | .instance_finalize = arm_cpu_finalizefn, |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1964 | .abstract = true, |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1965 | .class_size = sizeof(ARMCPUClass), |
| 1966 | .class_init = arm_cpu_class_init, |
| 1967 | }; |
| 1968 | |
Peter Maydell | 181962f | 2018-03-02 10:45:36 +0000 | [diff] [blame] | 1969 | static const TypeInfo idau_interface_type_info = { |
| 1970 | .name = TYPE_IDAU_INTERFACE, |
| 1971 | .parent = TYPE_INTERFACE, |
| 1972 | .class_size = sizeof(IDAUInterfaceClass), |
| 1973 | }; |
| 1974 | |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1975 | static void arm_cpu_register_types(void) |
| 1976 | { |
Peter Maydell | 83e6813 | 2014-01-13 10:26:16 +0000 | [diff] [blame] | 1977 | const ARMCPUInfo *info = arm_cpus; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1978 | |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1979 | type_register_static(&arm_cpu_type_info); |
Peter Maydell | 181962f | 2018-03-02 10:45:36 +0000 | [diff] [blame] | 1980 | type_register_static(&idau_interface_type_info); |
Peter Maydell | 83e6813 | 2014-01-13 10:26:16 +0000 | [diff] [blame] | 1981 | |
| 1982 | while (info->name) { |
| 1983 | cpu_register(info); |
| 1984 | info++; |
Peter Maydell | 777dc78 | 2012-04-20 17:58:31 +0000 | [diff] [blame] | 1985 | } |
Peter Maydell | 86f0a18 | 2018-03-09 17:09:44 +0000 | [diff] [blame] | 1986 | |
| 1987 | #ifdef CONFIG_KVM |
| 1988 | type_register_static(&host_arm_cpu_type_info); |
| 1989 | #endif |
Andreas Färber | dec9c2d | 2012-03-29 04:50:31 +0000 | [diff] [blame] | 1990 | } |
| 1991 | |
| 1992 | type_init(arm_cpu_register_types) |