This source file includes following definitions.
- consputc
- consolewrite
- consoleread
- consoleintr
- consoleinit
1
2
3
4
5
6
7
8
9
10
11
12 #include <stdarg.h>
13
14 #include "types.h"
15 #include "param.h"
16 #include "spinlock.h"
17 #include "sleeplock.h"
18 #include "fs.h"
19 #include "file.h"
20 #include "memlayout.h"
21 #include "riscv.h"
22 #include "defs.h"
23 #include "proc.h"
24
25 #define BACKSPACE 0x100
26 #define C(x) ((x) - '@')
27
28
29
30
31
32
33
34 void
35 consputc(int c)
36 {
37 if (c == BACKSPACE) {
38
39 uartputc_sync('\b');
40 uartputc_sync(' ');
41 uartputc_sync('\b');
42 } else {
43 uartputc_sync(c);
44 }
45 }
46
47 struct {
48 struct spinlock lock;
49
50
51 #define INPUT_BUF_SIZE 128
52 char buf[INPUT_BUF_SIZE];
53 uint r;
54 uint w;
55 uint e;
56 } cons;
57
58
59
60
61
62 int
63 consolewrite(int user_src, uint64 src, int n)
64 {
65 char buf[32];
66 int i = 0;
67
68 while (i < n) {
69 int nn = sizeof(buf);
70 if (nn > n - i)
71 nn = n - i;
72 if (either_copyin(buf, user_src, src + i, nn) == -1)
73 break;
74 uartwrite(buf, nn);
75 i += nn;
76 }
77
78 return i;
79 }
80
81
82
83
84
85
86
87 int
88 consoleread(int user_dst, uint64 dst, int n)
89 {
90 uint target;
91 int c;
92 char cbuf;
93
94 target = n;
95 acquire(&cons.lock);
96 while (n > 0) {
97
98
99 while (cons.r == cons.w) {
100 if (killed(myproc())) {
101 release(&cons.lock);
102 return -1;
103 }
104 sleep_prepare(&cons.r);
105 release(&cons.lock);
106 sleep();
107 acquire(&cons.lock);
108 }
109
110 c = cons.buf[cons.r++ % INPUT_BUF_SIZE];
111
112 if (c == C('D')) {
113 if (n < target) {
114
115
116 cons.r--;
117 }
118 break;
119 }
120
121
122 cbuf = c;
123 if (either_copyout(user_dst, dst, &cbuf, 1) == -1)
124 break;
125
126 dst++;
127 --n;
128
129 if (c == '\n') {
130
131
132 break;
133 }
134 }
135 release(&cons.lock);
136
137 return target - n;
138 }
139
140
141
142
143
144
145
146 void
147 consoleintr(int c)
148 {
149 acquire(&cons.lock);
150
151 switch (c) {
152 case C('P'):
153 procdump();
154 break;
155 case C('U'):
156 while (cons.e != cons.w &&
157 cons.buf[(cons.e - 1) % INPUT_BUF_SIZE] != '\n') {
158 cons.e--;
159 consputc(BACKSPACE);
160 }
161 break;
162 case C('H'):
163 case '\x7f':
164 if (cons.e != cons.w) {
165 cons.e--;
166 consputc(BACKSPACE);
167 }
168 break;
169 default:
170 if (c != 0 && cons.e - cons.r < INPUT_BUF_SIZE) {
171 c = (c == '\r') ? '\n' : c;
172
173
174 consputc(c);
175
176
177 cons.buf[cons.e++ % INPUT_BUF_SIZE] = c;
178
179 if (c == '\n' || c == C('D') || cons.e - cons.r == INPUT_BUF_SIZE) {
180
181
182 cons.w = cons.e;
183 wakeup(&cons.r);
184 }
185 }
186 break;
187 }
188
189 release(&cons.lock);
190 }
191
192 void
193 consoleinit(void)
194 {
195 initlock(&cons.lock, "cons");
196
197 uartinit();
198
199
200
201 devsw[CONSOLE].read = consoleread;
202 devsw[CONSOLE].write = consolewrite;
203 }