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