Revision 87f19eb2
b/target-arm/translate.c | ||
---|---|---|
2498 | 2498 |
if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT))) |
2499 | 2499 |
return 1; |
2500 | 2500 |
} |
2501 |
if (cpn == 7) { |
|
2502 |
/* ISB, DSB, DMB. */ |
|
2503 |
if ((cpm == 5 && op == 4) |
|
2504 |
|| (cpm == 10 && (op == 4 || op == 5))) |
|
2505 |
return 1; |
|
2506 |
} |
|
2507 | 2501 |
return 0; |
2508 | 2502 |
} |
2509 | 2503 |
|
... | ... | |
2579 | 2573 |
/* cdp */ |
2580 | 2574 |
return 1; |
2581 | 2575 |
} |
2582 |
if (IS_USER(s) && !cp15_user_ok(env, insn)) { |
|
2583 |
return 1; |
|
2584 |
} |
|
2585 |
|
|
2586 |
/* Pre-v7 versions of the architecture implemented WFI via coprocessor |
|
2587 |
* instructions rather than a separate instruction. |
|
2576 |
/* We special case a number of cp15 instructions which were used |
|
2577 |
* for things which are real instructions in ARMv7. This allows |
|
2578 |
* them to work in linux-user mode which doesn't provide functional |
|
2579 |
* get_cp15/set_cp15 helpers, and is more efficient anyway. |
|
2588 | 2580 |
*/ |
2589 |
if ((insn & 0x0fff0fff) == 0x0e070f90) { |
|
2581 |
switch ((insn & 0x0fff0fff)) { |
|
2582 |
case 0x0e070f90: |
|
2590 | 2583 |
/* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores). |
2591 | 2584 |
* In v7, this must NOP. |
2592 | 2585 |
*/ |
2586 |
if (IS_USER(s)) { |
|
2587 |
return 1; |
|
2588 |
} |
|
2593 | 2589 |
if (!arm_feature(env, ARM_FEATURE_V7)) { |
2594 | 2590 |
/* Wait for interrupt. */ |
2595 | 2591 |
gen_set_pc_im(s->pc); |
2596 | 2592 |
s->is_jmp = DISAS_WFI; |
2597 | 2593 |
} |
2598 | 2594 |
return 0; |
2599 |
} |
|
2600 |
|
|
2601 |
if ((insn & 0x0fff0fff) == 0x0e070f58) { |
|
2595 |
case 0x0e070f58: |
|
2602 | 2596 |
/* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI, |
2603 | 2597 |
* so this is slightly over-broad. |
2604 | 2598 |
*/ |
2605 |
if (!arm_feature(env, ARM_FEATURE_V6)) { |
|
2599 |
if (!IS_USER(s) && !arm_feature(env, ARM_FEATURE_V6)) {
|
|
2606 | 2600 |
/* Wait for interrupt. */ |
2607 | 2601 |
gen_set_pc_im(s->pc); |
2608 | 2602 |
s->is_jmp = DISAS_WFI; |
2609 | 2603 |
return 0; |
2610 | 2604 |
} |
2611 |
/* Otherwise fall through to handle via helper function.
|
|
2605 |
/* Otherwise continue to handle via helper function.
|
|
2612 | 2606 |
* In particular, on v7 and some v6 cores this is one of |
2613 | 2607 |
* the VA-PA registers. |
2614 | 2608 |
*/ |
2609 |
break; |
|
2610 |
case 0x0e070f3d: |
|
2611 |
/* 0,c7,c13,1: prefetch-by-MVA in v6, NOP in v7 */ |
|
2612 |
if (arm_feature(env, ARM_FEATURE_V6)) { |
|
2613 |
return IS_USER(s) ? 1 : 0; |
|
2614 |
} |
|
2615 |
break; |
|
2616 |
case 0x0e070f95: /* 0,c7,c5,4 : ISB */ |
|
2617 |
case 0x0e070f9a: /* 0,c7,c10,4: DSB */ |
|
2618 |
case 0x0e070fba: /* 0,c7,c10,5: DMB */ |
|
2619 |
/* Barriers in both v6 and v7 */ |
|
2620 |
if (arm_feature(env, ARM_FEATURE_V6)) { |
|
2621 |
return 0; |
|
2622 |
} |
|
2623 |
break; |
|
2624 |
default: |
|
2625 |
break; |
|
2626 |
} |
|
2627 |
|
|
2628 |
if (IS_USER(s) && !cp15_user_ok(env, insn)) { |
|
2629 |
return 1; |
|
2615 | 2630 |
} |
2616 | 2631 |
|
2617 | 2632 |
rd = (insn >> 12) & 0xf; |
Also available in: Unified diff