1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
28 #if ((CONFIG_CPU != PP5020) && (CONFIG_CPU != PP5002)) || !defined(BOOTLOADER)
29 long current_tick
= 0;
32 static void (*tick_funcs
[MAX_NUM_TICK_TASKS
])(void);
34 /* This array holds all queues that are initiated. It is used for broadcast. */
35 static struct event_queue
*all_queues
[32];
36 static int num_queues
;
38 void sleep(int ticks
) ICODE_ATTR
;
39 void queue_wait(struct event_queue
*q
, struct event
*ev
) ICODE_ATTR
;
41 /****************************************************************************
42 * Standard kernel stuff
43 ****************************************************************************/
44 void kernel_init(void)
46 /* Init the threading API */
49 memset(tick_funcs
, 0, sizeof(tick_funcs
));
52 memset(all_queues
, 0, sizeof(all_queues
));
59 /* Always sleep at least 1 tick */
60 int timeout
= current_tick
+ ticks
+ 1;
62 while (TIME_BEFORE( current_tick
, timeout
)) {
74 /****************************************************************************
75 * Queue handling stuff
76 ****************************************************************************/
77 void queue_init(struct event_queue
*q
)
82 /* Add it to the all_queues array */
83 all_queues
[num_queues
++] = q
;
86 void queue_delete(struct event_queue
*q
)
91 /* Find the queue to be deleted */
92 for(i
= 0;i
< num_queues
;i
++)
94 if(all_queues
[i
] == q
)
103 /* Move the following queues up in the list */
104 for(;i
< num_queues
-1;i
++)
106 all_queues
[i
] = all_queues
[i
+1];
113 void queue_wait(struct event_queue
*q
, struct event
*ev
)
115 while(q
->read
== q
->write
)
121 *ev
= q
->events
[(q
->read
++) & QUEUE_LENGTH_MASK
];
124 void queue_wait_w_tmo(struct event_queue
*q
, struct event
*ev
, int ticks
)
126 unsigned int timeout
= current_tick
+ ticks
;
128 while(q
->read
== q
->write
&& TIME_BEFORE( current_tick
, timeout
))
134 if(q
->read
!= q
->write
)
136 *ev
= q
->events
[(q
->read
++) & QUEUE_LENGTH_MASK
];
140 ev
->id
= SYS_TIMEOUT
;
144 void queue_post(struct event_queue
*q
, long id
, void *data
)
149 oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
150 wr
= (q
->write
++) & QUEUE_LENGTH_MASK
;
152 q
->events
[wr
].id
= id
;
153 q
->events
[wr
].data
= data
;
154 set_irq_level(oldlevel
);
157 bool queue_empty(const struct event_queue
* q
)
159 return ( q
->read
== q
->write
);
162 void queue_clear(struct event_queue
* q
)
164 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
167 set_irq_level(oldlevel
);
170 int queue_broadcast(long id
, void *data
)
174 for(i
= 0;i
< num_queues
;i
++)
176 queue_post(all_queues
[i
], id
, data
);
182 /****************************************************************************
184 ****************************************************************************/
185 #if CONFIG_CPU == SH7034
186 void tick_start(unsigned int interval_in_ms
)
190 count
= CPU_FREQ
* interval_in_ms
/ 1000 / 8;
194 panicf("Error! The tick interval is too long (%d ms)\n",
199 /* We are using timer 0 */
201 TSTR
&= ~0x01; /* Stop the timer */
202 TSNC
&= ~0x01; /* No synchronization */
203 TMDR
&= ~0x01; /* Operate normally */
205 TCNT0
= 0; /* Start counting at 0 */
206 GRA0
= (unsigned short)(count
- 1);
207 TCR0
= 0x23; /* Clear at GRA match, sysclock/8 */
209 /* Enable interrupt on level 1 */
210 IPRC
= (IPRC
& ~0x00f0) | 0x0010;
213 TIER0
= 0xf9; /* Enable GRA match interrupt */
215 TSTR
|= 0x01; /* Start timer 1 */
218 void IMIA0(void) __attribute__ ((interrupt_handler
));
223 /* Run through the list of tick tasks */
224 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
237 #elif defined(CPU_COLDFIRE)
238 void tick_start(unsigned int interval_in_ms
)
243 count
= CPU_FREQ
/2 * interval_in_ms
/ 1000 / 16;
247 panicf("Error! The tick interval is too long (%d ms)\n",
252 prescale
= cpu_frequency
/ CPU_FREQ
;
253 /* Note: The prescaler is later adjusted on-the-fly on CPU frequency
254 changes within timer.c */
256 /* We are using timer 0 */
258 TRR0
= (unsigned short)(count
- 1); /* The reference count */
259 TCN0
= 0; /* reset the timer */
260 TMR0
= 0x001d | ((unsigned short)(prescale
- 1) << 8);
261 /* restart, CLK/16, enabled, prescaler */
263 TER0
= 0xff; /* Clear all events */
265 ICR1
= 0x8c; /* Interrupt on level 3.0 */
269 void TIMER0(void) __attribute__ ((interrupt_handler
));
274 /* Run through the list of tick tasks */
275 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
286 TER0
= 0xff; /* Clear all events */
289 #elif CONFIG_CPU == TCC730
296 * If this is not done, power goes down when DC is unplugged.
298 if (current_tick
% 2 == 0)
303 /* Run through the list of tick tasks */
304 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
315 /* re-enable timer by clearing the counter */
319 void tick_start(unsigned int interval_in_ms
)
322 count
= (long)FREQ
* (long)interval_in_ms
/ 1000 / 16;
326 panicf("Error! The tick interval is too long (%dms->%lx)\n",
327 interval_in_ms
, count
);
338 /* TICS = F(osc) / 16 */
339 /* TCS = internal clock */
342 /* enable the interrupt */
343 interrupt_vector
[2] = TIMER0
;
347 #elif (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
354 TIMER1_VAL
; /* Read value to ack IRQ */
355 /* Run through the list of tick tasks */
356 for (i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
369 void tick_start(unsigned int interval_in_ms
)
375 TIMER1_CFG
= 0xc0000000 | (interval_in_ms
*1000);
376 /* unmask interrupt source */
377 CPU_INT_EN
= TIMER1_MASK
;
379 /* We don't enable interrupts in the bootloader */
380 (void)interval_in_ms
;
384 #elif CONFIG_CPU == PNX0101
386 void timer_handler(void)
390 /* Run through the list of tick tasks */
391 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
403 void tick_start(unsigned int interval_in_ms
)
409 TIMERR00
= 3000000 * interval_in_ms
/ 1000;
413 irq_set_int_handler(4, timer_handler
);
421 int tick_add_task(void (*f
)(void))
424 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
426 /* Add a task if there is room */
427 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
429 if(tick_funcs
[i
] == NULL
)
432 set_irq_level(oldlevel
);
436 set_irq_level(oldlevel
);
437 panicf("Error! tick_add_task(): out of tasks");
441 int tick_remove_task(void (*f
)(void))
444 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
446 /* Remove a task if it is there */
447 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
449 if(tick_funcs
[i
] == f
)
451 tick_funcs
[i
] = NULL
;
452 set_irq_level(oldlevel
);
457 set_irq_level(oldlevel
);
463 * Simulator versions in uisimulator/SIMVER/
466 /****************************************************************************
467 * Simple mutex functions
468 ****************************************************************************/
469 void mutex_init(struct mutex
*m
)
474 void mutex_lock(struct mutex
*m
)
476 /* Wait until the lock is open... */
485 void mutex_unlock(struct mutex
*m
)