xref: /minix3/minix/lib/libddekit/src/dde.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc #include "common.h"
2*433d6423SLionel Sambuc #include <ddekit/initcall.h>
3*433d6423SLionel Sambuc #include <ddekit/minix/msg_queue.h>
4*433d6423SLionel Sambuc #include <ddekit/panic.h>
5*433d6423SLionel Sambuc #include <ddekit/pci.h>
6*433d6423SLionel Sambuc #include <ddekit/semaphore.h>
7*433d6423SLionel Sambuc #include <ddekit/timer.h>
8*433d6423SLionel Sambuc #include <signal.h>
9*433d6423SLionel Sambuc 
10*433d6423SLionel Sambuc #include "debug.h"
11*433d6423SLionel Sambuc #include "timer.h"  /* _ddekit_timer_interrupt()   */
12*433d6423SLionel Sambuc #include "thread.h" /* _ddekit_thread_set_myprio() */
13*433d6423SLionel Sambuc #include "irq.h"
14*433d6423SLionel Sambuc 
15*433d6423SLionel Sambuc 
16*433d6423SLionel Sambuc static ddekit_sem_t *exit_sem;
17*433d6423SLionel Sambuc 
18*433d6423SLionel Sambuc unsigned long long jiffies;
19*433d6423SLionel Sambuc 
20*433d6423SLionel Sambuc void ddekit_pgtab_init(void);
21*433d6423SLionel Sambuc 
22*433d6423SLionel Sambuc static  ddekit_thread_t *dispatch_th = 0;
23*433d6423SLionel Sambuc 
24*433d6423SLionel Sambuc 
25*433d6423SLionel Sambuc static void dispatcher_thread(void * unused);
26*433d6423SLionel Sambuc static void ddekit_dispatcher_thread_init(void);
27*433d6423SLionel Sambuc 
28*433d6423SLionel Sambuc /****************************************************************************/
29*433d6423SLionel Sambuc /*      dispatcher_thread                                                   */
30*433d6423SLionel Sambuc /****************************************************************************/
dispatcher_thread(void * unused)31*433d6423SLionel Sambuc static void dispatcher_thread(void *unused) {
32*433d6423SLionel Sambuc 
33*433d6423SLionel Sambuc 	/*
34*433d6423SLionel Sambuc 	 * Gets all messages and dispatches them.
35*433d6423SLionel Sambuc 	 *
36*433d6423SLionel Sambuc 	 * NOTE: this thread runs only when no other ddekit is
37*433d6423SLionel Sambuc 	 *       ready. So please take care that youre threads
38*433d6423SLionel Sambuc 	 *       leave some time for the others!
39*433d6423SLionel Sambuc 	 */
40*433d6423SLionel Sambuc 	message m;
41*433d6423SLionel Sambuc 	int r;
42*433d6423SLionel Sambuc 	int i;
43*433d6423SLionel Sambuc 	int ipc_status;
44*433d6423SLionel Sambuc 
45*433d6423SLionel Sambuc 	_ddekit_thread_set_myprio(0);
46*433d6423SLionel Sambuc 
47*433d6423SLionel Sambuc 	for( ; ; ) {
48*433d6423SLionel Sambuc 
49*433d6423SLionel Sambuc 		/* Trigger a timer interrupt at each loop iteration */
50*433d6423SLionel Sambuc 		_ddekit_timer_update();
51*433d6423SLionel Sambuc 
52*433d6423SLionel Sambuc 		/* Wait for messages */
53*433d6423SLionel Sambuc 		if ((r = sef_receive_status(ANY, &m, &ipc_status)) != 0) {
54*433d6423SLionel Sambuc 				ddekit_panic("ddekit", "sef_receive failed", r);
55*433d6423SLionel Sambuc 		}
56*433d6423SLionel Sambuc 
57*433d6423SLionel Sambuc 
58*433d6423SLionel Sambuc 		_ddekit_timer_interrupt();
59*433d6423SLionel Sambuc 
60*433d6423SLionel Sambuc 		_ddekit_thread_wakeup_sleeping();
61*433d6423SLionel Sambuc 
62*433d6423SLionel Sambuc 		if (is_notify(m.m_type)) {
63*433d6423SLionel Sambuc 			switch (_ENDPOINT_P(m.m_source)) {
64*433d6423SLionel Sambuc 				case HARDWARE:
65*433d6423SLionel Sambuc 					for	(i =0 ; i < 32 ; i++)
66*433d6423SLionel Sambuc 					{
67*433d6423SLionel Sambuc 						if(m.m_notify.interrupts & (1 << i))
68*433d6423SLionel Sambuc 						{
69*433d6423SLionel Sambuc 							_ddekit_interrupt_trigger(i);
70*433d6423SLionel Sambuc 						}
71*433d6423SLionel Sambuc 					}
72*433d6423SLionel Sambuc 					break;
73*433d6423SLionel Sambuc 				case CLOCK:
74*433d6423SLionel Sambuc 					_ddekit_timer_pending = 0;
75*433d6423SLionel Sambuc 					break;
76*433d6423SLionel Sambuc 				default:
77*433d6423SLionel Sambuc 					ddekit_thread_schedule();
78*433d6423SLionel Sambuc 			}
79*433d6423SLionel Sambuc 
80*433d6423SLionel Sambuc 		} else {
81*433d6423SLionel Sambuc 
82*433d6423SLionel Sambuc 			/*
83*433d6423SLionel Sambuc 			 * I don't know how to handle this msg,
84*433d6423SLionel Sambuc 			 * but maybe we have a msg queue which can
85*433d6423SLionel Sambuc 			 * handle this msg.
86*433d6423SLionel Sambuc 			 */
87*433d6423SLionel Sambuc 
88*433d6423SLionel Sambuc 			ddekit_minix_queue_msg(&m, ipc_status);
89*433d6423SLionel Sambuc 		}
90*433d6423SLionel Sambuc 	}
91*433d6423SLionel Sambuc }
92*433d6423SLionel Sambuc 
93*433d6423SLionel Sambuc /****************************************************************************/
94*433d6423SLionel Sambuc /*      ddekit_dispatcher_thread_init                                       */
95*433d6423SLionel Sambuc /****************************************************************************/
ddekit_dispatcher_thread_init()96*433d6423SLionel Sambuc static void ddekit_dispatcher_thread_init()
97*433d6423SLionel Sambuc {
98*433d6423SLionel Sambuc 
99*433d6423SLionel Sambuc 	dispatch_th = ddekit_thread_create(dispatcher_thread, NULL, "dispatch");
100*433d6423SLionel Sambuc 
101*433d6423SLionel Sambuc 	ddekit_thread_schedule();
102*433d6423SLionel Sambuc }
103*433d6423SLionel Sambuc 
104*433d6423SLionel Sambuc /****************************************************************************/
105*433d6423SLionel Sambuc /*      ddekit_init                                                         */
106*433d6423SLionel Sambuc /****************************************************************************/
ddekit_init(void)107*433d6423SLionel Sambuc void ddekit_init(void)
108*433d6423SLionel Sambuc {
109*433d6423SLionel Sambuc 	sef_startup();
110*433d6423SLionel Sambuc 
111*433d6423SLionel Sambuc 	ddekit_pgtab_init();
112*433d6423SLionel Sambuc 
113*433d6423SLionel Sambuc 	ddekit_init_threads();
114*433d6423SLionel Sambuc 
115*433d6423SLionel Sambuc 	ddekit_init_irqs();
116*433d6423SLionel Sambuc 
117*433d6423SLionel Sambuc 	ddekit_init_timers();
118*433d6423SLionel Sambuc 
119*433d6423SLionel Sambuc 	ddekit_dispatcher_thread_init();
120*433d6423SLionel Sambuc 
121*433d6423SLionel Sambuc 	exit_sem = ddekit_sem_init(0);
122*433d6423SLionel Sambuc }
123*433d6423SLionel Sambuc 
124*433d6423SLionel Sambuc /****************************************************************************/
125*433d6423SLionel Sambuc /*      dispatcher_shutdown                                                 */
126*433d6423SLionel Sambuc /****************************************************************************/
ddekit_shutdown()127*433d6423SLionel Sambuc void ddekit_shutdown()
128*433d6423SLionel Sambuc {
129*433d6423SLionel Sambuc 	ddekit_sem_up(exit_sem);
130*433d6423SLionel Sambuc }
131*433d6423SLionel Sambuc 
132*433d6423SLionel Sambuc /****************************************************************************/
133*433d6423SLionel Sambuc /*  ddekit_minix_wait_exit                                                  */
134*433d6423SLionel Sambuc /****************************************************************************/
ddekit_minix_wait_exit(void)135*433d6423SLionel Sambuc void ddekit_minix_wait_exit(void)
136*433d6423SLionel Sambuc {
137*433d6423SLionel Sambuc 	ddekit_sem_down(exit_sem);
138*433d6423SLionel Sambuc }
139*433d6423SLionel Sambuc 
140