Commit 50443c98e4149e8cde3b371f9ed60d943d95d286
1 parent
6f5a9f7e
specialize the power save code for 7x0 CPUs
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1671 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
19 additions
and
4 deletions
cpu-exec.c
| @@ -265,11 +265,11 @@ int cpu_exec(CPUState *env1) | @@ -265,11 +265,11 @@ int cpu_exec(CPUState *env1) | ||
| 265 | } | 265 | } |
| 266 | } | 266 | } |
| 267 | #elif defined(TARGET_PPC) | 267 | #elif defined(TARGET_PPC) |
| 268 | - if (env1->msr[MSR_POW]) { | 268 | + if (env1->halted) { |
| 269 | if (env1->msr[MSR_EE] && | 269 | if (env1->msr[MSR_EE] && |
| 270 | (env1->interrupt_request & | 270 | (env1->interrupt_request & |
| 271 | (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) { | 271 | (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) { |
| 272 | - env1->msr[MSR_POW] = 0; | 272 | + env1->halted = 0; |
| 273 | } else { | 273 | } else { |
| 274 | return EXCP_HALTED; | 274 | return EXCP_HALTED; |
| 275 | } | 275 | } |
monitor.c
| @@ -257,7 +257,7 @@ static void do_info_cpus(void) | @@ -257,7 +257,7 @@ static void do_info_cpus(void) | ||
| 257 | term_printf(" (halted)"); | 257 | term_printf(" (halted)"); |
| 258 | #elif defined(TARGET_PPC) | 258 | #elif defined(TARGET_PPC) |
| 259 | term_printf(" nip=0x" TARGET_FMT_lx, env->nip); | 259 | term_printf(" nip=0x" TARGET_FMT_lx, env->nip); |
| 260 | - if (msr_pow) | 260 | + if (env->halted) |
| 261 | term_printf(" (halted)"); | 261 | term_printf(" (halted)"); |
| 262 | #endif | 262 | #endif |
| 263 | term_printf("\n"); | 263 | term_printf("\n"); |
target-ppc/cpu.h
| @@ -495,6 +495,8 @@ struct CPUPPCState { | @@ -495,6 +495,8 @@ struct CPUPPCState { | ||
| 495 | 495 | ||
| 496 | CPU_COMMON | 496 | CPU_COMMON |
| 497 | 497 | ||
| 498 | + int halted; /* TRUE if the CPU is in suspend state */ | ||
| 499 | + | ||
| 498 | int access_type; /* when a memory exception occurs, the access | 500 | int access_type; /* when a memory exception occurs, the access |
| 499 | type is stored here */ | 501 | type is stored here */ |
| 500 | 502 |
target-ppc/helper.c
| @@ -807,6 +807,8 @@ void do_compute_hflags (CPUPPCState *env) | @@ -807,6 +807,8 @@ void do_compute_hflags (CPUPPCState *env) | ||
| 807 | 807 | ||
| 808 | void do_store_msr (CPUPPCState *env, target_ulong value) | 808 | void do_store_msr (CPUPPCState *env, target_ulong value) |
| 809 | { | 809 | { |
| 810 | + int enter_pm; | ||
| 811 | + | ||
| 810 | value &= env->msr_mask; | 812 | value &= env->msr_mask; |
| 811 | if (((value >> MSR_IR) & 1) != msr_ir || | 813 | if (((value >> MSR_IR) & 1) != msr_ir || |
| 812 | ((value >> MSR_DR) & 1) != msr_dr) { | 814 | ((value >> MSR_DR) & 1) != msr_dr) { |
| @@ -846,8 +848,19 @@ void do_store_msr (CPUPPCState *env, target_ulong value) | @@ -846,8 +848,19 @@ void do_store_msr (CPUPPCState *env, target_ulong value) | ||
| 846 | msr_ri = (value >> MSR_RI) & 1; | 848 | msr_ri = (value >> MSR_RI) & 1; |
| 847 | msr_le = (value >> MSR_LE) & 1; | 849 | msr_le = (value >> MSR_LE) & 1; |
| 848 | do_compute_hflags(env); | 850 | do_compute_hflags(env); |
| 849 | - if (msr_pow) { | 851 | + |
| 852 | + enter_pm = 0; | ||
| 853 | + switch (PPC_EXCP(env)) { | ||
| 854 | + case PPC_FLAGS_EXCP_7x0: | ||
| 855 | + if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0) | ||
| 856 | + enter_pm = 1; | ||
| 857 | + break; | ||
| 858 | + default: | ||
| 859 | + break; | ||
| 860 | + } | ||
| 861 | + if (enter_pm) { | ||
| 850 | /* power save: exit cpu loop */ | 862 | /* power save: exit cpu loop */ |
| 863 | + env->halted = 1; | ||
| 851 | env->exception_index = EXCP_HLT; | 864 | env->exception_index = EXCP_HLT; |
| 852 | cpu_loop_exit(); | 865 | cpu_loop_exit(); |
| 853 | } | 866 | } |