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 ****************************************************************************/
27 long current_tick
= 0;
29 static void (*tick_funcs
[MAX_NUM_TICK_TASKS
])(void);
31 static void tick_start(unsigned int interval_in_ms
);
33 /* This array holds all queues that are initiated. It is used for broadcast. */
34 static struct event_queue
*all_queues
[32];
35 static int num_queues
;
37 void sleep(int ticks
) __attribute__ ((section(".icode")));
38 void queue_wait(struct event_queue
*q
, struct event
*ev
) __attribute__ ((section(".icode")));
40 /****************************************************************************
41 * Standard kernel stuff
42 ****************************************************************************/
43 void kernel_init(void)
45 /* Init the threading API */
48 memset(tick_funcs
, 0, sizeof(tick_funcs
));
51 memset(all_queues
, 0, sizeof(all_queues
));
58 /* Always sleep at least 1 tick */
59 int timeout
= current_tick
+ ticks
+ 1;
61 while (TIME_BEFORE( current_tick
, timeout
)) {
73 /****************************************************************************
74 * Queue handling stuff
75 ****************************************************************************/
76 void queue_init(struct event_queue
*q
)
81 /* Add it to the all_queues array */
82 all_queues
[num_queues
++] = q
;
85 void queue_wait(struct event_queue
*q
, struct event
*ev
)
87 while(q
->read
== q
->write
)
93 *ev
= q
->events
[(q
->read
++) & QUEUE_LENGTH_MASK
];
96 void queue_wait_w_tmo(struct event_queue
*q
, struct event
*ev
, int ticks
)
98 unsigned int timeout
= current_tick
+ ticks
;
100 while(q
->read
== q
->write
&& TIME_BEFORE( current_tick
, timeout
))
106 if(q
->read
!= q
->write
)
108 *ev
= q
->events
[(q
->read
++) & QUEUE_LENGTH_MASK
];
112 ev
->id
= SYS_TIMEOUT
;
116 void queue_post(struct event_queue
*q
, int id
, void *data
)
121 oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
122 wr
= (q
->write
++) & QUEUE_LENGTH_MASK
;
124 q
->events
[wr
].id
= id
;
125 q
->events
[wr
].data
= data
;
126 set_irq_level(oldlevel
);
129 bool queue_empty(const struct event_queue
* q
)
131 return ( q
->read
== q
->write
);
134 void queue_clear(struct event_queue
* q
)
136 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
139 set_irq_level(oldlevel
);
142 int queue_broadcast(int id
, void *data
)
146 for(i
= 0;i
< num_queues
;i
++)
148 queue_post(all_queues
[i
], id
, data
);
154 /****************************************************************************
156 ****************************************************************************/
157 #if CONFIG_CPU == SH7034
158 static void tick_start(unsigned int interval_in_ms
)
162 count
= FREQ
* interval_in_ms
/ 1000 / 8;
166 panicf("Error! The tick interval is too long (%d ms)\n",
171 /* We are using timer 0 */
173 TSTR
&= ~0x01; /* Stop the timer */
174 TSNC
&= ~0x01; /* No synchronization */
175 TMDR
&= ~0x01; /* Operate normally */
177 TCNT0
= 0; /* Start counting at 0 */
179 TCR0
= 0x23; /* Clear at GRA match, sysclock/8 */
181 /* Enable interrupt on level 1 */
182 IPRC
= (IPRC
& ~0x00f0) | 0x0010;
185 TIER0
= 0xf9; /* Enable GRA match interrupt */
187 TSTR
|= 0x01; /* Start timer 1 */
195 /* Run through the list of tick tasks */
196 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
209 #elif CONFIG_CPU == MCF5249
210 static void tick_start(unsigned int interval_in_ms
)
214 count
= FREQ
/2 * interval_in_ms
/ 1000 / 16;
218 panicf("Error! The tick interval is too long (%d ms)\n",
223 /* We are using timer 0 */
225 TRR0
= count
; /* The reference count */
226 TCN0
= 0; /* reset the timer */
227 TMR0
= 0x001d; /* no prescaler, restart, CLK/16, enabled */
229 TER0
= 0xff; /* Clear all events */
231 ICR0
= (ICR0
& 0xff00ffff) | 0x008c0000; /* Interrupt on level 3.0 */
235 void TIMER0(void) __attribute__ ((interrupt_handler
));
240 /* Run through the list of tick tasks */
241 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
252 TER0
= 0xff; /* Clear all events */
256 int tick_add_task(void (*f
)(void))
259 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
261 /* Add a task if there is room */
262 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
264 if(tick_funcs
[i
] == NULL
)
267 set_irq_level(oldlevel
);
271 set_irq_level(oldlevel
);
272 panicf("Error! tick_add_task(): out of tasks");
276 int tick_remove_task(void (*f
)(void))
279 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
281 /* Remove a task if it is there */
282 for(i
= 0;i
< MAX_NUM_TICK_TASKS
;i
++)
284 if(tick_funcs
[i
] == f
)
286 tick_funcs
[i
] = NULL
;
287 set_irq_level(oldlevel
);
292 set_irq_level(oldlevel
);
296 /****************************************************************************
297 * Simple mutex functions
298 ****************************************************************************/
299 void mutex_init(struct mutex
*m
)
304 void mutex_lock(struct mutex
*m
)
306 /* Wait until the lock is open... */
315 void mutex_unlock(struct mutex
*m
)