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