summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/thread.c83
1 files changed, 76 insertions, 7 deletions
diff --git a/firmware/thread.c b/firmware/thread.c
index ea8d650f15..537a1f0700 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -37,8 +37,19 @@ struct regs
37 void *sp; /* Stack pointer (r15) */ 37 void *sp; /* Stack pointer (r15) */
38 void* pr; /* Procedure register */ 38 void* pr; /* Procedure register */
39}; 39};
40
41#elif CONFIG_CPU == TCC730
42struct regs
43{
44 void *sp; /* Stack pointer (a15) */
45 void *start; /* Thread start address */
46 int started; /* 0 when not started */
47};
40#endif 48#endif
41 49
50#define DEADBEEF ((int)0xdeadbeef)
51
52
42int num_threads; 53int num_threads;
43static volatile int num_sleepers; 54static volatile int num_sleepers;
44static int current_thread; 55static int current_thread;
@@ -109,6 +120,51 @@ static inline void load_context(const void* addr)
109 "lds %0,pr\n\t" 120 "lds %0,pr\n\t"
110 "mov.l %0, @(0, r15)" : "+r" (addr)); 121 "mov.l %0, @(0, r15)" : "+r" (addr));
111} 122}
123#elif CONFIG_CPU == TCC730
124/*---------------------------------------------------------------------------
125 * Store non-volatile context.
126 *---------------------------------------------------------------------------
127 */
128#define store_context(addr) \
129 __asm__ volatile ( \
130 "push r0,r1\n\t" \
131 "push r2,r3\n\t" \
132 "push r4,r5\n\t" \
133 "push r6,r7\n\t" \
134 "push a8,a9\n\t" \
135 "push a10,a11\n\t" \
136 "push a12,a13\n\t" \
137 "push a14\n\t" \
138 "ldw @[%0+0], a15\n\t" : : "a" (addr) );
139
140/*---------------------------------------------------------------------------
141 * Load non-volatile context.
142 *---------------------------------------------------------------------------
143 */
144#define load_context(addr) \
145 { \
146 if (!(addr)->started) { \
147 (addr)->started = 1; \
148 __asm__ volatile ( \
149 "ldw a15, @[%0+0]\n\t" \
150 "ldw a14, @[%0+4]\n\t" \
151 "jmp a14\n\t" : : "a" (addr) \
152 ); \
153 } else \
154 __asm__ volatile ( \
155 "ldw a15, @[%0+0]\n\t" \
156 "pop a14\n\t" \
157 "pop a13,a12\n\t" \
158 "pop a11,a10\n\t" \
159 "pop a9,a8\n\t" \
160 "pop r7,r6\n\t" \
161 "pop r5,r4\n\t" \
162 "pop r3,r2\n\t" \
163 "pop r1,r0\n\t" : : "a" (addr) \
164 ); \
165 \
166 }
167
112#endif 168#endif
113 169
114/*--------------------------------------------------------------------------- 170/*---------------------------------------------------------------------------
@@ -130,6 +186,10 @@ void switch_thread(void)
130 /* Enter sleep mode, woken up on interrupt */ 186 /* Enter sleep mode, woken up on interrupt */
131#if CONFIG_CPU == MCF5249 187#if CONFIG_CPU == MCF5249
132 asm volatile ("stop #0x2000"); 188 asm volatile ("stop #0x2000");
189#elif CONFIG_CPU == TCC730
190 /* No sleep instr on the CalmRisc. (?)
191 * TODO: investigate the SYS instruction
192 */
133#else 193#else
134 SBYCR &= 0x7F; 194 SBYCR &= 0x7F;
135 asm volatile ("sleep"); 195 asm volatile ("sleep");
@@ -145,9 +205,9 @@ void switch_thread(void)
145 store_context(&thread_contexts[current]); 205 store_context(&thread_contexts[current]);
146 206
147 /* Check if the current thread stack is overflown */ 207 /* Check if the current thread stack is overflown */
148 stackptr = thread_stack[current]; 208 stackptr = thread_stack[current];
149#ifndef IRIVER_H100 209#if ! (defined(IRIVER_H100) || defined (ARCHOS_GMINI120))
150 if(stackptr[0] != 0xdeadbeef) 210 if(stackptr[0] != DEADBEEF)
151 panicf("Stkov %s", thread_name[current]); 211 panicf("Stkov %s", thread_name[current]);
152#endif 212#endif
153 213
@@ -182,11 +242,11 @@ int create_thread(void* function, void* stack, int stack_size,
182 return -1; 242 return -1;
183 243
184 /* Munge the stack to make it easy to spot stack overflows */ 244 /* Munge the stack to make it easy to spot stack overflows */
185 stacklen = stack_size / 4; 245 stacklen = stack_size / sizeof(int);
186 stackptr = stack; 246 stackptr = stack;
187 for(i = 0;i < stacklen;i++) 247 for(i = 0;i < stacklen;i++)
188 { 248 {
189 stackptr[i] = 0xdeadbeef; 249 stackptr[i] = DEADBEEF;
190 } 250 }
191 251
192 /* Store interesting information */ 252 /* Store interesting information */
@@ -194,16 +254,22 @@ int create_thread(void* function, void* stack, int stack_size,
194 thread_stack[num_threads] = stack; 254 thread_stack[num_threads] = stack;
195 thread_stack_size[num_threads] = stack_size; 255 thread_stack_size[num_threads] = stack_size;
196 regs = &thread_contexts[num_threads]; 256 regs = &thread_contexts[num_threads];
197 store_context(regs);
198#if CONFIG_CPU == MCF5249 257#if CONFIG_CPU == MCF5249
258 store_context(regs);
199 regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3); 259 regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3);
200 /* Put the return address on the stack */ 260 /* Put the return address on the stack */
201 *(unsigned long *)(regs->sp) = (int)function; 261 *(unsigned long *)(regs->sp) = (int)function;
202#elif CONFIG_CPU == SH7034 262#elif CONFIG_CPU == SH7034
263 store_context(regs);
203 /* Subtract 4 to leave room for the PR push in load_context() 264 /* Subtract 4 to leave room for the PR push in load_context()
204 Align it on an even 32 bit boundary */ 265 Align it on an even 32 bit boundary */
205 regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3); 266 regs->sp = (void*)(((unsigned int)stack + stack_size - 4) & ~3);
206 regs->pr = function; 267 regs->pr = function;
268#elif CONFIG_CPU == TCC730
269 /* Align stack on word boundary */
270 regs->sp = (void*)(((unsigned int)stack + stack_size - 2) & ~1);
271 regs->start = (void*)function;
272 regs->started = 0;
207#endif 273#endif
208 274
209 wake_up_thread(); 275 wake_up_thread();
@@ -244,6 +310,9 @@ void init_threads(void)
244 thread_name[0] = main_thread_name; 310 thread_name[0] = main_thread_name;
245 thread_stack[0] = stackbegin; 311 thread_stack[0] = stackbegin;
246 thread_stack_size[0] = (int)stackend - (int)stackbegin; 312 thread_stack_size[0] = (int)stackend - (int)stackbegin;
313#if CONFIG_CPU == TCC730
314 thread_contexts[0].started = 1;
315#endif
247 num_sleepers = 0; 316 num_sleepers = 0;
248} 317}
249 318
@@ -257,7 +326,7 @@ int thread_stack_usage(int threadnum)
257 326
258 for(i = 0;i < thread_stack_size[threadnum]/sizeof(int);i++) 327 for(i = 0;i < thread_stack_size[threadnum]/sizeof(int);i++)
259 { 328 {
260 if(stackptr[i] != 0xdeadbeef) 329 if(stackptr[i] != DEADBEEF)
261 break; 330 break;
262 } 331 }
263 332