Commit 2f462816ac343a804d51e157dad6b5d91426d3e1
1 parent
e494ead5
Implement power-management for all defined PowerPC CPUs.
Fix PowerPC 970MP definition. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3440 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
174 additions
and
30 deletions
target-ppc/helper_regs.h
| ... | ... | @@ -82,7 +82,7 @@ static always_inline void hreg_compute_hflags (CPUPPCState *env) |
| 82 | 82 | |
| 83 | 83 | static always_inline int hreg_store_msr (CPUPPCState *env, target_ulong value) |
| 84 | 84 | { |
| 85 | - int enter_pm, excp; | |
| 85 | + int excp; | |
| 86 | 86 | |
| 87 | 87 | excp = 0; |
| 88 | 88 | value &= env->msr_mask; |
| ... | ... | @@ -106,30 +106,9 @@ static always_inline int hreg_store_msr (CPUPPCState *env, target_ulong value) |
| 106 | 106 | #endif |
| 107 | 107 | env->msr = value; |
| 108 | 108 | hreg_compute_hflags(env); |
| 109 | - enter_pm = 0; | |
| 110 | 109 | #if !defined (CONFIG_USER_ONLY) |
| 111 | 110 | if (unlikely(msr_pow == 1)) { |
| 112 | - switch (env->excp_model) { | |
| 113 | - case POWERPC_EXCP_603: | |
| 114 | - case POWERPC_EXCP_603E: | |
| 115 | - case POWERPC_EXCP_G2: | |
| 116 | - /* Don't handle SLEEP mode: we should disable all clocks... | |
| 117 | - * No dynamic power-management. | |
| 118 | - */ | |
| 119 | - if ((env->spr[SPR_HID0] & 0x00C00000) != 0) | |
| 120 | - enter_pm = 1; | |
| 121 | - break; | |
| 122 | - case POWERPC_EXCP_604: | |
| 123 | - enter_pm = 1; | |
| 124 | - break; | |
| 125 | - case POWERPC_EXCP_7x0: | |
| 126 | - if ((env->spr[SPR_HID0] & 0x00E00000) != 0) | |
| 127 | - enter_pm = 1; | |
| 128 | - break; | |
| 129 | - default: | |
| 130 | - break; | |
| 131 | - } | |
| 132 | - if (enter_pm) { | |
| 111 | + if ((*env->check_pow)(env)) { | |
| 133 | 112 | env->halted = 1; |
| 134 | 113 | excp = EXCP_HALTED; |
| 135 | 114 | } | ... | ... |
target-ppc/translate_init.c
| ... | ... | @@ -42,6 +42,7 @@ struct ppc_def_t { |
| 42 | 42 | uint32_t flags; |
| 43 | 43 | int bfd_mach; |
| 44 | 44 | void (*init_proc)(CPUPPCState *env); |
| 45 | + int (*check_pow)(CPUPPCState *env); | |
| 45 | 46 | }; |
| 46 | 47 | |
| 47 | 48 | /* For user-mode emulation, we don't emulate any IRQ controller */ |
| ... | ... | @@ -2606,6 +2607,26 @@ static void init_excp_970 (CPUPPCState *env) |
| 2606 | 2607 | #endif |
| 2607 | 2608 | |
| 2608 | 2609 | /*****************************************************************************/ |
| 2610 | +/* Power management enable checks */ | |
| 2611 | +static int check_pow_none (CPUPPCState *env) | |
| 2612 | +{ | |
| 2613 | + return 0; | |
| 2614 | +} | |
| 2615 | + | |
| 2616 | +static int check_pow_nocheck (CPUPPCState *env) | |
| 2617 | +{ | |
| 2618 | + return 1; | |
| 2619 | +} | |
| 2620 | + | |
| 2621 | +static int check_pow_hid0 (CPUPPCState *env) | |
| 2622 | +{ | |
| 2623 | + if (env->spr[SPR_HID0] & 0x00E00000) | |
| 2624 | + return 1; | |
| 2625 | + | |
| 2626 | + return 0; | |
| 2627 | +} | |
| 2628 | + | |
| 2629 | +/*****************************************************************************/ | |
| 2609 | 2630 | /* PowerPC implementations definitions */ |
| 2610 | 2631 | |
| 2611 | 2632 | /* PowerPC 40x instruction set */ |
| ... | ... | @@ -2621,6 +2642,7 @@ static void init_excp_970 (CPUPPCState *env) |
| 2621 | 2642 | #define POWERPC_INPUT_401 (PPC_FLAGS_INPUT_401) |
| 2622 | 2643 | #define POWERPC_BFDM_401 (bfd_mach_ppc_403) |
| 2623 | 2644 | #define POWERPC_FLAG_401 (POWERPC_FLAG_CE | POWERPC_FLAG_DE) |
| 2645 | +#define check_pow_401 check_pow_nocheck | |
| 2624 | 2646 | |
| 2625 | 2647 | static void init_proc_401 (CPUPPCState *env) |
| 2626 | 2648 | { |
| ... | ... | @@ -2646,6 +2668,7 @@ static void init_proc_401 (CPUPPCState *env) |
| 2646 | 2668 | #define POWERPC_INPUT_401x2 (PPC_FLAGS_INPUT_401) |
| 2647 | 2669 | #define POWERPC_BFDM_401x2 (bfd_mach_ppc_403) |
| 2648 | 2670 | #define POWERPC_FLAG_401x2 (POWERPC_FLAG_CE | POWERPC_FLAG_DE) |
| 2671 | +#define check_pow_401x2 check_pow_nocheck | |
| 2649 | 2672 | |
| 2650 | 2673 | static void init_proc_401x2 (CPUPPCState *env) |
| 2651 | 2674 | { |
| ... | ... | @@ -2678,6 +2701,7 @@ static void init_proc_401x2 (CPUPPCState *env) |
| 2678 | 2701 | #define POWERPC_INPUT_401x3 (PPC_FLAGS_INPUT_401) |
| 2679 | 2702 | #define POWERPC_BFDM_401x3 (bfd_mach_ppc_403) |
| 2680 | 2703 | #define POWERPC_FLAG_401x3 (POWERPC_FLAG_CE | POWERPC_FLAG_DE) |
| 2704 | +#define check_pow_401x3 check_pow_nocheck | |
| 2681 | 2705 | |
| 2682 | 2706 | __attribute__ (( unused )) |
| 2683 | 2707 | static void init_proc_401x3 (CPUPPCState *env) |
| ... | ... | @@ -2706,6 +2730,7 @@ static void init_proc_401x3 (CPUPPCState *env) |
| 2706 | 2730 | #define POWERPC_INPUT_IOP480 (PPC_FLAGS_INPUT_401) |
| 2707 | 2731 | #define POWERPC_BFDM_IOP480 (bfd_mach_ppc_403) |
| 2708 | 2732 | #define POWERPC_FLAG_IOP480 (POWERPC_FLAG_CE | POWERPC_FLAG_DE) |
| 2733 | +#define check_pow_IOP480 check_pow_nocheck | |
| 2709 | 2734 | |
| 2710 | 2735 | static void init_proc_IOP480 (CPUPPCState *env) |
| 2711 | 2736 | { |
| ... | ... | @@ -2736,6 +2761,7 @@ static void init_proc_IOP480 (CPUPPCState *env) |
| 2736 | 2761 | #define POWERPC_INPUT_403 (PPC_FLAGS_INPUT_401) |
| 2737 | 2762 | #define POWERPC_BFDM_403 (bfd_mach_ppc_403) |
| 2738 | 2763 | #define POWERPC_FLAG_403 (POWERPC_FLAG_CE | POWERPC_FLAG_PX) |
| 2764 | +#define check_pow_403 check_pow_nocheck | |
| 2739 | 2765 | |
| 2740 | 2766 | static void init_proc_403 (CPUPPCState *env) |
| 2741 | 2767 | { |
| ... | ... | @@ -2765,6 +2791,7 @@ static void init_proc_403 (CPUPPCState *env) |
| 2765 | 2791 | #define POWERPC_INPUT_403GCX (PPC_FLAGS_INPUT_401) |
| 2766 | 2792 | #define POWERPC_BFDM_403GCX (bfd_mach_ppc_403) |
| 2767 | 2793 | #define POWERPC_FLAG_403GCX (POWERPC_FLAG_CE | POWERPC_FLAG_PX) |
| 2794 | +#define check_pow_403GCX check_pow_nocheck | |
| 2768 | 2795 | |
| 2769 | 2796 | static void init_proc_403GCX (CPUPPCState *env) |
| 2770 | 2797 | { |
| ... | ... | @@ -2810,6 +2837,7 @@ static void init_proc_403GCX (CPUPPCState *env) |
| 2810 | 2837 | #define POWERPC_BFDM_405 (bfd_mach_ppc_403) |
| 2811 | 2838 | #define POWERPC_FLAG_405 (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \ |
| 2812 | 2839 | POWERPC_FLAG_DE) |
| 2840 | +#define check_pow_405 check_pow_nocheck | |
| 2813 | 2841 | |
| 2814 | 2842 | static void init_proc_405 (CPUPPCState *env) |
| 2815 | 2843 | { |
| ... | ... | @@ -2853,6 +2881,7 @@ static void init_proc_405 (CPUPPCState *env) |
| 2853 | 2881 | #define POWERPC_BFDM_440EP (bfd_mach_ppc_403) |
| 2854 | 2882 | #define POWERPC_FLAG_440EP (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \ |
| 2855 | 2883 | POWERPC_FLAG_DE) |
| 2884 | +#define check_pow_440EP check_pow_nocheck | |
| 2856 | 2885 | |
| 2857 | 2886 | static void init_proc_440EP (CPUPPCState *env) |
| 2858 | 2887 | { |
| ... | ... | @@ -2902,6 +2931,7 @@ static void init_proc_440EP (CPUPPCState *env) |
| 2902 | 2931 | #define POWERPC_BFDM_440GP (bfd_mach_ppc_403) |
| 2903 | 2932 | #define POWERPC_FLAG_440GP (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \ |
| 2904 | 2933 | POWERPC_FLAG_DE) |
| 2934 | +#define check_pow_440GP check_pow_nocheck | |
| 2905 | 2935 | |
| 2906 | 2936 | static void init_proc_440GP (CPUPPCState *env) |
| 2907 | 2937 | { |
| ... | ... | @@ -2933,6 +2963,7 @@ static void init_proc_440GP (CPUPPCState *env) |
| 2933 | 2963 | #define POWERPC_BFDM_440x4 (bfd_mach_ppc_403) |
| 2934 | 2964 | #define POWERPC_FLAG_440x4 (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \ |
| 2935 | 2965 | POWERPC_FLAG_DE) |
| 2966 | +#define check_pow_440x4 check_pow_nocheck | |
| 2936 | 2967 | |
| 2937 | 2968 | __attribute__ (( unused )) |
| 2938 | 2969 | static void init_proc_440x4 (CPUPPCState *env) |
| ... | ... | @@ -2965,6 +2996,7 @@ static void init_proc_440x4 (CPUPPCState *env) |
| 2965 | 2996 | #define POWERPC_BFDM_440x5 (bfd_mach_ppc_403) |
| 2966 | 2997 | #define POWERPC_FLAG_440x5 (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \ |
| 2967 | 2998 | POWERPC_FLAG_DE) |
| 2999 | +#define check_pow_440x5 check_pow_nocheck | |
| 2968 | 3000 | |
| 2969 | 3001 | static void init_proc_440x5 (CPUPPCState *env) |
| 2970 | 3002 | { |
| ... | ... | @@ -3014,6 +3046,7 @@ static void init_proc_440x5 (CPUPPCState *env) |
| 3014 | 3046 | #define POWERPC_BFDM_460 (bfd_mach_ppc_403) |
| 3015 | 3047 | #define POWERPC_FLAG_460 (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \ |
| 3016 | 3048 | POWERPC_FLAG_DE) |
| 3049 | +#define check_pow_460 check_pow_nocheck | |
| 3017 | 3050 | |
| 3018 | 3051 | __attribute__ (( unused )) |
| 3019 | 3052 | static void init_proc_460 (CPUPPCState *env) |
| ... | ... | @@ -3072,6 +3105,7 @@ static void init_proc_460 (CPUPPCState *env) |
| 3072 | 3105 | #define POWERPC_BFDM_460F (bfd_mach_ppc_403) |
| 3073 | 3106 | #define POWERPC_FLAG_460F (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \ |
| 3074 | 3107 | POWERPC_FLAG_DE) |
| 3108 | +#define check_pow_460F check_pow_nocheck | |
| 3075 | 3109 | |
| 3076 | 3110 | __attribute__ (( unused )) |
| 3077 | 3111 | static void init_proc_460F (CPUPPCState *env) |
| ... | ... | @@ -3129,6 +3163,7 @@ static void init_proc_460F (CPUPPCState *env) |
| 3129 | 3163 | #define POWERPC_INPUT_BookE (PPC_FLAGS_INPUT_BookE) |
| 3130 | 3164 | #define POWERPC_BFDM_BookE (bfd_mach_ppc_403) |
| 3131 | 3165 | #define POWERPC_FLAG_BookE (POWERPC_FLAG_NONE) |
| 3166 | +#define check_pow_BookE check_pow_nocheck | |
| 3132 | 3167 | |
| 3133 | 3168 | __attribute__ (( unused )) |
| 3134 | 3169 | static void init_proc_BookE (CPUPPCState *env) |
| ... | ... | @@ -3152,6 +3187,7 @@ static void init_proc_BookE (CPUPPCState *env) |
| 3152 | 3187 | #define POWERPC_INPUT_e500 (PPC_FLAGS_INPUT_BookE) |
| 3153 | 3188 | #define POWERPC_BFDM_e500 (bfd_mach_ppc_403) |
| 3154 | 3189 | #define POWERPC_FLAG_e500 (POWERPC_FLAG_SPE) |
| 3190 | +#define check_pow_e500 check_pow_hid0 | |
| 3155 | 3191 | |
| 3156 | 3192 | __attribute__ (( unused )) |
| 3157 | 3193 | static void init_proc_e500 (CPUPPCState *env) |
| ... | ... | @@ -3201,6 +3237,7 @@ static void init_proc_e500 (CPUPPCState *env) |
| 3201 | 3237 | #define POWERPC_INPUT_601 (PPC_FLAGS_INPUT_6xx) |
| 3202 | 3238 | #define POWERPC_BFDM_601 (bfd_mach_ppc_601) |
| 3203 | 3239 | #define POWERPC_FLAG_601 (POWERPC_FLAG_SE) |
| 3240 | +#define check_pow_601 check_pow_none | |
| 3204 | 3241 | |
| 3205 | 3242 | static void init_proc_601 (CPUPPCState *env) |
| 3206 | 3243 | { |
| ... | ... | @@ -3257,6 +3294,7 @@ static void init_proc_601 (CPUPPCState *env) |
| 3257 | 3294 | #define POWERPC_BFDM_602 (bfd_mach_ppc_602) |
| 3258 | 3295 | #define POWERPC_FLAG_602 (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \ |
| 3259 | 3296 | POWERPC_FLAG_BE) |
| 3297 | +#define check_pow_602 check_pow_hid0 | |
| 3260 | 3298 | |
| 3261 | 3299 | static void init_proc_602 (CPUPPCState *env) |
| 3262 | 3300 | { |
| ... | ... | @@ -3294,6 +3332,7 @@ static void init_proc_602 (CPUPPCState *env) |
| 3294 | 3332 | #define POWERPC_BFDM_603 (bfd_mach_ppc_603) |
| 3295 | 3333 | #define POWERPC_FLAG_603 (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \ |
| 3296 | 3334 | POWERPC_FLAG_BE) |
| 3335 | +#define check_pow_603 check_pow_hid0 | |
| 3297 | 3336 | |
| 3298 | 3337 | static void init_proc_603 (CPUPPCState *env) |
| 3299 | 3338 | { |
| ... | ... | @@ -3331,6 +3370,7 @@ static void init_proc_603 (CPUPPCState *env) |
| 3331 | 3370 | #define POWERPC_BFDM_603E (bfd_mach_ppc_ec603e) |
| 3332 | 3371 | #define POWERPC_FLAG_603E (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \ |
| 3333 | 3372 | POWERPC_FLAG_BE) |
| 3373 | +#define check_pow_603E check_pow_hid0 | |
| 3334 | 3374 | |
| 3335 | 3375 | static void init_proc_603E (CPUPPCState *env) |
| 3336 | 3376 | { |
| ... | ... | @@ -3373,6 +3413,7 @@ static void init_proc_603E (CPUPPCState *env) |
| 3373 | 3413 | #define POWERPC_BFDM_G2 (bfd_mach_ppc_ec603e) |
| 3374 | 3414 | #define POWERPC_FLAG_G2 (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \ |
| 3375 | 3415 | POWERPC_FLAG_BE) |
| 3416 | +#define check_pow_G2 check_pow_hid0 | |
| 3376 | 3417 | |
| 3377 | 3418 | static void init_proc_G2 (CPUPPCState *env) |
| 3378 | 3419 | { |
| ... | ... | @@ -3417,6 +3458,7 @@ static void init_proc_G2 (CPUPPCState *env) |
| 3417 | 3458 | #define POWERPC_BFDM_G2LE (bfd_mach_ppc_ec603e) |
| 3418 | 3459 | #define POWERPC_FLAG_G2LE (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \ |
| 3419 | 3460 | POWERPC_FLAG_BE) |
| 3461 | +#define check_pow_G2LE check_pow_hid0 | |
| 3420 | 3462 | |
| 3421 | 3463 | static void init_proc_G2LE (CPUPPCState *env) |
| 3422 | 3464 | { |
| ... | ... | @@ -3461,6 +3503,7 @@ static void init_proc_G2LE (CPUPPCState *env) |
| 3461 | 3503 | #define POWERPC_BFDM_604 (bfd_mach_ppc_604) |
| 3462 | 3504 | #define POWERPC_FLAG_604 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \ |
| 3463 | 3505 | POWERPC_FLAG_PMM) |
| 3506 | +#define check_pow_604 check_pow_nocheck | |
| 3464 | 3507 | |
| 3465 | 3508 | static void init_proc_604 (CPUPPCState *env) |
| 3466 | 3509 | { |
| ... | ... | @@ -3497,6 +3540,7 @@ static void init_proc_604 (CPUPPCState *env) |
| 3497 | 3540 | #define POWERPC_BFDM_7x0 (bfd_mach_ppc_750) |
| 3498 | 3541 | #define POWERPC_FLAG_7x0 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \ |
| 3499 | 3542 | POWERPC_FLAG_PMM) |
| 3543 | +#define check_pow_7x0 check_pow_hid0 | |
| 3500 | 3544 | |
| 3501 | 3545 | static void init_proc_7x0 (CPUPPCState *env) |
| 3502 | 3546 | { |
| ... | ... | @@ -3535,6 +3579,7 @@ static void init_proc_7x0 (CPUPPCState *env) |
| 3535 | 3579 | #define POWERPC_BFDM_750fx (bfd_mach_ppc_750) |
| 3536 | 3580 | #define POWERPC_FLAG_750fx (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \ |
| 3537 | 3581 | POWERPC_FLAG_PMM) |
| 3582 | +#define check_pow_750fx check_pow_hid0 | |
| 3538 | 3583 | |
| 3539 | 3584 | static void init_proc_750fx (CPUPPCState *env) |
| 3540 | 3585 | { |
| ... | ... | @@ -3580,6 +3625,7 @@ static void init_proc_750fx (CPUPPCState *env) |
| 3580 | 3625 | #define POWERPC_BFDM_7x5 (bfd_mach_ppc_750) |
| 3581 | 3626 | #define POWERPC_FLAG_7x5 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \ |
| 3582 | 3627 | POWERPC_FLAG_PMM) |
| 3628 | +#define check_pow_7x5 check_pow_hid0 | |
| 3583 | 3629 | |
| 3584 | 3630 | static void init_proc_7x5 (CPUPPCState *env) |
| 3585 | 3631 | { |
| ... | ... | @@ -3640,6 +3686,7 @@ static void init_proc_7x5 (CPUPPCState *env) |
| 3640 | 3686 | #define POWERPC_BFDM_7400 (bfd_mach_ppc_7400) |
| 3641 | 3687 | #define POWERPC_FLAG_7400 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ |
| 3642 | 3688 | POWERPC_FLAG_BE | POWERPC_FLAG_PMM) |
| 3689 | +#define check_pow_7400 check_pow_hid0 | |
| 3643 | 3690 | |
| 3644 | 3691 | static void init_proc_7400 (CPUPPCState *env) |
| 3645 | 3692 | { |
| ... | ... | @@ -3671,6 +3718,7 @@ static void init_proc_7400 (CPUPPCState *env) |
| 3671 | 3718 | #define POWERPC_BFDM_7410 (bfd_mach_ppc_7400) |
| 3672 | 3719 | #define POWERPC_FLAG_7410 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ |
| 3673 | 3720 | POWERPC_FLAG_BE | POWERPC_FLAG_PMM) |
| 3721 | +#define check_pow_7410 check_pow_hid0 | |
| 3674 | 3722 | |
| 3675 | 3723 | static void init_proc_7410 (CPUPPCState *env) |
| 3676 | 3724 | { |
| ... | ... | @@ -3714,6 +3762,7 @@ static void init_proc_7410 (CPUPPCState *env) |
| 3714 | 3762 | #define POWERPC_BFDM_7440 (bfd_mach_ppc_7400) |
| 3715 | 3763 | #define POWERPC_FLAG_7440 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ |
| 3716 | 3764 | POWERPC_FLAG_BE | POWERPC_FLAG_PMM) |
| 3765 | +#define check_pow_7440 check_pow_hid0 | |
| 3717 | 3766 | |
| 3718 | 3767 | __attribute__ (( unused )) |
| 3719 | 3768 | static void init_proc_7440 (CPUPPCState *env) |
| ... | ... | @@ -3784,6 +3833,7 @@ static void init_proc_7440 (CPUPPCState *env) |
| 3784 | 3833 | #define POWERPC_BFDM_7450 (bfd_mach_ppc_7400) |
| 3785 | 3834 | #define POWERPC_FLAG_7450 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ |
| 3786 | 3835 | POWERPC_FLAG_BE | POWERPC_FLAG_PMM) |
| 3836 | +#define check_pow_7450 check_pow_hid0 | |
| 3787 | 3837 | |
| 3788 | 3838 | __attribute__ (( unused )) |
| 3789 | 3839 | static void init_proc_7450 (CPUPPCState *env) |
| ... | ... | @@ -3856,6 +3906,7 @@ static void init_proc_7450 (CPUPPCState *env) |
| 3856 | 3906 | #define POWERPC_BFDM_7445 (bfd_mach_ppc_7400) |
| 3857 | 3907 | #define POWERPC_FLAG_7445 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ |
| 3858 | 3908 | POWERPC_FLAG_BE | POWERPC_FLAG_PMM) |
| 3909 | +#define check_pow_7445 check_pow_hid0 | |
| 3859 | 3910 | |
| 3860 | 3911 | __attribute__ (( unused )) |
| 3861 | 3912 | static void init_proc_7445 (CPUPPCState *env) |
| ... | ... | @@ -3960,6 +4011,7 @@ static void init_proc_7445 (CPUPPCState *env) |
| 3960 | 4011 | #define POWERPC_BFDM_7455 (bfd_mach_ppc_7400) |
| 3961 | 4012 | #define POWERPC_FLAG_7455 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ |
| 3962 | 4013 | POWERPC_FLAG_BE | POWERPC_FLAG_PMM) |
| 4014 | +#define check_pow_7455 check_pow_hid0 | |
| 3963 | 4015 | |
| 3964 | 4016 | __attribute__ (( unused )) |
| 3965 | 4017 | static void init_proc_7455 (CPUPPCState *env) |
| ... | ... | @@ -4078,6 +4130,14 @@ static void init_proc_7455 (CPUPPCState *env) |
| 4078 | 4130 | #define POWERPC970_HID5_INIT 0x00000000 |
| 4079 | 4131 | #endif |
| 4080 | 4132 | |
| 4133 | +static int check_pow_970 (CPUPPCState *env) | |
| 4134 | +{ | |
| 4135 | + if (env->spr[SPR_HID0] & 0x00600000) | |
| 4136 | + return 1; | |
| 4137 | + | |
| 4138 | + return 0; | |
| 4139 | +} | |
| 4140 | + | |
| 4081 | 4141 | static void init_proc_970 (CPUPPCState *env) |
| 4082 | 4142 | { |
| 4083 | 4143 | gen_spr_ne_601(env); |
| ... | ... | @@ -4147,6 +4207,14 @@ static void init_proc_970 (CPUPPCState *env) |
| 4147 | 4207 | #define POWERPC_FLAG_970FX (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ |
| 4148 | 4208 | POWERPC_FLAG_BE | POWERPC_FLAG_PMM) |
| 4149 | 4209 | |
| 4210 | +static int check_pow_970FX (CPUPPCState *env) | |
| 4211 | +{ | |
| 4212 | + if (env->spr[SPR_HID0] & 0x00600000) | |
| 4213 | + return 1; | |
| 4214 | + | |
| 4215 | + return 0; | |
| 4216 | +} | |
| 4217 | + | |
| 4150 | 4218 | static void init_proc_970FX (CPUPPCState *env) |
| 4151 | 4219 | { |
| 4152 | 4220 | gen_spr_ne_601(env); |
| ... | ... | @@ -4216,6 +4284,14 @@ static void init_proc_970FX (CPUPPCState *env) |
| 4216 | 4284 | #define POWERPC_FLAG_970GX (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ |
| 4217 | 4285 | POWERPC_FLAG_BE | POWERPC_FLAG_PMM) |
| 4218 | 4286 | |
| 4287 | +static int check_pow_970GX (CPUPPCState *env) | |
| 4288 | +{ | |
| 4289 | + if (env->spr[SPR_HID0] & 0x00600000) | |
| 4290 | + return 1; | |
| 4291 | + | |
| 4292 | + return 0; | |
| 4293 | +} | |
| 4294 | + | |
| 4219 | 4295 | static void init_proc_970GX (CPUPPCState *env) |
| 4220 | 4296 | { |
| 4221 | 4297 | gen_spr_ne_601(env); |
| ... | ... | @@ -4273,6 +4349,83 @@ static void init_proc_970GX (CPUPPCState *env) |
| 4273 | 4349 | ppc970_irq_init(env); |
| 4274 | 4350 | } |
| 4275 | 4351 | |
| 4352 | +/* PowerPC 970 MP */ | |
| 4353 | +#define POWERPC_INSNS_970MP (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT | \ | |
| 4354 | + PPC_64B | PPC_ALTIVEC | \ | |
| 4355 | + PPC_SEGMENT_64B | PPC_SLBI) | |
| 4356 | +#define POWERPC_MSRM_970MP (0x900000000204FF36ULL) | |
| 4357 | +#define POWERPC_MMU_970MP (POWERPC_MMU_64B) | |
| 4358 | +#define POWERPC_EXCP_970MP (POWERPC_EXCP_970) | |
| 4359 | +#define POWERPC_INPUT_970MP (PPC_FLAGS_INPUT_970) | |
| 4360 | +#define POWERPC_BFDM_970MP (bfd_mach_ppc64) | |
| 4361 | +#define POWERPC_FLAG_970MP (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \ | |
| 4362 | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM) | |
| 4363 | + | |
| 4364 | +static int check_pow_970MP (CPUPPCState *env) | |
| 4365 | +{ | |
| 4366 | + if (env->spr[SPR_HID0] & 0x01C00000) | |
| 4367 | + return 1; | |
| 4368 | + | |
| 4369 | + return 0; | |
| 4370 | +} | |
| 4371 | + | |
| 4372 | +static void init_proc_970MP (CPUPPCState *env) | |
| 4373 | +{ | |
| 4374 | + gen_spr_ne_601(env); | |
| 4375 | + gen_spr_7xx(env); | |
| 4376 | + /* Time base */ | |
| 4377 | + gen_tbl(env); | |
| 4378 | + /* Hardware implementation registers */ | |
| 4379 | + /* XXX : not implemented */ | |
| 4380 | + spr_register(env, SPR_HID0, "HID0", | |
| 4381 | + SPR_NOACCESS, SPR_NOACCESS, | |
| 4382 | + &spr_read_generic, &spr_write_clear, | |
| 4383 | + 0x60000000); | |
| 4384 | + /* XXX : not implemented */ | |
| 4385 | + spr_register(env, SPR_HID1, "HID1", | |
| 4386 | + SPR_NOACCESS, SPR_NOACCESS, | |
| 4387 | + &spr_read_generic, &spr_write_generic, | |
| 4388 | + 0x00000000); | |
| 4389 | + /* XXX : not implemented */ | |
| 4390 | + spr_register(env, SPR_750_HID2, "HID2", | |
| 4391 | + SPR_NOACCESS, SPR_NOACCESS, | |
| 4392 | + &spr_read_generic, &spr_write_generic, | |
| 4393 | + 0x00000000); | |
| 4394 | + /* XXX : not implemented */ | |
| 4395 | + spr_register(env, SPR_970_HID5, "HID5", | |
| 4396 | + SPR_NOACCESS, SPR_NOACCESS, | |
| 4397 | + &spr_read_generic, &spr_write_generic, | |
| 4398 | + POWERPC970_HID5_INIT); | |
| 4399 | + /* Memory management */ | |
| 4400 | + /* XXX: not correct */ | |
| 4401 | + gen_low_BATs(env); | |
| 4402 | + /* XXX : not implemented */ | |
| 4403 | + spr_register(env, SPR_MMUCFG, "MMUCFG", | |
| 4404 | + SPR_NOACCESS, SPR_NOACCESS, | |
| 4405 | + &spr_read_generic, SPR_NOACCESS, | |
| 4406 | + 0x00000000); /* TOFIX */ | |
| 4407 | + /* XXX : not implemented */ | |
| 4408 | + spr_register(env, SPR_MMUCSR0, "MMUCSR0", | |
| 4409 | + SPR_NOACCESS, SPR_NOACCESS, | |
| 4410 | + &spr_read_generic, &spr_write_generic, | |
| 4411 | + 0x00000000); /* TOFIX */ | |
| 4412 | + spr_register(env, SPR_HIOR, "SPR_HIOR", | |
| 4413 | + SPR_NOACCESS, SPR_NOACCESS, | |
| 4414 | + &spr_read_generic, &spr_write_generic, | |
| 4415 | + 0xFFF00000); /* XXX: This is a hack */ | |
| 4416 | +#if !defined(CONFIG_USER_ONLY) | |
| 4417 | + env->excp_prefix = 0xFFF00000; | |
| 4418 | +#endif | |
| 4419 | +#if !defined(CONFIG_USER_ONLY) | |
| 4420 | + env->slb_nr = 32; | |
| 4421 | +#endif | |
| 4422 | + init_excp_970(env); | |
| 4423 | + env->dcache_line_size = 128; | |
| 4424 | + env->icache_line_size = 128; | |
| 4425 | + /* Allocate hardware IRQ controller */ | |
| 4426 | + ppc970_irq_init(env); | |
| 4427 | +} | |
| 4428 | + | |
| 4276 | 4429 | /* PowerPC 620 */ |
| 4277 | 4430 | #define POWERPC_INSNS_620 (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT | \ |
| 4278 | 4431 | PPC_64B | PPC_SLBI) |
| ... | ... | @@ -4282,6 +4435,7 @@ static void init_proc_970GX (CPUPPCState *env) |
| 4282 | 4435 | #define POWERPC_INPUT_620 (PPC_FLAGS_INPUT_970) |
| 4283 | 4436 | #define POWERPC_BFDM_620 (bfd_mach_ppc64) |
| 4284 | 4437 | #define POWERPC_FLAG_620 (POWERPC_FLAG_SE | POWERPC_FLAG_BE) |
| 4438 | +#define check_pow_620 check_pow_nocheck /* Check this */ | |
| 4285 | 4439 | |
| 4286 | 4440 | __attribute__ (( unused )) |
| 4287 | 4441 | static void init_proc_620 (CPUPPCState *env) |
| ... | ... | @@ -4313,9 +4467,10 @@ static void init_proc_620 (CPUPPCState *env) |
| 4313 | 4467 | #define POWERPC_MMU_PPC32 POWERPC_MMU_604 |
| 4314 | 4468 | #define POWERPC_EXCP_PPC32 POWERPC_EXCP_604 |
| 4315 | 4469 | #define POWERPC_INPUT_PPC32 POWERPC_INPUT_604 |
| 4316 | -#define init_proc_PPC32 init_proc_604 | |
| 4317 | 4470 | #define POWERPC_BFDM_PPC32 POWERPC_BFDM_604 |
| 4318 | 4471 | #define POWERPC_FLAG_PPC32 POWERPC_FLAG_604 |
| 4472 | +#define check_pow_PPC32 check_pow_604 | |
| 4473 | +#define init_proc_PPC32 init_proc_604 | |
| 4319 | 4474 | |
| 4320 | 4475 | /* Default 64 bits PowerPC target will be 970 FX */ |
| 4321 | 4476 | #define CPU_POWERPC_PPC64 CPU_POWERPC_970FX |
| ... | ... | @@ -4324,9 +4479,10 @@ static void init_proc_620 (CPUPPCState *env) |
| 4324 | 4479 | #define POWERPC_MMU_PPC64 POWERPC_MMU_970FX |
| 4325 | 4480 | #define POWERPC_EXCP_PPC64 POWERPC_EXCP_970FX |
| 4326 | 4481 | #define POWERPC_INPUT_PPC64 POWERPC_INPUT_970FX |
| 4327 | -#define init_proc_PPC64 init_proc_970FX | |
| 4328 | 4482 | #define POWERPC_BFDM_PPC64 POWERPC_BFDM_970FX |
| 4329 | 4483 | #define POWERPC_FLAG_PPC64 POWERPC_FLAG_970FX |
| 4484 | +#define check_pow_PPC64 check_pow_970FX | |
| 4485 | +#define init_proc_PPC64 init_proc_970FX | |
| 4330 | 4486 | |
| 4331 | 4487 | /* Default PowerPC target will be PowerPC 32 */ |
| 4332 | 4488 | #if defined (TARGET_PPC64) && 0 // XXX: TODO |
| ... | ... | @@ -4336,9 +4492,10 @@ static void init_proc_620 (CPUPPCState *env) |
| 4336 | 4492 | #define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC64 |
| 4337 | 4493 | #define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC64 |
| 4338 | 4494 | #define POWERPC_INPUT_DEFAULT POWERPC_INPUT_PPC64 |
| 4339 | -#define init_proc_DEFAULT init_proc_PPC64 | |
| 4340 | 4495 | #define POWERPC_BFDM_DEFAULT POWERPC_BFDM_PPC64 |
| 4341 | 4496 | #define POWERPC_FLAG_DEFAULT POWERPC_FLAG_PPC64 |
| 4497 | +#define check_pow_DEFAULT check_pow_PPC64 | |
| 4498 | +#define init_proc_DEFAULT init_proc_PPC64 | |
| 4342 | 4499 | #else |
| 4343 | 4500 | #define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC32 |
| 4344 | 4501 | #define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC32 |
| ... | ... | @@ -4346,9 +4503,10 @@ static void init_proc_620 (CPUPPCState *env) |
| 4346 | 4503 | #define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC32 |
| 4347 | 4504 | #define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC32 |
| 4348 | 4505 | #define POWERPC_INPUT_DEFAULT POWERPC_INPUT_PPC32 |
| 4349 | -#define init_proc_DEFAULT init_proc_PPC32 | |
| 4350 | 4506 | #define POWERPC_BFDM_DEFAULT POWERPC_BFDM_PPC32 |
| 4351 | 4507 | #define POWERPC_FLAG_DEFAULT POWERPC_FLAG_PPC32 |
| 4508 | +#define check_pow_DEFAULT check_pow_PPC32 | |
| 4509 | +#define init_proc_DEFAULT init_proc_PPC32 | |
| 4352 | 4510 | #endif |
| 4353 | 4511 | |
| 4354 | 4512 | /*****************************************************************************/ |
| ... | ... | @@ -4848,6 +5006,7 @@ enum { |
| 4848 | 5006 | .bfd_mach = glue(POWERPC_BFDM_,_type), \ |
| 4849 | 5007 | .flags = glue(POWERPC_FLAG_,_type), \ |
| 4850 | 5008 | .init_proc = &glue(init_proc_,_type), \ |
| 5009 | + .check_pow = &glue(check_pow_,_type), \ | |
| 4851 | 5010 | } |
| 4852 | 5011 | |
| 4853 | 5012 | static ppc_def_t ppc_defs[] = { |
| ... | ... | @@ -5671,11 +5830,11 @@ static ppc_def_t ppc_defs[] = { |
| 5671 | 5830 | /* PowerPC 970GX (G5) */ |
| 5672 | 5831 | POWERPC_DEF("970gx", CPU_POWERPC_970GX, 0xFFFFFFFF, 970GX), |
| 5673 | 5832 | /* PowerPC 970MP */ |
| 5674 | - POWERPC_DEF("970mp", CPU_POWERPC_970MP, 0xFFFFFFFF, 970), | |
| 5833 | + POWERPC_DEF("970mp", CPU_POWERPC_970MP, 0xFFFFFFFF, 970MP), | |
| 5675 | 5834 | /* PowerPC 970MP v1.0 */ |
| 5676 | - POWERPC_DEF("970mp1.0", CPU_POWERPC_970MP_v10, 0xFFFFFFFF, 970), | |
| 5835 | + POWERPC_DEF("970mp1.0", CPU_POWERPC_970MP_v10, 0xFFFFFFFF, 970MP), | |
| 5677 | 5836 | /* PowerPC 970MP v1.1 */ |
| 5678 | - POWERPC_DEF("970mp1.1", CPU_POWERPC_970MP_v11, 0xFFFFFFFF, 970), | |
| 5837 | + POWERPC_DEF("970mp1.1", CPU_POWERPC_970MP_v11, 0xFFFFFFFF, 970MP), | |
| 5679 | 5838 | #if defined (TODO) |
| 5680 | 5839 | /* PowerPC Cell */ |
| 5681 | 5840 | POWERPC_DEF("Cell", CPU_POWERPC_CELL, 0xFFFFFFFF, 970), |
| ... | ... | @@ -5884,6 +6043,11 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) |
| 5884 | 6043 | " Attempt Qemu to crash very soon !\n"); |
| 5885 | 6044 | } |
| 5886 | 6045 | #endif |
| 6046 | + if (env->check_pow == NULL) { | |
| 6047 | + fprintf(stderr, "WARNING: no power management check handler " | |
| 6048 | + "registered.\n" | |
| 6049 | + " Attempt Qemu to crash very soon !\n"); | |
| 6050 | + } | |
| 5887 | 6051 | } |
| 5888 | 6052 | |
| 5889 | 6053 | #if defined(PPC_DUMP_CPU) |
| ... | ... | @@ -6186,6 +6350,7 @@ int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def) |
| 6186 | 6350 | env->bus_model = def->bus_model; |
| 6187 | 6351 | env->flags = def->flags; |
| 6188 | 6352 | env->bfd_mach = def->bfd_mach; |
| 6353 | + env->check_pow = def->check_pow; | |
| 6189 | 6354 | if (create_ppc_opcodes(env, def) < 0) |
| 6190 | 6355 | return -1; |
| 6191 | 6356 | init_ppc_proc(env, def); | ... | ... |