18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h> 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h> 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cpu.h" 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "exec-all.h" 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "gdbstub.h" 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "helpers.h" 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h" 10ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#ifdef CONFIG_TRACE 11ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#include "trace.h" 12ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#endif 135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck/memcheck_api.h" 155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t cortexa8_cp15_c0_c1[8] = 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 }; 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t cortexa8_cp15_c0_c2[8] = 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x00101111, 0x12112111, 0x21232031, 0x11112131, 0x00111142, 0, 0, 0 }; 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t mpcore_cp15_c0_c1[8] = 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x111, 0x1, 0, 0x2, 0x01100103, 0x10020302, 0x01222000, 0 }; 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t mpcore_cp15_c0_c2[8] = 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x00100011, 0x12002111, 0x11221011, 0x01102131, 0x141, 0, 0, 0 }; 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t arm1136_cp15_c0_c1[8] = 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x111, 0x1, 0x2, 0x3, 0x01130003, 0x10030302, 0x01222110, 0 }; 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t arm1136_cp15_c0_c2[8] = 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 0x00140011, 0x12002111, 0x11231111, 0x01102131, 0x141, 0, 0, 0 }; 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t cpu_arm_find_by_name(const char *name); 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void set_feature(CPUARMState *env, int feature) 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->features |= 1u << feature; 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void cpu_reset_model_id(CPUARMState *env, uint32_t id) 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cpuid = id; 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (id) { 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM926: 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_VFP); 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cachetype = 0x1dd20d2; 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c1_sys = 0x00090078; 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM946: 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_MPU); 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cachetype = 0x0f004006; 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c1_sys = 0x00000078; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM1026: 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_VFP); 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_AUXCR); 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0; 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cachetype = 0x1dd20d2; 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c1_sys = 0x00090078; 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM1136_R2: 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM1136: 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V6); 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_VFP); 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_AUXCR); 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t)); 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t)); 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cachetype = 0x1dd20d2; 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM11MPCORE: 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V6); 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V6K); 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_VFP); 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_AUXCR); 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4; 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111; 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000; 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t)); 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t)); 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cachetype = 0x1dd20d2; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_CORTEXA8: 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V6); 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V6K); 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V7); 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_AUXCR); 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_THUMB2); 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_VFP); 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_VFP3); 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_NEON); 975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner set_feature(env, ARM_FEATURE_THUMB2EE); 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t)); 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t)); 1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c0_cachetype = 0x82048004; 1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c0_clid = (1 << 27) | (2 << 24) | 3; 1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c0_ccsid[0] = 0xe007e01a; /* 16k L1 dcache. */ 1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c0_ccsid[1] = 0x2007e01a; /* 16k L1 icache. */ 1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c0_ccsid[2] = 0xf0000000; /* No L2 icache. */ 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_CORTEXM3: 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V6); 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_THUMB2); 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V7); 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_M); 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_DIV); 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ANY: /* For userspace emulation. */ 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V6); 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V6K); 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_V7); 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_THUMB2); 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_VFP); 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_VFP3); 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_NEON); 1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner set_feature(env, ARM_FEATURE_THUMB2EE); 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_DIV); 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_TI915T: 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_TI925T: 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_OMAPCP); 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring. */ 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cachetype = 0x5109149; 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c1_sys = 0x00000070; 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_i_max = 0x000; 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_i_min = 0xff0; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA250: 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA255: 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA260: 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA261: 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA262: 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_XSCALE); 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* JTAG_ID is ((id << 28) | 0x09265013) */ 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cachetype = 0xd172172; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c1_sys = 0x00000078; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA270_A0: 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA270_A1: 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA270_B0: 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA270_B1: 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA270_C0: 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_PXA270_C5: 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_XSCALE); 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* JTAG_ID is ((id << 28) | 0x09265013) */ 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_feature(env, ARM_FEATURE_IWMMXT); 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cachetype = 0xd172172; 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c1_sys = 0x00000078; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Bad CPU ID: %x\n", id); 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_reset(CPUARMState *env) 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t id; 1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (qemu_loglevel_mask(CPU_LOG_RESET)) { 1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); 1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner log_cpu_state(env, 0); 1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project id = env->cp15.c0_cpuid; 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset(env, 0, offsetof(CPUARMState, breakpoints)); 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (id) 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_reset_model_id(env, id); 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined (CONFIG_USER_ONLY) 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr = ARM_CPU_MODE_USR; 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* SVC mode with interrupts disabled. */ 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project clear at reset. */ 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (IS_M(env)) 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr &= ~CPSR_I; 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPEXC] = 0; 1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c2_base_mask = 0xffffc000u; 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[15] = 0; 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, 1); 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vfp_gdb_get_reg(CPUState *env, uint8_t *buf, int reg) 1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nregs; 1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* VFP data registers are always little-endian. */ 2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16; 2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (reg < nregs) { 2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner stfq_le_p(buf, env->vfp.regs[reg]); 2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 8; 2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (arm_feature(env, ARM_FEATURE_NEON)) { 2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Aliases for Q regs. */ 2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nregs += 16; 2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (reg < nregs) { 2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]); 2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]); 2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 16; 2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (reg - nregs) { 2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4; 2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4; 2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4; 2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int vfp_gdb_set_reg(CPUState *env, uint8_t *buf, int reg) 2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nregs; 2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16; 2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (reg < nregs) { 2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->vfp.regs[reg] = ldfq_le_p(buf); 2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 8; 2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (arm_feature(env, ARM_FEATURE_NEON)) { 2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nregs += 16; 2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (reg < nregs) { 2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf); 2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8); 2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 16; 2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (reg - nregs) { 2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4; 2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4; 2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf); return 4; 2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectCPUARMState *cpu_arm_init(const char *cpu_model) 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project CPUARMState *env; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t id; 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static int inited = 0; 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project id = cpu_arm_find_by_name(cpu_model); 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (id == 0) 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env = qemu_mallocz(sizeof(CPUARMState)); 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_exec_init(env); 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!inited) { 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inited = 1; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project arm_translate_init(); 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cpu_model_str = cpu_model; 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cpuid = id; 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_reset(env); 2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (arm_feature(env, ARM_FEATURE_NEON)) { 2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, 2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 51, "arm-neon.xml", 0); 2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (arm_feature(env, ARM_FEATURE_VFP3)) { 2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, 2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 35, "arm-vfp3.xml", 0); 2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (arm_feature(env, ARM_FEATURE_VFP)) { 2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, 2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 19, "arm-vfp.xml", 0); 2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_init_vcpu(env); 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env; 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct arm_cpu_t { 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t id; 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *name; 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const struct arm_cpu_t arm_cpu_names[] = { 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_ARM926, "arm926"}, 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_ARM946, "arm946"}, 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_ARM1026, "arm1026"}, 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_ARM1136, "arm1136"}, 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_ARM1136_R2, "arm1136-r2"}, 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_ARM11MPCORE, "arm11mpcore"}, 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_CORTEXM3, "cortex-m3"}, 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_CORTEXA8, "cortex-a8"}, 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_TI925T, "ti925t" }, 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA250, "pxa250" }, 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA255, "pxa255" }, 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA260, "pxa260" }, 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA261, "pxa261" }, 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA262, "pxa262" }, 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA270, "pxa270" }, 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA270_A0, "pxa270-a0" }, 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA270_A1, "pxa270-a1" }, 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA270_B0, "pxa270-b0" }, 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA270_B1, "pxa270-b1" }, 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA270_C0, "pxa270-c0" }, 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_PXA270_C5, "pxa270-c5" }, 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { ARM_CPUID_ANY, "any"}, 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 0, NULL} 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (*cpu_fprintf)(f, "Available CPUs:\n"); 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; arm_cpu_names[i].name; i++) { 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (*cpu_fprintf)(f, " %s\n", arm_cpu_names[i].name); 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return 0 if not found */ 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t cpu_arm_find_by_name(const char *name) 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t id; 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project id = 0; 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; arm_cpu_names[i].name; i++) { 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strcmp(name, arm_cpu_names[i].name) == 0) { 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project id = arm_cpu_names[i].id; 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return id; 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_arm_close(CPUARMState *env) 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(env); 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t cpsr_read(CPUARMState *env) 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ZF; 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ZF = (env->ZF == 0); 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) | 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27) 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | (env->thumb << 5) | ((env->condexec_bits & 3) << 25) 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | ((env->condexec_bits & 0xfc) << 8) 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | (env->GE << 16); 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mask & CPSR_NZCV) { 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->ZF = (~val) & CPSR_Z; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->NF = val; 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->CF = (val >> 29) & 1; 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->VF = (val << 3) & 0x80000000; 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mask & CPSR_Q) 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->QF = ((val & CPSR_Q) != 0); 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mask & CPSR_T) 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->thumb = ((val & CPSR_T) != 0); 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mask & CPSR_IT_0_1) { 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->condexec_bits &= ~3; 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->condexec_bits |= (val >> 25) & 3; 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mask & CPSR_IT_2_7) { 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->condexec_bits &= 3; 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->condexec_bits |= (val >> 8) & 0xfc; 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mask & CPSR_GE) { 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->GE = (val >> 16) & 0xf; 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((env->uncached_cpsr ^ val) & mask & CPSR_M) { 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch_mode(env, val & CPSR_M); 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask &= ~CACHED_CPSR_BITS; 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask); 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Sign/zero extend */ 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(sxtb16)(uint32_t x) 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t res; 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = (uint16_t)(int8_t)x; 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res |= (uint32_t)(int8_t)(x >> 16) << 16; 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(uxtb16)(uint32_t x) 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t res; 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = (uint16_t)(uint8_t)x; 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res |= (uint32_t)(uint8_t)(x >> 16) << 16; 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(clz)(uint32_t x) 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int count; 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (count = 32; x; count--) 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x >>= 1; 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return count; 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32_t HELPER(sdiv)(int32_t num, int32_t den) 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (den == 0) 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return num / den; 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(udiv)(uint32_t num, uint32_t den) 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (den == 0) 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return num / den; 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(rbit)(uint32_t x) 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x = ((x & 0xff000000) >> 24) 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | ((x & 0x00ff0000) >> 8) 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | ((x & 0x0000ff00) << 8) 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | ((x & 0x000000ff) << 24); 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x = ((x & 0xf0f0f0f0) >> 4) 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | ((x & 0x0f0f0f0f) << 4); 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x = ((x & 0x88888888) >> 3) 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | ((x & 0x44444444) >> 1) 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | ((x & 0x22222222) << 1) 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | ((x & 0x11111111) << 3); 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return x; 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(abs)(uint32_t x) 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ((int32_t)x < 0) ? -x : x; 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(CONFIG_USER_ONLY) 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid do_interrupt (CPUState *env) 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->exception_index = -1; 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Structure used to record exclusive memory locations. */ 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct mmon_state { 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct mmon_state *next; 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project CPUARMState *cpu_env; 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr; 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} mmon_state; 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Chain of current locks. */ 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic mmon_state* mmon_head = NULL; 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mmu_idx, int is_softmmu) 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (rw == 2) { 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->exception_index = EXCP_PREFETCH_ABORT; 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c6_insn = address; 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->exception_index = EXCP_DATA_ABORT; 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c6_data = address; 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void allocate_mmon_state(CPUState *env) 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->mmon_entry = malloc(sizeof (mmon_state)); 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset (env->mmon_entry, 0, sizeof (mmon_state)); 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->mmon_entry->cpu_env = env; 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mmon_head = env->mmon_entry; 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Flush any monitor locks for the specified address. */ 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void flush_mmon(uint32_t addr) 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mmon_state *mon; 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (mon = mmon_head; mon; mon = mon->next) 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mon->addr != addr) 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mon->addr = 0; 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Mark an address for exclusive access. */ 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(mark_exclusive)(CPUState *env, uint32_t addr) 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!env->mmon_entry) 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project allocate_mmon_state(env); 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Clear any previous locks. */ 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flush_mmon(addr); 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->mmon_entry->addr = addr; 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Test if an exclusive address is still exclusive. Returns zero 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if the address is still exclusive. */ 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr) 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int res; 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!env->mmon_entry) 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->mmon_entry->addr == addr) 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0; 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 1; 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flush_mmon(addr); 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(clrex)(CPUState *env) 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(env->mmon_entry && env->mmon_entry->addr)) 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flush_mmon(env->mmon_entry->addr); 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttarget_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return addr; 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* These should probably raise undefined insn exceptions. */ 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val) 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int op1 = (insn >> 8) & 0xf; 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "cp%i insn %08x\n", op1, insn); 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_cp)(CPUState *env, uint32_t insn) 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int op1 = (insn >> 8) & 0xf; 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "cp%i insn %08x\n", op1, insn); 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "cp15 insn %08x\n", insn); 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "cp15 insn %08x\n", insn); 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* These should probably raise undefined insn exceptions. */ 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val) 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "v7m_mrs %d\n", reg); 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg) 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "v7m_mrs %d\n", reg); 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid switch_mode(CPUState *env, int mode) 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mode != ARM_CPU_MODE_USR) 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Tried to switch out of user mode\n"); 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val) 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "banked r13 write\n"); 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode) 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "banked r13 read\n"); 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern int semihosting_enabled; 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Map CPU modes onto saved register banks. */ 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int bank_number (int mode) 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (mode) { 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPU_MODE_USR: 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPU_MODE_SYS: 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPU_MODE_SVC: 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPU_MODE_ABT: 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 2; 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPU_MODE_UND: 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 3; 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPU_MODE_IRQ: 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 4; 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPU_MODE_FIQ: 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 5; 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(cpu_single_env, "Bad mode %x\n", mode); 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid switch_mode(CPUState *env, int mode) 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int old_mode; 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_mode = env->uncached_cpsr & CPSR_M; 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mode == old_mode) 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (old_mode == ARM_CPU_MODE_FIQ) { 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t)); 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t)); 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (mode == ARM_CPU_MODE_FIQ) { 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t)); 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t)); 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = bank_number(old_mode); 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->banked_r13[i] = env->regs[13]; 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->banked_r14[i] = env->regs[14]; 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->banked_spsr[i] = env->spsr; 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = bank_number(mode); 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[13] = env->banked_r13[i]; 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[14] = env->banked_r14[i]; 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->spsr = env->banked_spsr[i]; 6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void v7m_push(CPUARMState *env, uint32_t val) 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[13] -= 4; 6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stl_phys(env->regs[13], val); 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t v7m_pop(CPUARMState *env) 6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t val; 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val = ldl_phys(env->regs[13]); 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[13] += 4; 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return val; 6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Switch to V7M main or process stack pointer. */ 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void switch_v7m_sp(CPUARMState *env, int process) 6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t tmp; 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->v7m.current_sp != process) { 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = env->v7m.other_sp; 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->v7m.other_sp = env->regs[13]; 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[13] = tmp; 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->v7m.current_sp = process; 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void do_v7m_exception_exit(CPUARMState *env) 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t type; 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t xpsr; 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project type = env->regs[15]; 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->v7m.exception != 0) 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project armv7m_nvic_complete_irq(env->v7m.nvic, env->v7m.exception); 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Switch to the target stack. */ 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch_v7m_sp(env, (type & 4) != 0); 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Pop registers. */ 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[0] = v7m_pop(env); 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[1] = v7m_pop(env); 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[2] = v7m_pop(env); 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[3] = v7m_pop(env); 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[12] = v7m_pop(env); 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[14] = v7m_pop(env); 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[15] = v7m_pop(env); 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr = v7m_pop(env); 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr_write(env, xpsr, 0xfffffdff); 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Undo stack alignment. */ 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (xpsr & 0x200) 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[13] |= 4; 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? The exception return type specifies Thread/Handler mode. However 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project this is also implied by the xPSR value. Not sure what to do 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if there is a mismatch. */ 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? Likewise for mismatches between the CONTROL register and the stack 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pointer. */ 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void do_interrupt_v7m(CPUARMState *env) 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t xpsr = xpsr_read(env); 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t lr; 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr; 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lr = 0xfffffff1; 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->v7m.current_sp) 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lr |= 4; 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->v7m.exception == 0) 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lr |= 8; 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* For exceptions we just mark as pending on the NVIC, and let that 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project handle it. */ 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* TODO: Need to escalate if the current priority is higher than the 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project one we're raising. */ 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (env->exception_index) { 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_UDEF: 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_USAGE); 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_SWI: 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[15] += 2; 7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_SVC); 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_PREFETCH_ABORT: 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_DATA_ABORT: 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_MEM); 7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_BKPT: 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (semihosting_enabled) { 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nr; 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nr = lduw_code(env->regs[15]) & 0xff; 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nr == 0xab) { 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[15] += 2; 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[0] = do_arm_semihosting(env); 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project armv7m_nvic_set_pending(env->v7m.nvic, ARMV7M_EXCP_DEBUG); 7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_IRQ: 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->v7m.exception = armv7m_nvic_acknowledge_irq(env->v7m.nvic); 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_EXCEPTION_EXIT: 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do_v7m_exception_exit(env); 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index); 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; /* Never happens. Keep compiler happy. */ 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Align stack pointer. */ 7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? Should only do this if Configuration Control Register 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project STACKALIGN bit is set. */ 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->regs[13] & 4) { 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[13] -= 4; 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr |= 0x200; 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Switch to the handler mode. */ 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v7m_push(env, xpsr); 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v7m_push(env, env->regs[15]); 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v7m_push(env, env->regs[14]); 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v7m_push(env, env->regs[12]); 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v7m_push(env, env->regs[3]); 7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v7m_push(env, env->regs[2]); 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v7m_push(env, env->regs[1]); 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v7m_push(env, env->regs[0]); 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch_v7m_sp(env, 0); 7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr &= ~CPSR_IT; 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[14] = lr; 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4); 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[15] = addr & 0xfffffffe; 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->thumb = addr & 1; 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Handle a CPU exception. */ 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid do_interrupt(CPUARMState *env) 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr; 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t mask; 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int new_mode; 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t offset; 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 783ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#ifdef CONFIG_TRACE 784ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra if (tracing) { 785ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra trace_exception(env->regs[15]); 786ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra } 787ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra#endif 788ab42ada6ecfb81d6e231d5997b5892efd0fde5adJack Veenstra 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (IS_M(env)) { 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do_interrupt_v7m(env); 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* TODO: Vectored interrupt controller. */ 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (env->exception_index) { 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_UDEF: 7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_mode = ARM_CPU_MODE_UND; 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr = 0x04; 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = CPSR_I; 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->thumb) 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset = 2; 8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset = 4; 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_SWI: 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (semihosting_enabled) { 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Check for semihosting interrupt. */ 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->thumb) { 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = lduw_code(env->regs[15] - 2) & 0xff; 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = ldl_code(env->regs[15] - 4) & 0xffffff; 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Only intercept calls from privileged modes, to provide some 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project semblance of security. */ 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (((mask == 0x123456 && !env->thumb) 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project || (mask == 0xab && env->thumb)) 8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { 8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[0] = do_arm_semihosting(env); 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_mode = ARM_CPU_MODE_SVC; 8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr = 0x08; 8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = CPSR_I; 8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* The PC already points to the next instruction. */ 8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset = 0; 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_BKPT: 8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* See if this is a semihosting syscall. */ 8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->thumb && semihosting_enabled) { 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = lduw_code(env->regs[15]) & 0xff; 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mask == 0xab 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) { 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[15] += 2; 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[0] = do_arm_semihosting(env); 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Fall through to prefetch abort. */ 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_PREFETCH_ABORT: 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_mode = ARM_CPU_MODE_ABT; 8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr = 0x0c; 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = CPSR_A | CPSR_I; 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset = 4; 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_DATA_ABORT: 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_mode = ARM_CPU_MODE_ABT; 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr = 0x10; 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = CPSR_A | CPSR_I; 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset = 8; 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_IRQ: 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_mode = ARM_CPU_MODE_IRQ; 8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr = 0x18; 8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Disable IRQ and imprecise data aborts. */ 8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = CPSR_A | CPSR_I; 8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset = 4; 8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EXCP_FIQ: 8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_mode = ARM_CPU_MODE_FIQ; 8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr = 0x1c; 8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Disable FIQ, IRQ and imprecise data aborts. */ 8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = CPSR_A | CPSR_I | CPSR_F; 8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset = 4; 8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index); 8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; /* Never happens. Keep compiler happy. */ 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* High vectors. */ 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->cp15.c1_sys & (1 << 13)) { 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr += 0xffff0000; 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch_mode (env, new_mode); 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->spsr = cpsr_read(env); 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Clear IT bits. */ 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->condexec_bits = 0; 8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Switch to the new mode, and switch to Arm mode. */ 8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? Thumb interrupt handlers not implemented. */ 8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode; 8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr |= mask; 8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->thumb = 0; 8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[14] = env->regs[15] + offset; 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[15] = addr; 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->interrupt_request |= CPU_INTERRUPT_EXITTB; 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Check section/page access permissions. 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Returns the page protection flags, or zero if the access is not 8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project permitted. */ 8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int check_ap(CPUState *env, int ap, int domain, int access_type, 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int is_user) 8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int prot_ro; 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (domain == 3) 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return PAGE_READ | PAGE_WRITE; 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (access_type == 1) 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project prot_ro = 0; 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project prot_ro = PAGE_READ; 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (ap) { 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (access_type == 1) 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch ((env->cp15.c1_sys >> 8) & 3) { 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return is_user ? 0 : PAGE_READ; 9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return PAGE_READ; 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return is_user ? 0 : PAGE_READ | PAGE_WRITE; 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_user) 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return prot_ro; 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return PAGE_READ | PAGE_WRITE; 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return PAGE_READ | PAGE_WRITE; 9245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 4: /* Reserved. */ 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return is_user ? 0 : prot_ro; 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 6: 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return prot_ro; 9305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 7: 9315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!arm_feature (env, ARM_FEATURE_V7)) 9325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 9335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return prot_ro; 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project abort(); 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t get_level1_table_address(CPUState *env, uint32_t address) 9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t table; 9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (address & env->cp15.c2_mask) 9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner table = env->cp15.c2_base1 & 0xffffc000; 9455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 9465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner table = env->cp15.c2_base0 & env->cp15.c2_base_mask; 9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner table |= (address >> 18) & 0x3ffc; 9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return table; 9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type, 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int is_user, uint32_t *phys_ptr, int *prot) 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int code; 9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t table; 9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t desc; 9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int type; 9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ap; 9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int domain; 9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t phys_addr; 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Pagetable walk. */ 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Lookup l1 descriptor. */ 9655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner table = get_level1_table_address(env, address); 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project desc = ldl_phys(table); 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project type = (desc & 3); 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3; 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == 0) { 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Section translation fault. */ 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 5; 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (domain == 0 || domain == 2) { 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == 2) 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 9; /* Section domain fault. */ 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 11; /* Page domain fault. */ 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == 2) { 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1Mb section. */ 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xfff00000) | (address & 0x000fffff); 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ap = (desc >> 10) & 3; 9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 13; 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Lookup l2 entry. */ 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == 1) { 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Coarse pagetable. */ 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Fine pagetable. */ 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project table = (desc & 0xfffff000) | ((address >> 8) & 0xffc); 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project desc = ldl_phys(table); 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (desc & 3) { 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* Page translation fault. */ 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 7; 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* 64k page. */ 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xffff0000) | (address & 0xffff); 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ap = (desc >> (4 + ((address >> 13) & 6))) & 3; 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* 4k page. */ 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xfffff000) | (address & 0xfff); 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ap = (desc >> (4 + ((address >> 13) & 6))) & 3; 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* 1k page. */ 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == 1) { 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_XSCALE)) { 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xfffff000) | (address & 0xfff); 10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Page translation fault. */ 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 7; 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xfffffc00) | (address & 0x3ff); 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ap = (desc >> 4) & 3; 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Never happens, but compiler isn't smart enough to tell. */ 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project abort(); 10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 15; 10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot = check_ap(env, ap, domain, access_type, is_user); 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!*prot) { 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Access permission fault. */ 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *phys_ptr = phys_addr; 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_fault: 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return code | (domain << 4); 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type, 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int is_user, uint32_t *phys_ptr, int *prot) 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int code; 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t table; 10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t desc; 10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t xn; 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int type; 10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ap; 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int domain; 10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t phys_addr; 10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Pagetable walk. */ 10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Lookup l1 descriptor. */ 10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner table = get_level1_table_address(env, address); 10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project desc = ldl_phys(table); 10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project type = (desc & 3); 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == 0) { 10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Section translation fault. */ 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 5; 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project domain = 0; 10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (type == 2 && (desc & (1 << 18))) { 10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Supersection. */ 10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project domain = 0; 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Section or page. */ 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project domain = (desc >> 4) & 0x1e; 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project domain = (env->cp15.c3 >> domain) & 3; 10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (domain == 0 || domain == 2) { 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == 2) 10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 9; /* Section domain fault. */ 10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 11; /* Page domain fault. */ 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == 2) { 10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (desc & (1 << 18)) { 10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Supersection. */ 10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xff000000) | (address & 0x00ffffff); 10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Section. */ 10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xfff00000) | (address & 0x000fffff); 10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ap = ((desc >> 10) & 3) | ((desc >> 13) & 4); 10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xn = desc & (1 << 4); 10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 13; 10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Lookup l2 entry. */ 10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); 10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project desc = ldl_phys(table); 10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ap = ((desc >> 4) & 3) | ((desc >> 7) & 4); 10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (desc & 3) { 10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* Page translation fault. */ 10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 7; 10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* 64k page. */ 10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xffff0000) | (address & 0xffff); 10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xn = desc & (1 << 15); 10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: case 3: /* 4k page. */ 11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr = (desc & 0xfffff000) | (address & 0xfff); 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xn = desc & 1; 11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Never happens, but compiler isn't smart enough to tell. */ 11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project abort(); 11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code = 15; 11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (xn && access_type == 2) 11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* The simplified model uses AP[0] as an access control bit. */ 11145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((env->cp15.c1_sys & (1 << 29)) && (ap & 1) == 0) { 11155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Access flag fault. */ 11165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner code = (code == 15) ? 6 : 3; 11175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto do_fault; 11185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot = check_ap(env, ap, domain, access_type, is_user); 11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!*prot) { 11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Access permission fault. */ 11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto do_fault; 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *phys_ptr = phys_addr; 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdo_fault: 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return code | (domain << 4); 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type, 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int is_user, uint32_t *phys_ptr, int *prot) 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n; 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t mask; 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t base; 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *phys_ptr = address; 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = 7; n >= 0; n--) { 11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project base = env->cp15.c6_region[n]; 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((base & 1) == 0) 11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = 1 << ((base >> 1) & 0x1f); 11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Keep this shift separate from the above to avoid an 11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (undefined) << 32. */ 11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = (mask << 1) - 1; 11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (((base ^ address) & ~mask) == 0) 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n < 0) 11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 2; 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (access_type == 2) { 11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = env->cp15.c5_insn; 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = env->cp15.c5_data; 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = (mask >> (n * 4)) & 0xf; 11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (mask) { 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_user) 11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot = PAGE_READ | PAGE_WRITE; 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot = PAGE_READ; 11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!is_user) 11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot |= PAGE_WRITE; 11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot = PAGE_READ | PAGE_WRITE; 11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: 11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_user) 11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot = PAGE_READ; 11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 6: 11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot = PAGE_READ; 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Bad permission. */ 11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int get_phys_addr(CPUState *env, uint32_t address, 11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int access_type, int is_user, 11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t *phys_ptr, int *prot) 11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Fast Context Switch Extension. */ 11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (address < 0x02000000) 11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address += env->cp15.c13_fcse; 11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((env->cp15.c1_sys & 1) == 0) { 11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* MMU/MPU disabled. */ 11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *phys_ptr = address; 12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *prot = PAGE_READ | PAGE_WRITE; 12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (arm_feature(env, ARM_FEATURE_MPU)) { 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr, 12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project prot); 12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (env->cp15.c1_sys & (1 << 23)) { 12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr, 12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project prot); 12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr, 12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project prot); 12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, 12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int access_type, int mmu_idx, int is_softmmu) 12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t phys_addr; 12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int prot; 12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret, is_user; 12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project is_user = mmu_idx == MMU_USER_IDX; 12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot); 12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == 0) { 12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Map a single [sub]page. */ 12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project phys_addr &= ~(uint32_t)0x3ff; 12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address &= ~(uint32_t)0x3ff; 12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return tlb_set_page (env, address, phys_addr, prot, mmu_idx, 12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project is_softmmu); 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (access_type == 2) { 12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c5_insn = ret; 12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c6_insn = address; 12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->exception_index = EXCP_PREFETCH_ABORT; 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c5_data = ret; 12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6)) 12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c5_data |= (1 << 11); 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c6_data = address; 12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->exception_index = EXCP_DATA_ABORT; 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttarget_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t phys_addr; 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int prot; 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot); 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret != 0) 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return phys_addr; 12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Not really implemented. Need to figure out a sane way of doing this. 12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Maybe add generic watchpoint support and use that. */ 12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(mark_exclusive)(CPUState *env, uint32_t addr) 12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->mmon_addr = addr; 12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(test_exclusive)(CPUState *env, uint32_t addr) 12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (env->mmon_addr != addr); 12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(clrex)(CPUState *env) 12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->mmon_addr = -1; 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val) 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int cp_num = (insn >> 8) & 0xf; 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int cp_info = (insn >> 5) & 7; 12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int src = (insn >> 16) & 0xf; 12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int operand = insn & 0xf; 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->cp[cp_num].cp_write) 12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp[cp_num].cp_write(env->cp[cp_num].opaque, 12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cp_info, src, operand, val); 12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_cp)(CPUState *env, uint32_t insn) 12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int cp_num = (insn >> 8) & 0xf; 12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int cp_info = (insn >> 5) & 7; 12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int dest = (insn >> 16) & 0xf; 12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int operand = insn & 0xf; 12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->cp[cp_num].cp_read) 12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp[cp_num].cp_read(env->cp[cp_num].opaque, 12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cp_info, dest, operand); 12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return basic MPU access permission bits. */ 13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t simple_mpu_ap_bits(uint32_t val) 13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t ret; 13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t mask; 13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = 0; 13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = 3; 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < 16; i += 2) { 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret |= (val >> i) & mask; 13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask <<= 2; 13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Pad basic MPU access permission bits to extended format. */ 13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint32_t extended_mpu_ap_bits(uint32_t val) 13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t ret; 13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t mask; 13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = 0; 13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = 3; 13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < 16; i += 2) { 13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret |= (val & mask) << i; 13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask <<= 2; 13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val) 13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int op1; 13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int op2; 13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int crm; 13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op1 = (insn >> 21) & 7; 13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op2 = (insn >> 5) & 7; 13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project crm = insn & 0xf; 13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch ((insn >> 16) & 0xf) { 13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ID codes. */ 13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_XSCALE)) 13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (arm_feature(env, ARM_FEATURE_V7) 13495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner && op1 == 2 && crm == 0 && op2 == 0) { 13505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c0_cssel = val & 0xf; 13515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 13525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* System configuration. */ 13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op2 = 0; 13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0) 13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c1_sys = val; 13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? Lots of these bits are not implemented. */ 13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* This may enable/disable the MMU, so do a TLB flush. */ 13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, 1); 13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* Auxiliary cotrol register. */ 13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_XSCALE)) { 13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c1_xscaleauxcr = val; 13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Not implemented. */ 13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_XSCALE)) 13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 13755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (env->cp15.c1_coproc != val) { 13765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c1_coproc = val; 13775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* ??? Is this safe when called from within a TB? */ 13785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tb_flush(env); 13795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* MMU Page table control / MPU cache control. */ 13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_MPU)) { 13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c2_data = val; 13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c2_insn = val; 13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c2_base0 = val; 14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c2_base1 = val; 14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 14065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner val &= 7; 14075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c2_control = val; 14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val); 14095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val); 14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* MMU Domain access control / MPU write buffer control. */ 14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c3 = val; 14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */ 14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: /* Reserved. */ 14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: /* MMU Fault status / MPU access permission. */ 14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op2 = 0; 14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_MPU)) 14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val = extended_mpu_ap_bits(val); 14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c5_data = val; 14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_MPU)) 14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val = extended_mpu_ap_bits(val); 14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c5_insn = val; 14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_MPU)) 14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c5_data = val; 14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_MPU)) 14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c5_insn = val; 14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 6: /* MMU Fault address / MPU base/size. */ 14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_MPU)) { 14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (crm >= 8) 14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c6_region[crm] = val; 14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op2 = 0; 14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c6_data = val; 14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* ??? This is WFAR on armv6 */ 14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c6_insn = val; 14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 7: /* Cache control. */ 14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_i_max = 0x000; 14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_i_min = 0xff0; 14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* No cache, so nothing to do. */ 14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? MPCore has VA to PA translation functions. */ 14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 8: /* MMU TLB control. */ 14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* Invalidate all. */ 14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, 0); 14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* Invalidate single TLB entry. */ 14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? This is wrong for large pages and sections. */ 14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* As an ugly hack to make linux work we always flush a 4K 14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pages. */ 14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val &= 0xfffff000; 14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush_page(env, val); 14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush_page(env, val + 0x400); 14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush_page(env, val + 0x800); 14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush_page(env, val + 0xc00); 14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, 1); 14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* Invalidate on ASID. */ 14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, val == 0); 14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* Invalidate single entry on MVA. */ 15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? This is like case 1, but ignores ASID. */ 15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, 1); 15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 9: 15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (crm) { 15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* Cache lockdown. */ 15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op1) { 15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* L1 cache. */ 15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c9_data = val; 15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c9_insn = val; 15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* L2 cache. */ 15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Ignore writes to L2 lockdown/auxiliary registers. */ 15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* TCM memory region registers. */ 15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Not implemented. */ 15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 10: /* MMU TLB lockdown. */ 15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? TLB lockdown not implemented. */ 15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 12: /* Reserved. */ 15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 13: /* Process ID. */ 15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Unlike real hardware the qemu TLB uses virtual addresses, 15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project not modified virtual addresses, so this causes a TLB flush. 15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->cp15.c13_fcse != val) 15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, 1); 15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c13_fcse = val; 15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* This changes the ASID, so do a TLB flush. */ 15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->cp15.c13_context != val 15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project && !arm_feature(env, ARM_FEATURE_MPU)) 15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlb_flush(env, 0); 15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c13_context = val; 15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c13_tls1 = val; 15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c13_tls2 = val; 15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: 15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c13_tls3 = val; 15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 14: /* Reserved. */ 15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 15: /* Implementation specific. */ 15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_XSCALE)) { 15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (op2 == 0 && crm == 1) { 15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->cp15.c15_cpar != (val & 0x3fff)) { 15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Changes cp0 to cp13 behavior, so needs a TB flush. */ 15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tb_flush(env); 15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_cpar = val & 0x3fff; 15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) { 15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (crm) { 15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* Set TI925T configuration. */ 15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_ticonfig = val & 0xe7; 15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */ 15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ARM_CPUID_TI915T : ARM_CPUID_TI925T; 15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* Set I_max. */ 15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_i_max = val; 15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* Set I_min. */ 16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_i_min = val; 16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: /* Set thread-ID. */ 16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp15.c15_threadid = val & 0xffff; 16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 8: /* Wait-for-interrupt (deprecated). */ 16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_interrupt(env, CPU_INTERRUPT_HALT); 16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbad_reg: 16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? For debugging only. Should raise illegal instruction exception. */ 16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n", 16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (insn >> 16) & 0xf, crm, op1, op2); 16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) 16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int op1; 16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int op2; 16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int crm; 16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op1 = (insn >> 21) & 7; 16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op2 = (insn >> 5) & 7; 16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project crm = insn & 0xf; 16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch ((insn >> 16) & 0xf) { 16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* ID codes. */ 16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op1) { 16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (crm) { 16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* Device ID. */ 16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c0_cpuid; 16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* Cache Type. */ 16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c0_cachetype; 16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* TCM status. */ 16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* TLB type register. */ 16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; /* No lockable TLB entries. */ 16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: /* CPU ID */ 16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cpu_index; 16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_V6)) 16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c0_c1[op2]; 16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_V6)) 16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c0_c2[op2]; 16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: case 4: case 5: case 6: case 7: 16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* These registers aren't documented on arm11 cores. However 16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Linux looks at them anyway. */ 16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_V6)) 16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (crm != 0) 16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!arm_feature(env, ARM_FEATURE_V7)) 16725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 16735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 16745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (op2) { 16755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 0: 16765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return env->cp15.c0_ccsid[env->cp15.c0_cssel]; 16775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 1: 16785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return env->cp15.c0_clid; 16795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 7: 16805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 16815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 16825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto bad_reg; 16835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 2: 16845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (op2 != 0 || crm != 0) 16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return env->cp15.c0_cssel; 16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* System configuration. */ 16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op2 = 0; 16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* Control register. */ 16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c1_sys; 16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* Auxiliary control register. */ 16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_XSCALE)) 16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c1_xscaleauxcr; 16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_AUXCR)) 17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (ARM_CPUID(env)) { 17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM1026: 17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM1136: 17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM1136_R2: 17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 7; 17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_ARM11MPCORE: 17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case ARM_CPUID_CORTEXA8: 17105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 2; 17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* Coprocessor access register. */ 17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_XSCALE)) 17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c1_coproc; 17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* MMU Page table control / MPU cache control. */ 17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_MPU)) { 17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c2_data; 17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c2_insn; 17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c2_base0; 17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c2_base1; 17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 17405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return env->cp15.c2_control; 17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* MMU Domain access control / MPU write buffer control. */ 17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c3; 17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: /* Reserved. */ 17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: /* MMU Fault status / MPU access permission. */ 17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op2 = 0; 17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_MPU)) 17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return simple_mpu_ap_bits(env->cp15.c5_data); 17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c5_data; 17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_MPU)) 17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return simple_mpu_ap_bits(env->cp15.c5_data); 17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c5_insn; 17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_MPU)) 17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c5_data; 17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!arm_feature(env, ARM_FEATURE_MPU)) 17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c5_insn; 17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 6: /* MMU Fault address. */ 17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_MPU)) { 17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (crm >= 8) 17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c6_region[crm]; 17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project op2 = 0; 17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c6_data; 17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_V6)) { 17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Watchpoint Fault Adrress. */ 17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; /* Not implemented. */ 17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Instruction Fault Adrress. */ 17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Arm9 doesn't have an IFAR, but implementing it anyway 17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shouldn't do any harm. */ 17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c6_insn; 17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_V6)) { 17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Instruction Fault Adrress. */ 17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c6_insn; 17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 7: /* Cache control. */ 18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* FIXME: Should only clear Z flag if destination is r15. */ 18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->ZF = 0; 18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 8: /* MMU TLB control. */ 18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 9: /* Cache lockdown. */ 18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op1) { 18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* L1 cache. */ 18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) 18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c9_data; 18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c9_insn; 18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* L2 cache */ 18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (crm != 0) 18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* L2 Lockdown and Auxiliary control. */ 18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 10: /* MMU TLB lockdown. */ 18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? TLB lockdown not implemented. */ 18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 11: /* TCM DMA control. */ 18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 12: /* Reserved. */ 18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 13: /* Process ID. */ 18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (op2) { 18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c13_fcse; 18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c13_context; 18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c13_tls1; 18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c13_tls2; 18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: 18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c13_tls3; 18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 14: /* Reserved. */ 18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 15: /* Implementation specific. */ 18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_XSCALE)) { 18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (op2 == 0 && crm == 1) 18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c15_cpar; 18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (arm_feature(env, ARM_FEATURE_OMAPCP)) { 18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (crm) { 18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* Read TI925T configuration. */ 18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c15_ticonfig; 18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* Read I_max. */ 18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c15_i_max; 18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* Read I_min. */ 18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c15_i_min; 18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: /* Read thread-ID. */ 18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->cp15.c15_threadid; 18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 8: /* TI925T_status */ 18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 18758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* TODO: Peripheral port remap register: 18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt 18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * controller base address at $rn & ~0xfff and map size of 18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0x200 << ($rn & 0xfff), when MMU is off. */ 18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto bad_reg; 18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 18838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbad_reg: 18858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? For debugging only. Should raise illegal instruction exception. */ 18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n", 18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (insn >> 16) & 0xf, crm, op1, op2); 18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 18908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(set_r13_banked)(CPUState *env, uint32_t mode, uint32_t val) 18928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 18938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->banked_r13[bank_number(mode)] = val; 18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode) 18978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->banked_r13[bank_number(mode)]; 18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(v7m_mrs)(CPUState *env, uint32_t reg) 19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 19038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (reg) { 19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* APSR */ 19058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return xpsr_read(env) & 0xf8000000; 19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* IAPSR */ 19078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return xpsr_read(env) & 0xf80001ff; 19088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* EAPSR */ 19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return xpsr_read(env) & 0xff00fc00; 19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* xPSR */ 19118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return xpsr_read(env) & 0xff00fdff; 19128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: /* IPSR */ 19138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return xpsr_read(env) & 0x000001ff; 19148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 6: /* EPSR */ 19158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return xpsr_read(env) & 0x0700fc00; 19168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 7: /* IEPSR */ 19178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return xpsr_read(env) & 0x0700edff; 19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 8: /* MSP */ 19198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->v7m.current_sp ? env->v7m.other_sp : env->regs[13]; 19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 9: /* PSP */ 19218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->v7m.current_sp ? env->regs[13] : env->v7m.other_sp; 19228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 16: /* PRIMASK */ 19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (env->uncached_cpsr & CPSR_I) != 0; 19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 17: /* FAULTMASK */ 19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (env->uncached_cpsr & CPSR_F) != 0; 19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 18: /* BASEPRI */ 19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 19: /* BASEPRI_MAX */ 19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->v7m.basepri; 19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 20: /* CONTROL */ 19308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return env->v7m.control; 19318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? For debugging only. */ 19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Unimplemented system register read (%d)\n", reg); 19348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 19358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 19378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(v7m_msr)(CPUState *env, uint32_t reg, uint32_t val) 19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 19408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (reg) { 19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* APSR */ 19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr_write(env, val, 0xf8000000); 19438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* IAPSR */ 19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr_write(env, val, 0xf8000000); 19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* EAPSR */ 19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr_write(env, val, 0xfe00fc00); 19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: /* xPSR */ 19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr_write(env, val, 0xfe00fc00); 19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: /* IPSR */ 19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* IPSR bits are readonly. */ 19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 6: /* EPSR */ 19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr_write(env, val, 0x0600fc00); 19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 7: /* IEPSR */ 19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xpsr_write(env, val, 0x0600fc00); 19618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 8: /* MSP */ 19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->v7m.current_sp) 19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->v7m.other_sp = val; 19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[13] = val; 19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 9: /* PSP */ 19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (env->v7m.current_sp) 19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[13] = val; 19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 19728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->v7m.other_sp = val; 19738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 16: /* PRIMASK */ 19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (val & 1) 19768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr |= CPSR_I; 19778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr &= ~CPSR_I; 19798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 17: /* FAULTMASK */ 19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (val & 1) 19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr |= CPSR_F; 19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->uncached_cpsr &= ~CPSR_F; 19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 18: /* BASEPRI */ 19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->v7m.basepri = val & 0xff; 19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 19: /* BASEPRI_MAX */ 19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val &= 0xff; 19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0)) 19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->v7m.basepri = val; 19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 20: /* CONTROL */ 19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->v7m.control = val & 3; 19968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch_v7m_sp(env, (val & 2) != 0); 19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ??? For debugging only. */ 20008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Unimplemented system register write (%d)\n", reg); 20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_arm_set_cp_io(CPUARMState *env, int cpnum, 20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write, 20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *opaque) 20088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cpnum < 0 || cpnum > 14) { 20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_abort(env, "Bad coprocessor number: %i\n", cpnum); 20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp[cpnum].cp_read = cp_read; 20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp[cpnum].cp_write = cp_write; 20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->cp[cpnum].opaque = opaque; 20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note that signed overflow is undefined in C. The following routines are 20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project careful to use unsigned types where modulo arithmetic is required. 20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Failure to do so _will_ break on newer gcc. */ 20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Signed saturating arithmetic. */ 20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Perform 16-bit signed saturating addition. */ 20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint16_t add16_sat(uint16_t a, uint16_t b) 20298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 20308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t res; 20318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = a + b; 20338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) { 20348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a & 0x8000) 20358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0x8000; 20368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 20378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0x7fff; 20388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 20408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 20418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Perform 8-bit signed saturating addition. */ 20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t add8_sat(uint8_t a, uint8_t b) 20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t res; 20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = a + b; 20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) { 20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a & 0x80) 20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0x80; 20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0x7f; 20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Perform 16-bit signed saturating subtraction. */ 20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint16_t sub16_sat(uint16_t a, uint16_t b) 20598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 20608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t res; 20618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = a - b; 20638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) { 20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a & 0x8000) 20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0x8000; 20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0x7fff; 20688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 20718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Perform 8-bit signed saturating subtraction. */ 20738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t sub8_sat(uint8_t a, uint8_t b) 20748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 20758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t res; 20768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = a - b; 20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) { 20798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a & 0x80) 20808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0x80; 20818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 20828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0x7f; 20838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16); 20888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16); 20898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8); 20908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8); 20918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX q 20928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h" 20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Unsigned saturating arithmetic. */ 20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint16_t add16_usat(uint16_t a, uint16_t b) 20978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t res; 20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = a + b; 21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (res < a) 21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0xffff; 21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint16_t sub16_usat(uint16_t a, uint16_t b) 21068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a < b) 21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return a - b; 21098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t add8_usat(uint8_t a, uint8_t b) 21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t res; 21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = a + b; 21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (res < a) 21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res = 0xff; 21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t sub8_usat(uint8_t a, uint8_t b) 21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a < b) 21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return a - b; 21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 21288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16); 21318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16); 21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8); 21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8); 21348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX uq 21358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h" 21378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Signed modulo arithmetic. */ 21398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SARITH16(a, b, n, op) do { \ 21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int32_t sum; \ 21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (int16_t)((uint16_t)(a) op (uint16_t)(b)); \ 21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(sum, n, 16); \ 21438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum >= 0) \ 21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ge |= 3 << (n * 2); \ 21458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while(0) 21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SARITH8(a, b, n, op) do { \ 21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int32_t sum; \ 21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (int8_t)((uint8_t)(a) op (uint8_t)(b)); \ 21508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(sum, n, 8); \ 21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum >= 0) \ 21528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ge |= 1 << n; \ 21538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while(0) 21548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) SARITH16(a, b, n, +) 21578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) SARITH16(a, b, n, -) 21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) SARITH8(a, b, n, +) 21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) SARITH8(a, b, n, -) 21608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX s 21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ARITH_GE 21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h" 21648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Unsigned modulo arithmetic. */ 21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) do { \ 21678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t sum; \ 21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \ 21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(sum, n, 16); \ 21708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((sum >> 16) == 1) \ 21718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ge |= 3 << (n * 2); \ 21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while(0) 21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) do { \ 21758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t sum; \ 21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \ 21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(sum, n, 8); \ 21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((sum >> 8) == 1) \ 21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ge |= 1 << n; \ 21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while(0) 21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) do { \ 21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t sum; \ 21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \ 21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(sum, n, 16); \ 21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((sum >> 16) == 0) \ 21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ge |= 3 << (n * 2); \ 21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while(0) 21898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) do { \ 21918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t sum; \ 21928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \ 21938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(sum, n, 8); \ 21948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((sum >> 8) == 0) \ 21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ge |= 1 << n; \ 21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while(0) 21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX u 21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ARITH_GE 22008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h" 22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Halved signed arithmetic. */ 22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) \ 22058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16) 22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) \ 22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16) 22088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) \ 22098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8) 22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) \ 22118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8) 22128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX sh 22138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h" 22158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Halved unsigned arithmetic. */ 22178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD16(a, b, n) \ 22188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16) 22198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB16(a, b, n) \ 22208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16) 22218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ADD8(a, b, n) \ 22228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8) 22238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SUB8(a, b, n) \ 22248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8) 22258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PFX uh 22268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "op_addsub.h" 22288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint8_t do_usad(uint8_t a, uint8_t b) 22308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 22318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a > b) 22328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return a - b; 22338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 22348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return b - a; 22358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 22368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Unsigned sum of absolute byte differences. */ 22388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(usad8)(uint32_t a, uint32_t b) 22398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t sum; 22418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = do_usad(a, b); 22428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += do_usad(a >> 8, b >> 8); 22438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += do_usad(a >> 16, b >>16); 22448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += do_usad(a >> 24, b >> 24); 22458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sum; 22468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 22478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* For ARMv6 SEL instruction. */ 22498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b) 22508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 22518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t mask; 22528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = 0; 22548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & 1) 22558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask |= 0xff; 22568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & 2) 22578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask |= 0xff00; 22588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & 4) 22598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask |= 0xff0000; 22608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & 8) 22618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask |= 0xff000000; 22628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (a & mask) | (b & ~mask); 22638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 22648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(logicq_cc)(uint64_t val) 22668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 22678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (val >> 32) | (val != 0); 22688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 22698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* VFP support. We follow the convention used for VFP instrunctions: 22718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Single precition routines have a "s" suffix, double precision a 22728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "d" suffix. */ 22738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Convert host exception flags to vfp form. */ 22758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int vfp_exceptbits_from_host(int host_bits) 22768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 22778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int target_bits = 0; 22788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (host_bits & float_flag_invalid) 22808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_bits |= 1; 22818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (host_bits & float_flag_divbyzero) 22828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_bits |= 2; 22838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (host_bits & float_flag_overflow) 22848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_bits |= 4; 22858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (host_bits & float_flag_underflow) 22868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_bits |= 8; 22878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (host_bits & float_flag_inexact) 22888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_bits |= 0x10; 22898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return target_bits; 22908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 22918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(vfp_get_fpscr)(CPUState *env) 22938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 22948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 22958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t fpscr; 22968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff) 22988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | (env->vfp.vec_len << 16) 22998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | (env->vfp.vec_stride << 20); 23008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = get_float_exception_flags(&env->vfp.fp_status); 23018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fpscr |= vfp_exceptbits_from_host(i); 23028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return fpscr; 23038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 23048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Convert vfp exception flags to target form. */ 23068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int vfp_exceptbits_to_host(int target_bits) 23078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 23088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int host_bits = 0; 23098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (target_bits & 1) 23118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project host_bits |= float_flag_invalid; 23128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (target_bits & 2) 23138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project host_bits |= float_flag_divbyzero; 23148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (target_bits & 4) 23158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project host_bits |= float_flag_overflow; 23168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (target_bits & 8) 23178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project host_bits |= float_flag_underflow; 23188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (target_bits & 0x10) 23198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project host_bits |= float_flag_inexact; 23208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return host_bits; 23218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 23228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val) 23248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 23258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 23268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t changed; 23278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project changed = env->vfp.xregs[ARM_VFP_FPSCR]; 23298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff); 23308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.vec_len = (val >> 16) & 7; 23318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.vec_stride = (val >> 20) & 3; 23328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project changed ^= val; 23348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (changed & (3 << 22)) { 23358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = (val >> 22) & 3; 23368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (i) { 23378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 23388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = float_round_nearest_even; 23398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 23408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 23418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = float_round_up; 23428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 23438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 23448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = float_round_down; 23458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 23478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = float_round_to_zero; 23488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 23498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_float_rounding_mode(i, &env->vfp.fp_status); 23518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (changed & (1 << 24)) 23535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status); 23545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (changed & (1 << 25)) 23555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status); 23568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i = vfp_exceptbits_to_host((val >> 8) & 0x1f); 23588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project set_float_exception_flags(i, &env->vfp.fp_status); 23598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 23608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p)) 23628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define VFP_BINOP(name) \ 23648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \ 23658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \ 23668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_ ## name (a, b, &env->vfp.fp_status); \ 23678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} \ 23688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \ 23698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \ 23708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float64_ ## name (a, b, &env->vfp.fp_status); \ 23718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 23728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_BINOP(add) 23738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_BINOP(sub) 23748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_BINOP(mul) 23758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_BINOP(div) 23768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef VFP_BINOP 23778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(neg, s)(float32 a) 23798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 23808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_chs(a); 23818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 23828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(neg, d)(float64 a) 23848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 23858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float64_chs(a); 23868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 23878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(abs, s)(float32 a) 23898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 23908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_abs(a); 23918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 23928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(abs, d)(float64 a) 23948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 23958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float64_abs(a); 23968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 23978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env) 23998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_sqrt(a, &env->vfp.fp_status); 24018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env) 24048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float64_sqrt(a, &env->vfp.fp_status); 24068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: check quiet/signaling case */ 24098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DO_VFP_cmp(p, type) \ 24108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid VFP_HELPER(cmp, p)(type a, type b, CPUState *env) \ 24118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \ 24128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t flags; \ 24138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \ 24148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: flags = 0x6; break; \ 24158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case -1: flags = 0x8; break; \ 24168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: flags = 0x2; break; \ 24178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: case 2: flags = 0x3; break; \ 24188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } \ 24198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ 24208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ 24218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} \ 24228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \ 24238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \ 24248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t flags; \ 24258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(type ## _compare(a, b, &env->vfp.fp_status)) { \ 24268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: flags = 0x6; break; \ 24278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case -1: flags = 0x8; break; \ 24288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: flags = 0x2; break; \ 24298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: case 2: flags = 0x3; break; \ 24308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } \ 24318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \ 24328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \ 24338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectDO_VFP_cmp(s, float32) 24358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectDO_VFP_cmp(d, float64) 24368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef DO_VFP_cmp 24378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Helper routines to perform bitwise copies between float and int. */ 24398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline float32 vfp_itos(uint32_t i) 24408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project union { 24428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t i; 24438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float32 s; 24448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } v; 24458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v.i = i; 24478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return v.s; 24488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint32_t vfp_stoi(float32 s) 24518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project union { 24538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t i; 24548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float32 s; 24558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } v; 24568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v.s = s; 24588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return v.i; 24598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline float64 vfp_itod(uint64_t i) 24628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project union { 24648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint64_t i; 24658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float64 d; 24668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } v; 24678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v.i = i; 24698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return v.d; 24708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline uint64_t vfp_dtoi(float64 d) 24738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project union { 24758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint64_t i; 24768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float64 d; 24778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } v; 24788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v.d = d; 24808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return v.i; 24818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Integer to float conversion. */ 24848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(uito, s)(float32 x, CPUState *env) 24858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status); 24878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(uito, d)(float32 x, CPUState *env) 24908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status); 24928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(sito, s)(float32 x, CPUState *env) 24958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 24968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status); 24978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 24988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(sito, d)(float32 x, CPUState *env) 25008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status); 25028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Float to integer conversion. */ 25058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(toui, s)(float32 x, CPUState *env) 25068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status)); 25088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(toui, d)(float64 x, CPUState *env) 25118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status)); 25138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(tosi, s)(float32 x, CPUState *env) 25168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_itos(float32_to_int32(x, &env->vfp.fp_status)); 25188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(tosi, d)(float64 x, CPUState *env) 25218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_itos(float64_to_int32(x, &env->vfp.fp_status)); 25238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(touiz, s)(float32 x, CPUState *env) 25268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status)); 25288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(touiz, d)(float64 x, CPUState *env) 25318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status)); 25338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env) 25368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status)); 25388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env) 25418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status)); 25438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* floating point conversion */ 25468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env) 25478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_to_float64(x, &env->vfp.fp_status); 25498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env) 25528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float64_to_float32(x, &env->vfp.fp_status); 25548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* VFP3 fixed point conversion. */ 25578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define VFP_CONV_FIX(name, p, ftype, itype, sign) \ 25588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \ 25598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \ 25608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ftype tmp; \ 25618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(x), \ 25628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &env->vfp.fp_status); \ 25635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ftype##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \ 25648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} \ 25658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \ 25668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ \ 25678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ftype tmp; \ 25688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \ 25698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \ 25708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &env->vfp.fp_status)); \ 25718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(sh, d, float64, int16, ) 25748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(sl, d, float64, int32, ) 25758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(uh, d, float64, uint16, u) 25768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(ul, d, float64, uint32, u) 25778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(sh, s, float32, int16, ) 25788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(sl, s, float32, int32, ) 25798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(uh, s, float32, uint16, u) 25808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectVFP_CONV_FIX(ul, s, float32, uint32, u) 25818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef VFP_CONV_FIX 25828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env) 25848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float_status *s = &env->vfp.fp_status; 25868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float32 two = int32_to_float32(2, s); 25878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_sub(two, float32_mul(a, b, s), s); 25888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env) 25918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 25928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float_status *s = &env->vfp.fp_status; 25938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float32 three = int32_to_float32(3, s); 25948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_sub(three, float32_mul(a, b, s), s); 25958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 25968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* NEON helpers. */ 25988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* TODO: The architecture specifies the value that the estimate functions 26008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project should return. We return the exact reciprocal/root instead. */ 26018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 HELPER(recpe_f32)(float32 a, CPUState *env) 26028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float_status *s = &env->vfp.fp_status; 26048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float32 one = int32_to_float32(1, s); 26058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_div(one, a, s); 26068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 HELPER(rsqrte_f32)(float32 a, CPUState *env) 26098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float_status *s = &env->vfp.fp_status; 26118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float32 one = int32_to_float32(1, s); 26128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_div(one, float32_sqrt(a, s), s); 26138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env) 26168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float_status *s = &env->vfp.fp_status; 26188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float32 tmp; 26198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = int32_to_float32(a, s); 26208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = float32_scalbn(tmp, -32, s); 26218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = helper_recpe_f32(tmp, env); 26228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = float32_scalbn(tmp, 31, s); 26238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_to_int32(tmp, s); 26248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env) 26278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float_status *s = &env->vfp.fp_status; 26298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project float32 tmp; 26308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = int32_to_float32(a, s); 26318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = float32_scalbn(tmp, -32, s); 26328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = helper_rsqrte_f32(tmp, env); 26338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = float32_scalbn(tmp, 31, s); 26348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return float32_to_int32(tmp, s); 26358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_TRACE 26388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "trace.h" 26398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(traceTicks)(uint32_t ticks) 26408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sim_time += ticks; 26428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(traceInsn)(void) 26458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_insn_helper(); 26478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HOST_LONG_BITS == 32 2650a577fcadc0b365ee629aec313f57a65d54fe5d89David 'Digit' Turnervoid HELPER(traceBB32)(uint64_t bb_num, uint32_t tb) 26518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_bb_helper(bb_num, (void*)tb); 26538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 26558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HOST_LONG_BITS == 64 26578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid HELPER(traceBB64)(uint64_t bb_num, uint64_t tb) 26588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 26598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trace_bb_helper(bb_num, (void*)tb); 26608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 26618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 26628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* CONFIG_TRACE */ 26645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 26655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid HELPER(set_teecr)(CPUState *env, uint32_t val) 26665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 26675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner val &= 1; 26685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (env->teecr != val) { 26695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->teecr = val; 26705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tb_flush(env); 26715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 26725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 26735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 26745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#ifdef CONFIG_MEMCHECK 26755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid HELPER(on_call)(void* pc, void* ret) { 26765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_on_call((target_ulong)pc, (target_ulong)ret); 26775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine} 26785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 26795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid HELPER(on_ret)(void* ret) { 26805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine memcheck_on_ret((target_ulong)ret); 26815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine} 26825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#endif // CONFIG_MEMCHECK 2683