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,6 +151,10 @@ typedef struct CPUARMState {
151 void *opaque; 151 void *opaque;
152 } cp[15]; 152 } cp[15];
153 153
  154 + /* Thumb-2 EE state. */
  155 + uint32_t teecr;
  156 + uint32_t teehbr;
  157 +
154 /* Internal CPU feature flags. */ 158 /* Internal CPU feature flags. */
155 uint32_t features; 159 uint32_t features;
156 160
@@ -329,7 +333,8 @@ enum arm_features { @@ -329,7 +333,8 @@ enum arm_features {
329 ARM_FEATURE_NEON, 333 ARM_FEATURE_NEON,
330 ARM_FEATURE_DIV, 334 ARM_FEATURE_DIV,
331 ARM_FEATURE_M, /* Microcontroller profile. */ 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 static inline int arm_feature(CPUARMState *env, int feature) 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,6 +88,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
88 set_feature(env, ARM_FEATURE_VFP); 88 set_feature(env, ARM_FEATURE_VFP);
89 set_feature(env, ARM_FEATURE_VFP3); 89 set_feature(env, ARM_FEATURE_VFP3);
90 set_feature(env, ARM_FEATURE_NEON); 90 set_feature(env, ARM_FEATURE_NEON);
  91 + set_feature(env, ARM_FEATURE_THUMB2EE);
91 env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0; 92 env->vfp.xregs[ARM_VFP_FPSID] = 0x410330c0;
92 env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222; 93 env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
93 env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100; 94 env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
@@ -110,6 +111,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) @@ -110,6 +111,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
110 set_feature(env, ARM_FEATURE_VFP); 111 set_feature(env, ARM_FEATURE_VFP);
111 set_feature(env, ARM_FEATURE_VFP3); 112 set_feature(env, ARM_FEATURE_VFP3);
112 set_feature(env, ARM_FEATURE_NEON); 113 set_feature(env, ARM_FEATURE_NEON);
  114 + set_feature(env, ARM_FEATURE_THUMB2EE);
113 set_feature(env, ARM_FEATURE_DIV); 115 set_feature(env, ARM_FEATURE_DIV);
114 break; 116 break;
115 case ARM_CPUID_TI915T: 117 case ARM_CPUID_TI915T:
@@ -2595,3 +2597,12 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env) @@ -2595,3 +2597,12 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
2595 tmp = float32_scalbn(tmp, 31, s); 2597 tmp = float32_scalbn(tmp, 31, s);
2596 return float32_to_int32(tmp, s); 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,4 +453,6 @@ DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
453 DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32) 453 DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
454 DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32) 454 DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
455 455
  456 +DEF_HELPER_2(set_teecr, void, env, i32)
  457 +
456 #include "def-helper.h" 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,6 +5536,71 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
5536 return 0; 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 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn) 5604 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5540 { 5605 {
5541 int cpnum; 5606 int cpnum;
@@ -5557,9 +5622,19 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -5557,9 +5622,19 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
5557 case 10: 5622 case 10:
5558 case 11: 5623 case 11:
5559 return disas_vfp_insn (env, s, insn); 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 case 15: 5634 case 15:
5561 return disas_cp15_insn (env, s, insn); 5635 return disas_cp15_insn (env, s, insn);
5562 default: 5636 default:
  5637 + board:
5563 /* Unknown coprocessor. See if the board has hooked it. */ 5638 /* Unknown coprocessor. See if the board has hooked it. */
5564 return disas_cp_insn (env, s, insn); 5639 return disas_cp_insn (env, s, insn);
5565 } 5640 }