aboutsummaryrefslogtreecommitdiff
path: root/target-arm
diff options
context:
space:
mode:
authorbalrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>2007-07-29 17:57:26 +0000
committerbalrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>2007-07-29 17:57:26 +0000
commitc3d2689d88159291ef8af338b5f01cfbe5551d2c (patch)
tree814183cc0c4631b3762355f4e48fe77b1c3654ff /target-arm
parenta5236105dbf7b971715f1ac55f52f716081a0632 (diff)
Basic OMAP310 support. Basic Palm Tungsten|E machine emulation.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3091 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/cpu.h9
-rw-r--r--target-arm/helper.c76
2 files changed, 83 insertions, 2 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5bd40ffbc4..ef203c3315 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -99,6 +99,10 @@ typedef struct CPUARMState {
uint32_t c13_fcse; /* FCSE PID. */
uint32_t c13_context; /* Context ID. */
uint32_t c15_cpar; /* XScale Coprocessor Access Register */
+ uint32_t c15_ticonfig; /* TI925T configuration byte. */
+ uint32_t c15_i_max; /* Maximum D-cache dirty line index. */
+ uint32_t c15_i_min; /* Minimum D-cache dirty line index. */
+ uint32_t c15_threadid; /* TI debugger thread-ID. */
} cp15;
/* Coprocessor IO used by peripherals */
@@ -247,7 +251,8 @@ enum arm_features {
ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */
ARM_FEATURE_XSCALE, /* Intel XScale extensions. */
ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */
- ARM_FEATURE_MPU /* Only has Memory Protection Unit, not full MMU. */
+ ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */
+ ARM_FEATURE_OMAPCP /* OMAP specific CP15 ops handling. */
};
static inline int arm_feature(CPUARMState *env, int feature)
@@ -265,6 +270,8 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
#define ARM_CPUID_ARM1026 0x4106a262
#define ARM_CPUID_ARM926 0x41069265
#define ARM_CPUID_ARM946 0x41059461
+#define ARM_CPUID_TI915T 0x54029152
+#define ARM_CPUID_TI925T 0x54029252
#define ARM_CPUID_PXA250 0x69052100
#define ARM_CPUID_PXA255 0x69052d00
#define ARM_CPUID_PXA260 0x69052903
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 61f8109064..260a04aa06 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -32,6 +32,15 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
env->cp15.c0_cachetype = 0x1dd20d2;
env->cp15.c1_sys = 0x00090078;
break;
+ case ARM_CPUID_TI915T:
+ case ARM_CPUID_TI925T:
+ set_feature(env, ARM_FEATURE_OMAPCP);
+ env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring. */
+ env->cp15.c0_cachetype = 0x5109149;
+ env->cp15.c1_sys = 0x00000070;
+ env->cp15.c15_i_max = 0x000;
+ env->cp15.c15_i_min = 0xff0;
+ break;
case ARM_CPUID_PXA250:
case ARM_CPUID_PXA255:
case ARM_CPUID_PXA260:
@@ -101,6 +110,7 @@ static const struct arm_cpu_t arm_cpu_names[] = {
{ ARM_CPUID_ARM926, "arm926"},
{ ARM_CPUID_ARM946, "arm946"},
{ ARM_CPUID_ARM1026, "arm1026"},
+ { ARM_CPUID_TI925T, "ti925t" },
{ ARM_CPUID_PXA250, "pxa250" },
{ ARM_CPUID_PXA255, "pxa255" },
{ ARM_CPUID_PXA260, "pxa260" },
@@ -644,8 +654,12 @@ void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
case 0: /* ID codes. */
if (arm_feature(env, ARM_FEATURE_XSCALE))
break;
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ break;
goto bad_reg;
case 1: /* System configuration. */
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ op2 = 0;
switch (op2) {
case 0:
if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)
@@ -693,6 +707,8 @@ void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
case 4: /* Reserved. */
goto bad_reg;
case 5: /* MMU Fault status / MPU access permission. */
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ op2 = 0;
switch (op2) {
case 0:
if (arm_feature(env, ARM_FEATURE_MPU))
@@ -724,6 +740,8 @@ void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
goto bad_reg;
env->cp15.c6_region[crm] = val;
} else {
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ op2 = 0;
switch (op2) {
case 0:
env->cp15.c6_data = val;
@@ -737,6 +755,8 @@ void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
}
break;
case 7: /* Cache control. */
+ env->cp15.c15_i_max = 0x000;
+ env->cp15.c15_i_min = 0xff0;
/* No cache, so nothing to do. */
break;
case 8: /* MMU TLB control. */
@@ -763,6 +783,8 @@ void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
}
break;
case 9:
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ break;
switch (crm) {
case 0: /* Cache lockdown. */
switch (op2) {
@@ -823,6 +845,31 @@ void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val)
}
goto bad_reg;
}
+ if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
+ switch (crm) {
+ case 0:
+ break;
+ case 1: /* Set TI925T configuration. */
+ env->cp15.c15_ticonfig = val & 0xe7;
+ env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */
+ ARM_CPUID_TI915T : ARM_CPUID_TI925T;
+ break;
+ case 2: /* Set I_max. */
+ env->cp15.c15_i_max = val;
+ break;
+ case 3: /* Set I_min. */
+ env->cp15.c15_i_min = val;
+ break;
+ case 4: /* Set thread-ID. */
+ env->cp15.c15_threadid = val & 0xffff;
+ break;
+ case 8: /* Wait-for-interrupt (deprecated). */
+ cpu_interrupt(env, CPU_INTERRUPT_HALT);
+ break;
+ default:
+ goto bad_reg;
+ }
+ }
break;
}
return;
@@ -834,8 +881,10 @@ bad_reg:
uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
{
uint32_t op2;
+ uint32_t crm;
op2 = (insn >> 5) & 7;
+ crm = insn & 0xf;
switch ((insn >> 16) & 0xf) {
case 0: /* ID codes. */
switch (op2) {
@@ -849,6 +898,8 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
return 0;
}
case 1: /* System configuration. */
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ op2 = 0;
switch (op2) {
case 0: /* Control register. */
return env->cp15.c1_sys;
@@ -885,6 +936,8 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
case 4: /* Reserved. */
goto bad_reg;
case 5: /* MMU Fault status / MPU access permission. */
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ op2 = 0;
switch (op2) {
case 0:
if (arm_feature(env, ARM_FEATURE_MPU))
@@ -913,6 +966,8 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
goto bad_reg;
return env->cp15.c6_region[n];
} else {
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ op2 = 0;
switch (op2) {
case 0:
return env->cp15.c6_data;
@@ -933,6 +988,8 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
case 8: /* MMU TLB control. */
goto bad_reg;
case 9: /* Cache lockdown. */
+ if (arm_feature(env, ARM_FEATURE_OMAPCP))
+ return 0;
switch (op2) {
case 0:
return env->cp15.c9_data;
@@ -960,11 +1017,28 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn)
goto bad_reg;
case 15: /* Implementation specific. */
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
- if (op2 == 0 && (insn & 0xf) == 1)
+ if (op2 == 0 && crm == 1)
return env->cp15.c15_cpar;
goto bad_reg;
}
+ if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
+ switch (crm) {
+ case 0:
+ return 0;
+ case 1: /* Read TI925T configuration. */
+ return env->cp15.c15_ticonfig;
+ case 2: /* Read I_max. */
+ return env->cp15.c15_i_max;
+ case 3: /* Read I_min. */
+ return env->cp15.c15_i_min;
+ case 4: /* Read thread-ID. */
+ return env->cp15.c15_threadid;
+ case 8: /* TI925T_status */
+ return 0;
+ }
+ goto bad_reg;
+ }
return 0;
}
bad_reg: