diff options
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-rw-r--r-- | firmware/thread.c | 45 |
2 files changed, 45 insertions, 1 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 10aecf3a43..82d32fb8ad 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifdef IRIVER_H100 | 1 | #ifdef IRIVER_H100 |
2 | crt0.S | 2 | crt0.S |
3 | backlight.c | 3 | backlight.c |
4 | thread.c | ||
4 | #else | 5 | #else |
5 | backlight.c | 6 | backlight.c |
6 | buffer.c | 7 | buffer.c |
diff --git a/firmware/thread.c b/firmware/thread.c index e44db5706d..ea8d650f15 100644 --- a/firmware/thread.c +++ b/firmware/thread.c | |||
@@ -16,18 +16,28 @@ | |||
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | #include "config.h" | ||
19 | #include <stdbool.h> | 20 | #include <stdbool.h> |
20 | #include "thread.h" | 21 | #include "thread.h" |
21 | #include "panic.h" | 22 | #include "panic.h" |
22 | #include "kernel.h" | 23 | #include "kernel.h" |
23 | #include "sh7034.h" | 24 | #include "cpu.h" |
24 | 25 | ||
26 | #if CONFIG_CPU == MCF5249 | ||
27 | struct regs | ||
28 | { | ||
29 | unsigned int d[6]; /* d2-d7 */ | ||
30 | unsigned int a[5]; /* a2-a6 */ | ||
31 | void *sp; /* Stack pointer (a7) */ | ||
32 | }; | ||
33 | #elif CONFIG_CPU == SH7034 | ||
25 | struct regs | 34 | struct regs |
26 | { | 35 | { |
27 | unsigned int r[7]; /* Registers r8 thru r14 */ | 36 | unsigned int r[7]; /* Registers r8 thru r14 */ |
28 | void *sp; /* Stack pointer (r15) */ | 37 | void *sp; /* Stack pointer (r15) */ |
29 | void* pr; /* Procedure register */ | 38 | void* pr; /* Procedure register */ |
30 | }; | 39 | }; |
40 | #endif | ||
31 | 41 | ||
32 | int num_threads; | 42 | int num_threads; |
33 | static volatile int num_sleepers; | 43 | static volatile int num_sleepers; |
@@ -43,6 +53,26 @@ extern int stackend[]; | |||
43 | 53 | ||
44 | void switch_thread(void) __attribute__ ((section(".icode"))); | 54 | void switch_thread(void) __attribute__ ((section(".icode"))); |
45 | 55 | ||
56 | #if CONFIG_CPU == MCF5249 | ||
57 | /*--------------------------------------------------------------------------- | ||
58 | * Store non-volatile context. | ||
59 | *--------------------------------------------------------------------------- | ||
60 | */ | ||
61 | static inline void store_context(void* addr) | ||
62 | { | ||
63 | asm volatile ("movem.l %%d2-%%d7/%%a2-%%a7,(%0)\n\t" : : "a" (addr)); | ||
64 | } | ||
65 | |||
66 | /*--------------------------------------------------------------------------- | ||
67 | * Load non-volatile context. | ||
68 | *--------------------------------------------------------------------------- | ||
69 | */ | ||
70 | static inline void load_context(const void* addr) | ||
71 | { | ||
72 | asm volatile ("movem.l (%0),%%d2-%%d7/%%a2-%%a7\n\t" : : "a" (addr)); | ||
73 | } | ||
74 | |||
75 | #elif CONFIG_CPU == SH7034 | ||
46 | /*--------------------------------------------------------------------------- | 76 | /*--------------------------------------------------------------------------- |
47 | * Store non-volatile context. | 77 | * Store non-volatile context. |
48 | *--------------------------------------------------------------------------- | 78 | *--------------------------------------------------------------------------- |
@@ -79,6 +109,7 @@ static inline void load_context(const void* addr) | |||
79 | "lds %0,pr\n\t" | 109 | "lds %0,pr\n\t" |
80 | "mov.l %0, @(0, r15)" : "+r" (addr)); | 110 | "mov.l %0, @(0, r15)" : "+r" (addr)); |
81 | } | 111 | } |
112 | #endif | ||
82 | 113 | ||
83 | /*--------------------------------------------------------------------------- | 114 | /*--------------------------------------------------------------------------- |
84 | * Switch thread in round robin fashion. | 115 | * Switch thread in round robin fashion. |
@@ -97,8 +128,12 @@ void switch_thread(void) | |||
97 | while (num_sleepers == num_threads) | 128 | while (num_sleepers == num_threads) |
98 | { | 129 | { |
99 | /* Enter sleep mode, woken up on interrupt */ | 130 | /* Enter sleep mode, woken up on interrupt */ |
131 | #if CONFIG_CPU == MCF5249 | ||
132 | asm volatile ("stop #0x2000"); | ||
133 | #else | ||
100 | SBYCR &= 0x7F; | 134 | SBYCR &= 0x7F; |
101 | asm volatile ("sleep"); | 135 | asm volatile ("sleep"); |
136 | #endif | ||
102 | } | 137 | } |
103 | 138 | ||
104 | #endif | 139 | #endif |
@@ -111,8 +146,10 @@ void switch_thread(void) | |||
111 | 146 | ||
112 | /* Check if the current thread stack is overflown */ | 147 | /* Check if the current thread stack is overflown */ |
113 | stackptr = thread_stack[current]; | 148 | stackptr = thread_stack[current]; |
149 | #ifndef IRIVER_H100 | ||
114 | if(stackptr[0] != 0xdeadbeef) | 150 | if(stackptr[0] != 0xdeadbeef) |
115 | panicf("Stkov %s", thread_name[current]); | 151 | panicf("Stkov %s", thread_name[current]); |
152 | #endif | ||
116 | 153 | ||
117 | load_context(&thread_contexts[next]); | 154 | load_context(&thread_contexts[next]); |
118 | } | 155 | } |
@@ -158,10 +195,16 @@ int create_thread(void* function, void* stack, int stack_size, | |||
158 | thread_stack_size[num_threads] = stack_size; | 195 | thread_stack_size[num_threads] = stack_size; |
159 | regs = &thread_contexts[num_threads]; | 196 | regs = &thread_contexts[num_threads]; |
160 | store_context(regs); | 197 | store_context(regs); |
198 | #if CONFIG_CPU == MCF5249 | ||
199 | regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3); | ||
200 | /* Put the return address on the stack */ | ||
201 | *(unsigned long *)(regs->sp) = (int)function; | ||
202 | #elif CONFIG_CPU == SH7034 | ||
161 | /* Subtract 4 to leave room for the PR push in load_context() | 203 | /* Subtract 4 to leave room for the PR push in load_context() |
162 | Align it on an even 32 bit boundary */ | 204 | Align it on an even 32 bit boundary */ |
163 | regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3); | 205 | regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3); |
164 | regs->pr = function; | 206 | regs->pr = function; |
207 | #endif | ||
165 | 208 | ||
166 | wake_up_thread(); | 209 | wake_up_thread(); |
167 | return num_threads++; /* return the current ID, e.g for remove_thread() */ | 210 | return num_threads++; /* return the current ID, e.g for remove_thread() */ |