mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 09:55:55 +00:00
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:
parent
644ad8066d
commit
fe1479c3ad
|
@ -151,6 +151,10 @@ typedef struct CPUARMState {
|
||||||
void *opaque;
|
void *opaque;
|
||||||
} cp[15];
|
} cp[15];
|
||||||
|
|
||||||
|
/* Thumb-2 EE state. */
|
||||||
|
uint32_t teecr;
|
||||||
|
uint32_t teehbr;
|
||||||
|
|
||||||
/* Internal CPU feature flags. */
|
/* Internal CPU feature flags. */
|
||||||
uint32_t features;
|
uint32_t features;
|
||||||
|
|
||||||
|
@ -329,7 +333,8 @@ enum arm_features {
|
||||||
ARM_FEATURE_NEON,
|
ARM_FEATURE_NEON,
|
||||||
ARM_FEATURE_DIV,
|
ARM_FEATURE_DIV,
|
||||||
ARM_FEATURE_M, /* Microcontroller profile. */
|
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)
|
static inline int arm_feature(CPUARMState *env, int feature)
|
||||||
|
|
|
@ -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_VFP);
|
||||||
set_feature(env, ARM_FEATURE_VFP3);
|
set_feature(env, ARM_FEATURE_VFP3);
|
||||||
set_feature(env, ARM_FEATURE_NEON);
|
set_feature(env, ARM_FEATURE_NEON);
|
||||||
|
set_feature(env, ARM_FEATURE_THUMB2EE);
|
||||||
env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
|
env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
|
||||||
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
|
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
|
||||||
env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
|
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_VFP);
|
||||||
set_feature(env, ARM_FEATURE_VFP3);
|
set_feature(env, ARM_FEATURE_VFP3);
|
||||||
set_feature(env, ARM_FEATURE_NEON);
|
set_feature(env, ARM_FEATURE_NEON);
|
||||||
|
set_feature(env, ARM_FEATURE_THUMB2EE);
|
||||||
set_feature(env, ARM_FEATURE_DIV);
|
set_feature(env, ARM_FEATURE_DIV);
|
||||||
break;
|
break;
|
||||||
case ARM_CPUID_TI915T:
|
case ARM_CPUID_TI915T:
|
||||||
|
@ -2595,3 +2597,12 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
|
||||||
tmp = float32_scalbn(tmp, 31, s);
|
tmp = float32_scalbn(tmp, 31, s);
|
||||||
return float32_to_int32(tmp, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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_muladdsw, i64, i64, i32, i32)
|
||||||
DEF_HELPER_3(iwmmxt_muladdswl, 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"
|
#include "def-helper.h"
|
||||||
|
|
|
@ -5536,6 +5536,71 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
return 0;
|
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)
|
static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
{
|
{
|
||||||
int cpnum;
|
int cpnum;
|
||||||
|
@ -5557,9 +5622,19 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
case 10:
|
case 10:
|
||||||
case 11:
|
case 11:
|
||||||
return disas_vfp_insn (env, s, insn);
|
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:
|
case 15:
|
||||||
return disas_cp15_insn (env, s, insn);
|
return disas_cp15_insn (env, s, insn);
|
||||||
default:
|
default:
|
||||||
|
board:
|
||||||
/* Unknown coprocessor. See if the board has hooked it. */
|
/* Unknown coprocessor. See if the board has hooked it. */
|
||||||
return disas_cp_insn (env, s, insn);
|
return disas_cp_insn (env, s, insn);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue