Rev 1842 | Rev 1896 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1842 | Rev 1843 | ||
---|---|---|---|
Line 35... | Line 35... | ||
35 | * |
35 | * |
36 | * It takes care of low-level keyboard functions. |
36 | * It takes care of low-level keyboard functions. |
37 | */ |
37 | */ |
38 | 38 | ||
39 | #include <genarch/kbd/i8042.h> |
39 | #include <genarch/kbd/i8042.h> |
- | 40 | #include <genarch/kbd/key.h> |
|
40 | #include <genarch/kbd/scanc.h> |
41 | #include <genarch/kbd/scanc.h> |
41 | #include <genarch/kbd/scanc_pc.h> |
42 | #include <genarch/kbd/scanc_pc.h> |
42 | #include <arch/drivers/i8042.h> |
43 | #include <arch/drivers/i8042.h> |
43 | #include <arch/interrupt.h> |
44 | #include <arch/interrupt.h> |
44 | #include <cpu.h> |
45 | #include <cpu.h> |
45 | #include <arch/asm.h> |
46 | #include <arch/asm.h> |
46 | #include <arch.h> |
47 | #include <arch.h> |
47 | #include <synch/spinlock.h> |
- | |
48 | #include <typedefs.h> |
48 | #include <typedefs.h> |
49 | #include <console/chardev.h> |
49 | #include <console/chardev.h> |
50 | #include <console/console.h> |
50 | #include <console/console.h> |
51 | #include <macros.h> |
- | |
52 | #include <interrupt.h> |
51 | #include <interrupt.h> |
53 | 52 | ||
54 | /* Keyboard commands. */ |
53 | /* Keyboard commands. */ |
55 | #define KBD_ENABLE 0xf4 |
54 | #define KBD_ENABLE 0xf4 |
56 | #define KBD_DISABLE 0xf5 |
55 | #define KBD_DISABLE 0xf5 |
Line 76... | Line 75... | ||
76 | 75 | ||
77 | #define i8042_BUFFER_FULL_MASK 0x01 |
76 | #define i8042_BUFFER_FULL_MASK 0x01 |
78 | #define i8042_WAIT_MASK 0x02 |
77 | #define i8042_WAIT_MASK 0x02 |
79 | #define i8042_MOUSE_DATA 0x20 |
78 | #define i8042_MOUSE_DATA 0x20 |
80 | 79 | ||
81 | #define KEY_RELEASE 0x80 |
- | |
82 | - | ||
83 | static void key_released(uint8_t sc); |
- | |
84 | static void key_pressed(uint8_t sc); |
- | |
85 | static char key_read(chardev_t *d); |
- | |
86 | - | ||
87 | #define PRESSED_SHIFT (1<<0) |
- | |
88 | #define PRESSED_CAPSLOCK (1<<1) |
- | |
89 | #define LOCKED_CAPSLOCK (1<<0) |
- | |
90 | - | ||
91 | #define ACTIVE_READ_BUFF_SIZE 16 /* Must be power of 2 */ |
- | |
92 | - | ||
93 | static uint8_t active_read_buff[ACTIVE_READ_BUFF_SIZE]; |
- | |
94 | - | ||
95 | SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
- | |
96 | static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
- | |
97 | static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
- | |
98 | - | ||
99 | static void i8042_suspend(chardev_t *); |
80 | static void i8042_suspend(chardev_t *); |
100 | static void i8042_resume(chardev_t *); |
81 | static void i8042_resume(chardev_t *); |
101 | 82 | ||
102 | static chardev_t kbrd; |
83 | chardev_t kbrd; |
103 | static chardev_operations_t ops = { |
84 | static chardev_operations_t ops = { |
104 | .suspend = i8042_suspend, |
85 | .suspend = i8042_suspend, |
105 | .resume = i8042_resume, |
86 | .resume = i8042_resume, |
106 | .read = key_read |
87 | .read = key_read |
107 | }; |
88 | }; |
Line 180... | Line 161... | ||
180 | while (i8042_status_read() & i8042_WAIT_MASK) { |
161 | while (i8042_status_read() & i8042_WAIT_MASK) { |
181 | /* wait */ |
162 | /* wait */ |
182 | } |
163 | } |
183 | } |
164 | } |
184 | 165 | ||
185 | /** Process release of key. |
- | |
186 | * |
- | |
187 | * @param sc Scancode of the key being released. |
- | |
188 | */ |
- | |
189 | void key_released(uint8_t sc) |
- | |
190 | { |
- | |
191 | spinlock_lock(&keylock); |
- | |
192 | switch (sc) { |
- | |
193 | case SC_LSHIFT: |
- | |
194 | case SC_RSHIFT: |
- | |
195 | keyflags &= ~PRESSED_SHIFT; |
- | |
196 | break; |
- | |
197 | case SC_CAPSLOCK: |
- | |
198 | keyflags &= ~PRESSED_CAPSLOCK; |
- | |
199 | if (lockflags & LOCKED_CAPSLOCK) |
- | |
200 | lockflags &= ~LOCKED_CAPSLOCK; |
- | |
201 | else |
- | |
202 | lockflags |= LOCKED_CAPSLOCK; |
- | |
203 | break; |
- | |
204 | default: |
- | |
205 | break; |
- | |
206 | } |
- | |
207 | spinlock_unlock(&keylock); |
- | |
208 | } |
- | |
209 | - | ||
210 | /** Process keypress. |
- | |
211 | * |
- | |
212 | * @param sc Scancode of the key being pressed. |
- | |
213 | */ |
- | |
214 | void key_pressed(uint8_t sc) |
- | |
215 | { |
- | |
216 | char *map = sc_primary_map; |
- | |
217 | char ascii = sc_primary_map[sc]; |
- | |
218 | bool shift, capslock; |
- | |
219 | bool letter = false; |
- | |
220 | - | ||
221 | spinlock_lock(&keylock); |
- | |
222 | switch (sc) { |
- | |
223 | case SC_LSHIFT: |
- | |
224 | case SC_RSHIFT: |
- | |
225 | keyflags |= PRESSED_SHIFT; |
- | |
226 | break; |
- | |
227 | case SC_CAPSLOCK: |
- | |
228 | keyflags |= PRESSED_CAPSLOCK; |
- | |
229 | break; |
- | |
230 | case SC_SPEC_ESCAPE: |
- | |
231 | break; |
- | |
232 | case SC_LEFTARR: |
- | |
233 | chardev_push_character(&kbrd, 0x1b); |
- | |
234 | chardev_push_character(&kbrd, 0x5b); |
- | |
235 | chardev_push_character(&kbrd, 0x44); |
- | |
236 | break; |
- | |
237 | case SC_RIGHTARR: |
- | |
238 | chardev_push_character(&kbrd, 0x1b); |
- | |
239 | chardev_push_character(&kbrd, 0x5b); |
- | |
240 | chardev_push_character(&kbrd, 0x43); |
- | |
241 | break; |
- | |
242 | case SC_UPARR: |
- | |
243 | chardev_push_character(&kbrd, 0x1b); |
- | |
244 | chardev_push_character(&kbrd, 0x5b); |
- | |
245 | chardev_push_character(&kbrd, 0x41); |
- | |
246 | break; |
- | |
247 | case SC_DOWNARR: |
- | |
248 | chardev_push_character(&kbrd, 0x1b); |
- | |
249 | chardev_push_character(&kbrd, 0x5b); |
- | |
250 | chardev_push_character(&kbrd, 0x42); |
- | |
251 | break; |
- | |
252 | case SC_HOME: |
- | |
253 | chardev_push_character(&kbrd, 0x1b); |
- | |
254 | chardev_push_character(&kbrd, 0x4f); |
- | |
255 | chardev_push_character(&kbrd, 0x48); |
- | |
256 | break; |
- | |
257 | case SC_END: |
- | |
258 | chardev_push_character(&kbrd, 0x1b); |
- | |
259 | chardev_push_character(&kbrd, 0x4f); |
- | |
260 | chardev_push_character(&kbrd, 0x46); |
- | |
261 | break; |
- | |
262 | case SC_DELETE: |
- | |
263 | chardev_push_character(&kbrd, 0x1b); |
- | |
264 | chardev_push_character(&kbrd, 0x5b); |
- | |
265 | chardev_push_character(&kbrd, 0x33); |
- | |
266 | chardev_push_character(&kbrd, 0x7e); |
- | |
267 | break; |
- | |
268 | default: |
- | |
269 | letter = is_lower(ascii); |
- | |
270 | capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK); |
- | |
271 | shift = keyflags & PRESSED_SHIFT; |
- | |
272 | if (letter && capslock) |
- | |
273 | shift = !shift; |
- | |
274 | if (shift) |
- | |
275 | map = sc_secondary_map; |
- | |
276 | chardev_push_character(&kbrd, map[sc]); |
- | |
277 | break; |
- | |
278 | } |
- | |
279 | spinlock_unlock(&keylock); |
- | |
280 | } |
- | |
281 | - | ||
282 | /* Called from getc(). */ |
166 | /* Called from getc(). */ |
283 | void i8042_resume(chardev_t *d) |
167 | void i8042_resume(chardev_t *d) |
284 | { |
168 | { |
285 | } |
169 | } |
286 | 170 | ||
287 | /* Called from getc(). */ |
171 | /* Called from getc(). */ |
288 | void i8042_suspend(chardev_t *d) |
172 | void i8042_suspend(chardev_t *d) |
289 | { |
173 | { |
290 | } |
174 | } |
291 | 175 | ||
292 | static uint8_t active_read_buff_read(void) |
- | |
293 | { |
- | |
294 | static int i=0; |
- | |
295 | i &= (ACTIVE_READ_BUFF_SIZE-1); |
- | |
296 | if(!active_read_buff[i]) { |
- | |
297 | return 0; |
- | |
298 | } |
- | |
299 | return active_read_buff[i++]; |
- | |
300 | } |
- | |
301 | - | ||
302 | static void active_read_buff_write(uint8_t ch) |
- | |
303 | { |
- | |
304 | static int i=0; |
- | |
305 | active_read_buff[i] = ch; |
- | |
306 | i++; |
- | |
307 | i &= (ACTIVE_READ_BUFF_SIZE-1); |
- | |
308 | active_read_buff[i]=0; |
- | |
309 | } |
- | |
310 | - | ||
311 | - | ||
312 | static void active_read_key_pressed(uint8_t sc) |
- | |
313 | { |
- | |
314 | char *map = sc_primary_map; |
- | |
315 | char ascii = sc_primary_map[sc]; |
- | |
316 | bool shift, capslock; |
- | |
317 | bool letter = false; |
- | |
318 | - | ||
319 | /*spinlock_lock(&keylock);*/ |
- | |
320 | switch (sc) { |
- | |
321 | case SC_LSHIFT: |
- | |
322 | case SC_RSHIFT: |
- | |
323 | keyflags |= PRESSED_SHIFT; |
- | |
324 | break; |
- | |
325 | case SC_CAPSLOCK: |
- | |
326 | keyflags |= PRESSED_CAPSLOCK; |
- | |
327 | break; |
- | |
328 | case SC_SPEC_ESCAPE: |
- | |
329 | break; |
- | |
330 | case SC_LEFTARR: |
- | |
331 | active_read_buff_write(0x1b); |
- | |
332 | active_read_buff_write(0x5b); |
- | |
333 | active_read_buff_write(0x44); |
- | |
334 | break; |
- | |
335 | case SC_RIGHTARR: |
- | |
336 | active_read_buff_write(0x1b); |
- | |
337 | active_read_buff_write(0x5b); |
- | |
338 | active_read_buff_write(0x43); |
- | |
339 | break; |
- | |
340 | case SC_UPARR: |
- | |
341 | active_read_buff_write(0x1b); |
- | |
342 | active_read_buff_write(0x5b); |
- | |
343 | active_read_buff_write(0x41); |
- | |
344 | break; |
- | |
345 | case SC_DOWNARR: |
- | |
346 | active_read_buff_write(0x1b); |
- | |
347 | active_read_buff_write(0x5b); |
- | |
348 | active_read_buff_write(0x42); |
- | |
349 | break; |
- | |
350 | case SC_HOME: |
- | |
351 | active_read_buff_write(0x1b); |
- | |
352 | active_read_buff_write(0x4f); |
- | |
353 | active_read_buff_write(0x48); |
- | |
354 | break; |
- | |
355 | case SC_END: |
- | |
356 | active_read_buff_write(0x1b); |
- | |
357 | active_read_buff_write(0x4f); |
- | |
358 | active_read_buff_write(0x46); |
- | |
359 | break; |
- | |
360 | case SC_DELETE: |
- | |
361 | active_read_buff_write(0x1b); |
- | |
362 | active_read_buff_write(0x5b); |
- | |
363 | active_read_buff_write(0x33); |
- | |
364 | active_read_buff_write(0x7e); |
- | |
365 | break; |
- | |
366 | default: |
- | |
367 | letter = is_lower(ascii); |
- | |
368 | capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK); |
- | |
369 | shift = keyflags & PRESSED_SHIFT; |
- | |
370 | if (letter && capslock) |
- | |
371 | shift = !shift; |
- | |
372 | if (shift) |
- | |
373 | map = sc_secondary_map; |
- | |
374 | active_read_buff_write(map[sc]); |
- | |
375 | break; |
- | |
376 | } |
- | |
377 | /*spinlock_unlock(&keylock);*/ |
- | |
378 | - | ||
379 | } |
- | |
380 | - | ||
381 | static char key_read(chardev_t *d) |
176 | char key_read(chardev_t *d) |
382 | { |
177 | { |
383 | char ch; |
178 | char ch; |
384 | 179 | ||
385 | while(!(ch = active_read_buff_read())) { |
180 | while(!(ch = active_read_buff_read())) { |
386 | uint8_t x; |
181 | uint8_t x; |