Commit fe1479c3ad177df09d465338d5421a5f3b857f91

Authored by pbrook
1 parent 644ad806

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
target-arm/cpu.h
... ... @@ -151,6 +151,10 @@ typedef struct CPUARMState {
151 151 void *opaque;
152 152 } cp[15];
153 153  
  154 + /* Thumb-2 EE state. */
  155 + uint32_t teecr;
  156 + uint32_t teehbr;
  157 +
154 158 /* Internal CPU feature flags. */
155 159 uint32_t features;
156 160  
... ... @@ -329,7 +333,8 @@ enum arm_features {
329 333 ARM_FEATURE_NEON,
330 334 ARM_FEATURE_DIV,
331 335 ARM_FEATURE_M, /* Microcontroller profile. */
332   - ARM_FEATURE_OMAPCP /* OMAP specific CP15 ops handling. */
  336 + ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
  337 + ARM_FEATURE_THUMB2EE
333 338 };
334 339  
335 340 static inline int arm_feature(CPUARMState *env, int feature)
... ...
target-arm/helper.c
... ... @@ -88,6 +88,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
88 88 set_feature(env, ARM_FEATURE_VFP);
89 89 set_feature(env, ARM_FEATURE_VFP3);
90 90 set_feature(env, ARM_FEATURE_NEON);
  91 + set_feature(env, ARM_FEATURE_THUMB2EE);
91 92 env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
92 93 env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
93 94 env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
... ... @@ -110,6 +111,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
110 111 set_feature(env, ARM_FEATURE_VFP);
111 112 set_feature(env, ARM_FEATURE_VFP3);
112 113 set_feature(env, ARM_FEATURE_NEON);
  114 + set_feature(env, ARM_FEATURE_THUMB2EE);
113 115 set_feature(env, ARM_FEATURE_DIV);
114 116 break;
115 117 case ARM_CPUID_TI915T:
... ... @@ -2595,3 +2597,12 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
2595 2597 tmp = float32_scalbn(tmp, 31, s);
2596 2598 return float32_to_int32(tmp, s);
2597 2599 }
  2600 +
  2601 +void HELPER(set_teecr)(CPUState *env, uint32_t val)
  2602 +{
  2603 + val &= 1;
  2604 + if (env->teecr != val) {
  2605 + env->teecr = val;
  2606 + tb_flush(env);
  2607 + }
  2608 +}
... ...
target-arm/helpers.h
... ... @@ -453,4 +453,6 @@ DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
453 453 DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
454 454 DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
455 455  
  456 +DEF_HELPER_2(set_teecr, void, env, i32)
  457 +
456 458 #include "def-helper.h"
... ...
target-arm/translate.c
... ... @@ -5536,6 +5536,71 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
5536 5536 return 0;
5537 5537 }
5538 5538  
  5539 +static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
  5540 +{
  5541 + int crn = (insn >> 16) & 0xf;
  5542 + int crm = insn & 0xf;
  5543 + int op1 = (insn >> 21) & 7;
  5544 + int op2 = (insn >> 5) & 7;
  5545 + int rt = (insn >> 12) & 0xf;
  5546 + TCGv tmp;
  5547 +
  5548 + if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
  5549 + if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
  5550 + /* TEECR */
  5551 + if (IS_USER(s))
  5552 + return 1;
  5553 + tmp = load_cpu_field(teecr);
  5554 + store_reg(s, rt, tmp);
  5555 + return 0;
  5556 + }
  5557 + if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
  5558 + /* TEEHBR */
  5559 + if (IS_USER(s) && (env->teecr & 1))
  5560 + return 1;
  5561 + tmp = load_cpu_field(teehbr);
  5562 + store_reg(s, rt, tmp);
  5563 + return 0;
  5564 + }
  5565 + }
  5566 + fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
  5567 + op1, crn, crm, op2);
  5568 + return 1;
  5569 +}
  5570 +
  5571 +static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
  5572 +{
  5573 + int crn = (insn >> 16) & 0xf;
  5574 + int crm = insn & 0xf;
  5575 + int op1 = (insn >> 21) & 7;
  5576 + int op2 = (insn >> 5) & 7;
  5577 + int rt = (insn >> 12) & 0xf;
  5578 + TCGv tmp;
  5579 +
  5580 + if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
  5581 + if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
  5582 + /* TEECR */
  5583 + if (IS_USER(s))
  5584 + return 1;
  5585 + tmp = load_reg(s, rt);
  5586 + gen_helper_set_teecr(cpu_env, tmp);
  5587 + dead_tmp(tmp);
  5588 + return 0;
  5589 + }
  5590 + if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
  5591 + /* TEEHBR */
  5592 + if (IS_USER(s) && (env->teecr & 1))
  5593 + return 1;
  5594 + tmp = load_reg(s, rt);
  5595 + store_cpu_field(tmp, teehbr);
  5596 + return 0;
  5597 + }
  5598 + }
  5599 + fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
  5600 + op1, crn, crm, op2);
  5601 + return 1;
  5602 +}
  5603 +
5539 5604 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5540 5605 {
5541 5606 int cpnum;
... ... @@ -5557,9 +5622,19 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5557 5622 case 10:
5558 5623 case 11:
5559 5624 return disas_vfp_insn (env, s, insn);
  5625 + case 14:
  5626 + /* Coprocessors 7-15 are architecturally reserved by ARM.
  5627 + Unfortunately Intel decided to ignore this. */
  5628 + if (arm_feature(env, ARM_FEATURE_XSCALE))
  5629 + goto board;
  5630 + if (insn & (1 << 20))
  5631 + return disas_cp14_read(env, s, insn);
  5632 + else
  5633 + return disas_cp14_write(env, s, insn);
5560 5634 case 15:
5561 5635 return disas_cp15_insn (env, s, insn);
5562 5636 default:
  5637 + board:
5563 5638 /* Unknown coprocessor. See if the board has hooked it. */
5564 5639 return disas_cp_insn (env, s, insn);
5565 5640 }
... ...