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 */
#endif
while(1) {
COP_CTL = PROC_SLEEP;
sleep_core(COP);
}
}
#endif /* CPU_PP */

View file

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

View file

@ -88,6 +88,60 @@ static inline unsigned int processor_id(void)
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
/* All addresses within rockbox are in IRAM in the bootloader so
are therefore uncached */

View file

@ -404,8 +404,7 @@ void corelock_unlock(struct corelock *cl)
#if NUM_CORES == 1
static inline void core_sleep(void)
{
PROC_CTL(CURRENT_CORE) = PROC_SLEEP;
nop; nop; nop;
sleep_core(CURRENT_CORE);
enable_irq();
}
#else
@ -429,7 +428,7 @@ static inline void core_sleep(unsigned int core)
"tst r1, r0, lsr #2 \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");
#else /* C version for reference */
/* 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? */
if ((MBX_MSG_STAT & (0x10 << core)) == 0)
{
PROC_CTL(core) = PROC_SLEEP; nop; /* Snooze */
PROC_CTL(core) = 0; /* Clear control reg */
sleep_core(core);
wake_core(core);
}
/* Signal wake - clear wake flag */
@ -455,22 +454,7 @@ static inline void core_sleep(unsigned int core)
#if NUM_CORES == 1
static inline void core_sleep(void)
{
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(CURRENT_CORE))
: "r0"
);
sleep_core(CURRENT_CORE);
enable_irq();
}
#else
@ -505,7 +489,7 @@ static inline void core_sleep(unsigned int core)
"bne 1b \n"
:
: [sem]"r"(&core_semaphores[core]), [c]"r"(core),
[ctl]"r"(&PROC_CTL(CPU))
[ctl]"r"(&CPU_CTL)
: "r0"
);
#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? */
if (core_semaphores[core].stay_awake == 0)
{
PROC_CTL(core) = PROC_SLEEP; /* Snooze */
nop; nop; nop;
sleep_core(core);
}
/* Signal wake - clear wake flag */
@ -640,7 +623,7 @@ void core_wake(unsigned int othercore)
/* If sleeping, wake it up */
if (PROC_STAT & PROC_SLEEPING(othercore))
PROC_CTL(othercore) = PROC_WAKE;
wake_core(othercore);
/* Done with wake procedure */
core_semaphores[othercore].intend_wake = 0;
@ -747,15 +730,14 @@ static void core_thread_init(unsigned int core)
#ifdef CPU_PP502x
MBX_MSG_CLR = 0x3f;
#endif
COP_CTL = PROC_WAKE;
wake_core(COP);
/* Sleep until COP has finished */
CPU_CTL = PROC_SLEEP;
nop; nop; nop;
sleep_core(CPU);
}
else
{
/* Wake the CPU and return */
CPU_CTL = PROC_WAKE;
wake_core(CPU);
}
}
#endif /* NUM_CORES */