diff options
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 */ |