summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-04-20 17:53:05 +0000
committerJens Arnold <amiconn@rockbox.org>2008-04-20 17:53:05 +0000
commitcea07eb2a4ddb72d084c7085192521613004a997 (patch)
treeadbcaeac857c7fd10fa5f89f7acff0728f75f447
parent02bfba6c616a4e4aedf0e36d742598c36334e228 (diff)
downloadrockbox-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
-rw-r--r--apps/main.c2
-rw-r--r--firmware/panic.c5
-rw-r--r--firmware/target/arm/system-target.h54
-rw-r--r--firmware/thread.c40
4 files changed, 67 insertions, 34 deletions
diff --git a/apps/main.c b/apps/main.c
index 47af3ab07a..8b1e2e4556 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -604,7 +604,7 @@ void cop_main(void)
604 /* This should never be reached */ 604 /* This should never be reached */
605#endif 605#endif
606 while(1) { 606 while(1) {
607 COP_CTL = PROC_SLEEP; 607 sleep_core(COP);
608 } 608 }
609} 609}
610#endif /* CPU_PP */ 610#endif /* CPU_PP */
diff --git a/firmware/panic.c b/firmware/panic.c
index 0ac458953b..c61476c423 100644
--- a/firmware/panic.c
+++ b/firmware/panic.c
@@ -101,10 +101,7 @@ void panicf( const char *fmt, ...)
101 /* try to restart firmware if ON is pressed */ 101 /* try to restart firmware if ON is pressed */
102#if defined (CPU_PP) 102#if defined (CPU_PP)
103 /* For now, just sleep the core */ 103 /* For now, just sleep the core */
104 if (CURRENT_CORE == CPU) 104 sleep_core(CURRENT_CORE);
105 CPU_CTL = PROC_SLEEP;
106 else
107 COP_CTL = PROC_SLEEP;
108 #define system_reboot() nop 105 #define system_reboot() nop
109#elif defined (TOSHIBA_GIGABEAT_F) 106#elif defined (TOSHIBA_GIGABEAT_F)
110 if ((GPGDAT & (1 << 0)) != 0) 107 if ((GPGDAT & (1 << 0)) != 0)
diff --git a/firmware/target/arm/system-target.h b/firmware/target/arm/system-target.h
index 2a72b524f7..ebfc162cf1 100644
--- a/firmware/target/arm/system-target.h
+++ b/firmware/target/arm/system-target.h
@@ -88,6 +88,60 @@ static inline unsigned int processor_id(void)
88 return id; 88 return id;
89} 89}
90 90
91#if CONFIG_CPU == PP5002
92static inline void sleep_core(int core)
93{
94 asm volatile (
95 /* Sleep: PP5002 crashes if the instruction that puts it to sleep is
96 * located at 0xNNNNNNN0. 4/8/C works. This sequence makes sure
97 * that the correct alternative is executed. Don't change the order
98 * of the next 4 instructions! */
99 "tst pc, #0x0c \n"
100 "mov r0, #0xca \n"
101 "strne r0, [%[ctl]] \n"
102 "streq r0, [%[ctl]] \n"
103 "nop \n" /* nop's needed because of pipeline */
104 "nop \n"
105 "nop \n"
106 :
107 : [ctl]"r"(&PROC_CTL(core))
108 : "r0"
109 );
110}
111static inline void wake_core(int core)
112{
113 asm volatile (
114 "mov r0, #0xce \n"
115 "str r0, [%[ctl]] \n"
116 :
117 : [ctl]"r"(&PROC_CTL(core))
118 : "r0"
119 );
120}
121#else /* PP502x */
122static inline void sleep_core(int core)
123{
124 asm volatile (
125 "mov r0, #0x80000000 \n"
126 "str r0, [%[ctl]] \n"
127 "nop \n"
128 :
129 : [ctl]"r"(&PROC_CTL(core))
130 : "r0"
131 );
132}
133static inline void wake_core(int core)
134{
135 asm volatile (
136 "mov r0, #0 \n"
137 "str r0, [%[ctl]] \n"
138 :
139 : [ctl]"r"(&PROC_CTL(core))
140 : "r0"
141 );
142}
143#endif
144
91#ifdef BOOTLOADER 145#ifdef BOOTLOADER
92/* All addresses within rockbox are in IRAM in the bootloader so 146/* All addresses within rockbox are in IRAM in the bootloader so
93 are therefore uncached */ 147 are therefore uncached */
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
405static inline void core_sleep(void) 405static 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
456static inline void core_sleep(void) 455static 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 */