From 8d4d84ee71048638fd101ed27ba37b038ddf4651 Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Sat, 17 Mar 2007 22:13:29 +0100 Subject: [PATCH] PXA-specific ARM hacks. --- cpu-all.h | 3 ++- cpu-exec.c | 20 +++++++++++--------- hw/pxa2xx.c | 3 ++- target-arm/translate.c | 11 ++++++++--- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 9b617fc..177bcba 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -763,7 +763,8 @@ void cpu_dump_statistics (CPUState *env, FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...), int flags); -void cpu_abort(CPUState *env, const char *fmt, ...); +void cpu_abort(CPUState *env, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); extern CPUState *first_cpu; extern CPUState *cpu_single_env; extern int code_copy_enabled; diff --git a/cpu-exec.c b/cpu-exec.c index 48c2a93..10e2f2b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -275,9 +275,10 @@ int cpu_exec(CPUState *env1) #elif defined(TARGET_ARM) if (env1->halted) { /* An interrupt wakes the CPU even if the I and F CPSR bits are - set. */ - if (env1->interrupt_request - & (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD)) { + set. We use EXITTB to silently wake CPU without causing an + actual interrupt. */ + if (env1->interrupt_request & + (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB)) { env1->halted = 0; } else { return EXCP_HALTED; @@ -414,6 +415,12 @@ int cpu_exec(CPUState *env1) env->exception_index = EXCP_DEBUG; cpu_loop_exit(); } + if (interrupt_request & CPU_INTERRUPT_HALT) { + env->interrupt_request &= ~CPU_INTERRUPT_HALT; + env->halted = 1; + env->exception_index = EXCP_HLT; + cpu_loop_exit(); + } #if defined(TARGET_I386) if ((interrupt_request & CPU_INTERRUPT_SMI) && !(env->hflags & HF_SMM_MASK)) { @@ -511,12 +518,7 @@ int cpu_exec(CPUState *env1) } else if (interrupt_request & CPU_INTERRUPT_TIMER) { //do_interrupt(0, 0, 0, 0, 0); env->interrupt_request &= ~CPU_INTERRUPT_TIMER; - } else if (interrupt_request & CPU_INTERRUPT_HALT) { - env->interrupt_request &= ~CPU_INTERRUPT_HALT; - env->halted = 1; - env->exception_index = EXCP_HLT; - cpu_loop_exit(); - } + } #elif defined(TARGET_ARM) if (interrupt_request & CPU_INTERRUPT_FIQ && !(env->uncached_cpsr & CPSR_F)) { diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c index c8c6eb4..2d2d72a 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -259,7 +259,8 @@ static void pxa2xx_clkpwr_write(void *opaque, int op2, int reg, int crm, goto message; case 3: - cpu_reset(s->env); + s->env->uncached_cpsr = + ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; s->env->cp15.c1_sys = 0; s->env->cp15.c1_coproc = 0; s->env->cp15.c2 = 0; diff --git a/target-arm/translate.c b/target-arm/translate.c index cd1c04d..3e8367a 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -1579,7 +1579,7 @@ static int disas_cp_insn(DisasContext *s, uint32_t insn) /* Disassemble system coprocessor (cp15) instruction. Return nonzero if instruction is not defined. */ -static int disas_cp15_insn(DisasContext *s, uint32_t insn) +static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn) { uint32_t rd; @@ -1605,8 +1605,13 @@ static int disas_cp15_insn(DisasContext *s, uint32_t insn) } else { gen_movl_T0_reg(s, rd); gen_op_movl_cp15_T0(insn); + /* Normally we would always end the TB here, but Linux + * arch/arm/mach-pxa/sleep.S expects two instructions following + * an MMU enable to execute from cache. Imitate this behaviour. */ + if (!arm_feature(env, ARM_FEATURE_XSCALE) || + (insn & 0x0fff0fff) != 0x0e010f10) + gen_lookup_tb(s); } - gen_lookup_tb(s); return 0; } @@ -2907,7 +2912,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) goto illegal_op; break; case 15: - if (disas_cp15_insn (s, insn)) + if (disas_cp15_insn (env, s, insn)) goto illegal_op; break; default: -- 1.4.4.3