summaryrefslogtreecommitdiff
path: root/firmware/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/thread.c')
-rw-r--r--firmware/thread.c137
1 files changed, 49 insertions, 88 deletions
diff --git a/firmware/thread.c b/firmware/thread.c
index 8f89d1c71d..eb39c7ad32 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -24,51 +24,12 @@
24#include "kernel.h" 24#include "kernel.h"
25#include "cpu.h" 25#include "cpu.h"
26 26
27#ifdef CPU_COLDFIRE
28struct regs
29{
30 unsigned int macsr; /* EMAC status register */
31 unsigned int d[6]; /* d2-d7 */
32 unsigned int a[5]; /* a2-a6 */
33 void *sp; /* Stack pointer (a7) */
34 void *start; /* Thread start address, or NULL when started */
35};
36#elif CONFIG_CPU == SH7034
37struct regs
38{
39 unsigned int r[7]; /* Registers r8 thru r14 */
40 void *sp; /* Stack pointer (r15) */
41 void *pr; /* Procedure register */
42 void *start; /* Thread start address, or NULL when started */
43};
44#elif defined(CPU_ARM)
45struct regs
46{
47 unsigned int r[8]; /* Registers r4-r11 */
48 void *sp; /* Stack pointer (r13) */
49 unsigned int lr; /* r14 (lr) */
50 void *start; /* Thread start address, or NULL when started */
51};
52#elif CONFIG_CPU == TCC730
53struct regs
54{
55 void *sp; /* Stack pointer (a15) */
56 void *start; /* Thread start address */
57 int started; /* 0 when not started */
58};
59#endif
60 27
61#define DEADBEEF ((unsigned int)0xdeadbeef) 28#define DEADBEEF ((unsigned int)0xdeadbeef)
62/* Cast to the the machine int type, whose size could be < 4. */ 29/* Cast to the the machine int type, whose size could be < 4. */
63 30
31struct core_entry cores[NUM_CORES] IBSS_ATTR;
64 32
65int num_threads[NUM_CORES];
66static volatile int num_sleepers[NUM_CORES];
67static int current_thread[NUM_CORES];
68static struct regs thread_contexts[NUM_CORES][MAXTHREADS] IBSS_ATTR;
69const char *thread_name[NUM_CORES][MAXTHREADS];
70void *thread_stack[NUM_CORES][MAXTHREADS];
71int thread_stack_size[NUM_CORES][MAXTHREADS];
72static const char main_thread_name[] = "main"; 33static const char main_thread_name[] = "main";
73 34
74extern int stackbegin[]; 35extern int stackbegin[];
@@ -94,7 +55,7 @@ static inline void load_context(const void* addr) __attribute__ ((always_inline)
94#ifdef RB_PROFILE 55#ifdef RB_PROFILE
95#include <profile.h> 56#include <profile.h>
96void profile_thread(void) { 57void profile_thread(void) {
97 profstart(current_thread[CURRENT_CORE]); 58 profstart(cores[CURRENT_CORE].current_thread);
98} 59}
99#endif 60#endif
100 61
@@ -265,7 +226,7 @@ static inline void load_context(const void* addr)
265void switch_thread(void) 226void switch_thread(void)
266{ 227{
267#ifdef RB_PROFILE 228#ifdef RB_PROFILE
268 profile_thread_stopped(current_thread[CURRENT_CORE]); 229 profile_thread_stopped(cores[CURRENT_CORE].current_thread);
269#endif 230#endif
270 int current; 231 int current;
271 unsigned int *stackptr; 232 unsigned int *stackptr;
@@ -273,7 +234,7 @@ void switch_thread(void)
273#ifdef SIMULATOR 234#ifdef SIMULATOR
274 /* Do nothing */ 235 /* Do nothing */
275#else 236#else
276 while (num_sleepers[CURRENT_CORE] == num_threads[CURRENT_CORE]) 237 while (cores[CURRENT_CORE].num_sleepers == cores[CURRENT_CORE].num_threads)
277 { 238 {
278 /* Enter sleep mode, woken up on interrupt */ 239 /* Enter sleep mode, woken up on interrupt */
279#ifdef CPU_COLDFIRE 240#ifdef CPU_COLDFIRE
@@ -297,35 +258,35 @@ void switch_thread(void)
297#endif 258#endif
298 } 259 }
299#endif 260#endif
300 current = current_thread[CURRENT_CORE]; 261 current = cores[CURRENT_CORE].current_thread;
301 store_context(&thread_contexts[CURRENT_CORE][current]); 262 store_context(&cores[CURRENT_CORE].threads[current].context);
302 263
303#if CONFIG_CPU != TCC730 264#if CONFIG_CPU != TCC730
304 /* Check if the current thread stack is overflown */ 265 /* Check if the current thread stack is overflown */
305 stackptr = thread_stack[CURRENT_CORE][current]; 266 stackptr = cores[CURRENT_CORE].threads[current].stack;
306 if(stackptr[0] != DEADBEEF) 267 if(stackptr[0] != DEADBEEF)
307 panicf("Stkov %s", thread_name[CURRENT_CORE][current]); 268 panicf("Stkov %s", cores[CURRENT_CORE].threads[current].name);
308#endif 269#endif
309 270
310 if (++current >= num_threads[CURRENT_CORE]) 271 if (++current >= cores[CURRENT_CORE].num_threads)
311 current = 0; 272 current = 0;
312 273
313 current_thread[CURRENT_CORE] = current; 274 cores[CURRENT_CORE].current_thread = current;
314 load_context(&thread_contexts[CURRENT_CORE][current]); 275 load_context(&cores[CURRENT_CORE].threads[current].context);
315#ifdef RB_PROFILE 276#ifdef RB_PROFILE
316 profile_thread_started(current_thread[CURRENT_CORE]); 277 profile_thread_started(cores[CURRENT_CORE].current_thread);
317#endif 278#endif
318} 279}
319 280
320void sleep_thread(void) 281void sleep_thread(void)
321{ 282{
322 ++num_sleepers[CURRENT_CORE]; 283 ++cores[CURRENT_CORE].num_sleepers;
323 switch_thread(); 284 switch_thread();
324} 285}
325 286
326void wake_up_thread(void) 287void wake_up_thread(void)
327{ 288{
328 num_sleepers[CURRENT_CORE] = 0; 289 cores[CURRENT_CORE].num_sleepers = 0;
329} 290}
330 291
331 292
@@ -353,8 +314,9 @@ int create_thread_on_core(unsigned int core, void (*function)(void), void* stack
353 unsigned int stacklen; 314 unsigned int stacklen;
354 unsigned int *stackptr; 315 unsigned int *stackptr;
355 struct regs *regs; 316 struct regs *regs;
317 struct thread_entry *thread;
356 318
357 if (num_threads[core] >= MAXTHREADS) 319 if (cores[core].num_threads >= MAXTHREADS)
358 return -1; 320 return -1;
359 321
360 /* Munge the stack to make it easy to spot stack overflows */ 322 /* Munge the stack to make it easy to spot stack overflows */
@@ -366,10 +328,11 @@ int create_thread_on_core(unsigned int core, void (*function)(void), void* stack
366 } 328 }
367 329
368 /* Store interesting information */ 330 /* Store interesting information */
369 thread_name[core][num_threads[core]] = name; 331 thread = &cores[core].threads[cores[core].num_threads];
370 thread_stack[core][num_threads[core]] = stack; 332 thread->name = name;
371 thread_stack_size[core][num_threads[core]] = stack_size; 333 thread->stack = stack;
372 regs = &thread_contexts[core][num_threads[core]]; 334 thread->stack_size = stack_size;
335 regs = &thread->context;
373#if defined(CPU_COLDFIRE) || (CONFIG_CPU == SH7034) || defined(CPU_ARM) 336#if defined(CPU_COLDFIRE) || (CONFIG_CPU == SH7034) || defined(CPU_ARM)
374 /* Align stack to an even 32 bit boundary */ 337 /* Align stack to an even 32 bit boundary */
375 regs->sp = (void*)(((unsigned int)stack + stack_size) & ~3); 338 regs->sp = (void*)(((unsigned int)stack + stack_size) & ~3);
@@ -381,7 +344,7 @@ int create_thread_on_core(unsigned int core, void (*function)(void), void* stack
381 regs->start = (void*)function; 344 regs->start = (void*)function;
382 345
383 wake_up_thread(); 346 wake_up_thread();
384 return num_threads[core]++; /* return the current ID, e.g for remove_thread() */ 347 return cores[core].num_threads++; /* return the current ID, e.g for remove_thread() */
385} 348}
386 349
387/*--------------------------------------------------------------------------- 350/*---------------------------------------------------------------------------
@@ -403,69 +366,67 @@ void remove_thread_on_core(unsigned int core, int threadnum)
403{ 366{
404 int i; 367 int i;
405 368
406 if(threadnum >= num_threads[core]) 369 if (threadnum >= cores[core].num_threads)
407 return; 370 return;
408 371
409 num_threads[core]--; 372 cores[core].num_threads--;
410 for (i=threadnum; i<num_threads[core]-1; i++) 373 for (i=threadnum; i<cores[core].num_threads-1; i++)
411 { /* move all entries which are behind */ 374 { /* move all entries which are behind */
412 thread_name[core][i] = thread_name[core][i+1]; 375 cores[core].threads[i] = cores[core].threads[i+1];
413 thread_stack[core][i] = thread_stack[core][i+1];
414 thread_stack_size[core][i] = thread_stack_size[core][i+1];
415 thread_contexts[core][i] = thread_contexts[core][i+1];
416 } 376 }
417 377
418 if (current_thread[core] == threadnum) /* deleting the current one? */ 378 if (cores[core].current_thread == threadnum) /* deleting the current one? */
419 current_thread[core] = num_threads[core]; /* set beyond last, avoid store harm */ 379 cores[core].current_thread = cores[core].num_threads; /* set beyond last, avoid store harm */
420 else if (current_thread[core] > threadnum) /* within the moved positions? */ 380 else if (cores[core].current_thread > threadnum) /* within the moved positions? */
421 current_thread[core]--; /* adjust it, point to same context again */ 381 cores[core].current_thread--; /* adjust it, point to same context again */
422} 382}
423 383
424void init_threads(void) 384void init_threads(void)
425{ 385{
426 unsigned int core = CURRENT_CORE; 386 unsigned int core = CURRENT_CORE;
427 387
428 num_threads[core] = 1; /* We have 1 thread to begin with */ 388 cores[core].num_threads = 1; /* We have 1 thread to begin with */
429 current_thread[core] = 0; /* The current thread is number 0 */ 389 cores[core].current_thread = 0; /* The current thread is number 0 */
430 thread_name[core][0] = main_thread_name; 390 cores[core].threads[0].name = main_thread_name;
431/* In multiple core setups, each core has a different stack. There is probably 391/* In multiple core setups, each core has a different stack. There is probably
432 a much better way to do this. */ 392 a much better way to do this. */
433 if(core == CPU) 393 if (core == CPU)
434 { 394 {
435 thread_stack[CPU][0] = stackbegin; 395 cores[CPU].threads[0].stack = stackbegin;
436 thread_stack_size[CPU][0] = (int)stackend - (int)stackbegin; 396 cores[CPU].threads[0].stack_size = (int)stackend - (int)stackbegin;
437 } else { 397 } else {
438#if NUM_CORES > 1 /* This code path will not be run on single core targets */ 398#if NUM_CORES > 1 /* This code path will not be run on single core targets */
439 thread_stack[COP][0] = cop_stackbegin; 399 cores[COP].threads[0].stack = cop_stackbegin;
440 thread_stack_size[COP][0] = (int)cop_stackend - (int)cop_stackbegin; 400 cores[COP].threads[0].stack_size = (int)cop_stackend - (int)cop_stackbegin;
441#endif 401#endif
442 } 402 }
443#if CONFIG_CPU == TCC730 403#if CONFIG_CPU == TCC730
444 thread_contexts[core][0].started = 1; 404 cores[core].threads[0].context.started = 1;
445#else 405#else
446 thread_contexts[core][0].start = 0; /* thread 0 already running */ 406 cores[core].threads[0].context.start = 0; /* thread 0 already running */
447#endif 407#endif
448 num_sleepers[core] = 0; 408 cores[core].num_sleepers = 0;
449} 409}
450 410
451int thread_stack_usage(int threadnum){ 411int thread_stack_usage(int threadnum)
412{
452 return thread_stack_usage_on_core(CURRENT_CORE, threadnum); 413 return thread_stack_usage_on_core(CURRENT_CORE, threadnum);
453} 414}
454 415
455int thread_stack_usage_on_core(unsigned int core, int threadnum) 416int thread_stack_usage_on_core(unsigned int core, int threadnum)
456{ 417{
457 unsigned int i; 418 unsigned int i;
458 unsigned int *stackptr = thread_stack[core][threadnum]; 419 unsigned int *stackptr = cores[core].threads[threadnum].stack;
459 420
460 if(threadnum >= num_threads[core]) 421 if (threadnum >= cores[core].num_threads)
461 return -1; 422 return -1;
462 423
463 for(i = 0;i < thread_stack_size[core][threadnum]/sizeof(int);i++) 424 for (i = 0;i < cores[core].threads[threadnum].stack_size/sizeof(int);i++)
464 { 425 {
465 if(stackptr[i] != DEADBEEF) 426 if (stackptr[i] != DEADBEEF)
466 break; 427 break;
467 } 428 }
468 429
469 return ((thread_stack_size[core][threadnum] - i * sizeof(int)) * 100) / 430 return ((cores[core].threads[threadnum].stack_size - i * sizeof(int)) * 100) /
470 thread_stack_size[core][threadnum]; 431 cores[core].threads[threadnum].stack_size;
471} 432}