This source file includes following definitions.
- printint
- cprintf
- panic
- cgaputc
- consputc
- consoleintr
- consoleread
- consolewrite
- consoleinit
1
2
3
4
5 #include "types.h"
6 #include "defs.h"
7 #include "param.h"
8 #include "traps.h"
9 #include "spinlock.h"
10 #include "sleeplock.h"
11 #include "fs.h"
12 #include "file.h"
13 #include "memlayout.h"
14 #include "mmu.h"
15 #include "proc.h"
16 #include "x86.h"
17
18 static void consputc(int);
19
20 static int panicked = 0;
21
22 static struct {
23 struct spinlock lock;
24 int locking;
25 } cons;
26
27 static void
28 printint(int xx, int base, int sign)
29 {
30 static char digits[] = "0123456789abcdef";
31 char buf[16];
32 int i;
33 uint x;
34
35 if(sign && (sign = xx < 0))
36 x = -xx;
37 else
38 x = xx;
39
40 i = 0;
41 do{
42 buf[i++] = digits[x % base];
43 }while((x /= base) != 0);
44
45 if(sign)
46 buf[i++] = '-';
47
48 while(--i >= 0)
49 consputc(buf[i]);
50 }
51
52
53
54 void
55 cprintf(char *fmt, ...)
56 {
57 int i, c, locking;
58 uint *argp;
59 char *s;
60
61 locking = cons.locking;
62 if(locking)
63 acquire(&cons.lock);
64
65 if (fmt == 0)
66 panic("null fmt");
67
68 argp = (uint*)(void*)(&fmt + 1);
69 for(i = 0; (c = fmt[i] & 0xff) != 0; i++){
70 if(c != '%'){
71 consputc(c);
72 continue;
73 }
74 c = fmt[++i] & 0xff;
75 if(c == 0)
76 break;
77 switch(c){
78 case 'd':
79 printint(*argp++, 10, 1);
80 break;
81 case 'x':
82 case 'p':
83 printint(*argp++, 16, 0);
84 break;
85 case 's':
86 if((s = (char*)*argp++) == 0)
87 s = "(null)";
88 for(; *s; s++)
89 consputc(*s);
90 break;
91 case '%':
92 consputc('%');
93 break;
94 default:
95
96 consputc('%');
97 consputc(c);
98 break;
99 }
100 }
101
102 if(locking)
103 release(&cons.lock);
104 }
105
106 void
107 panic(char *s)
108 {
109 int i;
110 uint pcs[10];
111
112 cli();
113 cons.locking = 0;
114
115 cprintf("lapicid %d: panic: ", lapicid());
116 cprintf(s);
117 cprintf("\n");
118 getcallerpcs(&s, pcs);
119 for(i=0; i<10; i++)
120 cprintf(" %p", pcs[i]);
121 panicked = 1;
122 for(;;)
123 ;
124 }
125
126
127 #define BACKSPACE 0x100
128 #define CRTPORT 0x3d4
129 static ushort *crt = (ushort*)P2V(0xb8000);
130
131 static void
132 cgaputc(int c)
133 {
134 int pos;
135
136
137 outb(CRTPORT, 14);
138 pos = inb(CRTPORT+1) << 8;
139 outb(CRTPORT, 15);
140 pos |= inb(CRTPORT+1);
141
142 if(c == '\n')
143 pos += 80 - pos%80;
144 else if(c == BACKSPACE){
145 if(pos > 0) --pos;
146 } else
147 crt[pos++] = (c&0xff) | 0x0700;
148
149 if(pos < 0 || pos > 25*80)
150 panic("pos under/overflow");
151
152 if((pos/80) >= 24){
153 memmove(crt, crt+80, sizeof(crt[0])*23*80);
154 pos -= 80;
155 memset(crt+pos, 0, sizeof(crt[0])*(24*80 - pos));
156 }
157
158 outb(CRTPORT, 14);
159 outb(CRTPORT+1, pos>>8);
160 outb(CRTPORT, 15);
161 outb(CRTPORT+1, pos);
162 crt[pos] = ' ' | 0x0700;
163 }
164
165 void
166 consputc(int c)
167 {
168 if(panicked){
169 cli();
170 for(;;)
171 ;
172 }
173
174 if(c == BACKSPACE){
175 uartputc('\b'); uartputc(' '); uartputc('\b');
176 } else
177 uartputc(c);
178 cgaputc(c);
179 }
180
181 #define INPUT_BUF 128
182 struct {
183 char buf[INPUT_BUF];
184 uint r;
185 uint w;
186 uint e;
187 } input;
188
189 #define C(x) ((x)-'@')
190
191 void
192 consoleintr(int (*getc)(void))
193 {
194 int c, doprocdump = 0;
195
196 acquire(&cons.lock);
197 while((c = getc()) >= 0){
198 switch(c){
199 case C('P'):
200
201 doprocdump = 1;
202 break;
203 case C('U'):
204 while(input.e != input.w &&
205 input.buf[(input.e-1) % INPUT_BUF] != '\n'){
206 input.e--;
207 consputc(BACKSPACE);
208 }
209 break;
210 case C('H'): case '\x7f':
211 if(input.e != input.w){
212 input.e--;
213 consputc(BACKSPACE);
214 }
215 break;
216 default:
217 if(c != 0 && input.e-input.r < INPUT_BUF){
218 c = (c == '\r') ? '\n' : c;
219 input.buf[input.e++ % INPUT_BUF] = c;
220 consputc(c);
221 if(c == '\n' || c == C('D') || input.e == input.r+INPUT_BUF){
222 input.w = input.e;
223 wakeup(&input.r);
224 }
225 }
226 break;
227 }
228 }
229 release(&cons.lock);
230 if(doprocdump) {
231 procdump();
232 }
233 }
234
235 int
236 consoleread(struct inode *ip, char *dst, int n)
237 {
238 uint target;
239 int c;
240
241 iunlock(ip);
242 target = n;
243 acquire(&cons.lock);
244 while(n > 0){
245 while(input.r == input.w){
246 if(myproc()->killed){
247 release(&cons.lock);
248 ilock(ip);
249 return -1;
250 }
251 sleep(&input.r, &cons.lock);
252 }
253 c = input.buf[input.r++ % INPUT_BUF];
254 if(c == C('D')){
255 if(n < target){
256
257
258 input.r--;
259 }
260 break;
261 }
262 *dst++ = c;
263 --n;
264 if(c == '\n')
265 break;
266 }
267 release(&cons.lock);
268 ilock(ip);
269
270 return target - n;
271 }
272
273 int
274 consolewrite(struct inode *ip, char *buf, int n)
275 {
276 int i;
277
278 iunlock(ip);
279 acquire(&cons.lock);
280 for(i = 0; i < n; i++)
281 consputc(buf[i] & 0xff);
282 release(&cons.lock);
283 ilock(ip);
284
285 return n;
286 }
287
288 void
289 consoleinit(void)
290 {
291 initlock(&cons.lock, "console");
292
293 devsw[CONSOLE].write = consolewrite;
294 devsw[CONSOLE].read = consoleread;
295 cons.locking = 1;
296
297 ioapicenable(IRQ_KBD, 0);
298 }
299