]> git.proxmox.com Git - qemu.git/blob - target-arm/helper.c
target-arm: Move SCTLR reset value setup to per cpu init fns
[qemu.git] / target-arm / helper.c
1 #include "cpu.h"
2 #include "gdbstub.h"
3 #include "helper.h"
4 #include "host-utils.h"
5 #if !defined(CONFIG_USER_ONLY)
6 #include "hw/loader.h"
7 #endif
8 #include "sysemu.h"
9
10 static uint32_t cortexa15_cp15_c0_c1[8] = {
11 0x00001131, 0x00011011, 0x02010555, 0x00000000,
12 0x10201105, 0x20000000, 0x01240000, 0x02102211
13 };
14
15 static uint32_t cortexa15_cp15_c0_c2[8] = {
16 0x02101110, 0x13112111, 0x21232041, 0x11112131, 0x10011142, 0, 0, 0
17 };
18
19 static uint32_t cortexa9_cp15_c0_c1[8] =
20 { 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 };
21
22 static uint32_t cortexa9_cp15_c0_c2[8] =
23 { 0x00101111, 0x13112111, 0x21232041, 0x11112131, 0x00111142, 0, 0, 0 };
24
25 static uint32_t cortexa8_cp15_c0_c1[8] =
26 { 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };
27
28 static uint32_t cortexa8_cp15_c0_c2[8] =
29 { 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 };
30
31 static uint32_t mpcore_cp15_c0_c1[8] =
32 { 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 };
33
34 static uint32_t mpcore_cp15_c0_c2[8] =
35 { 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 };
36
37 static uint32_t arm1136_cp15_c0_c1[8] =
38 { 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 };
39
40 static uint32_t arm1136_cp15_c0_c2[8] =
41 { 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 };
42
43 static uint32_t arm1176_cp15_c0_c1[8] =
44 { 0x111, 0x11, 0x33, 0, 0x01130003, 0x10030302, 0x01222100, 0 };
45
46 static uint32_t arm1176_cp15_c0_c2[8] =
47 { 0x0140011, 0x12002111, 0x11231121, 0x01102131, 0x01141, 0, 0, 0 };
48
49 static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
50 {
51 switch (id) {
52 case ARM_CPUID_ARM926:
53 break;
54 case ARM_CPUID_ARM946:
55 break;
56 case ARM_CPUID_ARM1026:
57 break;
58 case ARM_CPUID_ARM1136:
59 /* This is the 1136 r1, which is a v6K core */
60 case ARM_CPUID_ARM1136_R2:
61 /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
62 * older core than plain "arm1136". In particular this does not
63 * have the v6K features.
64 */
65 /* These ID register values are correct for 1136 but may be wrong
66 * for 1136_r2 (in particular r0p2 does not actually implement most
67 * of the ID registers).
68 */
69 memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t));
70 memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
71 break;
72 case ARM_CPUID_ARM1176:
73 memcpy(env->cp15.c0_c1, arm1176_cp15_c0_c1, 8 * sizeof(uint32_t));
74 memcpy(env->cp15.c0_c2, arm1176_cp15_c0_c2, 8 * sizeof(uint32_t));
75 break;
76 case ARM_CPUID_ARM11MPCORE:
77 memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t));
78 memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
79 break;
80 case ARM_CPUID_CORTEXA8:
81 memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
82 memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
83 env->cp15.c0_clid = (1 << 27) | (2 << 24) | 3;
84 env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */
85 env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */
86 env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */
87 break;
88 case ARM_CPUID_CORTEXA9:
89 memcpy(env->cp15.c0_c1, cortexa9_cp15_c0_c1, 8 * sizeof(uint32_t));
90 memcpy(env->cp15.c0_c2, cortexa9_cp15_c0_c2, 8 * sizeof(uint32_t));
91 env->cp15.c0_clid = (1 << 27) | (1 << 24) | 3;
92 env->cp15.c0_ccsid[0] = 0xe00fe015; /* 16k L1 dcache. */
93 env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */
94 break;
95 case ARM_CPUID_CORTEXA15:
96 memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t));
97 memcpy(env->cp15.c0_c2, cortexa15_cp15_c0_c2, 8 * sizeof(uint32_t));
98 env->cp15.c0_clid = 0x0a200023;
99 env->cp15.c0_ccsid[0] = 0x701fe00a; /* 32K L1 dcache */
100 env->cp15.c0_ccsid[1] = 0x201fe00a; /* 32K L1 icache */
101 env->cp15.c0_ccsid[2] = 0x711fe07a; /* 4096K L2 unified cache */
102 break;
103 case ARM_CPUID_CORTEXM3:
104 break;
105 case ARM_CPUID_ANY: /* For userspace emulation. */
106 break;
107 case ARM_CPUID_TI915T:
108 case ARM_CPUID_TI925T:
109 env->cp15.c15_i_max = 0x000;
110 env->cp15.c15_i_min = 0xff0;
111 break;
112 case ARM_CPUID_PXA250:
113 case ARM_CPUID_PXA255:
114 case ARM_CPUID_PXA260:
115 case ARM_CPUID_PXA261:
116 case ARM_CPUID_PXA262:
117 /* JTAG_ID is ((id << 28) | 0x09265013) */
118 break;
119 case ARM_CPUID_PXA270_A0:
120 case ARM_CPUID_PXA270_A1:
121 case ARM_CPUID_PXA270_B0:
122 case ARM_CPUID_PXA270_B1:
123 case ARM_CPUID_PXA270_C0:
124 case ARM_CPUID_PXA270_C5:
125 /* JTAG_ID is ((id << 28) | 0x09265013) */
126 env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
127 break;
128 case ARM_CPUID_SA1100:
129 case ARM_CPUID_SA1110:
130 break;
131 default:
132 cpu_abort(env, "Bad CPU ID: %x\n", id);
133 break;
134 }
135
136 }
137
138 /* TODO Move contents into arm_cpu_reset() in cpu.c,
139 * once cpu_reset_model_id() is eliminated,
140 * and then forward to cpu_reset() here.
141 */
142 void cpu_state_reset(CPUARMState *env)
143 {
144 uint32_t id;
145 uint32_t tmp = 0;
146 ARMCPU *cpu = arm_env_get_cpu(env);
147
148 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
149 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
150 log_cpu_state(env, 0);
151 }
152
153 id = cpu->midr;
154 tmp = env->cp15.c15_config_base_address;
155 memset(env, 0, offsetof(CPUARMState, breakpoints));
156 if (id)
157 cpu_reset_model_id(env, id);
158 env->cp15.c15_config_base_address = tmp;
159 env->cp15.c0_cpuid = cpu->midr;
160 env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
161 env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
162 env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
163 env->cp15.c0_cachetype = cpu->ctr;
164 env->cp15.c1_sys = cpu->reset_sctlr;
165
166 #if defined (CONFIG_USER_ONLY)
167 env->uncached_cpsr = ARM_CPU_MODE_USR;
168 /* For user mode we must enable access to coprocessors */
169 env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
170 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
171 env->cp15.c15_cpar = 3;
172 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
173 env->cp15.c15_cpar = 1;
174 }
175 #else
176 /* SVC mode with interrupts disabled. */
177 env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
178 /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
179 clear at reset. Initial SP and PC are loaded from ROM. */
180 if (IS_M(env)) {
181 uint32_t pc;
182 uint8_t *rom;
183 env->uncached_cpsr &= ~CPSR_I;
184 rom = rom_ptr(0);
185 if (rom) {
186 /* We should really use ldl_phys here, in case the guest
187 modified flash and reset itself. However images
188 loaded via -kernel have not been copied yet, so load the
189 values directly from there. */
190 env->regs[13] = ldl_p(rom);
191 pc = ldl_p(rom + 4);
192 env->thumb = pc & 1;
193 env->regs[15] = pc & ~1;
194 }
195 }
196 env->vfp.xregs[ARM_VFP_FPEXC] = 0;
197 env->cp15.c2_base_mask = 0xffffc000u;
198 /* v7 performance monitor control register: same implementor
199 * field as main ID register, and we implement no event counters.
200 */
201 env->cp15.c9_pmcr = (id & 0xff000000);
202 #endif
203 set_flush_to_zero(1, &env->vfp.standard_fp_status);
204 set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status);
205 set_default_nan_mode(1, &env->vfp.standard_fp_status);
206 set_float_detect_tininess(float_tininess_before_rounding,
207 &env->vfp.fp_status);
208 set_float_detect_tininess(float_tininess_before_rounding,
209 &env->vfp.standard_fp_status);
210 tlb_flush(env, 1);
211 /* Reset is a state change for some CPUARMState fields which we
212 * bake assumptions about into translated code, so we need to
213 * tb_flush().
214 */
215 tb_flush(env);
216 }
217
218 static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
219 {
220 int nregs;
221
222 /* VFP data registers are always little-endian. */
223 nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
224 if (reg < nregs) {
225 stfq_le_p(buf, env->vfp.regs[reg]);
226 return 8;
227 }
228 if (arm_feature(env, ARM_FEATURE_NEON)) {
229 /* Aliases for Q regs. */
230 nregs += 16;
231 if (reg < nregs) {
232 stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
233 stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
234 return 16;
235 }
236 }
237 switch (reg - nregs) {
238 case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4;
239 case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4;
240 case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4;
241 }
242 return 0;
243 }
244
245 static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
246 {
247 int nregs;
248
249 nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
250 if (reg < nregs) {
251 env->vfp.regs[reg] = ldfq_le_p(buf);
252 return 8;
253 }
254 if (arm_feature(env, ARM_FEATURE_NEON)) {
255 nregs += 16;
256 if (reg < nregs) {
257 env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf);
258 env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8);
259 return 16;
260 }
261 }
262 switch (reg - nregs) {
263 case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
264 case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4;
265 case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
266 }
267 return 0;
268 }
269
270 CPUARMState *cpu_arm_init(const char *cpu_model)
271 {
272 ARMCPU *cpu;
273 CPUARMState *env;
274 static int inited = 0;
275
276 if (!object_class_by_name(cpu_model)) {
277 return NULL;
278 }
279 cpu = ARM_CPU(object_new(cpu_model));
280 env = &cpu->env;
281 env->cpu_model_str = cpu_model;
282 arm_cpu_realize(cpu);
283
284 if (tcg_enabled() && !inited) {
285 inited = 1;
286 arm_translate_init();
287 }
288
289 cpu_state_reset(env);
290 if (arm_feature(env, ARM_FEATURE_NEON)) {
291 gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
292 51, "arm-neon.xml", 0);
293 } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
294 gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
295 35, "arm-vfp3.xml", 0);
296 } else if (arm_feature(env, ARM_FEATURE_VFP)) {
297 gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
298 19, "arm-vfp.xml", 0);
299 }
300 qemu_init_vcpu(env);
301 return env;
302 }
303
304 typedef struct ARMCPUListState {
305 fprintf_function cpu_fprintf;
306 FILE *file;
307 } ARMCPUListState;
308
309 /* Sort alphabetically by type name, except for "any". */
310 static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b)
311 {
312 ObjectClass *class_a = (ObjectClass *)a;
313 ObjectClass *class_b = (ObjectClass *)b;
314 const char *name_a, *name_b;
315
316 name_a = object_class_get_name(class_a);
317 name_b = object_class_get_name(class_b);
318 if (strcmp(name_a, "any") == 0) {
319 return 1;
320 } else if (strcmp(name_b, "any") == 0) {
321 return -1;
322 } else {
323 return strcmp(name_a, name_b);
324 }
325 }
326
327 static void arm_cpu_list_entry(gpointer data, gpointer user_data)
328 {
329 ObjectClass *oc = data;
330 ARMCPUListState *s = user_data;
331
332 (*s->cpu_fprintf)(s->file, " %s\n",
333 object_class_get_name(oc));
334 }
335
336 void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
337 {
338 ARMCPUListState s = {
339 .file = f,
340 .cpu_fprintf = cpu_fprintf,
341 };
342 GSList *list;
343
344 list = object_class_get_list(TYPE_ARM_CPU, false);
345 list = g_slist_sort(list, arm_cpu_list_compare);
346 (*cpu_fprintf)(f, "Available CPUs:\n");
347 g_slist_foreach(list, arm_cpu_list_entry, &s);
348 g_slist_free(list);
349 }
350
351 static int bad_mode_switch(CPUARMState *env, int mode)
352 {
353 /* Return true if it is not valid for us to switch to
354 * this CPU mode (ie all the UNPREDICTABLE cases in
355 * the ARM ARM CPSRWriteByInstr pseudocode).
356 */
357 switch (mode) {
358 case ARM_CPU_MODE_USR:
359 case ARM_CPU_MODE_SYS:
360 case ARM_CPU_MODE_SVC:
361 case ARM_CPU_MODE_ABT:
362 case ARM_CPU_MODE_UND:
363 case ARM_CPU_MODE_IRQ:
364 case ARM_CPU_MODE_FIQ:
365 return 0;
366 default:
367 return 1;
368 }
369 }
370
371 uint32_t cpsr_read(CPUARMState *env)
372 {
373 int ZF;
374 ZF = (env->ZF == 0);
375 return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
376 (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
377 | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
378 | ((env->condexec_bits & 0xfc) << 8)
379 | (env->GE << 16);
380 }
381
382 void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
383 {
384 if (mask & CPSR_NZCV) {
385 env->ZF = (~val) & CPSR_Z;
386 env->NF = val;
387 env->CF = (val >> 29) & 1;
388 env->VF = (val << 3) & 0x80000000;
389 }
390 if (mask & CPSR_Q)
391 env->QF = ((val & CPSR_Q) != 0);
392 if (mask & CPSR_T)
393 env->thumb = ((val & CPSR_T) != 0);
394 if (mask & CPSR_IT_0_1) {
395 env->condexec_bits &= ~3;
396 env->condexec_bits |= (val >> 25) & 3;
397 }
398 if (mask & CPSR_IT_2_7) {
399 env->condexec_bits &= 3;
400 env->condexec_bits |= (val >> 8) & 0xfc;
401 }
402 if (mask & CPSR_GE) {
403 env->GE = (val >> 16) & 0xf;
404 }
405
406 if ((env->uncached_cpsr ^ val) & mask & CPSR_M) {
407 if (bad_mode_switch(env, val & CPSR_M)) {
408 /* Attempt to switch to an invalid mode: this is UNPREDICTABLE.
409 * We choose to ignore the attempt and leave the CPSR M field
410 * untouched.
411 */
412 mask &= ~CPSR_M;
413 } else {
414 switch_mode(env, val & CPSR_M);
415 }
416 }
417 mask &= ~CACHED_CPSR_BITS;
418 env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
419 }
420
421 /* Sign/zero extend */
422 uint32_t HELPER(sxtb16)(uint32_t x)
423 {
424 uint32_t res;
425 res = (uint16_t)(int8_t)x;
426 res |= (uint32_t)(int8_t)(x >> 16) << 16;
427 return res;
428 }
429
430 uint32_t HELPER(uxtb16)(uint32_t x)
431 {
432 uint32_t res;
433 res = (uint16_t)(uint8_t)x;
434 res |= (uint32_t)(uint8_t)(x >> 16) << 16;
435 return res;
436 }
437
438 uint32_t HELPER(clz)(uint32_t x)
439 {
440 return clz32(x);
441 }
442
443 int32_t HELPER(sdiv)(int32_t num, int32_t den)
444 {
445 if (den == 0)
446 return 0;
447 if (num == INT_MIN && den == -1)
448 return INT_MIN;
449 return num / den;
450 }
451
452 uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
453 {
454 if (den == 0)
455 return 0;
456 return num / den;
457 }
458
459 uint32_t HELPER(rbit)(uint32_t x)
460 {
461 x = ((x & 0xff000000) >> 24)
462 | ((x & 0x00ff0000) >> 8)
463 | ((x & 0x0000ff00) << 8)
464 | ((x & 0x000000ff) << 24);
465 x = ((x & 0xf0f0f0f0) >> 4)
466 | ((x & 0x0f0f0f0f) << 4);
467 x = ((x & 0x88888888) >> 3)
468 | ((x & 0x44444444) >> 1)
469 | ((x & 0x22222222) << 1)
470 | ((x & 0x11111111) << 3);
471 return x;
472 }
473
474 uint32_t HELPER(abs)(uint32_t x)
475 {
476 return ((int32_t)x < 0) ? -x : x;
477 }
478
479 #if defined(CONFIG_USER_ONLY)
480
481 void do_interrupt (CPUARMState *env)
482 {
483 env->exception_index = -1;
484 }
485
486 int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
487 int mmu_idx)
488 {
489 if (rw == 2) {
490 env->exception_index = EXCP_PREFETCH_ABORT;
491 env->cp15.c6_insn = address;
492 } else {
493 env->exception_index = EXCP_DATA_ABORT;
494 env->cp15.c6_data = address;
495 }
496 return 1;
497 }
498
499 /* These should probably raise undefined insn exceptions. */
500 void HELPER(set_cp)(CPUARMState *env, uint32_t insn, uint32_t val)
501 {
502 int op1 = (insn >> 8) & 0xf;
503 cpu_abort(env, "cp%i insn %08x\n", op1, insn);
504 return;
505 }
506
507 uint32_t HELPER(get_cp)(CPUARMState *env, uint32_t insn)
508 {
509 int op1 = (insn >> 8) & 0xf;
510 cpu_abort(env, "cp%i insn %08x\n", op1, insn);
511 return 0;
512 }
513
514 void HELPER(set_cp15)(CPUARMState *env, uint32_t insn, uint32_t val)
515 {
516 cpu_abort(env, "cp15 insn %08x\n", insn);
517 }
518
519 uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
520 {
521 cpu_abort(env, "cp15 insn %08x\n", insn);
522 }
523
524 /* These should probably raise undefined insn exceptions. */
525 void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
526 {
527 cpu_abort(env, "v7m_mrs %d\n", reg);
528 }
529
530 uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
531 {
532 cpu_abort(env, "v7m_mrs %d\n", reg);
533 return 0;
534 }
535
536 void switch_mode(CPUARMState *env, int mode)
537 {
538 if (mode != ARM_CPU_MODE_USR)
539 cpu_abort(env, "Tried to switch out of user mode\n");
540 }
541
542 void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
543 {
544 cpu_abort(env, "banked r13 write\n");
545 }
546
547 uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
548 {
549 cpu_abort(env, "banked r13 read\n");
550 return 0;
551 }
552
553 #else
554
555 /* Map CPU modes onto saved register banks. */
556 static inline int bank_number(CPUARMState *env, int mode)
557 {
558 switch (mode) {
559 case ARM_CPU_MODE_USR:
560 case ARM_CPU_MODE_SYS:
561 return 0;
562 case ARM_CPU_MODE_SVC:
563 return 1;
564 case ARM_CPU_MODE_ABT:
565 return 2;
566 case ARM_CPU_MODE_UND:
567 return 3;
568 case ARM_CPU_MODE_IRQ:
569 return 4;
570 case ARM_CPU_MODE_FIQ:
571 return 5;
572 }
573 cpu_abort(env, "Bad mode %x\n", mode);
574 return -1;
575 }
576
577 void switch_mode(CPUARMState *env, int mode)
578 {
579 int old_mode;
580 int i;
581
582 old_mode = env->uncached_cpsr & CPSR_M;
583 if (mode == old_mode)
584 return;
585
586 if (old_mode == ARM_CPU_MODE_FIQ) {
587 memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
588 memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
589 } else if (mode == ARM_CPU_MODE_FIQ) {
590 memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
591 memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
592 }
593
594 i = bank_number(env, old_mode);
595 env->banked_r13[i] = env->regs[13];
596 env->banked_r14[i] = env->regs[14];
597 env->banked_spsr[i] = env->spsr;
598
599 i = bank_number(env, mode);
600 env->regs[13] = env->banked_r13[i];
601 env->regs[14] = env->banked_r14[i];
602 env->spsr = env->banked_spsr[i];
603 }
604
605 static void v7m_push(CPUARMState *env, uint32_t val)
606 {
607 env->regs[13] -= 4;
608 stl_phys(env->regs[13], val);
609 }
610
611 static uint32_t v7m_pop(CPUARMState *env)
612 {
613 uint32_t val;
614 val = ldl_phys(env->regs[13]);
615 env->regs[13] += 4;
616 return val;
617 }
618
619 /* Switch to V7M main or process stack pointer. */
620 static void switch_v7m_sp(CPUARMState *env, int process)
621 {
622 uint32_t tmp;
623 if (env->v7m.current_sp != process) {
624 tmp = env->v7m.other_sp;
625 env->v7m.other_sp = env->regs[13];
626 env->regs[13] = tmp;
627 env->v7m.current_sp = process;
628 }
629 }
630
631 static void do_v7m_exception_exit(CPUARMState *env)
632 {
633 uint32_t type;
634 uint32_t xpsr;
635
636 type = env->regs[15];
637 if (env->v7m.exception != 0)
638 armv7m_nvic_complete_irq(env->nvic, env->v7m.exception);
639
640 /* Switch to the target stack. */
641 switch_v7m_sp(env, (type & 4) != 0);
642 /* Pop registers. */
643 env->regs[0] = v7m_pop(env);
644 env->regs[1] = v7m_pop(env);
645 env->regs[2] = v7m_pop(env);
646 env->regs[3] = v7m_pop(env);
647 env->regs[12] = v7m_pop(env);
648 env->regs[14] = v7m_pop(env);
649 env->regs[15] = v7m_pop(env);
650 xpsr = v7m_pop(env);
651 xpsr_write(env, xpsr, 0xfffffdff);
652 /* Undo stack alignment. */
653 if (xpsr & 0x200)
654 env->regs[13] |= 4;
655 /* ??? The exception return type specifies Thread/Handler mode. However
656 this is also implied by the xPSR value. Not sure what to do
657 if there is a mismatch. */
658 /* ??? Likewise for mismatches between the CONTROL register and the stack
659 pointer. */
660 }
661
662 static void do_interrupt_v7m(CPUARMState *env)
663 {
664 uint32_t xpsr = xpsr_read(env);
665 uint32_t lr;
666 uint32_t addr;
667
668 lr = 0xfffffff1;
669 if (env->v7m.current_sp)
670 lr |= 4;
671 if (env->v7m.exception == 0)
672 lr |= 8;
673
674 /* For exceptions we just mark as pending on the NVIC, and let that
675 handle it. */
676 /* TODO: Need to escalate if the current priority is higher than the
677 one we're raising. */
678 switch (env->exception_index) {
679 case EXCP_UDEF:
680 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
681 return;
682 case EXCP_SWI:
683 env->regs[15] += 2;
684 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
685 return;
686 case EXCP_PREFETCH_ABORT:
687 case EXCP_DATA_ABORT:
688 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
689 return;
690 case EXCP_BKPT:
691 if (semihosting_enabled) {
692 int nr;
693 nr = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
694 if (nr == 0xab) {
695 env->regs[15] += 2;
696 env->regs[0] = do_arm_semihosting(env);
697 return;
698 }
699 }
700 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
701 return;
702 case EXCP_IRQ:
703 env->v7m.exception = armv7m_nvic_acknowledge_irq(env->nvic);
704 break;
705 case EXCP_EXCEPTION_EXIT:
706 do_v7m_exception_exit(env);
707 return;
708 default:
709 cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
710 return; /* Never happens. Keep compiler happy. */
711 }
712
713 /* Align stack pointer. */
714 /* ??? Should only do this if Configuration Control Register
715 STACKALIGN bit is set. */
716 if (env->regs[13] & 4) {
717 env->regs[13] -= 4;
718 xpsr |= 0x200;
719 }
720 /* Switch to the handler mode. */
721 v7m_push(env, xpsr);
722 v7m_push(env, env->regs[15]);
723 v7m_push(env, env->regs[14]);
724 v7m_push(env, env->regs[12]);
725 v7m_push(env, env->regs[3]);
726 v7m_push(env, env->regs[2]);
727 v7m_push(env, env->regs[1]);
728 v7m_push(env, env->regs[0]);
729 switch_v7m_sp(env, 0);
730 /* Clear IT bits */
731 env->condexec_bits = 0;
732 env->regs[14] = lr;
733 addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
734 env->regs[15] = addr & 0xfffffffe;
735 env->thumb = addr & 1;
736 }
737
738 /* Handle a CPU exception. */
739 void do_interrupt(CPUARMState *env)
740 {
741 uint32_t addr;
742 uint32_t mask;
743 int new_mode;
744 uint32_t offset;
745
746 if (IS_M(env)) {
747 do_interrupt_v7m(env);
748 return;
749 }
750 /* TODO: Vectored interrupt controller. */
751 switch (env->exception_index) {
752 case EXCP_UDEF:
753 new_mode = ARM_CPU_MODE_UND;
754 addr = 0x04;
755 mask = CPSR_I;
756 if (env->thumb)
757 offset = 2;
758 else
759 offset = 4;
760 break;
761 case EXCP_SWI:
762 if (semihosting_enabled) {
763 /* Check for semihosting interrupt. */
764 if (env->thumb) {
765 mask = arm_lduw_code(env->regs[15] - 2, env->bswap_code) & 0xff;
766 } else {
767 mask = arm_ldl_code(env->regs[15] - 4, env->bswap_code)
768 & 0xffffff;
769 }
770 /* Only intercept calls from privileged modes, to provide some
771 semblance of security. */
772 if (((mask == 0x123456 && !env->thumb)
773 || (mask == 0xab && env->thumb))
774 && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
775 env->regs[0] = do_arm_semihosting(env);
776 return;
777 }
778 }
779 new_mode = ARM_CPU_MODE_SVC;
780 addr = 0x08;
781 mask = CPSR_I;
782 /* The PC already points to the next instruction. */
783 offset = 0;
784 break;
785 case EXCP_BKPT:
786 /* See if this is a semihosting syscall. */
787 if (env->thumb && semihosting_enabled) {
788 mask = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
789 if (mask == 0xab
790 && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
791 env->regs[15] += 2;
792 env->regs[0] = do_arm_semihosting(env);
793 return;
794 }
795 }
796 env->cp15.c5_insn = 2;
797 /* Fall through to prefetch abort. */
798 case EXCP_PREFETCH_ABORT:
799 new_mode = ARM_CPU_MODE_ABT;
800 addr = 0x0c;
801 mask = CPSR_A | CPSR_I;
802 offset = 4;
803 break;
804 case EXCP_DATA_ABORT:
805 new_mode = ARM_CPU_MODE_ABT;
806 addr = 0x10;
807 mask = CPSR_A | CPSR_I;
808 offset = 8;
809 break;
810 case EXCP_IRQ:
811 new_mode = ARM_CPU_MODE_IRQ;
812 addr = 0x18;
813 /* Disable IRQ and imprecise data aborts. */
814 mask = CPSR_A | CPSR_I;
815 offset = 4;
816 break;
817 case EXCP_FIQ:
818 new_mode = ARM_CPU_MODE_FIQ;
819 addr = 0x1c;
820 /* Disable FIQ, IRQ and imprecise data aborts. */
821 mask = CPSR_A | CPSR_I | CPSR_F;
822 offset = 4;
823 break;
824 default:
825 cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
826 return; /* Never happens. Keep compiler happy. */
827 }
828 /* High vectors. */
829 if (env->cp15.c1_sys & (1 << 13)) {
830 addr += 0xffff0000;
831 }
832 switch_mode (env, new_mode);
833 env->spsr = cpsr_read(env);
834 /* Clear IT bits. */
835 env->condexec_bits = 0;
836 /* Switch to the new mode, and to the correct instruction set. */
837 env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
838 env->uncached_cpsr |= mask;
839 /* this is a lie, as the was no c1_sys on V4T/V5, but who cares
840 * and we should just guard the thumb mode on V4 */
841 if (arm_feature(env, ARM_FEATURE_V4T)) {
842 env->thumb = (env->cp15.c1_sys & (1 << 30)) != 0;
843 }
844 env->regs[14] = env->regs[15] + offset;
845 env->regs[15] = addr;
846 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
847 }
848
849 /* Check section/page access permissions.
850 Returns the page protection flags, or zero if the access is not
851 permitted. */
852 static inline int check_ap(CPUARMState *env, int ap, int domain_prot,
853 int access_type, int is_user)
854 {
855 int prot_ro;
856
857 if (domain_prot == 3) {
858 return PAGE_READ | PAGE_WRITE;
859 }
860
861 if (access_type == 1)
862 prot_ro = 0;
863 else
864 prot_ro = PAGE_READ;
865
866 switch (ap) {
867 case 0:
868 if (access_type == 1)
869 return 0;
870 switch ((env->cp15.c1_sys >> 8) & 3) {
871 case 1:
872 return is_user ? 0 : PAGE_READ;
873 case 2:
874 return PAGE_READ;
875 default:
876 return 0;
877 }
878 case 1:
879 return is_user ? 0 : PAGE_READ | PAGE_WRITE;
880 case 2:
881 if (is_user)
882 return prot_ro;
883 else
884 return PAGE_READ | PAGE_WRITE;
885 case 3:
886 return PAGE_READ | PAGE_WRITE;
887 case 4: /* Reserved. */
888 return 0;
889 case 5:
890 return is_user ? 0 : prot_ro;
891 case 6:
892 return prot_ro;
893 case 7:
894 if (!arm_feature (env, ARM_FEATURE_V6K))
895 return 0;
896 return prot_ro;
897 default:
898 abort();
899 }
900 }
901
902 static uint32_t get_level1_table_address(CPUARMState *env, uint32_t address)
903 {
904 uint32_t table;
905
906 if (address & env->cp15.c2_mask)
907 table = env->cp15.c2_base1 & 0xffffc000;
908 else
909 table = env->cp15.c2_base0 & env->cp15.c2_base_mask;
910
911 table |= (address >> 18) & 0x3ffc;
912 return table;
913 }
914
915 static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
916 int is_user, uint32_t *phys_ptr, int *prot,
917 target_ulong *page_size)
918 {
919 int code;
920 uint32_t table;
921 uint32_t desc;
922 int type;
923 int ap;
924 int domain;
925 int domain_prot;
926 uint32_t phys_addr;
927
928 /* Pagetable walk. */
929 /* Lookup l1 descriptor. */
930 table = get_level1_table_address(env, address);
931 desc = ldl_phys(table);
932 type = (desc & 3);
933 domain = (desc >> 5) & 0x0f;
934 domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
935 if (type == 0) {
936 /* Section translation fault. */
937 code = 5;
938 goto do_fault;
939 }
940 if (domain_prot == 0 || domain_prot == 2) {
941 if (type == 2)
942 code = 9; /* Section domain fault. */
943 else
944 code = 11; /* Page domain fault. */
945 goto do_fault;
946 }
947 if (type == 2) {
948 /* 1Mb section. */
949 phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
950 ap = (desc >> 10) & 3;
951 code = 13;
952 *page_size = 1024 * 1024;
953 } else {
954 /* Lookup l2 entry. */
955 if (type == 1) {
956 /* Coarse pagetable. */
957 table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
958 } else {
959 /* Fine pagetable. */
960 table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
961 }
962 desc = ldl_phys(table);
963 switch (desc & 3) {
964 case 0: /* Page translation fault. */
965 code = 7;
966 goto do_fault;
967 case 1: /* 64k page. */
968 phys_addr = (desc & 0xffff0000) | (address & 0xffff);
969 ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
970 *page_size = 0x10000;
971 break;
972 case 2: /* 4k page. */
973 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
974 ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
975 *page_size = 0x1000;
976 break;
977 case 3: /* 1k page. */
978 if (type == 1) {
979 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
980 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
981 } else {
982 /* Page translation fault. */
983 code = 7;
984 goto do_fault;
985 }
986 } else {
987 phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
988 }
989 ap = (desc >> 4) & 3;
990 *page_size = 0x400;
991 break;
992 default:
993 /* Never happens, but compiler isn't smart enough to tell. */
994 abort();
995 }
996 code = 15;
997 }
998 *prot = check_ap(env, ap, domain_prot, access_type, is_user);
999 if (!*prot) {
1000 /* Access permission fault. */
1001 goto do_fault;
1002 }
1003 *prot |= PAGE_EXEC;
1004 *phys_ptr = phys_addr;
1005 return 0;
1006 do_fault:
1007 return code | (domain << 4);
1008 }
1009
1010 static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
1011 int is_user, uint32_t *phys_ptr, int *prot,
1012 target_ulong *page_size)
1013 {
1014 int code;
1015 uint32_t table;
1016 uint32_t desc;
1017 uint32_t xn;
1018 int type;
1019 int ap;
1020 int domain;
1021 int domain_prot;
1022 uint32_t phys_addr;
1023
1024 /* Pagetable walk. */
1025 /* Lookup l1 descriptor. */
1026 table = get_level1_table_address(env, address);
1027 desc = ldl_phys(table);
1028 type = (desc & 3);
1029 if (type == 0) {
1030 /* Section translation fault. */
1031 code = 5;
1032 domain = 0;
1033 goto do_fault;
1034 } else if (type == 2 && (desc & (1 << 18))) {
1035 /* Supersection. */
1036 domain = 0;
1037 } else {
1038 /* Section or page. */
1039 domain = (desc >> 5) & 0x0f;
1040 }
1041 domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
1042 if (domain_prot == 0 || domain_prot == 2) {
1043 if (type == 2)
1044 code = 9; /* Section domain fault. */
1045 else
1046 code = 11; /* Page domain fault. */
1047 goto do_fault;
1048 }
1049 if (type == 2) {
1050 if (desc & (1 << 18)) {
1051 /* Supersection. */
1052 phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
1053 *page_size = 0x1000000;
1054 } else {
1055 /* Section. */
1056 phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
1057 *page_size = 0x100000;
1058 }
1059 ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
1060 xn = desc & (1 << 4);
1061 code = 13;
1062 } else {
1063 /* Lookup l2 entry. */
1064 table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
1065 desc = ldl_phys(table);
1066 ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
1067 switch (desc & 3) {
1068 case 0: /* Page translation fault. */
1069 code = 7;
1070 goto do_fault;
1071 case 1: /* 64k page. */
1072 phys_addr = (desc & 0xffff0000) | (address & 0xffff);
1073 xn = desc & (1 << 15);
1074 *page_size = 0x10000;
1075 break;
1076 case 2: case 3: /* 4k page. */
1077 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
1078 xn = desc & 1;
1079 *page_size = 0x1000;
1080 break;
1081 default:
1082 /* Never happens, but compiler isn't smart enough to tell. */
1083 abort();
1084 }
1085 code = 15;
1086 }
1087 if (domain_prot == 3) {
1088 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1089 } else {
1090 if (xn && access_type == 2)
1091 goto do_fault;
1092
1093 /* The simplified model uses AP[0] as an access control bit. */
1094 if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) {
1095 /* Access flag fault. */
1096 code = (code == 15) ? 6 : 3;
1097 goto do_fault;
1098 }
1099 *prot = check_ap(env, ap, domain_prot, access_type, is_user);
1100 if (!*prot) {
1101 /* Access permission fault. */
1102 goto do_fault;
1103 }
1104 if (!xn) {
1105 *prot |= PAGE_EXEC;
1106 }
1107 }
1108 *phys_ptr = phys_addr;
1109 return 0;
1110 do_fault:
1111 return code | (domain << 4);
1112 }
1113
1114 static int get_phys_addr_mpu(CPUARMState *env, uint32_t address, int access_type,
1115 int is_user, uint32_t *phys_ptr, int *prot)
1116 {
1117 int n;
1118 uint32_t mask;
1119 uint32_t base;
1120
1121 *phys_ptr = address;
1122 for (n = 7; n >= 0; n--) {
1123 base = env->cp15.c6_region[n];
1124 if ((base & 1) == 0)
1125 continue;
1126 mask = 1 << ((base >> 1) & 0x1f);
1127 /* Keep this shift separate from the above to avoid an
1128 (undefined) << 32. */
1129 mask = (mask << 1) - 1;
1130 if (((base ^ address) & ~mask) == 0)
1131 break;
1132 }
1133 if (n < 0)
1134 return 2;
1135
1136 if (access_type == 2) {
1137 mask = env->cp15.c5_insn;
1138 } else {
1139 mask = env->cp15.c5_data;
1140 }
1141 mask = (mask >> (n * 4)) & 0xf;
1142 switch (mask) {
1143 case 0:
1144 return 1;
1145 case 1:
1146 if (is_user)
1147 return 1;
1148 *prot = PAGE_READ | PAGE_WRITE;
1149 break;
1150 case 2:
1151 *prot = PAGE_READ;
1152 if (!is_user)
1153 *prot |= PAGE_WRITE;
1154 break;
1155 case 3:
1156 *prot = PAGE_READ | PAGE_WRITE;
1157 break;
1158 case 5:
1159 if (is_user)
1160 return 1;
1161 *prot = PAGE_READ;
1162 break;
1163 case 6:
1164 *prot = PAGE_READ;
1165 break;
1166 default:
1167 /* Bad permission. */
1168 return 1;
1169 }
1170 *prot |= PAGE_EXEC;
1171 return 0;
1172 }
1173
1174 static inline int get_phys_addr(CPUARMState *env, uint32_t address,
1175 int access_type, int is_user,
1176 uint32_t *phys_ptr, int *prot,
1177 target_ulong *page_size)
1178 {
1179 /* Fast Context Switch Extension. */
1180 if (address < 0x02000000)
1181 address += env->cp15.c13_fcse;
1182
1183 if ((env->cp15.c1_sys & 1) == 0) {
1184 /* MMU/MPU disabled. */
1185 *phys_ptr = address;
1186 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1187 *page_size = TARGET_PAGE_SIZE;
1188 return 0;
1189 } else if (arm_feature(env, ARM_FEATURE_MPU)) {
1190 *page_size = TARGET_PAGE_SIZE;
1191 return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,
1192 prot);
1193 } else if (env->cp15.c1_sys & (1 << 23)) {
1194 return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,
1195 prot, page_size);
1196 } else {
1197 return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,
1198 prot, page_size);
1199 }
1200 }
1201
1202 int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
1203 int access_type, int mmu_idx)
1204 {
1205 uint32_t phys_addr;
1206 target_ulong page_size;
1207 int prot;
1208 int ret, is_user;
1209
1210 is_user = mmu_idx == MMU_USER_IDX;
1211 ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot,
1212 &page_size);
1213 if (ret == 0) {
1214 /* Map a single [sub]page. */
1215 phys_addr &= ~(uint32_t)0x3ff;
1216 address &= ~(uint32_t)0x3ff;
1217 tlb_set_page (env, address, phys_addr, prot, mmu_idx, page_size);
1218 return 0;
1219 }
1220
1221 if (access_type == 2) {
1222 env->cp15.c5_insn = ret;
1223 env->cp15.c6_insn = address;
1224 env->exception_index = EXCP_PREFETCH_ABORT;
1225 } else {
1226 env->cp15.c5_data = ret;
1227 if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6))
1228 env->cp15.c5_data |= (1 << 11);
1229 env->cp15.c6_data = address;
1230 env->exception_index = EXCP_DATA_ABORT;
1231 }
1232 return 1;
1233 }
1234
1235 target_phys_addr_t cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr)
1236 {
1237 uint32_t phys_addr;
1238 target_ulong page_size;
1239 int prot;
1240 int ret;
1241
1242 ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot, &page_size);
1243
1244 if (ret != 0)
1245 return -1;
1246
1247 return phys_addr;
1248 }
1249
1250 void HELPER(set_cp)(CPUARMState *env, uint32_t insn, uint32_t val)
1251 {
1252 int cp_num = (insn >> 8) & 0xf;
1253 int cp_info = (insn >> 5) & 7;
1254 int src = (insn >> 16) & 0xf;
1255 int operand = insn & 0xf;
1256
1257 if (env->cp[cp_num].cp_write)
1258 env->cp[cp_num].cp_write(env->cp[cp_num].opaque,
1259 cp_info, src, operand, val);
1260 }
1261
1262 uint32_t HELPER(get_cp)(CPUARMState *env, uint32_t insn)
1263 {
1264 int cp_num = (insn >> 8) & 0xf;
1265 int cp_info = (insn >> 5) & 7;
1266 int dest = (insn >> 16) & 0xf;
1267 int operand = insn & 0xf;
1268
1269 if (env->cp[cp_num].cp_read)
1270 return env->cp[cp_num].cp_read(env->cp[cp_num].opaque,
1271 cp_info, dest, operand);
1272 return 0;
1273 }
1274
1275 /* Return basic MPU access permission bits. */
1276 static uint32_t simple_mpu_ap_bits(uint32_t val)
1277 {
1278 uint32_t ret;
1279 uint32_t mask;
1280 int i;
1281 ret = 0;
1282 mask = 3;
1283 for (i = 0; i < 16; i += 2) {
1284 ret |= (val >> i) & mask;
1285 mask <<= 2;
1286 }
1287 return ret;
1288 }
1289
1290 /* Pad basic MPU access permission bits to extended format. */
1291 static uint32_t extended_mpu_ap_bits(uint32_t val)
1292 {
1293 uint32_t ret;
1294 uint32_t mask;
1295 int i;
1296 ret = 0;
1297 mask = 3;
1298 for (i = 0; i < 16; i += 2) {
1299 ret |= (val & mask) << i;
1300 mask <<= 2;
1301 }
1302 return ret;
1303 }
1304
1305 void HELPER(set_cp15)(CPUARMState *env, uint32_t insn, uint32_t val)
1306 {
1307 int op1;
1308 int op2;
1309 int crm;
1310
1311 op1 = (insn >> 21) & 7;
1312 op2 = (insn >> 5) & 7;
1313 crm = insn & 0xf;
1314 switch ((insn >> 16) & 0xf) {
1315 case 0:
1316 /* ID codes. */
1317 if (arm_feature(env, ARM_FEATURE_XSCALE))
1318 break;
1319 if (arm_feature(env, ARM_FEATURE_OMAPCP))
1320 break;
1321 if (arm_feature(env, ARM_FEATURE_V7)
1322 && op1 == 2 && crm == 0 && op2 == 0) {
1323 env->cp15.c0_cssel = val & 0xf;
1324 break;
1325 }
1326 goto bad_reg;
1327 case 1: /* System configuration. */
1328 if (arm_feature(env, ARM_FEATURE_V7)
1329 && op1 == 0 && crm == 1 && op2 == 0) {
1330 env->cp15.c1_scr = val;
1331 break;
1332 }
1333 if (arm_feature(env, ARM_FEATURE_OMAPCP))
1334 op2 = 0;
1335 switch (op2) {
1336 case 0:
1337 if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
1338 env->cp15.c1_sys = val;
1339 /* ??? Lots of these bits are not implemented. */
1340 /* This may enable/disable the MMU, so do a TLB flush. */
1341 tlb_flush(env, 1);
1342 break;
1343 case 1: /* Auxiliary control register. */
1344 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1345 env->cp15.c1_xscaleauxcr = val;
1346 break;
1347 }
1348 /* Not implemented. */
1349 break;
1350 case 2:
1351 if (arm_feature(env, ARM_FEATURE_XSCALE))
1352 goto bad_reg;
1353 if (env->cp15.c1_coproc != val) {
1354 env->cp15.c1_coproc = val;
1355 /* ??? Is this safe when called from within a TB? */
1356 tb_flush(env);
1357 }
1358 break;
1359 default:
1360 goto bad_reg;
1361 }
1362 break;
1363 case 2: /* MMU Page table control / MPU cache control. */
1364 if (arm_feature(env, ARM_FEATURE_MPU)) {
1365 switch (op2) {
1366 case 0:
1367 env->cp15.c2_data = val;
1368 break;
1369 case 1:
1370 env->cp15.c2_insn = val;
1371 break;
1372 default:
1373 goto bad_reg;
1374 }
1375 } else {
1376 switch (op2) {
1377 case 0:
1378 env->cp15.c2_base0 = val;
1379 break;
1380 case 1:
1381 env->cp15.c2_base1 = val;
1382 break;
1383 case 2:
1384 val &= 7;
1385 env->cp15.c2_control = val;
1386 env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);
1387 env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val);
1388 break;
1389 default:
1390 goto bad_reg;
1391 }
1392 }
1393 break;
1394 case 3: /* MMU Domain access control / MPU write buffer control. */
1395 env->cp15.c3 = val;
1396 tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */
1397 break;
1398 case 4: /* Reserved. */
1399 goto bad_reg;
1400 case 5: /* MMU Fault status / MPU access permission. */
1401 if (arm_feature(env, ARM_FEATURE_OMAPCP))
1402 op2 = 0;
1403 switch (op2) {
1404 case 0:
1405 if (arm_feature(env, ARM_FEATURE_MPU))
1406 val = extended_mpu_ap_bits(val);
1407 env->cp15.c5_data = val;
1408 break;
1409 case 1:
1410 if (arm_feature(env, ARM_FEATURE_MPU))
1411 val = extended_mpu_ap_bits(val);
1412 env->cp15.c5_insn = val;
1413 break;
1414 case 2:
1415 if (!arm_feature(env, ARM_FEATURE_MPU))
1416 goto bad_reg;
1417 env->cp15.c5_data = val;
1418 break;
1419 case 3:
1420 if (!arm_feature(env, ARM_FEATURE_MPU))
1421 goto bad_reg;
1422 env->cp15.c5_insn = val;
1423 break;
1424 default:
1425 goto bad_reg;
1426 }
1427 break;
1428 case 6: /* MMU Fault address / MPU base/size. */
1429 if (arm_feature(env, ARM_FEATURE_MPU)) {
1430 if (crm >= 8)
1431 goto bad_reg;
1432 env->cp15.c6_region[crm] = val;
1433 } else {
1434 if (arm_feature(env, ARM_FEATURE_OMAPCP))
1435 op2 = 0;
1436 switch (op2) {
1437 case 0:
1438 env->cp15.c6_data = val;
1439 break;
1440 case 1: /* ??? This is WFAR on armv6 */
1441 case 2:
1442 env->cp15.c6_insn = val;
1443 break;
1444 default:
1445 goto bad_reg;
1446 }
1447 }
1448 break;
1449 case 7: /* Cache control. */
1450 env->cp15.c15_i_max = 0x000;
1451 env->cp15.c15_i_min = 0xff0;
1452 if (op1 != 0) {
1453 goto bad_reg;
1454 }
1455 /* No cache, so nothing to do except VA->PA translations. */
1456 if (arm_feature(env, ARM_FEATURE_VAPA)) {
1457 switch (crm) {
1458 case 4:
1459 if (arm_feature(env, ARM_FEATURE_V7)) {
1460 env->cp15.c7_par = val & 0xfffff6ff;
1461 } else {
1462 env->cp15.c7_par = val & 0xfffff1ff;
1463 }
1464 break;
1465 case 8: {
1466 uint32_t phys_addr;
1467 target_ulong page_size;
1468 int prot;
1469 int ret, is_user = op2 & 2;
1470 int access_type = op2 & 1;
1471
1472 if (op2 & 4) {
1473 /* Other states are only available with TrustZone */
1474 goto bad_reg;
1475 }
1476 ret = get_phys_addr(env, val, access_type, is_user,
1477 &phys_addr, &prot, &page_size);
1478 if (ret == 0) {
1479 /* We do not set any attribute bits in the PAR */
1480 if (page_size == (1 << 24)
1481 && arm_feature(env, ARM_FEATURE_V7)) {
1482 env->cp15.c7_par = (phys_addr & 0xff000000) | 1 << 1;
1483 } else {
1484 env->cp15.c7_par = phys_addr & 0xfffff000;
1485 }
1486 } else {
1487 env->cp15.c7_par = ((ret & (10 << 1)) >> 5) |
1488 ((ret & (12 << 1)) >> 6) |
1489 ((ret & 0xf) << 1) | 1;
1490 }
1491 break;
1492 }
1493 }
1494 }
1495 break;
1496 case 8: /* MMU TLB control. */
1497 switch (op2) {
1498 case 0: /* Invalidate all (TLBIALL) */
1499 tlb_flush(env, 1);
1500 break;
1501 case 1: /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
1502 tlb_flush_page(env, val & TARGET_PAGE_MASK);
1503 break;
1504 case 2: /* Invalidate by ASID (TLBIASID) */
1505 tlb_flush(env, val == 0);
1506 break;
1507 case 3: /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
1508 tlb_flush_page(env, val & TARGET_PAGE_MASK);
1509 break;
1510 default:
1511 goto bad_reg;
1512 }
1513 break;
1514 case 9:
1515 if (arm_feature(env, ARM_FEATURE_OMAPCP))
1516 break;
1517 if (arm_feature(env, ARM_FEATURE_STRONGARM))
1518 break; /* Ignore ReadBuffer access */
1519 switch (crm) {
1520 case 0: /* Cache lockdown. */
1521 switch (op1) {
1522 case 0: /* L1 cache. */
1523 switch (op2) {
1524 case 0:
1525 env->cp15.c9_data = val;
1526 break;
1527 case 1:
1528 env->cp15.c9_insn = val;
1529 break;
1530 default:
1531 goto bad_reg;
1532 }
1533 break;
1534 case 1: /* L2 cache. */
1535 /* Ignore writes to L2 lockdown/auxiliary registers. */
1536 break;
1537 default:
1538 goto bad_reg;
1539 }
1540 break;
1541 case 1: /* TCM memory region registers. */
1542 /* Not implemented. */
1543 goto bad_reg;
1544 case 12: /* Performance monitor control */
1545 /* Performance monitors are implementation defined in v7,
1546 * but with an ARM recommended set of registers, which we
1547 * follow (although we don't actually implement any counters)
1548 */
1549 if (!arm_feature(env, ARM_FEATURE_V7)) {
1550 goto bad_reg;
1551 }
1552 switch (op2) {
1553 case 0: /* performance monitor control register */
1554 /* only the DP, X, D and E bits are writable */
1555 env->cp15.c9_pmcr &= ~0x39;
1556 env->cp15.c9_pmcr |= (val & 0x39);
1557 break;
1558 case 1: /* Count enable set register */
1559 val &= (1 << 31);
1560 env->cp15.c9_pmcnten |= val;
1561 break;
1562 case 2: /* Count enable clear */
1563 val &= (1 << 31);
1564 env->cp15.c9_pmcnten &= ~val;
1565 break;
1566 case 3: /* Overflow flag status */
1567 env->cp15.c9_pmovsr &= ~val;
1568 break;
1569 case 4: /* Software increment */
1570 /* RAZ/WI since we don't implement the software-count event */
1571 break;
1572 case 5: /* Event counter selection register */
1573 /* Since we don't implement any events, writing to this register
1574 * is actually UNPREDICTABLE. So we choose to RAZ/WI.
1575 */
1576 break;
1577 default:
1578 goto bad_reg;
1579 }
1580 break;
1581 case 13: /* Performance counters */
1582 if (!arm_feature(env, ARM_FEATURE_V7)) {
1583 goto bad_reg;
1584 }
1585 switch (op2) {
1586 case 0: /* Cycle count register: not implemented, so RAZ/WI */
1587 break;
1588 case 1: /* Event type select */
1589 env->cp15.c9_pmxevtyper = val & 0xff;
1590 break;
1591 case 2: /* Event count register */
1592 /* Unimplemented (we have no events), RAZ/WI */
1593 break;
1594 default:
1595 goto bad_reg;
1596 }
1597 break;
1598 case 14: /* Performance monitor control */
1599 if (!arm_feature(env, ARM_FEATURE_V7)) {
1600 goto bad_reg;
1601 }
1602 switch (op2) {
1603 case 0: /* user enable */
1604 env->cp15.c9_pmuserenr = val & 1;
1605 /* changes access rights for cp registers, so flush tbs */
1606 tb_flush(env);
1607 break;
1608 case 1: /* interrupt enable set */
1609 /* We have no event counters so only the C bit can be changed */
1610 val &= (1 << 31);
1611 env->cp15.c9_pminten |= val;
1612 break;
1613 case 2: /* interrupt enable clear */
1614 val &= (1 << 31);
1615 env->cp15.c9_pminten &= ~val;
1616 break;
1617 }
1618 break;
1619 default:
1620 goto bad_reg;
1621 }
1622 break;
1623 case 10: /* MMU TLB lockdown. */
1624 /* ??? TLB lockdown not implemented. */
1625 break;
1626 case 12: /* Reserved. */
1627 goto bad_reg;
1628 case 13: /* Process ID. */
1629 switch (op2) {
1630 case 0:
1631 /* Unlike real hardware the qemu TLB uses virtual addresses,
1632 not modified virtual addresses, so this causes a TLB flush.
1633 */
1634 if (env->cp15.c13_fcse != val)
1635 tlb_flush(env, 1);
1636 env->cp15.c13_fcse = val;
1637 break;
1638 case 1:
1639 /* This changes the ASID, so do a TLB flush. */
1640 if (env->cp15.c13_context != val
1641 && !arm_feature(env, ARM_FEATURE_MPU))
1642 tlb_flush(env, 0);
1643 env->cp15.c13_context = val;
1644 break;
1645 default:
1646 goto bad_reg;
1647 }
1648 break;
1649 case 14: /* Generic timer */
1650 if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
1651 /* Dummy implementation: RAZ/WI for all */
1652 break;
1653 }
1654 goto bad_reg;
1655 case 15: /* Implementation specific. */
1656 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
1657 if (op2 == 0 && crm == 1) {
1658 if (env->cp15.c15_cpar != (val & 0x3fff)) {
1659 /* Changes cp0 to cp13 behavior, so needs a TB flush. */
1660 tb_flush(env);
1661 env->cp15.c15_cpar = val & 0x3fff;
1662 }
1663 break;
1664 }
1665 goto bad_reg;
1666 }
1667 if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1668 switch (crm) {
1669 case 0:
1670 break;
1671 case 1: /* Set TI925T configuration. */
1672 env->cp15.c15_ticonfig = val & 0xe7;
1673 env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */
1674 ARM_CPUID_TI915T : ARM_CPUID_TI925T;
1675 break;
1676 case 2: /* Set I_max. */
1677 env->cp15.c15_i_max = val;
1678 break;
1679 case 3: /* Set I_min. */
1680 env->cp15.c15_i_min = val;
1681 break;
1682 case 4: /* Set thread-ID. */
1683 env->cp15.c15_threadid = val & 0xffff;
1684 break;
1685 case 8: /* Wait-for-interrupt (deprecated). */
1686 cpu_interrupt(env, CPU_INTERRUPT_HALT);
1687 break;
1688 default:
1689 goto bad_reg;
1690 }
1691 }
1692 if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
1693 switch (crm) {
1694 case 0:
1695 if ((op1 == 0) && (op2 == 0)) {
1696 env->cp15.c15_power_control = val;
1697 } else if ((op1 == 0) && (op2 == 1)) {
1698 env->cp15.c15_diagnostic = val;
1699 } else if ((op1 == 0) && (op2 == 2)) {
1700 env->cp15.c15_power_diagnostic = val;
1701 }
1702 default:
1703 break;
1704 }
1705 }
1706 break;
1707 }
1708 return;
1709 bad_reg:
1710 /* ??? For debugging only. Should raise illegal instruction exception. */
1711 cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
1712 (insn >> 16) & 0xf, crm, op1, op2);
1713 }
1714
1715 uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
1716 {
1717 int op1;
1718 int op2;
1719 int crm;
1720
1721 op1 = (insn >> 21) & 7;
1722 op2 = (insn >> 5) & 7;
1723 crm = insn & 0xf;
1724 switch ((insn >> 16) & 0xf) {
1725 case 0: /* ID codes. */
1726 switch (op1) {
1727 case 0:
1728 switch (crm) {
1729 case 0:
1730 switch (op2) {
1731 case 0: /* Device ID. */
1732 return env->cp15.c0_cpuid;
1733 case 1: /* Cache Type. */
1734 return env->cp15.c0_cachetype;
1735 case 2: /* TCM status. */
1736 return 0;
1737 case 3: /* TLB type register. */
1738 return 0; /* No lockable TLB entries. */
1739 case 5: /* MPIDR */
1740 /* The MPIDR was standardised in v7; prior to
1741 * this it was implemented only in the 11MPCore.
1742 * For all other pre-v7 cores it does not exist.
1743 */
1744 if (arm_feature(env, ARM_FEATURE_V7) ||
1745 ARM_CPUID(env) == ARM_CPUID_ARM11MPCORE) {
1746 int mpidr = env->cpu_index;
1747 /* We don't support setting cluster ID ([8..11])
1748 * so these bits always RAZ.
1749 */
1750 if (arm_feature(env, ARM_FEATURE_V7MP)) {
1751 mpidr |= (1 << 31);
1752 /* Cores which are uniprocessor (non-coherent)
1753 * but still implement the MP extensions set
1754 * bit 30. (For instance, A9UP.) However we do
1755 * not currently model any of those cores.
1756 */
1757 }
1758 return mpidr;
1759 }
1760 /* otherwise fall through to the unimplemented-reg case */
1761 default:
1762 goto bad_reg;
1763 }
1764 case 1:
1765 if (!arm_feature(env, ARM_FEATURE_V6))
1766 goto bad_reg;
1767 return env->cp15.c0_c1[op2];
1768 case 2:
1769 if (!arm_feature(env, ARM_FEATURE_V6))
1770 goto bad_reg;
1771 return env->cp15.c0_c2[op2];
1772 case 3: case 4: case 5: case 6: case 7:
1773 return 0;
1774 default:
1775 goto bad_reg;
1776 }
1777 case 1:
1778 /* These registers aren't documented on arm11 cores. However
1779 Linux looks at them anyway. */
1780 if (!arm_feature(env, ARM_FEATURE_V6))
1781 goto bad_reg;
1782 if (crm != 0)
1783 goto bad_reg;
1784 if (!arm_feature(env, ARM_FEATURE_V7))
1785 return 0;
1786
1787 switch (op2) {
1788 case 0:
1789 return env->cp15.c0_ccsid[env->cp15.c0_cssel];
1790 case 1:
1791 return env->cp15.c0_clid;
1792 case 7:
1793 return 0;
1794 }
1795 goto bad_reg;
1796 case 2:
1797 if (op2 != 0 || crm != 0)
1798 goto bad_reg;
1799 return env->cp15.c0_cssel;
1800 default:
1801 goto bad_reg;
1802 }
1803 case 1: /* System configuration. */
1804 if (arm_feature(env, ARM_FEATURE_V7)
1805 && op1 == 0 && crm == 1 && op2 == 0) {
1806 return env->cp15.c1_scr;
1807 }
1808 if (arm_feature(env, ARM_FEATURE_OMAPCP))
1809 op2 = 0;
1810 switch (op2) {
1811 case 0: /* Control register. */
1812 return env->cp15.c1_sys;
1813 case 1: /* Auxiliary control register. */
1814 if (arm_feature(env, ARM_FEATURE_XSCALE))
1815 return env->cp15.c1_xscaleauxcr;
1816 if (!arm_feature(env, ARM_FEATURE_AUXCR))
1817 goto bad_reg;
1818 switch (ARM_CPUID(env)) {
1819 case ARM_CPUID_ARM1026:
1820 return 1;
1821 case ARM_CPUID_ARM1136:
1822 case ARM_CPUID_ARM1136_R2:
1823 case ARM_CPUID_ARM1176:
1824 return 7;
1825 case ARM_CPUID_ARM11MPCORE:
1826 return 1;
1827 case ARM_CPUID_CORTEXA8:
1828 return 2;
1829 case ARM_CPUID_CORTEXA9:
1830 case ARM_CPUID_CORTEXA15:
1831 return 0;
1832 default:
1833 goto bad_reg;
1834 }
1835 case 2: /* Coprocessor access register. */
1836 if (arm_feature(env, ARM_FEATURE_XSCALE))
1837 goto bad_reg;
1838 return env->cp15.c1_coproc;
1839 default:
1840 goto bad_reg;
1841 }
1842 case 2: /* MMU Page table control / MPU cache control. */
1843 if (arm_feature(env, ARM_FEATURE_MPU)) {
1844 switch (op2) {
1845 case 0:
1846 return env->cp15.c2_data;
1847 break;
1848 case 1:
1849 return env->cp15.c2_insn;
1850 break;
1851 default:
1852 goto bad_reg;
1853 }
1854 } else {
1855 switch (op2) {
1856 case 0:
1857 return env->cp15.c2_base0;
1858 case 1:
1859 return env->cp15.c2_base1;
1860 case 2:
1861 return env->cp15.c2_control;
1862 default:
1863 goto bad_reg;
1864 }
1865 }
1866 case 3: /* MMU Domain access control / MPU write buffer control. */
1867 return env->cp15.c3;
1868 case 4: /* Reserved. */
1869 goto bad_reg;
1870 case 5: /* MMU Fault status / MPU access permission. */
1871 if (arm_feature(env, ARM_FEATURE_OMAPCP))
1872 op2 = 0;
1873 switch (op2) {
1874 case 0:
1875 if (arm_feature(env, ARM_FEATURE_MPU))
1876 return simple_mpu_ap_bits(env->cp15.c5_data);
1877 return env->cp15.c5_data;
1878 case 1:
1879 if (arm_feature(env, ARM_FEATURE_MPU))
1880 return simple_mpu_ap_bits(env->cp15.c5_insn);
1881 return env->cp15.c5_insn;
1882 case 2:
1883 if (!arm_feature(env, ARM_FEATURE_MPU))
1884 goto bad_reg;
1885 return env->cp15.c5_data;
1886 case 3:
1887 if (!arm_feature(env, ARM_FEATURE_MPU))
1888 goto bad_reg;
1889 return env->cp15.c5_insn;
1890 default:
1891 goto bad_reg;
1892 }
1893 case 6: /* MMU Fault address. */
1894 if (arm_feature(env, ARM_FEATURE_MPU)) {
1895 if (crm >= 8)
1896 goto bad_reg;
1897 return env->cp15.c6_region[crm];
1898 } else {
1899 if (arm_feature(env, ARM_FEATURE_OMAPCP))
1900 op2 = 0;
1901 switch (op2) {
1902 case 0:
1903 return env->cp15.c6_data;
1904 case 1:
1905 if (arm_feature(env, ARM_FEATURE_V6)) {
1906 /* Watchpoint Fault Adrress. */
1907 return 0; /* Not implemented. */
1908 } else {
1909 /* Instruction Fault Adrress. */
1910 /* Arm9 doesn't have an IFAR, but implementing it anyway
1911 shouldn't do any harm. */
1912 return env->cp15.c6_insn;
1913 }
1914 case 2:
1915 if (arm_feature(env, ARM_FEATURE_V6)) {
1916 /* Instruction Fault Adrress. */
1917 return env->cp15.c6_insn;
1918 } else {
1919 goto bad_reg;
1920 }
1921 default:
1922 goto bad_reg;
1923 }
1924 }
1925 case 7: /* Cache control. */
1926 if (crm == 4 && op1 == 0 && op2 == 0) {
1927 return env->cp15.c7_par;
1928 }
1929 /* FIXME: Should only clear Z flag if destination is r15. */
1930 env->ZF = 0;
1931 return 0;
1932 case 8: /* MMU TLB control. */
1933 goto bad_reg;
1934 case 9:
1935 switch (crm) {
1936 case 0: /* Cache lockdown */
1937 switch (op1) {
1938 case 0: /* L1 cache. */
1939 if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
1940 return 0;
1941 }
1942 switch (op2) {
1943 case 0:
1944 return env->cp15.c9_data;
1945 case 1:
1946 return env->cp15.c9_insn;
1947 default:
1948 goto bad_reg;
1949 }
1950 case 1: /* L2 cache */
1951 /* L2 Lockdown and Auxiliary control. */
1952 switch (op2) {
1953 case 0:
1954 /* L2 cache lockdown (A8 only) */
1955 return 0;
1956 case 2:
1957 /* L2 cache auxiliary control (A8) or control (A15) */
1958 if (ARM_CPUID(env) == ARM_CPUID_CORTEXA15) {
1959 /* Linux wants the number of processors from here.
1960 * Might as well set the interrupt-controller bit too.
1961 */
1962 return ((smp_cpus - 1) << 24) | (1 << 23);
1963 }
1964 return 0;
1965 case 3:
1966 /* L2 cache extended control (A15) */
1967 return 0;
1968 default:
1969 goto bad_reg;
1970 }
1971 default:
1972 goto bad_reg;
1973 }
1974 break;
1975 case 12: /* Performance monitor control */
1976 if (!arm_feature(env, ARM_FEATURE_V7)) {
1977 goto bad_reg;
1978 }
1979 switch (op2) {
1980 case 0: /* performance monitor control register */
1981 return env->cp15.c9_pmcr;
1982 case 1: /* count enable set */
1983 case 2: /* count enable clear */
1984 return env->cp15.c9_pmcnten;
1985 case 3: /* overflow flag status */
1986 return env->cp15.c9_pmovsr;
1987 case 4: /* software increment */
1988 case 5: /* event counter selection register */
1989 return 0; /* Unimplemented, RAZ/WI */
1990 default:
1991 goto bad_reg;
1992 }
1993 case 13: /* Performance counters */
1994 if (!arm_feature(env, ARM_FEATURE_V7)) {
1995 goto bad_reg;
1996 }
1997 switch (op2) {
1998 case 1: /* Event type select */
1999 return env->cp15.c9_pmxevtyper;
2000 case 0: /* Cycle count register */
2001 case 2: /* Event count register */
2002 /* Unimplemented, so RAZ/WI */
2003 return 0;
2004 default:
2005 goto bad_reg;
2006 }
2007 case 14: /* Performance monitor control */
2008 if (!arm_feature(env, ARM_FEATURE_V7)) {
2009 goto bad_reg;
2010 }
2011 switch (op2) {
2012 case 0: /* user enable */
2013 return env->cp15.c9_pmuserenr;
2014 case 1: /* interrupt enable set */
2015 case 2: /* interrupt enable clear */
2016 return env->cp15.c9_pminten;
2017 default:
2018 goto bad_reg;
2019 }
2020 default:
2021 goto bad_reg;
2022 }
2023 break;
2024 case 10: /* MMU TLB lockdown. */
2025 /* ??? TLB lockdown not implemented. */
2026 return 0;
2027 case 11: /* TCM DMA control. */
2028 case 12: /* Reserved. */
2029 goto bad_reg;
2030 case 13: /* Process ID. */
2031 switch (op2) {
2032 case 0:
2033 return env->cp15.c13_fcse;
2034 case 1:
2035 return env->cp15.c13_context;
2036 default:
2037 goto bad_reg;
2038 }
2039 case 14: /* Generic timer */
2040 if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
2041 /* Dummy implementation: RAZ/WI for all */
2042 return 0;
2043 }
2044 goto bad_reg;
2045 case 15: /* Implementation specific. */
2046 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
2047 if (op2 == 0 && crm == 1)
2048 return env->cp15.c15_cpar;
2049
2050 goto bad_reg;
2051 }
2052 if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
2053 switch (crm) {
2054 case 0:
2055 return 0;
2056 case 1: /* Read TI925T configuration. */
2057 return env->cp15.c15_ticonfig;
2058 case 2: /* Read I_max. */
2059 return env->cp15.c15_i_max;
2060 case 3: /* Read I_min. */
2061 return env->cp15.c15_i_min;
2062 case 4: /* Read thread-ID. */
2063 return env->cp15.c15_threadid;
2064 case 8: /* TI925T_status */
2065 return 0;
2066 }
2067 /* TODO: Peripheral port remap register:
2068 * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
2069 * controller base address at $rn & ~0xfff and map size of
2070 * 0x200 << ($rn & 0xfff), when MMU is off. */
2071 goto bad_reg;
2072 }
2073 if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {
2074 switch (crm) {
2075 case 0:
2076 if ((op1 == 4) && (op2 == 0)) {
2077 /* The config_base_address should hold the value of
2078 * the peripheral base. ARM should get this from a CPU
2079 * object property, but that support isn't available in
2080 * December 2011. Default to 0 for now and board models
2081 * that care can set it by a private hook */
2082 return env->cp15.c15_config_base_address;
2083 } else if ((op1 == 0) && (op2 == 0)) {
2084 /* power_control should be set to maximum latency. Again,
2085 default to 0 and set by private hook */
2086 return env->cp15.c15_power_control;
2087 } else if ((op1 == 0) && (op2 == 1)) {
2088 return env->cp15.c15_diagnostic;
2089 } else if ((op1 == 0) && (op2 == 2)) {
2090 return env->cp15.c15_power_diagnostic;
2091 }
2092 break;
2093 case 1: /* NEON Busy */
2094 return 0;
2095 case 5: /* tlb lockdown */
2096 case 6:
2097 case 7:
2098 if ((op1 == 5) && (op2 == 2)) {
2099 return 0;
2100 }
2101 break;
2102 default:
2103 break;
2104 }
2105 goto bad_reg;
2106 }
2107 return 0;
2108 }
2109 bad_reg:
2110 /* ??? For debugging only. Should raise illegal instruction exception. */
2111 cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
2112 (insn >> 16) & 0xf, crm, op1, op2);
2113 return 0;
2114 }
2115
2116 void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
2117 {
2118 if ((env->uncached_cpsr & CPSR_M) == mode) {
2119 env->regs[13] = val;
2120 } else {
2121 env->banked_r13[bank_number(env, mode)] = val;
2122 }
2123 }
2124
2125 uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
2126 {
2127 if ((env->uncached_cpsr & CPSR_M) == mode) {
2128 return env->regs[13];
2129 } else {
2130 return env->banked_r13[bank_number(env, mode)];
2131 }
2132 }
2133
2134 uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
2135 {
2136 switch (reg) {
2137 case 0: /* APSR */
2138 return xpsr_read(env) & 0xf8000000;
2139 case 1: /* IAPSR */
2140 return xpsr_read(env) & 0xf80001ff;
2141 case 2: /* EAPSR */
2142 return xpsr_read(env) & 0xff00fc00;
2143 case 3: /* xPSR */
2144 return xpsr_read(env) & 0xff00fdff;
2145 case 5: /* IPSR */
2146 return xpsr_read(env) & 0x000001ff;
2147 case 6: /* EPSR */
2148 return xpsr_read(env) & 0x0700fc00;
2149 case 7: /* IEPSR */
2150 return xpsr_read(env) & 0x0700edff;
2151 case 8: /* MSP */
2152 return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13];
2153 case 9: /* PSP */
2154 return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp;
2155 case 16: /* PRIMASK */
2156 return (env->uncached_cpsr & CPSR_I) != 0;
2157 case 17: /* BASEPRI */
2158 case 18: /* BASEPRI_MAX */
2159 return env->v7m.basepri;
2160 case 19: /* FAULTMASK */
2161 return (env->uncached_cpsr & CPSR_F) != 0;
2162 case 20: /* CONTROL */
2163 return env->v7m.control;
2164 default:
2165 /* ??? For debugging only. */
2166 cpu_abort(env, "Unimplemented system register read (%d)\n", reg);
2167 return 0;
2168 }
2169 }
2170
2171 void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
2172 {
2173 switch (reg) {
2174 case 0: /* APSR */
2175 xpsr_write(env, val, 0xf8000000);
2176 break;
2177 case 1: /* IAPSR */
2178 xpsr_write(env, val, 0xf8000000);
2179 break;
2180 case 2: /* EAPSR */
2181 xpsr_write(env, val, 0xfe00fc00);
2182 break;
2183 case 3: /* xPSR */
2184 xpsr_write(env, val, 0xfe00fc00);
2185 break;
2186 case 5: /* IPSR */
2187 /* IPSR bits are readonly. */
2188 break;
2189 case 6: /* EPSR */
2190 xpsr_write(env, val, 0x0600fc00);
2191 break;
2192 case 7: /* IEPSR */
2193 xpsr_write(env, val, 0x0600fc00);
2194 break;
2195 case 8: /* MSP */
2196 if (env->v7m.current_sp)
2197 env->v7m.other_sp = val;
2198 else
2199 env->regs[13] = val;
2200 break;
2201 case 9: /* PSP */
2202 if (env->v7m.current_sp)
2203 env->regs[13] = val;
2204 else
2205 env->v7m.other_sp = val;
2206 break;
2207 case 16: /* PRIMASK */
2208 if (val & 1)
2209 env->uncached_cpsr |= CPSR_I;
2210 else
2211 env->uncached_cpsr &= ~CPSR_I;
2212 break;
2213 case 17: /* BASEPRI */
2214 env->v7m.basepri = val & 0xff;
2215 break;
2216 case 18: /* BASEPRI_MAX */
2217 val &= 0xff;
2218 if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
2219 env->v7m.basepri = val;
2220 break;
2221 case 19: /* FAULTMASK */
2222 if (val & 1)
2223 env->uncached_cpsr |= CPSR_F;
2224 else
2225 env->uncached_cpsr &= ~CPSR_F;
2226 break;
2227 case 20: /* CONTROL */
2228 env->v7m.control = val & 3;
2229 switch_v7m_sp(env, (val & 2) != 0);
2230 break;
2231 default:
2232 /* ??? For debugging only. */
2233 cpu_abort(env, "Unimplemented system register write (%d)\n", reg);
2234 return;
2235 }
2236 }
2237
2238 void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
2239 ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write,
2240 void *opaque)
2241 {
2242 if (cpnum < 0 || cpnum > 14) {
2243 cpu_abort(env, "Bad coprocessor number: %i\n", cpnum);
2244 return;
2245 }
2246
2247 env->cp[cpnum].cp_read = cp_read;
2248 env->cp[cpnum].cp_write = cp_write;
2249 env->cp[cpnum].opaque = opaque;
2250 }
2251
2252 #endif
2253
2254 /* Note that signed overflow is undefined in C. The following routines are
2255 careful to use unsigned types where modulo arithmetic is required.
2256 Failure to do so _will_ break on newer gcc. */
2257
2258 /* Signed saturating arithmetic. */
2259
2260 /* Perform 16-bit signed saturating addition. */
2261 static inline uint16_t add16_sat(uint16_t a, uint16_t b)
2262 {
2263 uint16_t res;
2264
2265 res = a + b;
2266 if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
2267 if (a & 0x8000)
2268 res = 0x8000;
2269 else
2270 res = 0x7fff;
2271 }
2272 return res;
2273 }
2274
2275 /* Perform 8-bit signed saturating addition. */
2276 static inline uint8_t add8_sat(uint8_t a, uint8_t b)
2277 {
2278 uint8_t res;
2279
2280 res = a + b;
2281 if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
2282 if (a & 0x80)
2283 res = 0x80;
2284 else
2285 res = 0x7f;
2286 }
2287 return res;
2288 }
2289
2290 /* Perform 16-bit signed saturating subtraction. */
2291 static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
2292 {
2293 uint16_t res;
2294
2295 res = a - b;
2296 if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
2297 if (a & 0x8000)
2298 res = 0x8000;
2299 else
2300 res = 0x7fff;
2301 }
2302 return res;
2303 }
2304
2305 /* Perform 8-bit signed saturating subtraction. */
2306 static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
2307 {
2308 uint8_t res;
2309
2310 res = a - b;
2311 if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
2312 if (a & 0x80)
2313 res = 0x80;
2314 else
2315 res = 0x7f;
2316 }
2317 return res;
2318 }
2319
2320 #define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
2321 #define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
2322 #define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
2323 #define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
2324 #define PFX q
2325
2326 #include "op_addsub.h"
2327
2328 /* Unsigned saturating arithmetic. */
2329 static inline uint16_t add16_usat(uint16_t a, uint16_t b)
2330 {
2331 uint16_t res;
2332 res = a + b;
2333 if (res < a)
2334 res = 0xffff;
2335 return res;
2336 }
2337
2338 static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
2339 {
2340 if (a > b)
2341 return a - b;
2342 else
2343 return 0;
2344 }
2345
2346 static inline uint8_t add8_usat(uint8_t a, uint8_t b)
2347 {
2348 uint8_t res;
2349 res = a + b;
2350 if (res < a)
2351 res = 0xff;
2352 return res;
2353 }
2354
2355 static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
2356 {
2357 if (a > b)
2358 return a - b;
2359 else
2360 return 0;
2361 }
2362
2363 #define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
2364 #define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
2365 #define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
2366 #define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
2367 #define PFX uq
2368
2369 #include "op_addsub.h"
2370
2371 /* Signed modulo arithmetic. */
2372 #define SARITH16(a, b, n, op) do { \
2373 int32_t sum; \
2374 sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
2375 RESULT(sum, n, 16); \
2376 if (sum >= 0) \
2377 ge |= 3 << (n * 2); \
2378 } while(0)
2379
2380 #define SARITH8(a, b, n, op) do { \
2381 int32_t sum; \
2382 sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
2383 RESULT(sum, n, 8); \
2384 if (sum >= 0) \
2385 ge |= 1 << n; \
2386 } while(0)
2387
2388
2389 #define ADD16(a, b, n) SARITH16(a, b, n, +)
2390 #define SUB16(a, b, n) SARITH16(a, b, n, -)
2391 #define ADD8(a, b, n) SARITH8(a, b, n, +)
2392 #define SUB8(a, b, n) SARITH8(a, b, n, -)
2393 #define PFX s
2394 #define ARITH_GE
2395
2396 #include "op_addsub.h"
2397
2398 /* Unsigned modulo arithmetic. */
2399 #define ADD16(a, b, n) do { \
2400 uint32_t sum; \
2401 sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
2402 RESULT(sum, n, 16); \
2403 if ((sum >> 16) == 1) \
2404 ge |= 3 << (n * 2); \
2405 } while(0)
2406
2407 #define ADD8(a, b, n) do { \
2408 uint32_t sum; \
2409 sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
2410 RESULT(sum, n, 8); \
2411 if ((sum >> 8) == 1) \
2412 ge |= 1 << n; \
2413 } while(0)
2414
2415 #define SUB16(a, b, n) do { \
2416 uint32_t sum; \
2417 sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
2418 RESULT(sum, n, 16); \
2419 if ((sum >> 16) == 0) \
2420 ge |= 3 << (n * 2); \
2421 } while(0)
2422
2423 #define SUB8(a, b, n) do { \
2424 uint32_t sum; \
2425 sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
2426 RESULT(sum, n, 8); \
2427 if ((sum >> 8) == 0) \
2428 ge |= 1 << n; \
2429 } while(0)
2430
2431 #define PFX u
2432 #define ARITH_GE
2433
2434 #include "op_addsub.h"
2435
2436 /* Halved signed arithmetic. */
2437 #define ADD16(a, b, n) \
2438 RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
2439 #define SUB16(a, b, n) \
2440 RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
2441 #define ADD8(a, b, n) \
2442 RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
2443 #define SUB8(a, b, n) \
2444 RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
2445 #define PFX sh
2446
2447 #include "op_addsub.h"
2448
2449 /* Halved unsigned arithmetic. */
2450 #define ADD16(a, b, n) \
2451 RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2452 #define SUB16(a, b, n) \
2453 RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2454 #define ADD8(a, b, n) \
2455 RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2456 #define SUB8(a, b, n) \
2457 RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2458 #define PFX uh
2459
2460 #include "op_addsub.h"
2461
2462 static inline uint8_t do_usad(uint8_t a, uint8_t b)
2463 {
2464 if (a > b)
2465 return a - b;
2466 else
2467 return b - a;
2468 }
2469
2470 /* Unsigned sum of absolute byte differences. */
2471 uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
2472 {
2473 uint32_t sum;
2474 sum = do_usad(a, b);
2475 sum += do_usad(a >> 8, b >> 8);
2476 sum += do_usad(a >> 16, b >>16);
2477 sum += do_usad(a >> 24, b >> 24);
2478 return sum;
2479 }
2480
2481 /* For ARMv6 SEL instruction. */
2482 uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
2483 {
2484 uint32_t mask;
2485
2486 mask = 0;
2487 if (flags & 1)
2488 mask |= 0xff;
2489 if (flags & 2)
2490 mask |= 0xff00;
2491 if (flags & 4)
2492 mask |= 0xff0000;
2493 if (flags & 8)
2494 mask |= 0xff000000;
2495 return (a & mask) | (b & ~mask);
2496 }
2497
2498 uint32_t HELPER(logicq_cc)(uint64_t val)
2499 {
2500 return (val >> 32) | (val != 0);
2501 }
2502
2503 /* VFP support. We follow the convention used for VFP instrunctions:
2504 Single precition routines have a "s" suffix, double precision a
2505 "d" suffix. */
2506
2507 /* Convert host exception flags to vfp form. */
2508 static inline int vfp_exceptbits_from_host(int host_bits)
2509 {
2510 int target_bits = 0;
2511
2512 if (host_bits & float_flag_invalid)
2513 target_bits |= 1;
2514 if (host_bits & float_flag_divbyzero)
2515 target_bits |= 2;
2516 if (host_bits & float_flag_overflow)
2517 target_bits |= 4;
2518 if (host_bits & (float_flag_underflow | float_flag_output_denormal))
2519 target_bits |= 8;
2520 if (host_bits & float_flag_inexact)
2521 target_bits |= 0x10;
2522 if (host_bits & float_flag_input_denormal)
2523 target_bits |= 0x80;
2524 return target_bits;
2525 }
2526
2527 uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
2528 {
2529 int i;
2530 uint32_t fpscr;
2531
2532 fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
2533 | (env->vfp.vec_len << 16)
2534 | (env->vfp.vec_stride << 20);
2535 i = get_float_exception_flags(&env->vfp.fp_status);
2536 i |= get_float_exception_flags(&env->vfp.standard_fp_status);
2537 fpscr |= vfp_exceptbits_from_host(i);
2538 return fpscr;
2539 }
2540
2541 uint32_t vfp_get_fpscr(CPUARMState *env)
2542 {
2543 return HELPER(vfp_get_fpscr)(env);
2544 }
2545
2546 /* Convert vfp exception flags to target form. */
2547 static inline int vfp_exceptbits_to_host(int target_bits)
2548 {
2549 int host_bits = 0;
2550
2551 if (target_bits & 1)
2552 host_bits |= float_flag_invalid;
2553 if (target_bits & 2)
2554 host_bits |= float_flag_divbyzero;
2555 if (target_bits & 4)
2556 host_bits |= float_flag_overflow;
2557 if (target_bits & 8)
2558 host_bits |= float_flag_underflow;
2559 if (target_bits & 0x10)
2560 host_bits |= float_flag_inexact;
2561 if (target_bits & 0x80)
2562 host_bits |= float_flag_input_denormal;
2563 return host_bits;
2564 }
2565
2566 void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
2567 {
2568 int i;
2569 uint32_t changed;
2570
2571 changed = env->vfp.xregs[ARM_VFP_FPSCR];
2572 env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
2573 env->vfp.vec_len = (val >> 16) & 7;
2574 env->vfp.vec_stride = (val >> 20) & 3;
2575
2576 changed ^= val;
2577 if (changed & (3 << 22)) {
2578 i = (val >> 22) & 3;
2579 switch (i) {
2580 case 0:
2581 i = float_round_nearest_even;
2582 break;
2583 case 1:
2584 i = float_round_up;
2585 break;
2586 case 2:
2587 i = float_round_down;
2588 break;
2589 case 3:
2590 i = float_round_to_zero;
2591 break;
2592 }
2593 set_float_rounding_mode(i, &env->vfp.fp_status);
2594 }
2595 if (changed & (1 << 24)) {
2596 set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
2597 set_flush_inputs_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
2598 }
2599 if (changed & (1 << 25))
2600 set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
2601
2602 i = vfp_exceptbits_to_host(val);
2603 set_float_exception_flags(i, &env->vfp.fp_status);
2604 set_float_exception_flags(0, &env->vfp.standard_fp_status);
2605 }
2606
2607 void vfp_set_fpscr(CPUARMState *env, uint32_t val)
2608 {
2609 HELPER(vfp_set_fpscr)(env, val);
2610 }
2611
2612 #define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
2613
2614 #define VFP_BINOP(name) \
2615 float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \
2616 { \
2617 float_status *fpst = fpstp; \
2618 return float32_ ## name(a, b, fpst); \
2619 } \
2620 float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \
2621 { \
2622 float_status *fpst = fpstp; \
2623 return float64_ ## name(a, b, fpst); \
2624 }
2625 VFP_BINOP(add)
2626 VFP_BINOP(sub)
2627 VFP_BINOP(mul)
2628 VFP_BINOP(div)
2629 #undef VFP_BINOP
2630
2631 float32 VFP_HELPER(neg, s)(float32 a)
2632 {
2633 return float32_chs(a);
2634 }
2635
2636 float64 VFP_HELPER(neg, d)(float64 a)
2637 {
2638 return float64_chs(a);
2639 }
2640
2641 float32 VFP_HELPER(abs, s)(float32 a)
2642 {
2643 return float32_abs(a);
2644 }
2645
2646 float64 VFP_HELPER(abs, d)(float64 a)
2647 {
2648 return float64_abs(a);
2649 }
2650
2651 float32 VFP_HELPER(sqrt, s)(float32 a, CPUARMState *env)
2652 {
2653 return float32_sqrt(a, &env->vfp.fp_status);
2654 }
2655
2656 float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
2657 {
2658 return float64_sqrt(a, &env->vfp.fp_status);
2659 }
2660
2661 /* XXX: check quiet/signaling case */
2662 #define DO_VFP_cmp(p, type) \
2663 void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
2664 { \
2665 uint32_t flags; \
2666 switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
2667 case 0: flags = 0x6; break; \
2668 case -1: flags = 0x8; break; \
2669 case 1: flags = 0x2; break; \
2670 default: case 2: flags = 0x3; break; \
2671 } \
2672 env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2673 | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2674 } \
2675 void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
2676 { \
2677 uint32_t flags; \
2678 switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
2679 case 0: flags = 0x6; break; \
2680 case -1: flags = 0x8; break; \
2681 case 1: flags = 0x2; break; \
2682 default: case 2: flags = 0x3; break; \
2683 } \
2684 env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2685 | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2686 }
2687 DO_VFP_cmp(s, float32)
2688 DO_VFP_cmp(d, float64)
2689 #undef DO_VFP_cmp
2690
2691 /* Integer to float and float to integer conversions */
2692
2693 #define CONV_ITOF(name, fsz, sign) \
2694 float##fsz HELPER(name)(uint32_t x, void *fpstp) \
2695 { \
2696 float_status *fpst = fpstp; \
2697 return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
2698 }
2699
2700 #define CONV_FTOI(name, fsz, sign, round) \
2701 uint32_t HELPER(name)(float##fsz x, void *fpstp) \
2702 { \
2703 float_status *fpst = fpstp; \
2704 if (float##fsz##_is_any_nan(x)) { \
2705 float_raise(float_flag_invalid, fpst); \
2706 return 0; \
2707 } \
2708 return float##fsz##_to_##sign##int32##round(x, fpst); \
2709 }
2710
2711 #define FLOAT_CONVS(name, p, fsz, sign) \
2712 CONV_ITOF(vfp_##name##to##p, fsz, sign) \
2713 CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
2714 CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
2715
2716 FLOAT_CONVS(si, s, 32, )
2717 FLOAT_CONVS(si, d, 64, )
2718 FLOAT_CONVS(ui, s, 32, u)
2719 FLOAT_CONVS(ui, d, 64, u)
2720
2721 #undef CONV_ITOF
2722 #undef CONV_FTOI
2723 #undef FLOAT_CONVS
2724
2725 /* floating point conversion */
2726 float64 VFP_HELPER(fcvtd, s)(float32 x, CPUARMState *env)
2727 {
2728 float64 r = float32_to_float64(x, &env->vfp.fp_status);
2729 /* ARM requires that S<->D conversion of any kind of NaN generates
2730 * a quiet NaN by forcing the most significant frac bit to 1.
2731 */
2732 return float64_maybe_silence_nan(r);
2733 }
2734
2735 float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
2736 {
2737 float32 r = float64_to_float32(x, &env->vfp.fp_status);
2738 /* ARM requires that S<->D conversion of any kind of NaN generates
2739 * a quiet NaN by forcing the most significant frac bit to 1.
2740 */
2741 return float32_maybe_silence_nan(r);
2742 }
2743
2744 /* VFP3 fixed point conversion. */
2745 #define VFP_CONV_FIX(name, p, fsz, itype, sign) \
2746 float##fsz HELPER(vfp_##name##to##p)(uint##fsz##_t x, uint32_t shift, \
2747 void *fpstp) \
2748 { \
2749 float_status *fpst = fpstp; \
2750 float##fsz tmp; \
2751 tmp = sign##int32_to_##float##fsz((itype##_t)x, fpst); \
2752 return float##fsz##_scalbn(tmp, -(int)shift, fpst); \
2753 } \
2754 uint##fsz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
2755 void *fpstp) \
2756 { \
2757 float_status *fpst = fpstp; \
2758 float##fsz tmp; \
2759 if (float##fsz##_is_any_nan(x)) { \
2760 float_raise(float_flag_invalid, fpst); \
2761 return 0; \
2762 } \
2763 tmp = float##fsz##_scalbn(x, shift, fpst); \
2764 return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \
2765 }
2766
2767 VFP_CONV_FIX(sh, d, 64, int16, )
2768 VFP_CONV_FIX(sl, d, 64, int32, )
2769 VFP_CONV_FIX(uh, d, 64, uint16, u)
2770 VFP_CONV_FIX(ul, d, 64, uint32, u)
2771 VFP_CONV_FIX(sh, s, 32, int16, )
2772 VFP_CONV_FIX(sl, s, 32, int32, )
2773 VFP_CONV_FIX(uh, s, 32, uint16, u)
2774 VFP_CONV_FIX(ul, s, 32, uint32, u)
2775 #undef VFP_CONV_FIX
2776
2777 /* Half precision conversions. */
2778 static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s)
2779 {
2780 int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
2781 float32 r = float16_to_float32(make_float16(a), ieee, s);
2782 if (ieee) {
2783 return float32_maybe_silence_nan(r);
2784 }
2785 return r;
2786 }
2787
2788 static uint32_t do_fcvt_f32_to_f16(float32 a, CPUARMState *env, float_status *s)
2789 {
2790 int ieee = (env->vfp.xregs[ARM_VFP_FPSCR] & (1 << 26)) == 0;
2791 float16 r = float32_to_float16(a, ieee, s);
2792 if (ieee) {
2793 r = float16_maybe_silence_nan(r);
2794 }
2795 return float16_val(r);
2796 }
2797
2798 float32 HELPER(neon_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env)
2799 {
2800 return do_fcvt_f16_to_f32(a, env, &env->vfp.standard_fp_status);
2801 }
2802
2803 uint32_t HELPER(neon_fcvt_f32_to_f16)(float32 a, CPUARMState *env)
2804 {
2805 return do_fcvt_f32_to_f16(a, env, &env->vfp.standard_fp_status);
2806 }
2807
2808 float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, CPUARMState *env)
2809 {
2810 return do_fcvt_f16_to_f32(a, env, &env->vfp.fp_status);
2811 }
2812
2813 uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, CPUARMState *env)
2814 {
2815 return do_fcvt_f32_to_f16(a, env, &env->vfp.fp_status);
2816 }
2817
2818 #define float32_two make_float32(0x40000000)
2819 #define float32_three make_float32(0x40400000)
2820 #define float32_one_point_five make_float32(0x3fc00000)
2821
2822 float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env)
2823 {
2824 float_status *s = &env->vfp.standard_fp_status;
2825 if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
2826 (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) {
2827 if (!(float32_is_zero(a) || float32_is_zero(b))) {
2828 float_raise(float_flag_input_denormal, s);
2829 }
2830 return float32_two;
2831 }
2832 return float32_sub(float32_two, float32_mul(a, b, s), s);
2833 }
2834
2835 float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
2836 {
2837 float_status *s = &env->vfp.standard_fp_status;
2838 float32 product;
2839 if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
2840 (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) {
2841 if (!(float32_is_zero(a) || float32_is_zero(b))) {
2842 float_raise(float_flag_input_denormal, s);
2843 }
2844 return float32_one_point_five;
2845 }
2846 product = float32_mul(a, b, s);
2847 return float32_div(float32_sub(float32_three, product, s), float32_two, s);
2848 }
2849
2850 /* NEON helpers. */
2851
2852 /* Constants 256 and 512 are used in some helpers; we avoid relying on
2853 * int->float conversions at run-time. */
2854 #define float64_256 make_float64(0x4070000000000000LL)
2855 #define float64_512 make_float64(0x4080000000000000LL)
2856
2857 /* The algorithm that must be used to calculate the estimate
2858 * is specified by the ARM ARM.
2859 */
2860 static float64 recip_estimate(float64 a, CPUARMState *env)
2861 {
2862 /* These calculations mustn't set any fp exception flags,
2863 * so we use a local copy of the fp_status.
2864 */
2865 float_status dummy_status = env->vfp.standard_fp_status;
2866 float_status *s = &dummy_status;
2867 /* q = (int)(a * 512.0) */
2868 float64 q = float64_mul(float64_512, a, s);
2869 int64_t q_int = float64_to_int64_round_to_zero(q, s);
2870
2871 /* r = 1.0 / (((double)q + 0.5) / 512.0) */
2872 q = int64_to_float64(q_int, s);
2873 q = float64_add(q, float64_half, s);
2874 q = float64_div(q, float64_512, s);
2875 q = float64_div(float64_one, q, s);
2876
2877 /* s = (int)(256.0 * r + 0.5) */
2878 q = float64_mul(q, float64_256, s);
2879 q = float64_add(q, float64_half, s);
2880 q_int = float64_to_int64_round_to_zero(q, s);
2881
2882 /* return (double)s / 256.0 */
2883 return float64_div(int64_to_float64(q_int, s), float64_256, s);
2884 }
2885
2886 float32 HELPER(recpe_f32)(float32 a, CPUARMState *env)
2887 {
2888 float_status *s = &env->vfp.standard_fp_status;
2889 float64 f64;
2890 uint32_t val32 = float32_val(a);
2891
2892 int result_exp;
2893 int a_exp = (val32 & 0x7f800000) >> 23;
2894 int sign = val32 & 0x80000000;
2895
2896 if (float32_is_any_nan(a)) {
2897 if (float32_is_signaling_nan(a)) {
2898 float_raise(float_flag_invalid, s);
2899 }
2900 return float32_default_nan;
2901 } else if (float32_is_infinity(a)) {
2902 return float32_set_sign(float32_zero, float32_is_neg(a));
2903 } else if (float32_is_zero_or_denormal(a)) {
2904 if (!float32_is_zero(a)) {
2905 float_raise(float_flag_input_denormal, s);
2906 }
2907 float_raise(float_flag_divbyzero, s);
2908 return float32_set_sign(float32_infinity, float32_is_neg(a));
2909 } else if (a_exp >= 253) {
2910 float_raise(float_flag_underflow, s);
2911 return float32_set_sign(float32_zero, float32_is_neg(a));
2912 }
2913
2914 f64 = make_float64((0x3feULL << 52)
2915 | ((int64_t)(val32 & 0x7fffff) << 29));
2916
2917 result_exp = 253 - a_exp;
2918
2919 f64 = recip_estimate(f64, env);
2920
2921 val32 = sign
2922 | ((result_exp & 0xff) << 23)
2923 | ((float64_val(f64) >> 29) & 0x7fffff);
2924 return make_float32(val32);
2925 }
2926
2927 /* The algorithm that must be used to calculate the estimate
2928 * is specified by the ARM ARM.
2929 */
2930 static float64 recip_sqrt_estimate(float64 a, CPUARMState *env)
2931 {
2932 /* These calculations mustn't set any fp exception flags,
2933 * so we use a local copy of the fp_status.
2934 */
2935 float_status dummy_status = env->vfp.standard_fp_status;
2936 float_status *s = &dummy_status;
2937 float64 q;
2938 int64_t q_int;
2939
2940 if (float64_lt(a, float64_half, s)) {
2941 /* range 0.25 <= a < 0.5 */
2942
2943 /* a in units of 1/512 rounded down */
2944 /* q0 = (int)(a * 512.0); */
2945 q = float64_mul(float64_512, a, s);
2946 q_int = float64_to_int64_round_to_zero(q, s);
2947
2948 /* reciprocal root r */
2949 /* r = 1.0 / sqrt(((double)q0 + 0.5) / 512.0); */
2950 q = int64_to_float64(q_int, s);
2951 q = float64_add(q, float64_half, s);
2952 q = float64_div(q, float64_512, s);
2953 q = float64_sqrt(q, s);
2954 q = float64_div(float64_one, q, s);
2955 } else {
2956 /* range 0.5 <= a < 1.0 */
2957
2958 /* a in units of 1/256 rounded down */
2959 /* q1 = (int)(a * 256.0); */
2960 q = float64_mul(float64_256, a, s);
2961 int64_t q_int = float64_to_int64_round_to_zero(q, s);
2962
2963 /* reciprocal root r */
2964 /* r = 1.0 /sqrt(((double)q1 + 0.5) / 256); */
2965 q = int64_to_float64(q_int, s);
2966 q = float64_add(q, float64_half, s);
2967 q = float64_div(q, float64_256, s);
2968 q = float64_sqrt(q, s);
2969 q = float64_div(float64_one, q, s);
2970 }
2971 /* r in units of 1/256 rounded to nearest */
2972 /* s = (int)(256.0 * r + 0.5); */
2973
2974 q = float64_mul(q, float64_256,s );
2975 q = float64_add(q, float64_half, s);
2976 q_int = float64_to_int64_round_to_zero(q, s);
2977
2978 /* return (double)s / 256.0;*/
2979 return float64_div(int64_to_float64(q_int, s), float64_256, s);
2980 }
2981
2982 float32 HELPER(rsqrte_f32)(float32 a, CPUARMState *env)
2983 {
2984 float_status *s = &env->vfp.standard_fp_status;
2985 int result_exp;
2986 float64 f64;
2987 uint32_t val;
2988 uint64_t val64;
2989
2990 val = float32_val(a);
2991
2992 if (float32_is_any_nan(a)) {
2993 if (float32_is_signaling_nan(a)) {
2994 float_raise(float_flag_invalid, s);
2995 }
2996 return float32_default_nan;
2997 } else if (float32_is_zero_or_denormal(a)) {
2998 if (!float32_is_zero(a)) {
2999 float_raise(float_flag_input_denormal, s);
3000 }
3001 float_raise(float_flag_divbyzero, s);
3002 return float32_set_sign(float32_infinity, float32_is_neg(a));
3003 } else if (float32_is_neg(a)) {
3004 float_raise(float_flag_invalid, s);
3005 return float32_default_nan;
3006 } else if (float32_is_infinity(a)) {
3007 return float32_zero;
3008 }
3009
3010 /* Normalize to a double-precision value between 0.25 and 1.0,
3011 * preserving the parity of the exponent. */
3012 if ((val & 0x800000) == 0) {
3013 f64 = make_float64(((uint64_t)(val & 0x80000000) << 32)
3014 | (0x3feULL << 52)
3015 | ((uint64_t)(val & 0x7fffff) << 29));
3016 } else {
3017 f64 = make_float64(((uint64_t)(val & 0x80000000) << 32)
3018 | (0x3fdULL << 52)
3019 | ((uint64_t)(val & 0x7fffff) << 29));
3020 }
3021
3022 result_exp = (380 - ((val & 0x7f800000) >> 23)) / 2;
3023
3024 f64 = recip_sqrt_estimate(f64, env);
3025
3026 val64 = float64_val(f64);
3027
3028 val = ((result_exp & 0xff) << 23)
3029 | ((val64 >> 29) & 0x7fffff);
3030 return make_float32(val);
3031 }
3032
3033 uint32_t HELPER(recpe_u32)(uint32_t a, CPUARMState *env)
3034 {
3035 float64 f64;
3036
3037 if ((a & 0x80000000) == 0) {
3038 return 0xffffffff;
3039 }
3040
3041 f64 = make_float64((0x3feULL << 52)
3042 | ((int64_t)(a & 0x7fffffff) << 21));
3043
3044 f64 = recip_estimate (f64, env);
3045
3046 return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
3047 }
3048
3049 uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUARMState *env)
3050 {
3051 float64 f64;
3052
3053 if ((a & 0xc0000000) == 0) {
3054 return 0xffffffff;
3055 }
3056
3057 if (a & 0x80000000) {
3058 f64 = make_float64((0x3feULL << 52)
3059 | ((uint64_t)(a & 0x7fffffff) << 21));
3060 } else { /* bits 31-30 == '01' */
3061 f64 = make_float64((0x3fdULL << 52)
3062 | ((uint64_t)(a & 0x3fffffff) << 22));
3063 }
3064
3065 f64 = recip_sqrt_estimate(f64, env);
3066
3067 return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
3068 }
3069
3070 /* VFPv4 fused multiply-accumulate */
3071 float32 VFP_HELPER(muladd, s)(float32 a, float32 b, float32 c, void *fpstp)
3072 {
3073 float_status *fpst = fpstp;
3074 return float32_muladd(a, b, c, 0, fpst);
3075 }
3076
3077 float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp)
3078 {
3079 float_status *fpst = fpstp;
3080 return float64_muladd(a, b, c, 0, fpst);
3081 }
3082
3083 void HELPER(set_teecr)(CPUARMState *env, uint32_t val)
3084 {
3085 val &= 1;
3086 if (env->teecr != val) {
3087 env->teecr = val;
3088 tb_flush(env);
3089 }
3090 }