summaryrefslogtreecommitdiff
path: root/firmware/kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/kernel.c')
-rw-r--r--firmware/kernel.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 75c6604682..313530ffba 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -26,7 +26,7 @@
26#include "panic.h" 26#include "panic.h"
27 27
28#if !defined(CPU_PP) || !defined(BOOTLOADER) 28#if !defined(CPU_PP) || !defined(BOOTLOADER)
29long current_tick = 0; 29long current_tick NOCACHEDATA_ATTR = 0;
30#endif 30#endif
31 31
32static void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 32static void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
@@ -45,10 +45,13 @@ void kernel_init(void)
45 /* Init the threading API */ 45 /* Init the threading API */
46 init_threads(); 46 init_threads();
47 47
48 memset(tick_funcs, 0, sizeof(tick_funcs)); 48 if(CURRENT_CORE == CPU)
49 {
50 memset(tick_funcs, 0, sizeof(tick_funcs));
49 51
50 num_queues = 0; 52 num_queues = 0;
51 memset(all_queues, 0, sizeof(all_queues)); 53 memset(all_queues, 0, sizeof(all_queues));
54 }
52 55
53 tick_start(1000/HZ); 56 tick_start(1000/HZ);
54} 57}
@@ -496,28 +499,36 @@ void TIMER1(void)
496 int i; 499 int i;
497 500
498 TIMER1_VAL; /* Read value to ack IRQ */ 501 TIMER1_VAL; /* Read value to ack IRQ */
499 /* Run through the list of tick tasks */ 502 /* Run through the list of tick tasks (using main core) */
500 for (i = 0;i < MAX_NUM_TICK_TASKS;i++) 503 if (CURRENT_CORE == CPU)
501 { 504 {
502 if (tick_funcs[i]) 505 for (i = 0;i < MAX_NUM_TICK_TASKS;i++)
503 { 506 {
504 tick_funcs[i](); 507 if (tick_funcs[i])
508 {
509 tick_funcs[i]();
510 }
505 } 511 }
506 }
507 512
508 current_tick++; 513 current_tick++;
514 }
509} 515}
510#endif 516#endif
511 517
512void tick_start(unsigned int interval_in_ms) 518void tick_start(unsigned int interval_in_ms)
513{ 519{
514#ifndef BOOTLOADER 520#ifndef BOOTLOADER
515 TIMER1_CFG = 0x0; 521 if(CURRENT_CORE == CPU)
516 TIMER1_VAL; 522 {
517 /* enable timer */ 523 TIMER1_CFG = 0x0;
518 TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1); 524 TIMER1_VAL;
519 /* unmask interrupt source */ 525 /* enable timer */
520 CPU_INT_EN = TIMER1_MASK; 526 TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1);
527 /* unmask interrupt source */
528 CPU_INT_EN = TIMER1_MASK;
529 } else {
530 COP_INT_EN = TIMER1_MASK;
531 }
521#else 532#else
522 /* We don't enable interrupts in the bootloader */ 533 /* We don't enable interrupts in the bootloader */
523 (void)interval_in_ms; 534 (void)interval_in_ms;
@@ -645,6 +656,29 @@ void mutex_init(struct mutex *m)
645 m->thread = NULL; 656 m->thread = NULL;
646} 657}
647 658
659#ifdef CPU_PP
660/* PortalPlayer chips have 2 cores, therefore need atomic mutexes */
661
662static inline bool test_and_set(bool *x, bool v)
663{
664 asm volatile (
665 "swpb %0, %0, [%1]\n"
666 : "+r"(v)
667 : "r"(x)
668 );
669 return v;
670}
671
672void mutex_lock(struct mutex *m)
673{
674 if (test_and_set(&m->locked,true))
675 {
676 /* Wait until the lock is open... */
677 block_thread(&m->thread);
678 }
679}
680
681#else
648void mutex_lock(struct mutex *m) 682void mutex_lock(struct mutex *m)
649{ 683{
650 if (m->locked) 684 if (m->locked)
@@ -656,6 +690,7 @@ void mutex_lock(struct mutex *m)
656 /* ...and lock it */ 690 /* ...and lock it */
657 m->locked = true; 691 m->locked = true;
658} 692}
693#endif
659 694
660void mutex_unlock(struct mutex *m) 695void mutex_unlock(struct mutex *m)
661{ 696{