Commit fe1479c3ad177df09d465338d5421a5f3b857f91
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
Showing
4 changed files
with
94 additions
and
1 deletions
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
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 | } | ... | ... |