Branch data Line data Source code
1 : : /* 2 : : * Kernel Debugger Architecture Dependent Console I/O handler 3 : : * 4 : : * This file is subject to the terms and conditions of the GNU General Public 5 : : * License. 6 : : * 7 : : * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved. 8 : : * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. 9 : : */ 10 : : 11 : : #include <linux/kdb.h> 12 : : #include <linux/keyboard.h> 13 : : #include <linux/ctype.h> 14 : : #include <linux/module.h> 15 : : #include <linux/io.h> 16 : : 17 : : /* Keyboard Controller Registers on normal PCs. */ 18 : : 19 : : #define KBD_STATUS_REG 0x64 /* Status register (R) */ 20 : : #define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ 21 : : 22 : : /* Status Register Bits */ 23 : : 24 : : #define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ 25 : : #define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ 26 : : 27 : : static int kbd_exists; 28 : : static int kbd_last_ret; 29 : : 30 : : /* 31 : : * Check if the keyboard controller has a keypress for us. 32 : : * Some parts (Enter Release, LED change) are still blocking polled here, 33 : : * but hopefully they are all short. 34 : : */ 35 : 0 : int kdb_get_kbd_char(void) 36 : : { 37 : : int scancode, scanstatus; 38 : : static int shift_lock; /* CAPS LOCK state (0-off, 1-on) */ 39 : : static int shift_key; /* Shift next keypress */ 40 : : static int ctrl_key; 41 : : u_short keychar; 42 : : 43 [ # # # # ]: 0 : if (KDB_FLAG(NO_I8042) || KDB_FLAG(NO_VT_CONSOLE) || 44 [ # # ]: 0 : (inb(KBD_STATUS_REG) == 0xff && inb(KBD_DATA_REG) == 0xff)) { 45 : 0 : kbd_exists = 0; 46 : 0 : return -1; 47 : : } 48 : 0 : kbd_exists = 1; 49 : : 50 [ # # ]: 0 : if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) 51 : : return -1; 52 : : 53 : : /* 54 : : * Fetch the scancode 55 : : */ 56 : 0 : scancode = inb(KBD_DATA_REG); 57 : 0 : scanstatus = inb(KBD_STATUS_REG); 58 : : 59 : : /* 60 : : * Ignore mouse events. 61 : : */ 62 [ # # ]: 0 : if (scanstatus & KBD_STAT_MOUSE_OBF) 63 : : return -1; 64 : : 65 : : /* 66 : : * Ignore release, trigger on make 67 : : * (except for shift keys, where we want to 68 : : * keep the shift state so long as the key is 69 : : * held down). 70 : : */ 71 : : 72 [ # # ]: 0 : if (((scancode&0x7f) == 0x2a) || ((scancode&0x7f) == 0x36)) { 73 : : /* 74 : : * Next key may use shift table 75 : : */ 76 [ # # ]: 0 : if ((scancode & 0x80) == 0) 77 : 0 : shift_key = 1; 78 : : else 79 : 0 : shift_key = 0; 80 : : return -1; 81 : : } 82 : : 83 [ # # ]: 0 : if ((scancode&0x7f) == 0x1d) { 84 : : /* 85 : : * Left ctrl key 86 : : */ 87 [ # # ]: 0 : if ((scancode & 0x80) == 0) 88 : 0 : ctrl_key = 1; 89 : : else 90 : 0 : ctrl_key = 0; 91 : : return -1; 92 : : } 93 : : 94 [ # # ]: 0 : if ((scancode & 0x80) != 0) { 95 [ # # ]: 0 : if (scancode == 0x9c) 96 : 0 : kbd_last_ret = 0; 97 : : return -1; 98 : : } 99 : : 100 : : scancode &= 0x7f; 101 : : 102 : : /* 103 : : * Translate scancode 104 : : */ 105 : : 106 [ # # ]: 0 : if (scancode == 0x3a) { 107 : : /* 108 : : * Toggle caps lock 109 : : */ 110 : 0 : shift_lock ^= 1; 111 : : 112 : : #ifdef KDB_BLINK_LED 113 : : kdb_toggleled(0x4); 114 : : #endif 115 : 0 : return -1; 116 : : } 117 : : 118 [ # # ]: 0 : if (scancode == 0x0e) { 119 : : /* 120 : : * Backspace 121 : : */ 122 : : return 8; 123 : : } 124 : : 125 : : /* Special Key */ 126 [ # # # # : 0 : switch (scancode) { # # # # # ] 127 : : case 0xF: /* Tab */ 128 : : return 9; 129 : : case 0x53: /* Del */ 130 : 0 : return 4; 131 : : case 0x47: /* Home */ 132 : 0 : return 1; 133 : : case 0x4F: /* End */ 134 : 0 : return 5; 135 : : case 0x4B: /* Left */ 136 : 0 : return 2; 137 : : case 0x48: /* Up */ 138 : 0 : return 16; 139 : : case 0x50: /* Down */ 140 : 0 : return 14; 141 : : case 0x4D: /* Right */ 142 : 0 : return 6; 143 : : } 144 : : 145 : : if (scancode == 0xe0) 146 : : return -1; 147 : : 148 : : /* 149 : : * For Japanese 86/106 keyboards 150 : : * See comment in drivers/char/pc_keyb.c. 151 : : * - Masahiro Adegawa 152 : : */ 153 [ # # ]: 0 : if (scancode == 0x73) 154 : : scancode = 0x59; 155 [ # # ]: 0 : else if (scancode == 0x7d) 156 : : scancode = 0x7c; 157 : : 158 [ # # # # : 0 : if (!shift_lock && !shift_key && !ctrl_key) { # # ] 159 : 0 : keychar = plain_map[scancode]; 160 [ # # # # : 0 : } else if ((shift_lock || shift_key) && key_maps[1]) { # # ] 161 : 0 : keychar = key_maps[1][scancode]; 162 [ # # # # ]: 0 : } else if (ctrl_key && key_maps[4]) { 163 : 0 : keychar = key_maps[4][scancode]; 164 : : } else { 165 : : keychar = 0x0020; 166 : 0 : kdb_printf("Unknown state/scancode (%d)\n", scancode); 167 : : } 168 : 0 : keychar &= 0x0fff; 169 [ # # ]: 0 : if (keychar == '\t') 170 : : keychar = ' '; 171 [ # # # ]: 0 : switch (KTYP(keychar)) { 172 : : case KT_LETTER: 173 : : case KT_LATIN: 174 [ # # ]: 0 : if (isprint(keychar)) 175 : : break; /* printable characters */ 176 : : /* fall through */ 177 : : case KT_SPEC: 178 [ # # ]: 0 : if (keychar == K_ENTER) 179 : : break; 180 : : /* fall through */ 181 : : default: 182 : : return -1; /* ignore unprintables */ 183 : : } 184 : : 185 [ # # ]: 0 : if (scancode == 0x1c) { 186 : 0 : kbd_last_ret = 1; 187 : 0 : return 13; 188 : : } 189 : : 190 : 0 : return keychar & 0xff; 191 : : } 192 : : EXPORT_SYMBOL_GPL(kdb_get_kbd_char); 193 : : 194 : : /* 195 : : * Best effort cleanup of ENTER break codes on leaving KDB. Called on 196 : : * exiting KDB, when we know we processed an ENTER or KP ENTER scan 197 : : * code. 198 : : */ 199 : 0 : void kdb_kbd_cleanup_state(void) 200 : : { 201 : : int scancode, scanstatus; 202 : : 203 : : /* 204 : : * Nothing to clean up, since either 205 : : * ENTER was never pressed, or has already 206 : : * gotten cleaned up. 207 : : */ 208 [ # # ]: 0 : if (!kbd_last_ret) 209 : : return; 210 : : 211 : 0 : kbd_last_ret = 0; 212 : : /* 213 : : * Enter key. Need to absorb the break code here, lest it gets 214 : : * leaked out if we exit KDB as the result of processing 'g'. 215 : : * 216 : : * This has several interesting implications: 217 : : * + Need to handle KP ENTER, which has break code 0xe0 0x9c. 218 : : * + Need to handle repeat ENTER and repeat KP ENTER. Repeats 219 : : * only get a break code at the end of the repeated 220 : : * sequence. This means we can't propagate the repeated key 221 : : * press, and must swallow it away. 222 : : * + Need to handle possible PS/2 mouse input. 223 : : * + Need to handle mashed keys. 224 : : */ 225 : : 226 : : while (1) { 227 [ # # ]: 0 : while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) 228 : 0 : cpu_relax(); 229 : : 230 : : /* 231 : : * Fetch the scancode. 232 : : */ 233 : 0 : scancode = inb(KBD_DATA_REG); 234 : 0 : scanstatus = inb(KBD_STATUS_REG); 235 : : 236 : : /* 237 : : * Skip mouse input. 238 : : */ 239 [ # # ]: 0 : if (scanstatus & KBD_STAT_MOUSE_OBF) 240 : 0 : continue; 241 : : 242 : : /* 243 : : * If we see 0xe0, this is either a break code for KP 244 : : * ENTER, or a repeat make for KP ENTER. Either way, 245 : : * since the second byte is equivalent to an ENTER, 246 : : * skip the 0xe0 and try again. 247 : : * 248 : : * If we see 0x1c, this must be a repeat ENTER or KP 249 : : * ENTER (and we swallowed 0xe0 before). Try again. 250 : : * 251 : : * We can also see make and break codes for other keys 252 : : * mashed before or after pressing ENTER. Thus, if we 253 : : * see anything other than 0x9c, we have to try again. 254 : : * 255 : : * Note, if you held some key as ENTER was depressed, 256 : : * that break code would get leaked out. 257 : : */ 258 [ # # ]: 0 : if (scancode != 0x9c) 259 : 0 : continue; 260 : : 261 : : return; 262 : : } 263 : : }