diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-04-20 17:53:05 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-04-20 17:53:05 +0000 |
commit | cea07eb2a4ddb72d084c7085192521613004a997 (patch) | |
tree | adbcaeac857c7fd10fa5f89f7acff0728f75f447 /firmware/thread.c | |
parent | 02bfba6c616a4e4aedf0e36d742598c36334e228 (diff) | |
download | rockbox-cea07eb2a4ddb72d084c7085192521613004a997.tar.gz rockbox-cea07eb2a4ddb72d084c7085192521613004a997.zip |
Fix freezing of some builds on PP5002. The PP5002 needs the not-sleep-at 0xNNNNNNN0-addresses fix everywhere when caching is enabled, not only in core_sleep(). Introduced a pair of inline functions to sleep and wake cores on PP for consistency.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17192 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/thread.c')
-rw-r--r-- | firmware/thread.c | 40 |
1 files changed, 11 insertions, 29 deletions
diff --git a/firmware/thread.c b/firmware/thread.c index a25a191b80..7ece27f4a6 100644 --- a/firmware/thread.c +++ b/firmware/thread.c | |||
@@ -404,8 +404,7 @@ void corelock_unlock(struct corelock *cl) | |||
404 | #if NUM_CORES == 1 | 404 | #if NUM_CORES == 1 |
405 | static inline void core_sleep(void) | 405 | static inline void core_sleep(void) |
406 | { | 406 | { |
407 | PROC_CTL(CURRENT_CORE) = PROC_SLEEP; | 407 | sleep_core(CURRENT_CORE); |
408 | nop; nop; nop; | ||
409 | enable_irq(); | 408 | enable_irq(); |
410 | } | 409 | } |
411 | #else | 410 | #else |
@@ -429,7 +428,7 @@ static inline void core_sleep(unsigned int core) | |||
429 | "tst r1, r0, lsr #2 \n" | 428 | "tst r1, r0, lsr #2 \n" |
430 | "bne 1b \n" | 429 | "bne 1b \n" |
431 | : | 430 | : |
432 | : [ctl]"r"(&PROC_CTL(CPU)), [mbx]"r"(MBX_BASE), [c]"r"(core) | 431 | : [ctl]"r"(&CPU_CTL), [mbx]"r"(MBX_BASE), [c]"r"(core) |
433 | : "r0", "r1"); | 432 | : "r0", "r1"); |
434 | #else /* C version for reference */ | 433 | #else /* C version for reference */ |
435 | /* Signal intent to sleep */ | 434 | /* Signal intent to sleep */ |
@@ -438,8 +437,8 @@ static inline void core_sleep(unsigned int core) | |||
438 | /* Something waking or other processor intends to wake us? */ | 437 | /* Something waking or other processor intends to wake us? */ |
439 | if ((MBX_MSG_STAT & (0x10 << core)) == 0) | 438 | if ((MBX_MSG_STAT & (0x10 << core)) == 0) |
440 | { | 439 | { |
441 | PROC_CTL(core) = PROC_SLEEP; nop; /* Snooze */ | 440 | sleep_core(core); |
442 | PROC_CTL(core) = 0; /* Clear control reg */ | 441 | wake_core(core); |
443 | } | 442 | } |
444 | 443 | ||
445 | /* Signal wake - clear wake flag */ | 444 | /* Signal wake - clear wake flag */ |
@@ -455,22 +454,7 @@ static inline void core_sleep(unsigned int core) | |||
455 | #if NUM_CORES == 1 | 454 | #if NUM_CORES == 1 |
456 | static inline void core_sleep(void) | 455 | static inline void core_sleep(void) |
457 | { | 456 | { |
458 | asm volatile ( | 457 | sleep_core(CURRENT_CORE); |
459 | /* Sleep: PP5002 crashes if the instruction that puts it to sleep is | ||
460 | * located at 0xNNNNNNN0. 4/8/C works. This sequence makes sure | ||
461 | * that the correct alternative is executed. Don't change the order | ||
462 | * of the next 4 instructions! */ | ||
463 | "tst pc, #0x0c \n" | ||
464 | "mov r0, #0xca \n" | ||
465 | "strne r0, [%[ctl]] \n" | ||
466 | "streq r0, [%[ctl]] \n" | ||
467 | "nop \n" /* nop's needed because of pipeline */ | ||
468 | "nop \n" | ||
469 | "nop \n" | ||
470 | : | ||
471 | : [ctl]"r"(&PROC_CTL(CURRENT_CORE)) | ||
472 | : "r0" | ||
473 | ); | ||
474 | enable_irq(); | 458 | enable_irq(); |
475 | } | 459 | } |
476 | #else | 460 | #else |
@@ -505,7 +489,7 @@ static inline void core_sleep(unsigned int core) | |||
505 | "bne 1b \n" | 489 | "bne 1b \n" |
506 | : | 490 | : |
507 | : [sem]"r"(&core_semaphores[core]), [c]"r"(core), | 491 | : [sem]"r"(&core_semaphores[core]), [c]"r"(core), |
508 | [ctl]"r"(&PROC_CTL(CPU)) | 492 | [ctl]"r"(&CPU_CTL) |
509 | : "r0" | 493 | : "r0" |
510 | ); | 494 | ); |
511 | #else /* C version for reference */ | 495 | #else /* C version for reference */ |
@@ -515,8 +499,7 @@ static inline void core_sleep(unsigned int core) | |||
515 | /* Something waking or other processor intends to wake us? */ | 499 | /* Something waking or other processor intends to wake us? */ |
516 | if (core_semaphores[core].stay_awake == 0) | 500 | if (core_semaphores[core].stay_awake == 0) |
517 | { | 501 | { |
518 | PROC_CTL(core) = PROC_SLEEP; /* Snooze */ | 502 | sleep_core(core); |
519 | nop; nop; nop; | ||
520 | } | 503 | } |
521 | 504 | ||
522 | /* Signal wake - clear wake flag */ | 505 | /* Signal wake - clear wake flag */ |
@@ -640,7 +623,7 @@ void core_wake(unsigned int othercore) | |||
640 | 623 | ||
641 | /* If sleeping, wake it up */ | 624 | /* If sleeping, wake it up */ |
642 | if (PROC_STAT & PROC_SLEEPING(othercore)) | 625 | if (PROC_STAT & PROC_SLEEPING(othercore)) |
643 | PROC_CTL(othercore) = PROC_WAKE; | 626 | wake_core(othercore); |
644 | 627 | ||
645 | /* Done with wake procedure */ | 628 | /* Done with wake procedure */ |
646 | core_semaphores[othercore].intend_wake = 0; | 629 | core_semaphores[othercore].intend_wake = 0; |
@@ -747,15 +730,14 @@ static void core_thread_init(unsigned int core) | |||
747 | #ifdef CPU_PP502x | 730 | #ifdef CPU_PP502x |
748 | MBX_MSG_CLR = 0x3f; | 731 | MBX_MSG_CLR = 0x3f; |
749 | #endif | 732 | #endif |
750 | COP_CTL = PROC_WAKE; | 733 | wake_core(COP); |
751 | /* Sleep until COP has finished */ | 734 | /* Sleep until COP has finished */ |
752 | CPU_CTL = PROC_SLEEP; | 735 | sleep_core(CPU); |
753 | nop; nop; nop; | ||
754 | } | 736 | } |
755 | else | 737 | else |
756 | { | 738 | { |
757 | /* Wake the CPU and return */ | 739 | /* Wake the CPU and return */ |
758 | CPU_CTL = PROC_WAKE; | 740 | wake_core(CPU); |
759 | } | 741 | } |
760 | } | 742 | } |
761 | #endif /* NUM_CORES */ | 743 | #endif /* NUM_CORES */ |