aboutsummaryrefslogtreecommitdiff
path: root/target-arm/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r--target-arm/helper.c63
1 files changed, 61 insertions, 2 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 5804df8264..d0cd6d8e54 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5,6 +5,61 @@
#include "cpu.h"
#include "exec-all.h"
+void cpu_reset(CPUARMState *env)
+{
+#if defined (CONFIG_USER_ONLY)
+ env->uncached_cpsr = ARM_CPU_MODE_USR;
+ env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
+#else
+ /* SVC mode with interrupts disabled. */
+ env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
+ env->vfp.xregs[ARM_VFP_FPEXC] = 0;
+#endif
+ env->regs[15] = 0;
+}
+
+CPUARMState *cpu_arm_init(void)
+{
+ CPUARMState *env;
+
+ env = qemu_mallocz(sizeof(CPUARMState));
+ if (!env)
+ return NULL;
+ cpu_exec_init(env);
+ cpu_reset(env);
+ tlb_flush(env, 1);
+ return env;
+}
+
+static inline void set_feature(CPUARMState *env, int feature)
+{
+ env->features |= 1u << feature;
+}
+
+void cpu_arm_set_model(CPUARMState *env, uint32_t id)
+{
+ env->cp15.c0_cpuid = id;
+ switch (id) {
+ case ARM_CPUID_ARM926:
+ set_feature(env, ARM_FEATURE_VFP);
+ env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
+ break;
+ case ARM_CPUID_ARM1026:
+ set_feature(env, ARM_FEATURE_VFP);
+ set_feature(env, ARM_FEATURE_AUXCR);
+ env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
+ break;
+ default:
+ cpu_abort(env, "Bad CPU ID: %x\n", id);
+ break;
+ }
+}
+
+void cpu_arm_close(CPUARMState *env)
+{
+ free(env);
+}
+
#if defined(CONFIG_USER_ONLY)
void do_interrupt (CPUState *env)
@@ -469,7 +524,7 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
case 0: /* ID codes. */
switch (op2) {
default: /* Device ID. */
- return 0x4106a262;
+ return env->cp15.c0_cpuid;
case 1: /* Cache Type. */
return 0x1dd20d2;
case 2: /* TCM status. */
@@ -480,7 +535,9 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
case 0: /* Control register. */
return env->cp15.c1_sys;
case 1: /* Auxiliary control register. */
- return 1;
+ if (arm_feature(env, ARM_FEATURE_AUXCR))
+ return 1;
+ goto bad_reg;
case 2: /* Coprocessor access register. */
return env->cp15.c1_coproc;
default:
@@ -506,6 +563,8 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
case 0:
return env->cp15.c6_data;
case 1:
+ /* Arm9 doesn't have an IFAR, but implementing it anyway shouldn't
+ do any harm. */
return env->cp15.c6_insn;
default:
goto bad_reg;