diff options
| author | Michael Sevakis <jethead71@rockbox.org> | 2007-04-13 20:55:48 +0000 |
|---|---|---|
| committer | Michael Sevakis <jethead71@rockbox.org> | 2007-04-13 20:55:48 +0000 |
| commit | d95c39072ace1a7aeaad3ee49ed668399b4862bd (patch) | |
| tree | 7f8c8e41e5e793daa64051f153bbbd52ccbe8fc9 /firmware/thread.c | |
| parent | e10f455fbd3149a034e35d30be333f958d773d92 (diff) | |
| download | rockbox-d95c39072ace1a7aeaad3ee49ed668399b4862bd.zip rockbox-d95c39072ace1a7aeaad3ee49ed668399b4862bd.tar.gz rockbox-d95c39072ace1a7aeaad3ee49ed668399b4862bd.tar.bz2 rockbox-d95c39072ace1a7aeaad3ee49ed668399b4862bd.tar.xz | |
Portal Player: Add invalidate_icache and flush_icache. Flush the cache on the core for newborn threads. In doing so, move more ARM stuff to the target tree and organize it to make a clean job of it. If anything isn't appropriate for some particular device give a hollar or even just fix it by some added #ifdefing. I was informed that the PP targets are register compatible so I'm going off that advice. The Sansa likes it though.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13144 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/thread.c')
| -rw-r--r-- | firmware/thread.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/firmware/thread.c b/firmware/thread.c index a803e4f..275f04d 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -64,12 +64,15 @@ int *cop_stackend = stackend; #endif #if NUM_CORES > 1 +#if 0 static long cores_locked IBSS_ATTR; #define LOCK(...) do { } while (test_and_set(&cores_locked, 1)) #define UNLOCK(...) cores_locked = 0 +#endif #warning "Core locking mechanism should be fixed on H10/4G!" + inline void lock_cores(void) { #if 0 @@ -125,15 +128,47 @@ static inline void store_context(void* addr) * Load non-volatile context. *--------------------------------------------------------------------------- */ +static void start_thread(void (*thread_func)(void), const void* addr) __attribute__((naked)); +static void start_thread(void (*thread_func)(void), const void* addr) +{ + /* r0 = thread_func, r1 = addr */ +#if NUM_CORES > 1 + asm volatile ( + "mov r2, #0 \n" + "str r2, [r1, #40] \n" + "ldr r1, =0xf000f044 \n" /* invalidate this core's cache */ + "ldr r2, [r1] \n" + "orr r2, r2, #6 \n" + "str r2, [r1] \n" + "ldr r1, =0x6000c000 \n" + "1: \n" + "ldr r2, [r1] \n" + "tst r2, #0x8000 \n" + "bne 1b \n" + "mov pc, r0 \n" + : : : "r1", "r2" + ); +#else + asm volatile ( + "mov r2, #0 \n" + "str r2, [r1, #40] \n" + "mov pc, r0 \n" + : : : "r1", "r2" + ); +#endif + (void)thread_func; + (void)addr; + (void)start_thread; +} + static inline void load_context(const void* addr) { asm volatile( - "ldmia %0, { r4-r11, sp, lr }\n" /* load regs r4 to r14 from context */ - "ldr r0, [%0, #40] \n" /* load start pointer */ - "mov r1, #0 \n" - "cmp r0, r1 \n" /* check for NULL */ - "strne r1, [%0, #40] \n" /* if it's NULL, we're already running */ - "movne pc, r0 \n" /* not already running, so jump to start */ + "ldmia %0, { r4-r11, sp, lr } \n" /* load regs r4 to r14 from context */ + "ldr r0, [%0, #40] \n" /* load start pointer */ + "cmp r0, #0 \n" /* check for NULL */ + "movne r1, %0 \n" /* if not already running, jump to start */ + "ldrne pc, =start_thread \n" : : "r" (addr) : "r0", "r1" ); } |