1 
2 #include <stdbool.h>
3 #include <stdint.h>
4 #include <stdlib.h>
5 
6 #include <sys/kassert.h>
7 #include <sys/kdebug.h>
8 #include <sys/irq.h>
9 
10 #include <machine/amd64.h>
11 #include <machine/amd64op.h>
12 
13 #include "../console.h"
14 #include "ps2.h"
15 
16 // Status/Command Port (Input/Output)
17 #define PS2_STATUS_PORT		0x64
18 #define PS2_COMMAND_PORT	0x64
19 #define PS2_DATA_PORT		0x60
20 
21 // Controller Status
22 #define PS2_STATUS_OBS		0x01	/* Input Buffer Ready */
23 #define PS2_STATUS_IBS		0x02	/* Output Buffer Full */
24 
25 // Controller Commands
26 #define PS2_COMMAND_AUXDISABLE	0xA7	/* Disable Auxiliary */
27 #define PS2_COMMAND_AUXENABLE	0xA8	/* Enable Auxiliary */
28 #define PS2_COMMAND_SELFTEST	0xAA	/* Test Controller */
29 #define PS2_COMMAND_KBDDISABLE	0xAD	/* Disable Keyboard */
30 #define PS2_COMMAND_KBDENABLE	0xAE	/* Enable Keyboard */
31 
32 // Keyboard Commands
33 #define PS2_KBD_RESET		0xFF	/* Reset */
34 #define PS2_KBD_SETLED		0xED	/* Set LED */
35 
36 // Keyboard Response
37 #define PS2_KBD_RESETDONE	0xAA	/* Reset Done */
38 
39 static IRQHandler kbdHandler;
40 static IRQHandler psmHandler;
41 
42 // Key state flags
43 #define KS_SHIFT		0x01
44 #define KS_ALT			0x02
45 #define KS_CONTROL		0x04
46 #define KS_CAPSLOCK		0x08
47 #define KS_NUMLOCK		0x10
48 #define KS_SCROLLLOCK		0x20
49 #define KS_E0ESCAPE		0x30
50 static uint32_t keyState;
51 
52 static uint8_t keyMap[256] = {
53     0x00, 0x1B,  '1',  '2',  '3',  '4',  '5',  '6',
54      '7',  '8',  '9',  '0',  '-',  '=',  0x08, 0x09,
55      'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
56      'o',  'p',  '[',  ']',  0x0A, 0x00, 'a',  's',
57      'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
58      '\'', '`',  0x00, '\\', 'z',  'x',  'c',  'v',
59      'b',  'n',  'm',  ',',  '.',  '/',  0x00, '*',
60     0x00,  ' ', KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
61 
62     KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, 0x00, 0x00, '7',
63      '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',
64      '2',  '3',  '0',  '.', 0x00, 0x00, 0x00, KEY_F11,
65     KEY_F12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 
71     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 
80     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 };
89 
90 static uint8_t shiftKeyMap[256] = {
91     0x00, 0x1B,  '!',  '@',  '#',  '$',  '%',  '^',
92      '&',  '*',  '(',  ')',  '_',  '+',  0x08, 0x09,
93      'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
94      'O',  'P',  '{',  '}',  0x0A, 0x00, 'A',  'S',
95      'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',
96      '"',  '~',  0x00, '|',  'Z',  'X',  'C',  'V',
97      'B',  'N',  'M',  '<',  '>',  '?',  0x00, '*',
98     0x00,  ' ', KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
99 
100     KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, 0x00, 0x00, '7',
101      '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',
102      '2',  '3',  '0',  '.', 0x00, 0x00, 0x00, KEY_F11,
103     KEY_F12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 
109     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 
118     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 };
127 
128 static uint8_t controlKeyMap[256] = {
129     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 
138     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 
147     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 
156     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 };
165 
166 static void
PS2_KeyboardIntr(void * arg)167 PS2_KeyboardIntr(void *arg)
168 {
169     uint8_t status;
170     uint8_t data;
171     uint8_t key;
172 
173     while (1) {
174 	status = inb(PS2_STATUS_PORT);
175         if ((status & PS2_STATUS_OBS) == 0)
176 	    return;
177 
178 	data = inb(PS2_DATA_PORT);
179 
180 	// E0 escape sequence
181 	if (data == 0xE0) {
182 	    keyState |= KS_E0ESCAPE;
183 	    continue;
184 	}
185 
186 	// Check for release of shift, alt, control
187 	if (data & 0x80) {
188 	    if (data == 0xAA || data == 0xB6)
189 		keyState &= ~KS_SHIFT;
190 	    if (data == 0x9D)
191 		keyState &= ~KS_CONTROL;
192 	    if (data == 0x38)
193 		keyState &= ~KS_ALT;
194 
195 	    // Other key release
196 	    continue;
197 	}
198 
199 	// Check for shift, alt, control
200 	if (data == 0x2A || data == 0x36)
201 	    keyState |= KS_SHIFT;
202 	if (data == 0x1D)
203 	    keyState |= KS_CONTROL;
204 	if (data == 0x38)
205 	    keyState |= KS_ALT;
206 
207 	// Check for numlock, capslock, scrolllock
208 	if (data == 0x3A)
209 	    keyState ^= KS_CAPSLOCK;
210 	if (data == 0x45)
211 	    keyState ^= KS_NUMLOCK;
212 	if (data == 0x46)
213 	    keyState ^= KS_SCROLLLOCK;
214 
215 	// Decode character
216 	if (keyState & KS_E0ESCAPE) {
217 	    keyState &= ~KS_E0ESCAPE;
218 
219 	    // Escape sequences
220 	    continue;
221 	}
222 
223 	// Debugger sequences
224 	if ((keyState & (KS_ALT | KS_CONTROL)) == (KS_ALT | KS_CONTROL)) {
225 	    // Debugger: Alt-Control-Backspace
226 	    if (data == 0x0E)
227 		breakpoint();
228 
229 	    // Reboot: Alt-Control-Delete
230 	}
231 
232 	int isShift = 0;
233 	if (keyState & KS_SHIFT)
234 	    isShift = 1;
235 	if (keyState & KS_CAPSLOCK)
236 	    isShift ^= 1;
237 
238 	if (keyState & KS_CONTROL) {
239 	    key = controlKeyMap[data];
240 	} else if (isShift) {
241 	    key = shiftKeyMap[data];
242 	} else {
243 	    key = keyMap[data];
244 	}
245 
246 	if (key == 0x00)
247 	    continue;
248 
249 	//kprintf("Key Press: %02X\n", key);
250 	Console_EnqueueKey(key);
251 
252 	continue;
253     }
254 }
255 
256 static void
PS2_MouseIntr(void * arg)257 PS2_MouseIntr(void *arg)
258 {
259 }
260 
261 void
PS2Wait()262 PS2Wait()
263 {
264     uint8_t status;
265 
266     while (1) {
267 	status = inb(PS2_STATUS_PORT);
268 	if ((status & PS2_STATUS_OBS) != 0)
269 	    return;
270     }
271 }
272 
273 void
PS2_Init()274 PS2_Init()
275 {
276     uint8_t status, data;
277 
278     keyState = 0;
279 
280     outb(PS2_COMMAND_PORT, PS2_COMMAND_KBDDISABLE);
281 
282     while (1) {
283 	status = inb(PS2_STATUS_PORT);
284         if ((status & PS2_STATUS_OBS) == 0)
285 	    break;
286 
287 	data = inb(PS2_DATA_PORT);
288     }
289 
290     // Self test
291     outb(PS2_COMMAND_PORT, PS2_COMMAND_SELFTEST);
292     PS2Wait();
293     data = inb(PS2_DATA_PORT);
294     if (data != 0x55)
295 	kprintf("PS2: Controller test failed\n");
296 
297     outb(PS2_COMMAND_PORT, PS2_COMMAND_KBDENABLE);
298 
299     kbdHandler.irq = 1;
300     kbdHandler.cb = &PS2_KeyboardIntr;
301     kbdHandler.arg = NULL;
302     psmHandler.irq = 12;
303     psmHandler.cb = &PS2_MouseIntr;
304     psmHandler.arg = NULL;
305 
306     IRQ_Register(1, &kbdHandler);
307     IRQ_Register(12, &psmHandler);
308 }
309 
310