1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Jens Arnold 2008-04-20 17:53:05 +00:00
parent 02bfba6c61
commit cea07eb2a4
4 changed files with 67 additions and 34 deletions

View file

@ -604,7 +604,7 @@ void cop_main(void)
/* This should never be reached */ /* This should never be reached */
#endif #endif
while(1) { while(1) {
COP_CTL = PROC_SLEEP; sleep_core(COP);
} }
} }
#endif /* CPU_PP */ #endif /* CPU_PP */

View file

@ -101,10 +101,7 @@ void panicf( const char *fmt, ...)
/* try to restart firmware if ON is pressed */ /* try to restart firmware if ON is pressed */
#if defined (CPU_PP) #if defined (CPU_PP)
/* For now, just sleep the core */ /* For now, just sleep the core */
if (CURRENT_CORE == CPU) sleep_core(CURRENT_CORE);
CPU_CTL = PROC_SLEEP;
else
COP_CTL = PROC_SLEEP;
#define system_reboot() nop #define system_reboot() nop
#elif defined (TOSHIBA_GIGABEAT_F) #elif defined (TOSHIBA_GIGABEAT_F)
if ((GPGDAT & (1 << 0)) != 0) if ((GPGDAT & (1 << 0)) != 0)

View file

@ -88,6 +88,60 @@ static inline unsigned int processor_id(void)
return id; return id;
} }
#if CONFIG_CPU == PP5002
static inline void sleep_core(int core)
{
asm volatile (
/* Sleep: PP5002 crashes if the instruction that puts it to sleep is
* located at 0xNNNNNNN0. 4/8/C works. This sequence makes sure
* that the correct alternative is executed. Don't change the order
* of the next 4 instructions! */
"tst pc, #0x0c \n"
"mov r0, #0xca \n"
"strne r0, [%[ctl]] \n"
"streq r0, [%[ctl]] \n"
"nop \n" /* nop's needed because of pipeline */
"nop \n"
"nop \n"
:
: [ctl]"r"(&PROC_CTL(core))
: "r0"
);
}
static inline void wake_core(int core)
{
asm volatile (
"mov r0, #0xce \n"
"str r0, [%[ctl]] \n"
:
: [ctl]"r"(&PROC_CTL(core))
: "r0"
);
}
#else /* PP502x */
static inline void sleep_core(int core)
{
asm volatile (
"mov r0, #0x80000000 \n"
"str r0, [%[ctl]] \n"
"nop \n"
:
: [ctl]"r"(&PROC_CTL(core))
: "r0"
);
}
static inline void wake_core(int core)
{
asm volatile (
"mov r0, #0 \n"
"str r0, [%[ctl]] \n"
:
: [ctl]"r"(&PROC_CTL(core))
: "r0"
);
}
#endif
#ifdef BOOTLOADER #ifdef BOOTLOADER
/* All addresses within rockbox are in IRAM in the bootloader so /* All addresses within rockbox are in IRAM in the bootloader so
are therefore uncached */ are therefore uncached */

View file

@ -404,8 +404,7 @@ void corelock_unlock(struct corelock *cl)
#if NUM_CORES == 1 #if NUM_CORES == 1
static inline void core_sleep(void) static inline void core_sleep(void)
{ {
PROC_CTL(CURRENT_CORE) = PROC_SLEEP; sleep_core(CURRENT_CORE);
nop; nop; nop;
enable_irq(); enable_irq();
} }
#else #else
@ -429,7 +428,7 @@ static inline void core_sleep(unsigned int core)
"tst r1, r0, lsr #2 \n" "tst r1, r0, lsr #2 \n"
"bne 1b \n" "bne 1b \n"
: :
: [ctl]"r"(&PROC_CTL(CPU)), [mbx]"r"(MBX_BASE), [c]"r"(core) : [ctl]"r"(&CPU_CTL), [mbx]"r"(MBX_BASE), [c]"r"(core)
: "r0", "r1"); : "r0", "r1");
#else /* C version for reference */ #else /* C version for reference */
/* Signal intent to sleep */ /* Signal intent to sleep */
@ -438,8 +437,8 @@ static inline void core_sleep(unsigned int core)
/* Something waking or other processor intends to wake us? */ /* Something waking or other processor intends to wake us? */
if ((MBX_MSG_STAT & (0x10 << core)) == 0) if ((MBX_MSG_STAT & (0x10 << core)) == 0)
{ {
PROC_CTL(core) = PROC_SLEEP; nop; /* Snooze */ sleep_core(core);
PROC_CTL(core) = 0; /* Clear control reg */ wake_core(core);
} }
/* Signal wake - clear wake flag */ /* Signal wake - clear wake flag */
@ -455,22 +454,7 @@ static inline void core_sleep(unsigned int core)
#if NUM_CORES == 1 #if NUM_CORES == 1
static inline void core_sleep(void) static inline void core_sleep(void)
{ {
asm volatile ( sleep_core(CURRENT_CORE);
/* Sleep: PP5002 crashes if the instruction that puts it to sleep is
* located at 0xNNNNNNN0. 4/8/C works. This sequence makes sure
* that the correct alternative is executed. Don't change the order
* of the next 4 instructions! */
"tst pc, #0x0c \n"
"mov r0, #0xca \n"
"strne r0, [%[ctl]] \n"
"streq r0, [%[ctl]] \n"
"nop \n" /* nop's needed because of pipeline */
"nop \n"
"nop \n"
:
: [ctl]"r"(&PROC_CTL(CURRENT_CORE))
: "r0"
);
enable_irq(); enable_irq();
} }
#else #else
@ -505,7 +489,7 @@ static inline void core_sleep(unsigned int core)
"bne 1b \n" "bne 1b \n"
: :
: [sem]"r"(&core_semaphores[core]), [c]"r"(core), : [sem]"r"(&core_semaphores[core]), [c]"r"(core),
[ctl]"r"(&PROC_CTL(CPU)) [ctl]"r"(&CPU_CTL)
: "r0" : "r0"
); );
#else /* C version for reference */ #else /* C version for reference */
@ -515,8 +499,7 @@ static inline void core_sleep(unsigned int core)
/* Something waking or other processor intends to wake us? */ /* Something waking or other processor intends to wake us? */
if (core_semaphores[core].stay_awake == 0) if (core_semaphores[core].stay_awake == 0)
{ {
PROC_CTL(core) = PROC_SLEEP; /* Snooze */ sleep_core(core);
nop; nop; nop;
} }
/* Signal wake - clear wake flag */ /* Signal wake - clear wake flag */
@ -640,7 +623,7 @@ void core_wake(unsigned int othercore)
/* If sleeping, wake it up */ /* If sleeping, wake it up */
if (PROC_STAT & PROC_SLEEPING(othercore)) if (PROC_STAT & PROC_SLEEPING(othercore))
PROC_CTL(othercore) = PROC_WAKE; wake_core(othercore);
/* Done with wake procedure */ /* Done with wake procedure */
core_semaphores[othercore].intend_wake = 0; core_semaphores[othercore].intend_wake = 0;
@ -747,15 +730,14 @@ static void core_thread_init(unsigned int core)
#ifdef CPU_PP502x #ifdef CPU_PP502x
MBX_MSG_CLR = 0x3f; MBX_MSG_CLR = 0x3f;
#endif #endif
COP_CTL = PROC_WAKE; wake_core(COP);
/* Sleep until COP has finished */ /* Sleep until COP has finished */
CPU_CTL = PROC_SLEEP; sleep_core(CPU);
nop; nop; nop;
} }
else else
{ {
/* Wake the CPU and return */ /* Wake the CPU and return */
CPU_CTL = PROC_WAKE; wake_core(CPU);
} }
} }
#endif /* NUM_CORES */ #endif /* NUM_CORES */