Rev 501 | Rev 509 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 501 | Rev 508 | ||
---|---|---|---|
Line 31... | Line 31... | ||
31 | #include <arch/interrupt.h> |
31 | #include <arch/interrupt.h> |
32 | #include <cpu.h> |
32 | #include <cpu.h> |
33 | #include <arch/asm.h> |
33 | #include <arch/asm.h> |
34 | #include <arch.h> |
34 | #include <arch.h> |
35 | #include <print.h> |
35 | #include <print.h> |
- | 36 | #include <synch/spinlock.h> |
|
- | 37 | #include <typedefs.h> |
|
36 | 38 | ||
37 | /* |
39 | /** |
38 | * i8042 processor driver. |
40 | * i8042 processor driver. |
- | 41 | * It takes care of low-level keyboard functions. |
|
39 | */ |
42 | */ |
40 | 43 | ||
- | 44 | #define SPECIAL '?' |
|
- | 45 | #define KEY_RELEASE 0x80 |
|
- | 46 | ||
- | 47 | static void key_released(__u8 sc); |
|
- | 48 | static void key_pressed(__u8 sc); |
|
- | 49 | ||
- | 50 | #define PRESSED_SHIFT (1<<0) |
|
- | 51 | #define PRESSED_CAPSLOCK (1<<1) |
|
- | 52 | #define LOCKED_CAPSLOCK (1<<0) |
|
- | 53 | ||
- | 54 | static spinlock_t keylock; /**< keylock protects keyflags and lockflags. */ |
|
- | 55 | static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
|
- | 56 | static volatile int lockflags; /**< Tracking of multiple lock keys keypresses. */ |
|
- | 57 | ||
- | 58 | /** Primary meaning of scancodes. */ |
|
- | 59 | static char sc_primary_map[] = { |
|
- | 60 | SPECIAL, /* 0x00 */ |
|
- | 61 | SPECIAL, /* 0x01 - Esc */ |
|
- | 62 | '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', |
|
- | 63 | SPECIAL, /* 0x0e - Backspace */ |
|
- | 64 | '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', |
|
- | 65 | SPECIAL, /* 0x1d - LCtrl */ |
|
- | 66 | 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', |
|
- | 67 | '`', |
|
- | 68 | SPECIAL, /* 0x2a - LShift */ |
|
- | 69 | '\\', |
|
- | 70 | 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', |
|
- | 71 | SPECIAL, /* 0x36 - RShift */ |
|
- | 72 | '*', |
|
- | 73 | SPECIAL, /* 0x38 - LAlt */ |
|
- | 74 | ' ', |
|
- | 75 | SPECIAL, /* 0x3a - CapsLock */ |
|
- | 76 | SPECIAL, /* 0x3b - F1 */ |
|
- | 77 | SPECIAL, /* 0x3c - F2 */ |
|
- | 78 | SPECIAL, /* 0x3d - F3 */ |
|
- | 79 | SPECIAL, /* 0x3e - F4 */ |
|
- | 80 | SPECIAL, /* 0x3f - F5 */ |
|
- | 81 | SPECIAL, /* 0x40 - F6 */ |
|
- | 82 | SPECIAL, /* 0x41 - F7 */ |
|
- | 83 | SPECIAL, /* 0x42 - F8 */ |
|
- | 84 | SPECIAL, /* 0x43 - F9 */ |
|
- | 85 | SPECIAL, /* 0x44 - F10 */ |
|
- | 86 | SPECIAL, /* 0x45 - NumLock */ |
|
- | 87 | SPECIAL, /* 0x46 - ScrollLock */ |
|
- | 88 | '7', '8', '9', '-', |
|
- | 89 | '4', '5', '6', '+', |
|
- | 90 | '1', '2', '3', |
|
- | 91 | '0', '.', |
|
- | 92 | SPECIAL, /* 0x54 - Alt-SysRq */ |
|
- | 93 | SPECIAL, /* 0x55 - F11/F12/PF1/FN */ |
|
- | 94 | SPECIAL, /* 0x56 - unlabelled key next to LAlt */ |
|
- | 95 | SPECIAL, /* 0x57 - F11 */ |
|
- | 96 | SPECIAL, /* 0x58 - F12 */ |
|
- | 97 | SPECIAL, /* 0x59 */ |
|
- | 98 | SPECIAL, /* 0x5a */ |
|
- | 99 | SPECIAL, /* 0x5b */ |
|
- | 100 | SPECIAL, /* 0x5c */ |
|
- | 101 | SPECIAL, /* 0x5d */ |
|
- | 102 | SPECIAL, /* 0x5e */ |
|
- | 103 | SPECIAL, /* 0x5f */ |
|
- | 104 | SPECIAL, /* 0x60 */ |
|
- | 105 | SPECIAL, /* 0x61 */ |
|
- | 106 | SPECIAL, /* 0x62 */ |
|
- | 107 | SPECIAL, /* 0x63 */ |
|
- | 108 | SPECIAL, /* 0x64 */ |
|
- | 109 | SPECIAL, /* 0x65 */ |
|
- | 110 | SPECIAL, /* 0x66 */ |
|
- | 111 | SPECIAL, /* 0x67 */ |
|
- | 112 | SPECIAL, /* 0x68 */ |
|
- | 113 | SPECIAL, /* 0x69 */ |
|
- | 114 | SPECIAL, /* 0x6a */ |
|
- | 115 | SPECIAL, /* 0x6b */ |
|
- | 116 | SPECIAL, /* 0x6c */ |
|
- | 117 | SPECIAL, /* 0x6d */ |
|
- | 118 | SPECIAL, /* 0x6e */ |
|
- | 119 | SPECIAL, /* 0x6f */ |
|
- | 120 | SPECIAL, /* 0x70 */ |
|
- | 121 | SPECIAL, /* 0x71 */ |
|
- | 122 | SPECIAL, /* 0x72 */ |
|
- | 123 | SPECIAL, /* 0x73 */ |
|
- | 124 | SPECIAL, /* 0x74 */ |
|
- | 125 | SPECIAL, /* 0x75 */ |
|
- | 126 | SPECIAL, /* 0x76 */ |
|
- | 127 | SPECIAL, /* 0x77 */ |
|
- | 128 | SPECIAL, /* 0x78 */ |
|
- | 129 | SPECIAL, /* 0x79 */ |
|
- | 130 | SPECIAL, /* 0x7a */ |
|
- | 131 | SPECIAL, /* 0x7b */ |
|
- | 132 | SPECIAL, /* 0x7c */ |
|
- | 133 | SPECIAL, /* 0x7d */ |
|
- | 134 | SPECIAL, /* 0x7e */ |
|
- | 135 | SPECIAL, /* 0x7f */ |
|
- | 136 | }; |
|
- | 137 | ||
- | 138 | /** Secondary meaning of scancodes. */ |
|
- | 139 | static char sc_secondary_map[] = { |
|
- | 140 | SPECIAL, /* 0x00 */ |
|
- | 141 | SPECIAL, /* 0x01 - Esc */ |
|
- | 142 | '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', |
|
- | 143 | SPECIAL, /* 0x0e - Backspace */ |
|
- | 144 | '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', |
|
- | 145 | SPECIAL, /* 0x1d - LCtrl */ |
|
- | 146 | 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', |
|
- | 147 | '~', |
|
- | 148 | SPECIAL, /* 0x2a - LShift */ |
|
- | 149 | '|', |
|
- | 150 | 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', |
|
- | 151 | SPECIAL, /* 0x36 - RShift */ |
|
- | 152 | '*', |
|
- | 153 | SPECIAL, /* 0x38 - LAlt */ |
|
- | 154 | ' ', |
|
- | 155 | SPECIAL, /* 0x3a - CapsLock */ |
|
- | 156 | SPECIAL, /* 0x3b - F1 */ |
|
- | 157 | SPECIAL, /* 0x3c - F2 */ |
|
- | 158 | SPECIAL, /* 0x3d - F3 */ |
|
- | 159 | SPECIAL, /* 0x3e - F4 */ |
|
- | 160 | SPECIAL, /* 0x3f - F5 */ |
|
- | 161 | SPECIAL, /* 0x40 - F6 */ |
|
- | 162 | SPECIAL, /* 0x41 - F7 */ |
|
- | 163 | SPECIAL, /* 0x42 - F8 */ |
|
- | 164 | SPECIAL, /* 0x43 - F9 */ |
|
- | 165 | SPECIAL, /* 0x44 - F10 */ |
|
- | 166 | SPECIAL, /* 0x45 - NumLock */ |
|
- | 167 | SPECIAL, /* 0x46 - ScrollLock */ |
|
- | 168 | '7', '8', '9', '-', |
|
- | 169 | '4', '5', '6', '+', |
|
- | 170 | '1', '2', '3', |
|
- | 171 | '0', '.', |
|
- | 172 | SPECIAL, /* 0x54 - Alt-SysRq */ |
|
- | 173 | SPECIAL, /* 0x55 - F11/F12/PF1/FN */ |
|
- | 174 | SPECIAL, /* 0x56 - unlabelled key next to LAlt */ |
|
- | 175 | SPECIAL, /* 0x57 - F11 */ |
|
- | 176 | SPECIAL, /* 0x58 - F12 */ |
|
- | 177 | SPECIAL, /* 0x59 */ |
|
- | 178 | SPECIAL, /* 0x5a */ |
|
- | 179 | SPECIAL, /* 0x5b */ |
|
- | 180 | SPECIAL, /* 0x5c */ |
|
- | 181 | SPECIAL, /* 0x5d */ |
|
- | 182 | SPECIAL, /* 0x5e */ |
|
- | 183 | SPECIAL, /* 0x5f */ |
|
- | 184 | SPECIAL, /* 0x60 */ |
|
- | 185 | SPECIAL, /* 0x61 */ |
|
- | 186 | SPECIAL, /* 0x62 */ |
|
- | 187 | SPECIAL, /* 0x63 */ |
|
- | 188 | SPECIAL, /* 0x64 */ |
|
- | 189 | SPECIAL, /* 0x65 */ |
|
- | 190 | SPECIAL, /* 0x66 */ |
|
- | 191 | SPECIAL, /* 0x67 */ |
|
- | 192 | SPECIAL, /* 0x68 */ |
|
- | 193 | SPECIAL, /* 0x69 */ |
|
- | 194 | SPECIAL, /* 0x6a */ |
|
- | 195 | SPECIAL, /* 0x6b */ |
|
- | 196 | SPECIAL, /* 0x6c */ |
|
- | 197 | SPECIAL, /* 0x6d */ |
|
- | 198 | SPECIAL, /* 0x6e */ |
|
- | 199 | SPECIAL, /* 0x6f */ |
|
- | 200 | SPECIAL, /* 0x70 */ |
|
- | 201 | SPECIAL, /* 0x71 */ |
|
- | 202 | SPECIAL, /* 0x72 */ |
|
- | 203 | SPECIAL, /* 0x73 */ |
|
- | 204 | SPECIAL, /* 0x74 */ |
|
- | 205 | SPECIAL, /* 0x75 */ |
|
- | 206 | SPECIAL, /* 0x76 */ |
|
- | 207 | SPECIAL, /* 0x77 */ |
|
- | 208 | SPECIAL, /* 0x78 */ |
|
- | 209 | SPECIAL, /* 0x79 */ |
|
- | 210 | SPECIAL, /* 0x7a */ |
|
- | 211 | SPECIAL, /* 0x7b */ |
|
- | 212 | SPECIAL, /* 0x7c */ |
|
- | 213 | SPECIAL, /* 0x7d */ |
|
- | 214 | SPECIAL, /* 0x7e */ |
|
- | 215 | SPECIAL, /* 0x7f */ |
|
- | 216 | }; |
|
- | 217 | ||
- | 218 | /** Initialize i8042. */ |
|
41 | void i8042_init(void) |
219 | void i8042_init(void) |
42 | { |
220 | { |
43 | trap_register(VECTOR_KBD, i8042_interrupt); |
221 | trap_register(VECTOR_KBD, i8042_interrupt); |
- | 222 | spinlock_initialize(&keylock); |
|
44 | } |
223 | } |
45 | 224 | ||
- | 225 | /** Process i8042 interrupt. |
|
- | 226 | * |
|
- | 227 | * @param n Interrupt vector. |
|
- | 228 | * @param stack Interrupted stack. |
|
- | 229 | */ |
|
46 | void i8042_interrupt(__u8 n, __native stack[]) |
230 | void i8042_interrupt(__u8 n, __native stack[]) |
47 | { |
231 | { |
48 | __u8 x; |
232 | __u8 x; |
49 | 233 | ||
50 | trap_virtual_eoi(); |
234 | trap_virtual_eoi(); |
51 | x = inb(0x60); |
235 | x = inb(0x60); |
- | 236 | if (x & KEY_RELEASE) |
|
- | 237 | key_released(x ^ KEY_RELEASE); |
|
- | 238 | else |
|
- | 239 | key_pressed(x); |
|
- | 240 | } |
|
- | 241 | ||
- | 242 | /** Process release of key. |
|
- | 243 | * |
|
- | 244 | * @param sc Scancode of the key being released. |
|
- | 245 | */ |
|
- | 246 | void key_released(__u8 sc) |
|
- | 247 | { |
|
- | 248 | spinlock_lock(&keylock); |
|
- | 249 | switch (sc) { |
|
- | 250 | case SC_LSHIFT: |
|
- | 251 | case SC_RSHIFT: |
|
- | 252 | keyflags &= ~PRESSED_SHIFT; |
|
- | 253 | break; |
|
- | 254 | case SC_CAPSLOCK: |
|
- | 255 | keyflags &= ~PRESSED_CAPSLOCK; |
|
- | 256 | if (lockflags & LOCKED_CAPSLOCK) |
|
- | 257 | lockflags &= ~LOCKED_CAPSLOCK; |
|
- | 258 | else |
|
- | 259 | lockflags |= LOCKED_CAPSLOCK; |
|
- | 260 | break; |
|
- | 261 | default: |
|
- | 262 | break; |
|
- | 263 | } |
|
- | 264 | spinlock_unlock(&keylock); |
|
- | 265 | } |
|
- | 266 | ||
- | 267 | /** Process keypress. |
|
- | 268 | * |
|
- | 269 | * @param sc Scancode of the key being pressed. |
|
- | 270 | */ |
|
- | 271 | void key_pressed(__u8 sc) |
|
- | 272 | { |
|
- | 273 | char *map = sc_primary_map; |
|
- | 274 | char ascii = sc_primary_map[sc]; |
|
- | 275 | bool shift, capslock; |
|
- | 276 | bool letter = false; |
|
- | 277 | ||
52 | printf("%d", CPU->id);; |
278 | spinlock_lock(&keylock); |
- | 279 | switch (sc) { |
|
- | 280 | case SC_LSHIFT: |
|
- | 281 | case SC_RSHIFT: |
|
- | 282 | keyflags |= PRESSED_SHIFT; |
|
- | 283 | break; |
|
- | 284 | case SC_CAPSLOCK: |
|
- | 285 | keyflags |= PRESSED_CAPSLOCK; |
|
- | 286 | break; |
|
- | 287 | default: |
|
- | 288 | letter = (ascii >= 'a') && (ascii <= 'z'); |
|
- | 289 | capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK); |
|
- | 290 | shift = keyflags & PRESSED_SHIFT; |
|
- | 291 | if (letter && capslock) |
|
- | 292 | shift = !shift; |
|
- | 293 | if (shift) |
|
- | 294 | map = sc_secondary_map; |
|
- | 295 | putchar(map[sc]); |
|
- | 296 | break; |
|
- | 297 | } |
|
- | 298 | spinlock_unlock(&keylock); |
|
53 | } |
299 | } |