summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/kernel.h12
-rw-r--r--firmware/kernel.c72
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c12
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c14
-rw-r--r--firmware/target/arm/tcc77x/timer-tcc77x.c14
-rw-r--r--firmware/target/arm/tcc780x/timer-tcc780x.c15
-rw-r--r--firmware/target/arm/tms320dm320/kernel-dm320.c13
-rw-r--r--firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c11
8 files changed, 37 insertions, 126 deletions
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index 51eb635004..9438f6d308 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -207,6 +207,18 @@ int tick_add_task(void (*f)(void));
207int tick_remove_task(void (*f)(void)); 207int tick_remove_task(void (*f)(void));
208extern void tick_start(unsigned int interval_in_ms); 208extern void tick_start(unsigned int interval_in_ms);
209 209
210/* inline helper for implementing target interrupt handler */
211static inline void call_tick_tasks(void)
212{
213 extern void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
214 int i;
215
216 current_tick++;
217
218 for (i = 0; tick_funcs[i] != NULL; i++)
219 tick_funcs[i]();
220}
221
210struct timeout; 222struct timeout;
211 223
212/* timeout callback type 224/* timeout callback type
diff --git a/firmware/kernel.c b/firmware/kernel.c
index fb9c5e2449..70b3e03615 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -54,7 +54,9 @@
54volatile long current_tick SHAREDDATA_ATTR = 0; 54volatile long current_tick SHAREDDATA_ATTR = 0;
55#endif 55#endif
56 56
57void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 57/* List of tick tasks - final element always NULL for termination */
58void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
59static int num_tick_funcs = 0;
58 60
59extern struct core_entry cores[NUM_CORES]; 61extern struct core_entry cores[NUM_CORES];
60 62
@@ -128,18 +130,8 @@ void tick_start(unsigned int interval_in_ms)
128void IMIA0(void) __attribute__ ((interrupt_handler)); 130void IMIA0(void) __attribute__ ((interrupt_handler));
129void IMIA0(void) 131void IMIA0(void)
130{ 132{
131 int i;
132
133 /* Run through the list of tick tasks */ 133 /* Run through the list of tick tasks */
134 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 134 call_tick_tasks();
135 {
136 if(tick_funcs[i])
137 {
138 tick_funcs[i]();
139 }
140 }
141
142 current_tick++;
143 135
144 TSR0 &= ~0x01; 136 TSR0 &= ~0x01;
145} 137}
@@ -178,18 +170,8 @@ void tick_start(unsigned int interval_in_ms)
178void TIMER0(void) __attribute__ ((interrupt_handler)); 170void TIMER0(void) __attribute__ ((interrupt_handler));
179void TIMER0(void) 171void TIMER0(void)
180{ 172{
181 int i;
182
183 /* Run through the list of tick tasks */ 173 /* Run through the list of tick tasks */
184 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 174 call_tick_tasks();
185 {
186 if(tick_funcs[i])
187 {
188 tick_funcs[i]();
189 }
190 }
191
192 current_tick++;
193 175
194 TER0 = 0xff; /* Clear all events */ 176 TER0 = 0xff; /* Clear all events */
195} 177}
@@ -199,27 +181,17 @@ void TIMER0(void)
199#ifndef BOOTLOADER 181#ifndef BOOTLOADER
200void TIMER1(void) 182void TIMER1(void)
201{ 183{
202 int i;
203
204 /* Run through the list of tick tasks (using main core) */ 184 /* Run through the list of tick tasks (using main core) */
205 TIMER1_VAL; /* Read value to ack IRQ */ 185 TIMER1_VAL; /* Read value to ack IRQ */
206 186
207 /* Run through the list of tick tasks using main CPU core - 187 /* Run through the list of tick tasks using main CPU core -
208 wake up the COP through its control interface to provide pulse */ 188 wake up the COP through its control interface to provide pulse */
209 for (i = 0;i < MAX_NUM_TICK_TASKS;i++) 189 call_tick_tasks();
210 {
211 if (tick_funcs[i])
212 {
213 tick_funcs[i]();
214 }
215 }
216 190
217#if NUM_CORES > 1 191#if NUM_CORES > 1
218 /* Pulse the COP */ 192 /* Pulse the COP */
219 core_wake(COP); 193 core_wake(COP);
220#endif /* NUM_CORES */ 194#endif /* NUM_CORES */
221
222 current_tick++;
223} 195}
224#endif 196#endif
225 197
@@ -243,16 +215,8 @@ void tick_start(unsigned int interval_in_ms)
243 215
244void timer_handler(void) 216void timer_handler(void)
245{ 217{
246 int i;
247
248 /* Run through the list of tick tasks */ 218 /* Run through the list of tick tasks */
249 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 219 call_tick_tasks();
250 {
251 if(tick_funcs[i])
252 tick_funcs[i]();
253 }
254
255 current_tick++;
256 220
257 TIMER0.clr = 0; 221 TIMER0.clr = 0;
258} 222}
@@ -274,19 +238,16 @@ void tick_start(unsigned int interval_in_ms)
274 238
275int tick_add_task(void (*f)(void)) 239int tick_add_task(void (*f)(void))
276{ 240{
277 int i;
278 int oldlevel = disable_irq_save(); 241 int oldlevel = disable_irq_save();
279 242
280 /* Add a task if there is room */ 243 /* Add a task if there is room */
281 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 244 if(num_tick_funcs < MAX_NUM_TICK_TASKS)
282 { 245 {
283 if(tick_funcs[i] == NULL) 246 tick_funcs[num_tick_funcs++] = f;
284 { 247 restore_irq(oldlevel);
285 tick_funcs[i] = f; 248 return 0;
286 restore_irq(oldlevel);
287 return 0;
288 }
289 } 249 }
250
290 restore_irq(oldlevel); 251 restore_irq(oldlevel);
291 panicf("Error! tick_add_task(): out of tasks"); 252 panicf("Error! tick_add_task(): out of tasks");
292 return -1; 253 return -1;
@@ -298,11 +259,16 @@ int tick_remove_task(void (*f)(void))
298 int oldlevel = disable_irq_save(); 259 int oldlevel = disable_irq_save();
299 260
300 /* Remove a task if it is there */ 261 /* Remove a task if it is there */
301 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 262 for(i = 0;i < num_tick_funcs;i++)
302 { 263 {
303 if(tick_funcs[i] == f) 264 if(tick_funcs[i] == f)
304 { 265 {
305 tick_funcs[i] = NULL; 266 /* Compact function list - propagates NULL-terminator as well */
267 for(; i < num_tick_funcs; i++)
268 tick_funcs[i] = tick_funcs[i+1];
269
270 num_tick_funcs--;
271
306 restore_irq(oldlevel); 272 restore_irq(oldlevel);
307 return 0; 273 return 0;
308 } 274 }
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
index e7bce8dc2c..3d7c577e3c 100644
--- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
@@ -27,22 +27,12 @@
27#include "kernel.h" 27#include "kernel.h"
28#include "thread.h" 28#include "thread.h"
29 29
30extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
31
32static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) 30static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void)
33{ 31{
34 int i;
35
36 EPITSR1 = EPITSR_OCIF; /* Clear the pending status */ 32 EPITSR1 = EPITSR_OCIF; /* Clear the pending status */
37 33
38 /* Run through the list of tick tasks */ 34 /* Run through the list of tick tasks */
39 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 35 call_tick_tasks();
40 {
41 if(tick_funcs[i])
42 tick_funcs[i]();
43 }
44
45 current_tick++;
46} 36}
47 37
48void tick_start(unsigned int interval_in_ms) 38void tick_start(unsigned int interval_in_ms)
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
index 4f878d4ed3..76917c8c82 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
@@ -24,8 +24,6 @@
24#include "timer.h" 24#include "timer.h"
25#include "thread.h" 25#include "thread.h"
26 26
27extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
28
29void tick_start(unsigned int interval_in_ms) 27void tick_start(unsigned int interval_in_ms)
30{ 28{
31 /* 29 /*
@@ -62,18 +60,8 @@ void tick_start(unsigned int interval_in_ms)
62 60
63void TIMER4(void) 61void TIMER4(void)
64{ 62{
65 int i;
66
67 /* Run through the list of tick tasks */ 63 /* Run through the list of tick tasks */
68 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 64 call_tick_tasks();
69 {
70 if(tick_funcs[i])
71 {
72 tick_funcs[i]();
73 }
74 }
75
76 current_tick++;
77 65
78 SRCPND = TIMER4_MASK; 66 SRCPND = TIMER4_MASK;
79 INTPND = TIMER4_MASK; 67 INTPND = TIMER4_MASK;
diff --git a/firmware/target/arm/tcc77x/timer-tcc77x.c b/firmware/target/arm/tcc77x/timer-tcc77x.c
index 4645e388cc..924ddda625 100644
--- a/firmware/target/arm/tcc77x/timer-tcc77x.c
+++ b/firmware/target/arm/tcc77x/timer-tcc77x.c
@@ -51,24 +51,12 @@ void __timer_unregister(void)
51 51
52 52
53/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */ 53/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
54
55extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
56
57void TIMER(void) 54void TIMER(void)
58{ 55{
59 if (TIREQ & TF0) /* Timer0 reached ref value */ 56 if (TIREQ & TF0) /* Timer0 reached ref value */
60 { 57 {
61 int i;
62
63 /* Run through the list of tick tasks */ 58 /* Run through the list of tick tasks */
64 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 59 call_tick_tasks();
65 {
66 if(tick_funcs[i])
67 {
68 tick_funcs[i]();
69 }
70 }
71 current_tick++;
72 60
73 /* reset Timer 0 IRQ & ref flags */ 61 /* reset Timer 0 IRQ & ref flags */
74 TIREQ |= TI0 | TF0; 62 TIREQ |= TI0 | TF0;
diff --git a/firmware/target/arm/tcc780x/timer-tcc780x.c b/firmware/target/arm/tcc780x/timer-tcc780x.c
index c08520116a..17956131c0 100644
--- a/firmware/target/arm/tcc780x/timer-tcc780x.c
+++ b/firmware/target/arm/tcc780x/timer-tcc780x.c
@@ -46,25 +46,12 @@ void __timer_unregister(void)
46 46
47 47
48/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */ 48/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
49
50extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
51
52void TIMER0(void) 49void TIMER0(void)
53{ 50{
54 if (TIREQ & TF0) /* Timer0 reached ref value */ 51 if (TIREQ & TF0) /* Timer0 reached ref value */
55 { 52 {
56 int i;
57
58 /* Run through the list of tick tasks */ 53 /* Run through the list of tick tasks */
59 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 54 call_tick_tasks();
60 {
61 if(tick_funcs[i])
62 {
63 tick_funcs[i]();
64 }
65 }
66
67 current_tick++;
68 55
69 /* reset Timer 0 IRQ & ref flags */ 56 /* reset Timer 0 IRQ & ref flags */
70 TIREQ |= TI0 | TF0; 57 TIREQ |= TI0 | TF0;
diff --git a/firmware/target/arm/tms320dm320/kernel-dm320.c b/firmware/target/arm/tms320dm320/kernel-dm320.c
index 42f9773d36..b5eb4233e4 100644
--- a/firmware/target/arm/tms320dm320/kernel-dm320.c
+++ b/firmware/target/arm/tms320dm320/kernel-dm320.c
@@ -25,8 +25,6 @@
25#include "timer.h" 25#include "timer.h"
26#include "thread.h" 26#include "thread.h"
27 27
28extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
29
30void tick_start(unsigned int interval_in_ms) 28void tick_start(unsigned int interval_in_ms)
31{ 29{
32/* TODO: set up TIMER1 clock settings 30/* TODO: set up TIMER1 clock settings
@@ -53,16 +51,7 @@ void tick_start(unsigned int interval_in_ms)
53void TIMER1(void) 51void TIMER1(void)
54{ 52{
55 IO_INTC_IRQ0 = INTR_IRQ0_TMR1; 53 IO_INTC_IRQ0 = INTR_IRQ0_TMR1;
56
57 int i;
58 54
59 /* Run through the list of tick tasks */ 55 /* Run through the list of tick tasks */
60 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 56 call_tick_tasks();
61 {
62 if(tick_funcs[i])
63 {
64 tick_funcs[i]();
65 }
66 }
67 current_tick++;
68} 57}
diff --git a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
index 62176cee24..dcfdfd6a38 100644
--- a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
@@ -24,8 +24,6 @@
24#include "kernel.h" 24#include "kernel.h"
25#include "jz4740.h" 25#include "jz4740.h"
26 26
27extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
28
29#define USE_RTC_CLOCK 0 27#define USE_RTC_CLOCK 0
30void tick_start(unsigned int interval_in_ms) 28void tick_start(unsigned int interval_in_ms)
31{ 29{
@@ -70,13 +68,6 @@ void TCU0(void)
70{ 68{
71 __tcu_clear_full_match_flag(0); 69 __tcu_clear_full_match_flag(0);
72 70
73 int i;
74
75 /* Run through the list of tick tasks */ 71 /* Run through the list of tick tasks */
76 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 72 call_tick_tasks();
77 {
78 if(tick_funcs[i])
79 tick_funcs[i]();
80 }
81 current_tick++;
82} 73}