Commit a90b7318ba55b1aed71e299ec965bbd8f393b9b3

Authored by balrog
1 parent 4207117c

Implement power state changes (IDLE and SLEEP) for PXA.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2762 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
@@ -772,7 +772,8 @@ void cpu_dump_statistics (CPUState *env, FILE *f, @@ -772,7 +772,8 @@ void cpu_dump_statistics (CPUState *env, FILE *f,
772 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 772 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
773 int flags); 773 int flags);
774 774
775 -void cpu_abort(CPUState *env, const char *fmt, ...); 775 +void cpu_abort(CPUState *env, const char *fmt, ...)
  776 + __attribute__ ((__format__ (__printf__, 2, 3)));
776 extern CPUState *first_cpu; 777 extern CPUState *first_cpu;
777 extern CPUState *cpu_single_env; 778 extern CPUState *cpu_single_env;
778 extern int code_copy_enabled; 779 extern int code_copy_enabled;
cpu-exec.c
@@ -279,9 +279,10 @@ int cpu_exec(CPUState *env1) @@ -279,9 +279,10 @@ int cpu_exec(CPUState *env1)
279 #elif defined(TARGET_ARM) 279 #elif defined(TARGET_ARM)
280 if (env1->halted) { 280 if (env1->halted) {
281 /* An interrupt wakes the CPU even if the I and F CPSR bits are 281 /* An interrupt wakes the CPU even if the I and F CPSR bits are
282 - set. */  
283 - if (env1->interrupt_request  
284 - & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) { 282 + set. We use EXITTB to silently wake CPU without causing an
  283 + actual interrupt. */
  284 + if (env1->interrupt_request &
  285 + (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB)) {
285 env1->halted = 0; 286 env1->halted = 0;
286 } else { 287 } else {
287 return EXCP_HALTED; 288 return EXCP_HALTED;
@@ -432,6 +433,15 @@ int cpu_exec(CPUState *env1) @@ -432,6 +433,15 @@ int cpu_exec(CPUState *env1)
432 env->exception_index = EXCP_DEBUG; 433 env->exception_index = EXCP_DEBUG;
433 cpu_loop_exit(); 434 cpu_loop_exit();
434 } 435 }
  436 +#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
  437 + defined(TARGET_PPC) || defined(TARGET_ALPHA)
  438 + if (interrupt_request & CPU_INTERRUPT_HALT) {
  439 + env->interrupt_request &= ~CPU_INTERRUPT_HALT;
  440 + env->halted = 1;
  441 + env->exception_index = EXCP_HLT;
  442 + cpu_loop_exit();
  443 + }
  444 +#endif
435 #if defined(TARGET_I386) 445 #if defined(TARGET_I386)
436 if ((interrupt_request & CPU_INTERRUPT_SMI) && 446 if ((interrupt_request & CPU_INTERRUPT_SMI) &&
437 !(env->hflags & HF_SMM_MASK)) { 447 !(env->hflags & HF_SMM_MASK)) {
@@ -514,12 +524,7 @@ int cpu_exec(CPUState *env1) @@ -514,12 +524,7 @@ int cpu_exec(CPUState *env1)
514 } else if (interrupt_request & CPU_INTERRUPT_TIMER) { 524 } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
515 //do_interrupt(0, 0, 0, 0, 0); 525 //do_interrupt(0, 0, 0, 0, 0);
516 env->interrupt_request &= ~CPU_INTERRUPT_TIMER; 526 env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
517 - } else if (interrupt_request & CPU_INTERRUPT_HALT) {  
518 - env->interrupt_request &= ~CPU_INTERRUPT_HALT;  
519 - env->halted = 1;  
520 - env->exception_index = EXCP_HLT;  
521 - cpu_loop_exit();  
522 - } 527 + }
523 #elif defined(TARGET_ARM) 528 #elif defined(TARGET_ARM)
524 if (interrupt_request & CPU_INTERRUPT_FIQ 529 if (interrupt_request & CPU_INTERRUPT_FIQ
525 && !(env->uncached_cpsr & CPSR_F)) { 530 && !(env->uncached_cpsr & CPSR_F)) {
hw/pxa2xx.c
@@ -247,7 +247,8 @@ static void pxa2xx_clkpwr_write(void *opaque, int op2, int reg, int crm, @@ -247,7 +247,8 @@ static void pxa2xx_clkpwr_write(void *opaque, int op2, int reg, int crm,
247 goto message; 247 goto message;
248 248
249 case 3: 249 case 3:
250 - cpu_reset(s->env); 250 + s->env->uncached_cpsr =
  251 + ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
251 s->env->cp15.c1_sys = 0; 252 s->env->cp15.c1_sys = 0;
252 s->env->cp15.c1_coproc = 0; 253 s->env->cp15.c1_coproc = 0;
253 s->env->cp15.c2 = 0; 254 s->env->cp15.c2 = 0;
target-arm/translate.c
@@ -1584,7 +1584,7 @@ static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn) @@ -1584,7 +1584,7 @@ static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
1584 1584
1585 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if 1585 /* Disassemble system coprocessor (cp15) instruction. Return nonzero if
1586 instruction is not defined. */ 1586 instruction is not defined. */
1587 -static int disas_cp15_insn(DisasContext *s, uint32_t insn) 1587 +static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
1588 { 1588 {
1589 uint32_t rd; 1589 uint32_t rd;
1590 1590
@@ -1610,8 +1610,13 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn) @@ -1610,8 +1610,13 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn)
1610 } else { 1610 } else {
1611 gen_movl_T0_reg(s, rd); 1611 gen_movl_T0_reg(s, rd);
1612 gen_op_movl_cp15_T0(insn); 1612 gen_op_movl_cp15_T0(insn);
  1613 + /* Normally we would always end the TB here, but Linux
  1614 + * arch/arm/mach-pxa/sleep.S expects two instructions following
  1615 + * an MMU enable to execute from cache. Imitate this behaviour. */
  1616 + if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
  1617 + (insn & 0x0fff0fff) != 0x0e010f10)
  1618 + gen_lookup_tb(s);
1613 } 1619 }
1614 - gen_lookup_tb(s);  
1615 return 0; 1620 return 0;
1616 } 1621 }
1617 1622
@@ -2927,7 +2932,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -2927,7 +2932,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
2927 goto illegal_op; 2932 goto illegal_op;
2928 break; 2933 break;
2929 case 15: 2934 case 15:
2930 - if (disas_cp15_insn (s, insn)) 2935 + if (disas_cp15_insn (env, s, insn))
2931 goto illegal_op; 2936 goto illegal_op;
2932 break; 2937 break;
2933 default: 2938 default: