diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-03-07 23:44:46 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-03-07 23:44:46 +0000 |
commit | cb57bf863a4bf0aca4d1807da648ff28e0d0daae (patch) | |
tree | b58be97b40d7c2f7a756d6e358e3eae801c62af5 /firmware/thread.c | |
parent | 2ccdc48ee943f1506809e94df990873cb937bd1a (diff) | |
download | rockbox-cb57bf863a4bf0aca4d1807da648ff28e0d0daae.tar.gz rockbox-cb57bf863a4bf0aca4d1807da648ff28e0d0daae.zip |
Fix the PP5002 crash bug affecting iPod 1st, 2nd and 3rd Gen. Yet another of those PP5002 quirks...
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16547 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/thread.c')
-rw-r--r-- | firmware/thread.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/firmware/thread.c b/firmware/thread.c index b144e97403..d348f7439d 100644 --- a/firmware/thread.c +++ b/firmware/thread.c | |||
@@ -466,11 +466,19 @@ static inline void core_sleep(unsigned int core) | |||
466 | "strb r0, [%[sem], #2] \n" | 466 | "strb r0, [%[sem], #2] \n" |
467 | "ldrb r0, [%[sem], #1] \n" /* && stay_awake == 0? */ | 467 | "ldrb r0, [%[sem], #1] \n" /* && stay_awake == 0? */ |
468 | "cmp r0, #0 \n" | 468 | "cmp r0, #0 \n" |
469 | "moveq r0, #0xca \n" /* Then sleep */ | 469 | "bne 2f \n" |
470 | "streqb r0, [%[ctl], %[c], lsl #2] \n" | 470 | /* Sleep: PP5002 crashes if the instruction that puts it to sleep is |
471 | * located at 0xNNNNNNN0. 4/8/C works. This sequence makes sure | ||
472 | * that the correct alternative is executed. Don't change the order | ||
473 | * of the next 4 instructions! */ | ||
474 | "tst pc, #0x0c \n" | ||
475 | "mov r0, #0xca \n" | ||
476 | "strne r0, [%[ctl], %[c], lsl #2] \n" | ||
477 | "streq r0, [%[ctl], %[c], lsl #2] \n" | ||
471 | "nop \n" /* nop's needed because of pipeline */ | 478 | "nop \n" /* nop's needed because of pipeline */ |
472 | "nop \n" | 479 | "nop \n" |
473 | "nop \n" | 480 | "nop \n" |
481 | "2: \n" | ||
474 | "mov r0, #0 \n" /* Clear stay_awake and sleep intent */ | 482 | "mov r0, #0 \n" /* Clear stay_awake and sleep intent */ |
475 | "strb r0, [%[sem], #1] \n" | 483 | "strb r0, [%[sem], #1] \n" |
476 | "strb r0, [%[sem], #2] \n" | 484 | "strb r0, [%[sem], #2] \n" |
@@ -593,7 +601,7 @@ void core_wake(unsigned int othercore) | |||
593 | "tst r1, r2, lsr %[oc] \n" | 601 | "tst r1, r2, lsr %[oc] \n" |
594 | "ldrne r2, =0xcf004054 \n" /* If sleeping, wake it */ | 602 | "ldrne r2, =0xcf004054 \n" /* If sleeping, wake it */ |
595 | "movne r1, #0xce \n" | 603 | "movne r1, #0xce \n" |
596 | "strneb r1, [r2, %[oc], lsl #2] \n" | 604 | "strne r1, [r2, %[oc], lsl #2] \n" |
597 | "mov r1, #0 \n" /* Done with wake procedure */ | 605 | "mov r1, #0 \n" /* Done with wake procedure */ |
598 | "strb r1, [%[sem], #0] \n" | 606 | "strb r1, [%[sem], #0] \n" |
599 | "msr cpsr_c, r3 \n" /* Restore int status */ | 607 | "msr cpsr_c, r3 \n" /* Restore int status */ |