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); | ... | ... |