Implement (very) basic Thumb2-EE support. This doesn't actually implement

EE state, just the associated system coprocessor registers.  It is sufficient
to keep OS setup and context switching code happy.

Signed-off-by: Paul Brook <paul@codesourcery.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6104 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook 2008-12-19 13:18:36 +00:00
parent 644ad8066d
commit fe1479c3ad
4 changed files with 94 additions and 1 deletions

View File

@ -151,6 +151,10 @@ typedef struct CPUARMState {
void *opaque;
} cp[15];
/* Thumb-2 EE state. */
uint32_t teecr;
uint32_t teehbr;
/* Internal CPU feature flags. */
uint32_t features;
@ -329,7 +333,8 @@ enum arm_features {
ARM_FEATURE_NEON,
ARM_FEATURE_DIV,
ARM_FEATURE_M, /* Microcontroller profile. */
ARM_FEATURE_OMAPCP /* OMAP specific CP15 ops handling. */
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
ARM_FEATURE_THUMB2EE
};
static inline int arm_feature(CPUARMState *env, int feature)

View File

@ -88,6 +88,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
set_feature(env, ARM_FEATURE_VFP);
set_feature(env, ARM_FEATURE_VFP3);
set_feature(env, ARM_FEATURE_NEON);
set_feature(env, ARM_FEATURE_THUMB2EE);
env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
@ -110,6 +111,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
set_feature(env, ARM_FEATURE_VFP);
set_feature(env, ARM_FEATURE_VFP3);
set_feature(env, ARM_FEATURE_NEON);
set_feature(env, ARM_FEATURE_THUMB2EE);
set_feature(env, ARM_FEATURE_DIV);
break;
case ARM_CPUID_TI915T:
@ -2595,3 +2597,12 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
tmp = float32_scalbn(tmp, 31, s);
return float32_to_int32(tmp, s);
}
void HELPER(set_teecr)(CPUState *env, uint32_t val)
{
val &= 1;
if (env->teecr != val) {
env->teecr = val;
tb_flush(env);
}
}

View File

@ -453,4 +453,6 @@ DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
DEF_HELPER_2(set_teecr, void, env, i32)
#include "def-helper.h"

View File

@ -5536,6 +5536,71 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
return 0;
}
static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
{
int crn = (insn >> 16) & 0xf;
int crm = insn & 0xf;
int op1 = (insn >> 21) & 7;
int op2 = (insn >> 5) & 7;
int rt = (insn >> 12) & 0xf;
TCGv tmp;
if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
/* TEECR */
if (IS_USER(s))
return 1;
tmp = load_cpu_field(teecr);
store_reg(s, rt, tmp);
return 0;
}
if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
/* TEEHBR */
if (IS_USER(s) && (env->teecr & 1))
return 1;
tmp = load_cpu_field(teehbr);
store_reg(s, rt, tmp);
return 0;
}
}
fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
op1, crn, crm, op2);
return 1;
}
static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
{
int crn = (insn >> 16) & 0xf;
int crm = insn & 0xf;
int op1 = (insn >> 21) & 7;
int op2 = (insn >> 5) & 7;
int rt = (insn >> 12) & 0xf;
TCGv tmp;
if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
/* TEECR */
if (IS_USER(s))
return 1;
tmp = load_reg(s, rt);
gen_helper_set_teecr(cpu_env, tmp);
dead_tmp(tmp);
return 0;
}
if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
/* TEEHBR */
if (IS_USER(s) && (env->teecr & 1))
return 1;
tmp = load_reg(s, rt);
store_cpu_field(tmp, teehbr);
return 0;
}
}
fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
op1, crn, crm, op2);
return 1;
}
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
{
int cpnum;
@ -5557,9 +5622,19 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
case 10:
case 11:
return disas_vfp_insn (env, s, insn);
case 14:
/* Coprocessors 7-15 are architecturally reserved by ARM.
Unfortunately Intel decided to ignore this. */
if (arm_feature(env, ARM_FEATURE_XSCALE))
goto board;
if (insn & (1 << 20))
return disas_cp14_read(env, s, insn);
else
return disas_cp14_write(env, s, insn);
case 15:
return disas_cp15_insn (env, s, insn);
default:
board:
/* Unknown coprocessor. See if the board has hooked it. */
return disas_cp_insn (env, s, insn);
}