CS350 COS
COS
Loading...
Searching...
No Matches
ps2.c
Go to the documentation of this file.
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
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
51
52static 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
90static 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
128static 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
166static void
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) {
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)
202 if (data == 0x1D)
204 if (data == 0x38)
205 keyState |= KS_ALT;
206
207 // Check for numlock, capslock, scrolllock
208 if (data == 0x3A)
210 if (data == 0x45)
212 if (data == 0x46)
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);
251
252 continue;
253 }
254}
255
256static void
258{
259}
260
261void
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
273void
275{
276 uint8_t status, data;
277
278 keyState = 0;
279
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
292 PS2Wait();
293 data = inb(PS2_DATA_PORT);
294 if (data != 0x55)
295 kprintf("PS2: Controller test failed\n");
296
298
299 kbdHandler.irq = 1;
302 psmHandler.irq = 12;
305
308}
309
static INLINE uint8_t inb(uint16_t port)
Definition: amd64op.h:452
static INLINE void outb(uint16_t port, uint8_t data)
Definition: amd64op.h:431
static INLINE void breakpoint()
Definition: amd64op.h:29
void Console_EnqueueKey(char key)
Definition: console.c:75
#define KEY_F12
Definition: console.h:18
#define KEY_F1
Definition: console.h:7
#define KEY_F5
Definition: console.h:11
#define KEY_F3
Definition: console.h:9
#define KEY_F9
Definition: console.h:15
#define KEY_F8
Definition: console.h:14
#define KEY_F7
Definition: console.h:13
#define KEY_F4
Definition: console.h:10
#define KEY_F11
Definition: console.h:17
#define KEY_F6
Definition: console.h:12
#define KEY_F10
Definition: console.h:16
#define KEY_F2
Definition: console.h:8
void IRQ_Register(int irq, struct IRQHandler *h)
Definition: irq.c:35
int kprintf(const char *fmt,...)
Definition: printf.c:210
static uint32_t keyState
Definition: ps2.c:50
#define KS_NUMLOCK
Definition: ps2.c:47
#define PS2_COMMAND_KBDDISABLE
Definition: ps2.c:29
#define KS_CAPSLOCK
Definition: ps2.c:46
void PS2Wait()
Definition: ps2.c:262
#define KS_CONTROL
Definition: ps2.c:45
#define PS2_STATUS_PORT
Definition: ps2.c:17
static void PS2_MouseIntr(void *arg)
Definition: ps2.c:257
static IRQHandler psmHandler
Definition: ps2.c:40
#define PS2_COMMAND_KBDENABLE
Definition: ps2.c:30
#define KS_ALT
Definition: ps2.c:44
void PS2_Init()
Definition: ps2.c:274
#define PS2_DATA_PORT
Definition: ps2.c:19
#define KS_SCROLLLOCK
Definition: ps2.c:48
#define PS2_COMMAND_SELFTEST
Definition: ps2.c:28
#define PS2_COMMAND_PORT
Definition: ps2.c:18
#define PS2_STATUS_OBS
Definition: ps2.c:22
static uint8_t controlKeyMap[256]
Definition: ps2.c:128
static uint8_t shiftKeyMap[256]
Definition: ps2.c:90
static IRQHandler kbdHandler
Definition: ps2.c:39
#define KS_E0ESCAPE
Definition: ps2.c:49
static void PS2_KeyboardIntr(void *arg)
Definition: ps2.c:167
static uint8_t keyMap[256]
Definition: ps2.c:52
#define KS_SHIFT
Definition: ps2.c:43
#define NULL
Definition: stddef.h:6
Definition: irq.h:7
void * arg
Definition: irq.h:10
int irq
Definition: irq.h:8
void(* cb)(void *)
Definition: irq.h:9
unsigned int uint32_t
Definition: types.h:12
unsigned char uint8_t
Definition: types.h:10