Mercurial > hg > CbC > CbC_xv6
comparison src/console.c @ 0:83c23a36980d
Init
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 26 May 2017 23:11:05 +0900 |
parents | |
children | 36bd61f5c847 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:83c23a36980d |
---|---|
1 // Console input and output. | |
2 // Input is from the keyboard or serial port. | |
3 // Output is written to the screen and serial port. | |
4 | |
5 #include "types.h" | |
6 #include "defs.h" | |
7 #include "param.h" | |
8 #include "spinlock.h" | |
9 #include "fs.h" | |
10 #include "file.h" | |
11 #include "memlayout.h" | |
12 #include "mmu.h" | |
13 #include "proc.h" | |
14 | |
15 static void consputc (int); | |
16 | |
17 static int panicked = 0; | |
18 | |
19 static struct { | |
20 struct spinlock lock; | |
21 int locking; | |
22 } cons; | |
23 | |
24 static void printint (int xx, int base, int sign) | |
25 { | |
26 static char digits[] = "0123456789abcdef"; | |
27 char buf[16]; | |
28 int i; | |
29 uint x; | |
30 | |
31 if (sign && (sign = xx < 0)) { | |
32 x = -xx; | |
33 } else { | |
34 x = xx; | |
35 } | |
36 | |
37 i = 0; | |
38 | |
39 do { | |
40 buf[i++] = digits[x % base]; | |
41 } while ((x /= base) != 0); | |
42 | |
43 if (sign) { | |
44 buf[i++] = '-'; | |
45 } | |
46 | |
47 while (--i >= 0) { | |
48 consputc(buf[i]); | |
49 } | |
50 } | |
51 //PAGEBREAK: 50 | |
52 | |
53 // Print to the console. only understands %d, %x, %p, %s. | |
54 void cprintf (char *fmt, ...) | |
55 { | |
56 int i, c, locking; | |
57 uint *argp; | |
58 char *s; | |
59 | |
60 locking = cons.locking; | |
61 | |
62 if (locking) { | |
63 acquire(&cons.lock); | |
64 } | |
65 | |
66 if (fmt == 0) { | |
67 panic("null fmt"); | |
68 } | |
69 | |
70 argp = (uint*) (void*) (&fmt + 1); | |
71 | |
72 for (i = 0; (c = fmt[i] & 0xff) != 0; i++) { | |
73 if (c != '%') { | |
74 consputc(c); | |
75 continue; | |
76 } | |
77 | |
78 c = fmt[++i] & 0xff; | |
79 | |
80 if (c == 0) { | |
81 break; | |
82 } | |
83 | |
84 switch (c) { | |
85 case 'd': | |
86 printint(*argp++, 10, 1); | |
87 break; | |
88 | |
89 case 'x': | |
90 case 'p': | |
91 printint(*argp++, 16, 0); | |
92 break; | |
93 | |
94 case 's': | |
95 if ((s = (char*) *argp++) == 0) { | |
96 s = "(null)"; | |
97 } | |
98 | |
99 for (; *s; s++) { | |
100 consputc(*s); | |
101 } | |
102 break; | |
103 | |
104 case '%': | |
105 consputc('%'); | |
106 break; | |
107 | |
108 default: | |
109 // Print unknown % sequence to draw attention. | |
110 consputc('%'); | |
111 consputc(c); | |
112 break; | |
113 } | |
114 } | |
115 | |
116 if (locking) { | |
117 release(&cons.lock); | |
118 } | |
119 } | |
120 | |
121 void panic (char *s) | |
122 { | |
123 cli(); | |
124 | |
125 cons.locking = 0; | |
126 | |
127 cprintf("cpu%d: panic: ", cpu->id); | |
128 | |
129 show_callstk(s); | |
130 panicked = 1; // freeze other CPU | |
131 | |
132 while (1) | |
133 ; | |
134 } | |
135 | |
136 //PAGEBREAK: 50 | |
137 #define BACKSPACE 0x100 | |
138 #define CRTPORT 0x3d4 | |
139 | |
140 void consputc (int c) | |
141 { | |
142 if (panicked) { | |
143 cli(); | |
144 while (1) | |
145 ; | |
146 } | |
147 | |
148 if (c == BACKSPACE) { | |
149 uartputc('\b'); | |
150 uartputc(' '); | |
151 uartputc('\b'); | |
152 } else { | |
153 uartputc(c); | |
154 } | |
155 | |
156 // cgaputc(c); | |
157 } | |
158 | |
159 #define INPUT_BUF 512 | |
160 struct { | |
161 struct spinlock lock; | |
162 char buf[INPUT_BUF]; | |
163 uint r; // Read index | |
164 uint w; // Write index | |
165 uint e; // Edit index | |
166 } input; | |
167 | |
168 #define C(x) ((x)-'@') // Control-x | |
169 void consoleintr (int (*getc) (void)) | |
170 { | |
171 int c; | |
172 | |
173 acquire(&input.lock); | |
174 | |
175 while ((c = getc()) >= 0) { | |
176 switch (c) { | |
177 case C('P'): // Process listing. | |
178 procdump(); | |
179 break; | |
180 | |
181 case C('U'): // Kill line. | |
182 while ((input.e != input.w) && (input.buf[(input.e - 1) % INPUT_BUF] != '\n')) { | |
183 input.e--; | |
184 consputc(BACKSPACE); | |
185 } | |
186 | |
187 break; | |
188 | |
189 case C('H'): | |
190 case '\x7f': // Backspace | |
191 if (input.e != input.w) { | |
192 input.e--; | |
193 consputc(BACKSPACE); | |
194 } | |
195 | |
196 break; | |
197 | |
198 default: | |
199 if ((c != 0) && (input.e - input.r < INPUT_BUF)) { | |
200 c = (c == '\r') ? '\n' : c; | |
201 | |
202 input.buf[input.e++ % INPUT_BUF] = c; | |
203 consputc(c); | |
204 | |
205 if (c == '\n' || c == C('D') || input.e == input.r + INPUT_BUF) { | |
206 input.w = input.e; | |
207 wakeup(&input.r); | |
208 } | |
209 } | |
210 | |
211 break; | |
212 } | |
213 } | |
214 | |
215 release(&input.lock); | |
216 } | |
217 | |
218 int consoleread (struct inode *ip, char *dst, int n) | |
219 { | |
220 uint target; | |
221 int c; | |
222 | |
223 iunlock(ip); | |
224 | |
225 target = n; | |
226 acquire(&input.lock); | |
227 | |
228 while (n > 0) { | |
229 while (input.r == input.w) { | |
230 if (proc->killed) { | |
231 release(&input.lock); | |
232 ilock(ip); | |
233 return -1; | |
234 } | |
235 | |
236 sleep(&input.r, &input.lock); | |
237 } | |
238 | |
239 c = input.buf[input.r++ % INPUT_BUF]; | |
240 | |
241 if (c == C('D')) { // EOF | |
242 if (n < target) { | |
243 // Save ^D for next time, to make sure | |
244 // caller gets a 0-byte result. | |
245 input.r--; | |
246 } | |
247 | |
248 break; | |
249 } | |
250 | |
251 *dst++ = c; | |
252 --n; | |
253 | |
254 if (c == '\n') { | |
255 break; | |
256 } | |
257 } | |
258 | |
259 release(&input.lock); | |
260 ilock(ip); | |
261 | |
262 return target - n; | |
263 } | |
264 | |
265 int consolewrite (struct inode *ip, char *buf, int n) | |
266 { | |
267 int i; | |
268 | |
269 iunlock(ip); | |
270 | |
271 acquire(&cons.lock); | |
272 | |
273 for (i = 0; i < n; i++) { | |
274 consputc(buf[i] & 0xff); | |
275 } | |
276 | |
277 release(&cons.lock); | |
278 | |
279 ilock(ip); | |
280 | |
281 return n; | |
282 } | |
283 | |
284 void consoleinit (void) | |
285 { | |
286 initlock(&cons.lock, "console"); | |
287 initlock(&input.lock, "input"); | |
288 | |
289 devsw[CONSOLE].write = consolewrite; | |
290 devsw[CONSOLE].read = consoleread; | |
291 | |
292 cons.locking = 1; | |
293 } | |
294 |