OSDN Git Service

Step 10 added.
[kozos-expbrd/kozos_expbrd.git] / firm / junk / 10 / os / driver / driver_console.c
1 #include "defines.h"
2 #include "kozos.h"
3 #include "intr.h"
4 #include "interrupt.h"
5 #include "serial.h"
6 #include "lib.h"
7 #include "driver_console.h"
8
9 #define CONS_BUFFER_SIZE 32
10
11 #define CONSDRV_CMD_USE   'u' /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï */
12 #define CONSDRV_CMD_WRITE 'w' /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎÏ */
13
14 static struct consreg {
15   kz_thread_id_t id; /* ¥³¥ó¥½¡¼¥ë¤òÍøÍѤ¹¤ë¥¹¥ì¥Ã¥É */
16   int index;         /* ÍøÍѤ¹¤ë¥·¥ê¥¢¥ë¤ÎÈÖ¹æ */
17
18   char *send_buf;    /* Á÷¿®¥Ð¥Ã¥Õ¥¡ */
19   char *recv_buf;    /* ¼õ¿®¥Ð¥Ã¥Õ¥¡ */
20   int send_len;      /* Á÷¿®¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥Ç¡¼¥¿¥µ¥¤¥º */
21   int recv_len;      /* ¼õ¿®¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥Ç¡¼¥¿¥µ¥¤¥º */
22
23   /* kozos.c ¤Î kz_msgbox ¤ÈƱÍͤÎÍýͳ¤Ç¡¤¥À¥ß¡¼¡¦¥á¥ó¥Ð¤Ç¥µ¥¤¥ºÄ´À°¤¹¤ë */
24   long dummy[3];
25 } consreg[CONSDRV_DEVICE_NUM];
26
27 /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï¤ò¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
28 void console_use(int index)
29 {
30   char *p;
31   p = kz_kmalloc(3);
32   p[0] = '0';
33   p[1] = CONSDRV_CMD_USE;
34   p[2] = '0' + index;
35   kz_send(MSGBOX_ID_CONSOUTPUT, 3, p);
36 }
37
38 /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎϤò¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
39 void console_write(char *str)
40 {
41   char *p;
42   int len;
43   len = strlen(str);
44   p = kz_kmalloc(len + 2);
45   p[0] = '0';
46   p[1] = CONSDRV_CMD_WRITE;
47   memcpy(&p[2], str, len);
48   kz_send(MSGBOX_ID_CONSOUTPUT, len + 2, p);
49 }
50
51 /*
52  * °Ê²¼¤Î£²¤Ä¤Î´Ø¿ô(send_char(), send_string())¤Ï³ä¹þ¤ß½èÍý¤È¥¹¥ì¥Ã¥É¤«¤é
53  * ¸Æ¤Ð¤ì¤ë¤¬Á÷¿®¥Ð¥Ã¥Õ¥¡¤òÁàºî¤·¤Æ¤ª¤êºÆÆþÉԲĤΤ¿¤á¡¤¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ó½Ð¤¹
54  * ¾ì¹ç¤ÏÇÓ¾¤Î¤¿¤á³ä¹þ¤ß¶Ø»ß¾õÂ֤ǸƤ֤³¤È¡¥
55  */
56
57 /* Á÷¿®¥Ð¥Ã¥Õ¥¡¤ÎÀèƬ£±Ê¸»ú¤òÁ÷¿®¤¹¤ë */
58 static void send_char(struct consreg *cons)
59 {
60   int i;
61   serial_send_byte(cons->index, cons->send_buf[0]);
62   cons->send_len--;
63   /* ÀèƬʸ»ú¤òÁ÷¿®¤·¤¿¤Î¤Ç¡¤£±Ê¸»ú¤Ö¤ó¤º¤é¤¹ */
64   for (i = 0; i < cons->send_len; i++)
65     cons->send_buf[i] = cons->send_buf[i + 1];
66 }
67
68 /* Ê¸»úÎó¤òÁ÷¿®¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤­¹þ¤ßÁ÷¿®³«»Ï¤¹¤ë */
69 static void send_string(struct consreg *cons, char *str, int len)
70 {
71   int i;
72   for (i = 0; i < len; i++) { /* Ê¸»úÎó¤òÁ÷¿®¥Ð¥Ã¥Õ¥¡¤Ë¥³¥Ô¡¼ */
73     if (str[i] == '\n') /* \n¢ª\r\n¤ËÊÑ´¹ */
74       cons->send_buf[cons->send_len++] = '\r';
75     cons->send_buf[cons->send_len++] = str[i];
76   }
77   /*
78    * Á÷¿®³ä¹þ¤ß̵¸ú¤Ê¤é¤Ð¡¤Á÷¿®³«»Ï¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤ÇÁ÷¿®³«»Ï¤¹¤ë¡¥
79    * Á÷¿®³ä¹þ¤ßÍ­¸ú¤Ê¤é¤ÐÁ÷¿®³«»Ï¤µ¤ì¤Æ¤ª¤ê¡¤Á÷¿®³ä¹þ¤ß¤Î±äŤÇ
80    * Á÷¿®¥Ð¥Ã¥Õ¥¡Æâ¤Î¥Ç¡¼¥¿¤¬½ç¼¡Á÷¿®¤µ¤ì¤ë¤Î¤Ç¡¤²¿¤â¤·¤Ê¤¯¤Æ¤è¤¤¡¥
81    */
82   if (cons->send_len && !serial_intr_is_send_enable(cons->index)) {
83     serial_intr_send_enable(cons->index); /* Á÷¿®³ä¹þ¤ßÍ­¸ú²½ */
84     send_char(cons); /* Á÷¿®³«»Ï */
85   }
86 }
87
88 /*
89  * °Ê²¼¤Ï³ä¹þ¤ß¥Ï¥ó¥É¥é¤«¤é¸Æ¤Ð¤ì¤ë³ä¹þ¤ß½èÍý¤Ç¤¢¤ê¡¤ÈóƱ´ü¤Ç
90  * ¸Æ¤Ð¤ì¤ë¤Î¤Ç¡¤¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Ê¤É¤ò¸Æ¤Ó½Ð¤¹¾ì¹ç¤Ë¤ÏÃí°Õ¤¬É¬Íס¥
91  * ´ðËܤȤ·¤Æ¡¤°Ê²¼¤Î¤¤¤º¤ì¤«¤ËÅö¤Æ¤Ï¤Þ¤ë´Ø¿ô¤·¤«¸Æ¤Ó½Ð¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
92  * ¡¦ºÆÆþ²Äǽ¤Ç¤¢¤ë¡¥
93  * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤Ï̵¤¤´Ø¿ô¤Ç¤¢¤ë¡¥
94  * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤¬¤¢¤ë¤¬¡¤³ä¹þ¤ß¶Ø»ß¤Ç¸Æ¤Ó½Ð¤·¤Æ¤¤¤ë¡¥
95  * ¤Þ¤¿Èó¥³¥ó¥Æ¥­¥¹¥È¾õÂ֤ǸƤФì¤ë¤¿¤á¡¤¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ÏÍøÍѤ·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
96  * (¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë¤³¤È)
97  */
98 static int consdrv_intrproc(struct consreg *cons)
99 {
100   unsigned char c;
101   char *p;
102
103   if (serial_is_recv_enable(cons->index)) { /* ¼õ¿®³ä¹þ¤ß */
104     c = serial_recv_byte(cons->index);
105     if (c == '\r') /* ²þ¹Ô¥³¡¼¥ÉÊÑ´¹(\r¢ª\n) */
106       c = '\n';
107
108     send_string(cons, &c, 1); /* ¥¨¥³¡¼¥Ð¥Ã¥¯½èÍý */
109
110     if (cons->id) {
111       if (c != '\n') {
112         /* ²þ¹Ô¤Ç¤Ê¤¤¤Ê¤é¡¤¼õ¿®¥Ð¥Ã¥Õ¥¡¤Ë¥Ð¥Ã¥Õ¥¡¥ê¥ó¥°¤¹¤ë */
113         cons->recv_buf[cons->recv_len++] = c;
114       } else {
115         /*
116          * Enter¤¬²¡¤µ¤ì¤¿¤é¡¤¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤò
117          * ¥³¥Þ¥ó¥É½èÍý¥¹¥ì¥Ã¥É¤ËÄÌÃΤ¹¤ë¡¥
118          * (³ä¹þ¤ß¥Ï¥ó¥É¥é¤Ê¤Î¤Ç¡¤¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë)
119          */
120         p = kx_kmalloc(CONS_BUFFER_SIZE);
121         memcpy(p, cons->recv_buf, cons->recv_len);
122         kx_send(MSGBOX_ID_CONSINPUT, cons->recv_len, p);
123         cons->recv_len = 0;
124       }
125     }
126   }
127
128   if (serial_is_send_enable(cons->index)) { /* Á÷¿®³ä¹þ¤ß */
129     if (!cons->id || !cons->send_len) {
130       /* Á÷¿®¥Ç¡¼¥¿¤¬Ìµ¤¤¤Ê¤é¤Ð¡¤Á÷¿®½èÍý½ªÎ» */
131       serial_intr_send_disable(cons->index);
132     } else {
133       /* Á÷¿®¥Ç¡¼¥¿¤¬¤¢¤ë¤Ê¤é¤Ð¡¤°ú³¤­Á÷¿®¤¹¤ë */
134       send_char(cons);
135     }
136   }
137
138   return 0;
139 }
140
141 /* ³ä¹þ¤ß¥Ï¥ó¥É¥é */
142 static void consdrv_intr(void)
143 {
144   int i;
145   struct consreg *cons;
146
147   for (i = 0; i < CONSDRV_DEVICE_NUM; i++) {
148     cons = &consreg[i];
149     if (cons->id) {
150       if (serial_is_send_enable(cons->index) ||
151           serial_is_recv_enable(cons->index))
152         /* ³ä¹þ¤ß¤¬¤¢¤ë¤Ê¤é¤Ð¡¤³ä¹þ¤ß½èÍý¤ò¸Æ¤Ó½Ð¤¹ */
153         consdrv_intrproc(cons);
154     }
155   }
156 }
157
158 static int consdrv_init(void)
159 {
160   memset(consreg, 0, sizeof(consreg));
161   return 0;
162 }
163
164 /* ¥¹¥ì¥Ã¥É¤«¤é¤ÎÍ×µá¤ò½èÍý¤¹¤ë */
165 static int consdrv_command(struct consreg *cons, kz_thread_id_t id,
166                            int index, int size, char *command)
167 {
168   switch (command[0]) {
169   case CONSDRV_CMD_USE: /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï */
170     cons->id = id;
171     cons->index = command[1] - '0';
172     cons->send_buf = kz_kmalloc(CONS_BUFFER_SIZE);
173     cons->recv_buf = kz_kmalloc(CONS_BUFFER_SIZE);
174     cons->send_len = 0;
175     cons->recv_len = 0;
176     serial_init(cons->index);
177     serial_intr_recv_enable(cons->index); /* ¼õ¿®³ä¹þ¤ßÍ­¸ú²½(¼õ¿®³«»Ï) */
178     break;
179
180   case CONSDRV_CMD_WRITE: /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎÏ */
181     /*
182      * send_string()¤Ç¤ÏÁ÷¿®¥Ð¥Ã¥Õ¥¡¤òÁàºî¤·¤Æ¤ª¤êºÆÆþÉԲĤʤΤǡ¤
183      * ÇÓ¾¤Î¤¿¤á¤Ë³ä¹þ¤ß¶Ø»ß¤Ë¤·¤Æ¸Æ¤Ó½Ð¤¹¡¥
184      */
185     INTR_DISABLE;
186     send_string(cons, command + 1, size - 1); /* Ê¸»úÎó¤ÎÁ÷¿® */
187     INTR_ENABLE;
188     break;
189
190   default:
191     break;
192   }
193
194   return 0;
195 }
196
197 int driver_console(int argc, char *argv[])
198 {
199   int size, index;
200   kz_thread_id_t id;
201   char *p;
202
203   consdrv_init();
204   kz_setintr(SOFTVEC_TYPE_SERINTR, consdrv_intr); /* ³ä¹þ¤ß¥Ï¥ó¥É¥éÀßÄê */
205
206   while (1) {
207     id = kz_recv(MSGBOX_ID_CONSOUTPUT, &size, &p);
208     index = p[0] - '0';
209     consdrv_command(&consreg[index], id, index, size - 1, p + 1);
210     kz_kmfree(p);
211   }
212
213   return 0;
214 }