OSDN Git Service

Moved the junk codes to junk directory.
[kozos-expbrd/kozos_expbrd.git] / firm / junk / 07 / os / kozos.c
1 #include "defines.h"
2 #include "kozos.h"
3 #include "intr.h"
4 #include "interrupt.h"
5 #include "syscall.h"
6 #include "memory.h"
7 #include "lib.h"
8
9 #define THREAD_NUM 8
10 #define PRIORITY_NUM 16
11 #define THREAD_NAME_SIZE 15
12
13 /* ¥¹¥ì¥Ã¥É¡¦¥³¥ó¥Æ¥­¥¹¥È */
14 typedef struct _kz_context {
15   uint32 sp; /* ¥¹¥¿¥Ã¥¯¡¦¥Ý¥¤¥ó¥¿ */
16 } kz_context;
17
18 /* ¥¿¥¹¥¯¡¦¥³¥ó¥È¥í¡¼¥ë¡¦¥Ö¥í¥Ã¥¯(TCB) */
19 typedef struct _kz_thread {
20   struct _kz_thread *next;
21   char name[THREAD_NAME_SIZE + 1]; /* ¥¹¥ì¥Ã¥É̾ */
22   int priority;   /* Í¥ÀèÅÙ */
23   char *stack;    /* ¥¹¥¿¥Ã¥¯ */
24   uint32 flags;   /* ³Æ¼ï¥Õ¥é¥° */
25 #define KZ_THREAD_FLAG_READY (1 << 0)
26
27   struct { /* ¥¹¥ì¥Ã¥É¤Î¥¹¥¿¡¼¥È¡¦¥¢¥Ã¥×(thread_init())¤ËÅϤ¹¥Ñ¥é¥á¡¼¥¿ */
28     kz_func_t func; /* ¥¹¥ì¥Ã¥É¤Î¥á¥¤¥ó´Ø¿ô */
29     int argc;       /* ¥¹¥ì¥Ã¥É¤Î¥á¥¤¥ó´Ø¿ô¤ËÅϤ¹ argc */
30     char **argv;    /* ¥¹¥ì¥Ã¥É¤Î¥á¥¤¥ó´Ø¿ô¤ËÅϤ¹ argv */
31   } init;
32
33   struct { /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ëÍѥХåե¡ */
34     kz_syscall_type_t type;
35     kz_syscall_param_t *param;
36   } syscall;
37
38   kz_context context; /* ¥³¥ó¥Æ¥­¥¹¥È¾ðÊó */
39 } kz_thread;
40
41 /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ð¥Ã¥Õ¥¡ */
42 typedef struct _kz_msgbuf {
43   struct _kz_msgbuf *next;
44   kz_thread *sender; /* ¥á¥Ã¥»¡¼¥¸¤òÁ÷¿®¤·¤¿¥¹¥ì¥Ã¥É */
45   struct { /* ¥á¥Ã¥»¡¼¥¸¤Î¥Ñ¥é¥á¡¼¥¿ÊݸÎΰè */
46     int size;
47     char *p;
48   } param;
49 } kz_msgbuf;
50
51 /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹ */
52 typedef struct _kz_msgbox {
53   kz_thread *receiver; /* ¼õ¿®ÂÔ¤Á¾õÂ֤Υ¹¥ì¥Ã¥É */
54   kz_msgbuf *head;
55   kz_msgbuf *tail;
56
57   /*
58    * H8¤Ï16¥Ó¥Ã¥ÈCPU¤Ê¤Î¤Ç¡¤32¥Ó¥Ã¥ÈÀ°¿ô¤ËÂФ·¤Æ¤Î¾è»»Ì¿Î᤬̵¤¤¡¥¤è¤Ã¤Æ
59    * ¹½Â¤ÂΤΥµ¥¤¥º¤¬£²¤Î³¬¾è¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¤È¡¤¹½Â¤ÂΤÎÇÛÎó¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹
60    * ·×»»¤Ç¾è»»¤¬»È¤ï¤ì¤Æ¡Ö___mulsi3¤¬Ìµ¤¤¡×¤Ê¤É¤Î¥ê¥ó¥¯¡¦¥¨¥é¡¼¤Ë¤Ê¤ë¾ì¹ç¤¬
61    * ¤¢¤ë¡¥(£²¤Î³¬¾è¤Ê¤é¤Ð¥·¥Õ¥È±é»»¤¬ÍøÍѤµ¤ì¤ë¤Î¤ÇÌäÂê¤Ï½Ð¤Ê¤¤)
62    * Âкö¤È¤·¤Æ¡¤¥µ¥¤¥º¤¬£²¤Î³¬¾è¤Ë¤Ê¤ë¤è¤¦¤Ë¥À¥ß¡¼¡¦¥á¥ó¥Ð¤ÇÄ´À°¤¹¤ë¡¥
63    * Â¾¹½Â¤ÂΤÇƱÍͤΥ¨¥é¡¼¤¬½Ð¤¿¾ì¹ç¤Ë¤Ï¡¤Æ±ÍͤÎÂнè¤ò¤¹¤ë¤³¤È¡¥
64    */
65   long dummy[1];
66 } kz_msgbox;
67
68 /* ¥¹¥ì¥Ã¥É¤Î¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼ */
69 static struct {
70   kz_thread *head;
71   kz_thread *tail;
72 } readyque[PRIORITY_NUM];
73
74 static kz_thread *current; /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É */
75 static kz_thread threads[THREAD_NUM]; /* ¥¿¥¹¥¯¡¦¥³¥ó¥È¥í¡¼¥ë¡¦¥Ö¥í¥Ã¥¯ */
76 static kz_handler_t handlers[SOFTVEC_TYPE_NUM]; /* ³ä¹þ¤ß¥Ï¥ó¥É¥é */
77 static kz_msgbox msgboxes[MSGBOX_ID_NUM]; /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹ */
78
79 void dispatch(kz_context *context);
80
81 /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤«¤éÈ´¤­½Ð¤¹ */
82 static int getcurrent(void)
83 {
84   if (current == NULL) {
85     return -1;
86   }
87   if (!(current->flags & KZ_THREAD_FLAG_READY)) {
88     /* ¤¹¤Ç¤Ë̵¤¤¾ì¹ç¤Ï̵»ë */
89     return 1;
90   }
91
92   /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤Ïɬ¤ºÀèƬ¤Ë¤¢¤ë¤Ï¤º¤Ê¤Î¤Ç¡¤ÀèƬ¤«¤éÈ´¤­½Ð¤¹ */
93   readyque[current->priority].head = current->next;
94   if (readyque[current->priority].head == NULL) {
95     readyque[current->priority].tail = NULL;
96   }
97   current->flags &= ~KZ_THREAD_FLAG_READY;
98   current->next = NULL;
99
100   return 0;
101 }
102
103 /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤Ë·Ò¤²¤ë */
104 static int putcurrent(void)
105 {
106   if (current == NULL) {
107     return -1;
108   }
109   if (current->flags & KZ_THREAD_FLAG_READY) {
110     /* ¤¹¤Ç¤ËÍ­¤ë¾ì¹ç¤Ï̵»ë */
111     return 1;
112   }
113
114   /* ¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤ÎËöÈø¤ËÀܳ¤¹¤ë */
115   if (readyque[current->priority].tail) {
116     readyque[current->priority].tail->next = current;
117   } else {
118     readyque[current->priority].head = current;
119   }
120   readyque[current->priority].tail = current;
121   current->flags |= KZ_THREAD_FLAG_READY;
122
123   return 0;
124 }
125
126 static void thread_end(void)
127 {
128   kz_exit();
129 }
130
131 /* ¥¹¥ì¥Ã¥É¤Î¥¹¥¿¡¼¥È¡¦¥¢¥Ã¥× */
132 static void thread_init(kz_thread *thp)
133 {
134   /* ¥¹¥ì¥Ã¥É¤Î¥á¥¤¥ó´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹ */
135   thp->init.func(thp->init.argc, thp->init.argv);
136   thread_end();
137 }
138
139 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_run():¥¹¥ì¥Ã¥É¤Îµ¯Æ°) */
140 static kz_thread_id_t thread_run(kz_func_t func, char *name, int priority,
141                                  int stacksize, int argc, char *argv[])
142 {
143   int i;
144   kz_thread *thp;
145   uint32 *sp;
146   extern char userstack; /* ¥ê¥ó¥«¡¦¥¹¥¯¥ê¥×¥È¤ÇÄêµÁ¤µ¤ì¤ë¥¹¥¿¥Ã¥¯Îΰè */
147   static char *thread_stack = &userstack;
148
149   /* ¶õ¤¤¤Æ¤¤¤ë¥¿¥¹¥¯¡¦¥³¥ó¥È¥í¡¼¥ë¡¦¥Ö¥í¥Ã¥¯¤ò¸¡º÷ */
150   for (i = 0; i < THREAD_NUM; i++) {
151     thp = &threads[i];
152     if (!thp->init.func) /* ¸«¤Ä¤«¤Ã¤¿ */
153       break;
154   }
155   if (i == THREAD_NUM) /* ¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿ */
156     return -1;
157
158   memset(thp, 0, sizeof(*thp));
159
160   /* ¥¿¥¹¥¯¡¦¥³¥ó¥È¥í¡¼¥ë¡¦¥Ö¥í¥Ã¥¯(TCB)¤ÎÀßÄê */
161   strcpy(thp->name, name);
162   thp->next     = NULL;
163   thp->priority = priority;
164   thp->flags    = 0;
165
166   thp->init.func = func;
167   thp->init.argc = argc;
168   thp->init.argv = argv;
169
170   /* ¥¹¥¿¥Ã¥¯Îΰè¤ò³ÍÆÀ */
171   memset(thread_stack, 0, stacksize);
172   thread_stack += stacksize;
173
174   thp->stack = thread_stack; /* ¥¹¥¿¥Ã¥¯¤òÀßÄê */
175
176   /* ¥¹¥¿¥Ã¥¯¤Î½é´ü²½ */
177   sp = (uint32 *)thp->stack;
178   *(--sp) = (uint32)thread_end;
179
180   /*
181    * ¥×¥í¥°¥é¥à¡¦¥«¥¦¥ó¥¿¤òÀßÄꤹ¤ë¡¥
182    * ¥¹¥ì¥Ã¥É¤ÎÍ¥ÀèÅÙ¤¬¥¼¥í¤Î¾ì¹ç¤Ë¤Ï¡¤³ä¹þ¤ß¶Ø»ß¥¹¥ì¥Ã¥É¤È¤¹¤ë¡¥
183    */
184   *(--sp) = (uint32)thread_init | ((uint32)(priority ? 0 : 0xc0) << 24);
185
186   *(--sp) = 0; /* ER6 */
187   *(--sp) = 0; /* ER5 */
188   *(--sp) = 0; /* ER4 */
189   *(--sp) = 0; /* ER3 */
190   *(--sp) = 0; /* ER2 */
191   *(--sp) = 0; /* ER1 */
192
193   /* ¥¹¥ì¥Ã¥É¤Î¥¹¥¿¡¼¥È¡¦¥¢¥Ã¥×(thread_init())¤ËÅϤ¹°ú¿ô */
194   *(--sp) = (uint32)thp;  /* ER0 */
195
196   /* ¥¹¥ì¥Ã¥É¤Î¥³¥ó¥Æ¥­¥¹¥È¤òÀßÄê */
197   thp->context.sp = (uint32)sp;
198
199   /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ò¸Æ¤Ó½Ð¤·¤¿¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤ËÌ᤹ */
200   putcurrent();
201
202   /* ¿·µ¬ºîÀ®¤·¤¿¥¹¥ì¥Ã¥É¤ò¡¤¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤ËÀܳ¤¹¤ë */
203   current = thp;
204   putcurrent();
205
206   return (kz_thread_id_t)current;
207 }
208
209 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_exit():¥¹¥ì¥Ã¥É¤Î½ªÎ») */
210 static int thread_exit(void)
211 {
212   /*
213    * ËÜÍè¤Ê¤é¥¹¥¿¥Ã¥¯¤â²òÊü¤·¤ÆºÆÍøÍѤǤ­¤ë¤è¤¦¤Ë¤¹¤Ù¤­¤À¤¬¾Êά¡¥
214    * ¤³¤Î¤¿¤á¡¤¥¹¥ì¥Ã¥É¤òÉÑÈˤËÀ¸À®¡¦¾Ãµî¤¹¤ë¤è¤¦¤Ê¤³¤È¤Ï¸½¾õ¤Ç¤Ç¤­¤Ê¤¤¡¥
215    */
216   puts(current->name);
217   puts(" EXIT.\n");
218   memset(current, 0, sizeof(*current));
219   return 0;
220 }
221
222 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_wait():¥¹¥ì¥Ã¥É¤Î¼Â¹Ô¸¢Êü´þ) */
223 static int thread_wait(void)
224 {
225   putcurrent();
226   return 0;
227 }
228
229 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_sleep():¥¹¥ì¥Ã¥É¤Î¥¹¥ê¡¼¥×) */
230 static int thread_sleep(void)
231 {
232   return 0;
233 }
234
235 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_wakeup():¥¹¥ì¥Ã¥É¤Î¥¦¥§¥¤¥¯¡¦¥¢¥Ã¥×) */
236 static int thread_wakeup(kz_thread_id_t id)
237 {
238   /* ¥¦¥§¥¤¥¯¡¦¥¢¥Ã¥×¤ò¸Æ¤Ó½Ð¤·¤¿¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤ËÌ᤹ */
239   putcurrent();
240
241   /* »ØÄꤵ¤ì¤¿¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤ËÀܳ¤·¤Æ¥¦¥§¥¤¥¯¡¦¥¢¥Ã¥×¤¹¤ë */
242   current = (kz_thread *)id;
243   putcurrent();
244
245   return 0;
246 }
247
248 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_getid():¥¹¥ì¥Ã¥ÉID¼èÆÀ) */
249 static kz_thread_id_t thread_getid(void)
250 {
251   putcurrent();
252   return (kz_thread_id_t)current;
253 }
254
255 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_chpri():¥¹¥ì¥Ã¥É¤ÎÍ¥ÀèÅÙÊѹ¹) */
256 static int thread_chpri(int priority)
257 {
258   int old = current->priority;
259   if (priority >= 0)
260     current->priority = priority; /* Í¥ÀèÅÙÊѹ¹ */
261   putcurrent(); /* ¿·¤·¤¤Í¥ÀèÅ٤Υì¥Ç¥£¡¼¡¦¥­¥å¡¼¤Ë·Ò¤®Ä¾¤¹ */
262   return old;
263 }
264
265 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_kmalloc():ưŪ¥á¥â¥ê³ÍÆÀ) */
266 static void *thread_kmalloc(int size)
267 {
268   putcurrent();
269   return kzmem_alloc(size);
270 }
271
272 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_kfree():¥á¥â¥ê²òÊü) */
273 static int thread_kmfree(char *p)
274 {
275   kzmem_free(p);
276   putcurrent();
277   return 0;
278 }
279
280 /* ¥á¥Ã¥»¡¼¥¸¤ÎÁ÷¿®½èÍý */
281 static void sendmsg(kz_msgbox *mboxp, kz_thread *thp, int size, char *p)
282 {
283   kz_msgbuf *mp;
284
285   /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ð¥Ã¥Õ¥¡¤ÎºîÀ® */
286   mp = (kz_msgbuf *)kzmem_alloc(sizeof(*mp));
287   if (mp == NULL)
288     kz_sysdown();
289   mp->next       = NULL;
290   mp->sender     = thp;
291   mp->param.size = size;
292   mp->param.p    = p;
293
294   /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹¤ÎËöÈø¤Ë¥á¥Ã¥»¡¼¥¸¤òÀܳ¤¹¤ë */
295   if (mboxp->tail) {
296     mboxp->tail->next = mp;
297   } else {
298     mboxp->head = mp;
299   }
300   mboxp->tail = mp;
301 }
302
303 /* ¥á¥Ã¥»¡¼¥¸¤Î¼õ¿®½èÍý */
304 static void recvmsg(kz_msgbox *mboxp)
305 {
306   kz_msgbuf *mp;
307   kz_syscall_param_t *p;
308
309   /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹¤ÎÀèƬ¤Ë¤¢¤ë¥á¥Ã¥»¡¼¥¸¤òÈ´¤­½Ð¤¹ */
310   mp = mboxp->head;
311   mboxp->head = mp->next;
312   if (mboxp->head == NULL)
313     mboxp->tail = NULL;
314   mp->next = NULL;
315
316   /* ¥á¥Ã¥»¡¼¥¸¤ò¼õ¿®¤¹¤ë¥¹¥ì¥Ã¥É¤ËÊÖ¤¹ÃͤòÀßÄꤹ¤ë */
317   p = mboxp->receiver->syscall.param;
318   p->un.recv.ret = (kz_thread_id_t)mp->sender;
319   if (p->un.recv.sizep)
320     *(p->un.recv.sizep) = mp->param.size;
321   if (p->un.recv.pp)
322     *(p->un.recv.pp) = mp->param.p;
323
324   /* ¼õ¿®ÂÔ¤Á¥¹¥ì¥Ã¥É¤Ï¤¤¤Ê¤¯¤Ê¤Ã¤¿¤Î¤Ç¡¤NULL¤ËÌ᤹ */
325   mboxp->receiver = NULL;
326
327   /* ¥á¥Ã¥»¡¼¥¸¡¦¥Ð¥Ã¥Õ¥¡¤Î²òÊü */
328   kzmem_free(mp);
329 }
330
331 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_send():¥á¥Ã¥»¡¼¥¸Á÷¿®) */
332 static int thread_send(kz_msgbox_id_t id, int size, char *p)
333 {
334   kz_msgbox *mboxp = &msgboxes[id];
335
336   putcurrent();
337   sendmsg(mboxp, current, size, p); /* ¥á¥Ã¥»¡¼¥¸¤ÎÁ÷¿®½èÍý */
338
339   /* ¼õ¿®ÂÔ¤Á¥¹¥ì¥Ã¥É¤¬Â¸ºß¤·¤Æ¤¤¤ë¾ì¹ç¤Ë¤Ï¼õ¿®½èÍý¤ò¹Ô¤¦ */
340   if (mboxp->receiver) {
341     current = mboxp->receiver; /* ¼õ¿®ÂÔ¤Á¥¹¥ì¥Ã¥É */
342     recvmsg(mboxp); /* ¥á¥Ã¥»¡¼¥¸¤Î¼õ¿®½èÍý */
343     putcurrent(); /* ¼õ¿®¤Ë¤è¤êÆ°ºî²Äǽ¤Ë¤Ê¤Ã¤¿¤Î¤Ç¡¤¥Ö¥í¥Ã¥¯²ò½ü¤¹¤ë */
344   }
345
346   return size;
347 }
348
349 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_recv():¥á¥Ã¥»¡¼¥¸¼õ¿®) */
350 static kz_thread_id_t thread_recv(kz_msgbox_id_t id, int *sizep, char **pp)
351 {
352   kz_msgbox *mboxp = &msgboxes[id];
353
354   if (mboxp->receiver) /* Â¾¤Î¥¹¥ì¥Ã¥É¤¬¤¹¤Ç¤Ë¼õ¿®ÂÔ¤Á¤·¤Æ¤¤¤ë */
355     kz_sysdown();
356
357   mboxp->receiver = current; /* ¼õ¿®ÂÔ¤Á¥¹¥ì¥Ã¥É¤ËÀßÄê */
358
359   if (mboxp->head == NULL) {
360     /*
361      * ¥á¥Ã¥»¡¼¥¸¡¦¥Ü¥Ã¥¯¥¹¤Ë¥á¥Ã¥»¡¼¥¸¤¬Ìµ¤¤¤Î¤Ç¡¤¥¹¥ì¥Ã¥É¤ò
362      * ¥¹¥ê¡¼¥×¤µ¤»¤ë¡¥(¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤¬¥Ö¥í¥Ã¥¯¤¹¤ë)
363      */
364     return -1;
365   }
366
367   recvmsg(mboxp); /* ¥á¥Ã¥»¡¼¥¸¤Î¼õ¿®½èÍý */
368   putcurrent(); /* ¥á¥Ã¥»¡¼¥¸¤ò¼õ¿®¤Ç¤­¤¿¤Î¤Ç¡¤¥ì¥Ç¥£¡¼¾õÂ֤ˤ¹¤ë */
369
370   return current->syscall.param->un.recv.ret;
371 }
372
373 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý(kz_setintr():³ä¹þ¤ß¥Ï¥ó¥É¥éÅÐÏ¿) */
374 static int thread_setintr(softvec_type_t type, kz_handler_t handler)
375 {
376   static void thread_intr(softvec_type_t type, unsigned long sp);
377
378   /*
379    * ³ä¹þ¤ß¤ò¼õ¤±ÉÕ¤±¤ë¤¿¤á¤Ë¡¤¥½¥Õ¥È¥¦¥¨¥¢¡¦³ä¹þ¤ß¥Ù¥¯¥¿¤Ë
380    * OS¤Î³ä¹þ¤ß½èÍý¤ÎÆþ¸ý¤È¤Ê¤ë´Ø¿ô¤òÅÐÏ¿¤¹¤ë¡¥
381    */
382   softvec_setintr(type, thread_intr);
383
384   handlers[type] = handler; /* OS¦¤«¤é¸Æ¤Ó½Ð¤¹³ä¹þ¤ß¥Ï¥ó¥É¥é¤òÅÐÏ¿ */
385   putcurrent();
386
387   return 0;
388 }
389
390 static void call_functions(kz_syscall_type_t type, kz_syscall_param_t *p)
391 {
392   /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î¼Â¹ÔÃæ¤Ëcurrent¤¬½ñ¤­´¹¤ï¤ë¤Î¤ÇÃí°Õ */
393   switch (type) {
394   case KZ_SYSCALL_TYPE_RUN: /* kz_run() */
395     p->un.run.ret = thread_run(p->un.run.func, p->un.run.name,
396                                p->un.run.priority, p->un.run.stacksize,
397                                p->un.run.argc, p->un.run.argv);
398     break;
399   case KZ_SYSCALL_TYPE_EXIT: /* kz_exit() */
400     /* TCB¤¬¾Ãµî¤µ¤ì¤ë¤Î¤Ç¡¤Ìá¤êÃͤò½ñ¤­¹þ¤ó¤Ç¤Ï¤¤¤±¤Ê¤¤ */
401     thread_exit();
402     break;
403   case KZ_SYSCALL_TYPE_WAIT: /* kz_wait() */
404     p->un.wait.ret = thread_wait();
405     break;
406   case KZ_SYSCALL_TYPE_SLEEP: /* kz_sleep() */
407     p->un.sleep.ret = thread_sleep();
408     break;
409   case KZ_SYSCALL_TYPE_WAKEUP: /* kz_wakeup() */
410     p->un.wakeup.ret = thread_wakeup(p->un.wakeup.id);
411     break;
412   case KZ_SYSCALL_TYPE_GETID: /* kz_getid() */
413     p->un.getid.ret = thread_getid();
414     break;
415   case KZ_SYSCALL_TYPE_CHPRI: /* kz_chpri() */
416     p->un.chpri.ret = thread_chpri(p->un.chpri.priority);
417     break;
418   case KZ_SYSCALL_TYPE_KMALLOC: /* kz_kmalloc() */
419     p->un.kmalloc.ret = thread_kmalloc(p->un.kmalloc.size);
420     break;
421   case KZ_SYSCALL_TYPE_KMFREE: /* kz_kmfree() */
422     p->un.kmfree.ret = thread_kmfree(p->un.kmfree.p);
423     break;
424   case KZ_SYSCALL_TYPE_SEND: /* kz_send() */
425     p->un.send.ret = thread_send(p->un.send.id,
426                                  p->un.send.size, p->un.send.p);
427     break;
428   case KZ_SYSCALL_TYPE_RECV: /* kz_recv() */
429     p->un.recv.ret = thread_recv(p->un.recv.id,
430                                  p->un.recv.sizep, p->un.recv.pp);
431     break;
432   case KZ_SYSCALL_TYPE_SETINTR: /* kz_setintr() */
433     p->un.setintr.ret = thread_setintr(p->un.setintr.type,
434                                        p->un.setintr.handler);
435     break;
436   default:
437     break;
438   }
439 }
440
441 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î½èÍý */
442 static void syscall_proc(kz_syscall_type_t type, kz_syscall_param_t *p)
443 {
444   /*
445    * ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ò¸Æ¤Ó½Ð¤·¤¿¥¹¥ì¥Ã¥É¤ò¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤«¤é
446    * ³°¤·¤¿¾õÂ֤ǽèÍý´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹¡¥¤³¤Î¤¿¤á¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ò
447    * ¸Æ¤Ó½Ð¤·¤¿¥¹¥ì¥Ã¥É¤ò¤½¤Î¤Þ¤ÞÆ°ºî·Ñ³¤µ¤»¤¿¤¤¾ì¹ç¤Ë¤Ï¡¤
448    * ½èÍý´Ø¿ô¤ÎÆâÉô¤Ç putcurrent() ¤ò¹Ô¤¦É¬Íפ¬¤¢¤ë¡¥
449    */
450   getcurrent();
451   call_functions(type, p);
452 }
453
454 /* ¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤Î½èÍý */
455 static void srvcall_proc(kz_syscall_type_t type, kz_syscall_param_t *p)
456 {
457   /*
458    * ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤È¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤Î½èÍý´Ø¿ô¤ÎÆâÉô¤Ç¡¤
459    * ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤Î¼Â¹Ô¤·¤¿¥¹¥ì¥Ã¥ÉID¤òÆÀ¤ë¤¿¤á¤Ë current ¤ò
460    * »²¾È¤·¤Æ¤¤¤ëÉôʬ¤¬¤¢¤ê(¤¿¤È¤¨¤Ð thread_send() ¤Ê¤É)¡¤
461    * current ¤¬»Ä¤Ã¤Æ¤¤¤ë¤È¸íÆ°ºî¤¹¤ë¤¿¤á NULL ¤ËÀßÄꤹ¤ë¡¥
462    * ¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤Ï thread_intrvec() ÆâÉô¤Î³ä¹þ¤ß¥Ï¥ó¥É¥é¸Æ¤Ó½Ð¤·¤Î
463    * ±äĹ¤Ç¸Æ¤Ð¤ì¤Æ¤¤¤ë¤Ï¤º¤Ç¤Ê¤Î¤Ç¡¤¸Æ¤Ó½Ð¤·¸å¤Ë thread_intrvec() ¤Ç
464    * ¥¹¥±¥¸¥å¡¼¥ê¥ó¥°½èÍý¤¬¹Ô¤ï¤ì¡¤current ¤ÏºÆÀßÄꤵ¤ì¤ë¡¥
465    */
466   current = NULL;
467   call_functions(type, p);
468 }
469
470 /* ¥¹¥ì¥Ã¥É¤Î¥¹¥±¥¸¥å¡¼¥ê¥ó¥° */
471 static void schedule(void)
472 {
473   int i;
474
475   /*
476    * Í¥Àè½ç°Ì¤Î¹â¤¤½ç(Í¥ÀèÅ٤οôÃͤµ¤¤½ç)¤Ë¥ì¥Ç¥£¡¼¡¦¥­¥å¡¼¤ò¸«¤Æ¡¤
477    * Æ°ºî²Äǽ¤Ê¥¹¥ì¥Ã¥É¤ò¸¡º÷¤¹¤ë¡¥
478    */
479   for (i = 0; i < PRIORITY_NUM; i++) {
480     if (readyque[i].head) /* ¸«¤Ä¤«¤Ã¤¿ */
481       break;
482   }
483   if (i == PRIORITY_NUM) /* ¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿ */
484     kz_sysdown();
485
486   current = readyque[i].head; /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤ËÀßÄꤹ¤ë */
487 }
488
489 static void syscall_intr(void)
490 {
491   syscall_proc(current->syscall.type, current->syscall.param);
492 }
493
494 static void softerr_intr(void)
495 {
496   puts(current->name);
497   puts(" DOWN.\n");
498   getcurrent(); /* ¥ì¥Ç¥£¡¼¥­¥å¡¼¤«¤é³°¤¹ */
499   thread_exit(); /* ¥¹¥ì¥Ã¥É½ªÎ»¤¹¤ë */
500 }
501
502 /* ³ä¹þ¤ß½èÍý¤ÎÆþ¸ý´Ø¿ô */
503 static void thread_intr(softvec_type_t type, unsigned long sp)
504 {
505   /* ¥«¥ì¥ó¥È¡¦¥¹¥ì¥Ã¥É¤Î¥³¥ó¥Æ¥­¥¹¥È¤òÊݸ¤¹¤ë */
506   current->context.sp = sp;
507
508   /*
509    * ³ä¹þ¤ß¤´¤È¤Î½èÍý¤ò¼Â¹Ô¤¹¤ë¡¥
510    * SOFTVEC_TYPE_SYSCALL, SOFTVEC_TYPE_SOFTERR ¤Î¾ì¹ç¤Ï
511    * syscall_intr(), softerr_intr() ¤¬¥Ï¥ó¥É¥é¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¤
512    * ¤½¤ì¤é¤¬¼Â¹Ô¤µ¤ì¤ë¡¥
513    * ¤½¤ì°Ê³°¤Î¾ì¹ç¤Ï¡¤kz_setintr()¤Ë¤è¤Ã¤Æ¥æ¡¼¥¶ÅÐÏ¿¤µ¤ì¤¿¥Ï¥ó¥É¥é¤¬
514    * ¼Â¹Ô¤µ¤ì¤ë¡¥
515    */
516   if (handlers[type])
517     handlers[type]();
518
519   schedule(); /* ¥¹¥ì¥Ã¥É¤Î¥¹¥±¥¸¥å¡¼¥ê¥ó¥° */
520
521   /*
522    * ¥¹¥ì¥Ã¥É¤Î¥Ç¥£¥¹¥Ñ¥Ã¥Á
523    * (dispatch()´Ø¿ô¤ÎËÜÂΤÏstartup.s¤Ë¤¢¤ê¡¤¥¢¥»¥ó¥Ö¥é¤Çµ­½Ò¤µ¤ì¤Æ¤¤¤ë)
524    */
525   dispatch(&current->context);
526   /* ¤³¤³¤Ë¤ÏÊ֤äƤ³¤Ê¤¤ */
527 }
528
529 void kz_start(kz_func_t func, char *name, int priority, int stacksize,
530               int argc, char *argv[])
531 {
532   kzmem_init(); /* Æ°Åª¥á¥â¥ê¤Î½é´ü²½ */
533
534   /*
535    * °Ê¹ß¤Ç¸Æ¤Ó½Ð¤¹¥¹¥ì¥Ã¥É´ØÏ¢¤Î¥é¥¤¥Ö¥é¥ê´Ø¿ô¤ÎÆâÉô¤Ç current ¤ò
536    * ¸«¤Æ¤¤¤ë¾ì¹ç¤¬¤¢¤ë¤Î¤Ç¡¤current ¤ò NULL ¤Ë½é´ü²½¤·¤Æ¤ª¤¯¡¥
537    */
538   current = NULL;
539
540   memset(readyque, 0, sizeof(readyque));
541   memset(threads,  0, sizeof(threads));
542   memset(handlers, 0, sizeof(handlers));
543   memset(msgboxes, 0, sizeof(msgboxes));
544
545   /* ³ä¹þ¤ß¥Ï¥ó¥É¥é¤ÎÅÐÏ¿ */
546   thread_setintr(SOFTVEC_TYPE_SYSCALL, syscall_intr); /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë */
547   thread_setintr(SOFTVEC_TYPE_SOFTERR, softerr_intr); /* ¥À¥¦¥óÍ×°øȯÀ¸ */
548
549   /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ëȯ¹ÔÉԲĤʤΤÇľÀÜ´Ø¿ô¤ò¸Æ¤Ó½Ð¤·¤Æ¥¹¥ì¥Ã¥ÉºîÀ®¤¹¤ë */
550   current = (kz_thread *)thread_run(func, name, priority, stacksize,
551                                     argc, argv);
552
553   /* ºÇ½é¤Î¥¹¥ì¥Ã¥É¤òµ¯Æ° */
554   dispatch(&current->context);
555
556   /* ¤³¤³¤Ë¤ÏÊ֤äƤ³¤Ê¤¤ */
557 }
558
559 void kz_sysdown(void)
560 {
561   puts("system error!\n");
562   while (1)
563     ;
564 }
565
566 /* ¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¸Æ¤Ó½Ð¤·Íѥ饤¥Ö¥é¥ê´Ø¿ô */
567 void kz_syscall(kz_syscall_type_t type, kz_syscall_param_t *param)
568 {
569   current->syscall.type  = type;
570   current->syscall.param = param;
571   asm volatile ("trapa #0"); /* ¥È¥é¥Ã¥×³ä¹þ¤ßȯ¹Ô */
572 }
573
574 /* ¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¸Æ¤Ó½Ð¤·Íѥ饤¥Ö¥é¥ê´Ø¿ô */
575 void kz_srvcall(kz_syscall_type_t type, kz_syscall_param_t *param)
576 {
577   srvcall_proc(type, param);
578 }