Warning, cross-references for /kernel/drivers/input/keyboard_8042.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "drivers/input/keyboard.h"
0019 #include "arch/i386.h"
0020 #include "sched/sched.h"
0021 #include "smp/smp.h"
0022 #include "smp/apic.h"
0023 #include "util/circular.h"
0024 #include "util/printf.h"
0025
0026
0027
0028
0029
0030 static circular keyb_buffer;
0031 static key_event buffer_space[KEYBOARD_BUFFER_SIZE];
0032
0033
0034 static key_event cur_event;
0035
0036
0037
0038 static uint8 escape;
0039
0040
0041
0042
0043 static inline void
0044 clean_entry (int i)
0045 {
0046 cur_event.keys[i].scancode = 0;
0047 cur_event.keys[i].present = 0;
0048 cur_event.keys[i].release = 0;
0049 cur_event.keys[i].pressed = 0;
0050 cur_event.keys[i].latest = 0;
0051 }
0052
0053 #ifdef DEBUG_KEYS
0054 static inline void
0055 check_debug_keys (void)
0056 {
0057 int i;
0058 for (i=0; i<KEY_EVENT_MAX; i++) {
0059 if (cur_event.keys[i].present && cur_event.keys[i].pressed) {
0060 if (cur_event.keys[i].scancode == 0x16) {
0061
0062 void debug_dump_bulk_qhs (void);
0063 lock_kernel ();
0064 debug_dump_bulk_qhs ();
0065 unlock_kernel ();
0066 }
0067 }
0068 }
0069 }
0070 #endif
0071
0072 static inline void
0073 check_control_alt_del (void)
0074 {
0075 bool ctrl, alt, del;
0076 int i;
0077 ctrl = alt = del = FALSE;
0078
0079 for (i=0; i<KEY_EVENT_MAX; i++) {
0080 if (cur_event.keys[i].present && cur_event.keys[i].pressed) {
0081 switch (cur_event.keys[i].scancode) {
0082 case 0x001d:
0083 case 0xe01d:
0084 ctrl = TRUE; break;
0085 case 0x0038:
0086 case 0xe038:
0087 alt = TRUE; break;
0088 case 0x0053:
0089 case 0xe053:
0090 del = TRUE; break;
0091 }
0092 }
0093 }
0094
0095 if (ctrl && alt && del) {
0096 uint8 state;
0097 printf ("REBOOTING...\n");
0098 com1_printf ("REBOOTING...\n");
0099 while (((state = inb (KEYBOARD_STATUS_PORT)) & 2) != 0);
0100 outb (0xFE, KEYBOARD_STATUS_PORT);
0101 asm volatile ("hlt");
0102 }
0103 }
0104
0105
0106 static uint32
0107 kbd_irq_handler (uint8 vec)
0108 {
0109 uint8 code;
0110 int i;
0111
0112 code = inb (KEYBOARD_DATA_PORT);
0113
0114 if (escape) {
0115
0116 code |= (escape << 8);
0117 escape = 0;
0118 }
0119
0120 if (code == 0xE0 || code == 0xE1)
0121 escape = code;
0122 else if (code & 0x80) {
0123
0124
0125 code &= (~0x80);
0126
0127
0128
0129 for (i=0; i<KEY_EVENT_MAX; i++) {
0130 if (cur_event.keys[i].present == 1 &&
0131 cur_event.keys[i].scancode == code) {
0132
0133
0134 cur_event.keys[i].release = 1;
0135 cur_event.keys[i].pressed = 0;
0136 cur_event.keys[i].latest = 1;
0137
0138
0139 if (circular_insert_nowait (&keyb_buffer, (void *)&cur_event) < 0) {
0140 lock_kernel();
0141 com1_printf ("keyboard_8042: dropped break code: %X\n", code);
0142 unlock_kernel();
0143 }
0144
0145 clean_entry (i);
0146
0147 break;
0148 }
0149 }
0150
0151
0152 if (i == KEY_EVENT_MAX) {
0153 lock_kernel();
0154 com1_printf ("keyboard_8042: spurious break code: %X\n", code);
0155 unlock_kernel();
0156 }
0157
0158 } else {
0159
0160
0161 for (i=0; i<KEY_EVENT_MAX; i++) {
0162
0163
0164
0165 if (cur_event.keys[i].present == 1 &&
0166 cur_event.keys[i].scancode == code) {
0167 break;
0168 }
0169 }
0170
0171 if (i == KEY_EVENT_MAX) {
0172
0173 for (i=0; i<KEY_EVENT_MAX; i++) {
0174 if (cur_event.keys[i].present == 0) {
0175 break;
0176 }
0177 }
0178 }
0179
0180 if (i == KEY_EVENT_MAX) {
0181
0182 lock_kernel();
0183 com1_printf ("keyboard_8042: too many keys: %X\n", code);
0184 unlock_kernel();
0185
0186 } else {
0187
0188
0189 cur_event.keys[i].scancode = code;
0190 cur_event.keys[i].present = 1;
0191 cur_event.keys[i].pressed = 1;
0192 cur_event.keys[i].latest = 1;
0193
0194
0195 if (circular_insert_nowait (&keyb_buffer, (void *)&cur_event) < 0) {
0196 lock_kernel();
0197 com1_printf ("keyboard_8042: dropped make code: %X\n", code);
0198 unlock_kernel();
0199 }
0200
0201 cur_event.keys[i].latest = 0;
0202 }
0203 }
0204
0205 check_control_alt_del ();
0206
0207 #ifdef DEBUG_KEYS
0208 check_debug_keys ();
0209 #endif
0210
0211 return 0;
0212 }
0213
0214
0215 bool
0216 init_keyboard_8042 (void)
0217 {
0218 int i;
0219
0220 escape = 0;
0221
0222 for (i=0; i<KEY_EVENT_MAX; i++)
0223 clean_entry (i);
0224
0225 circular_init (&keyb_buffer,
0226 (void *)buffer_space,
0227 KEYBOARD_BUFFER_SIZE,
0228 sizeof (key_event));
0229
0230 if (mp_ISA_PC) {
0231 set_vector_handler (KEYBOARD_IRQ + PIC1_BASE_IRQ, kbd_irq_handler);
0232 } else {
0233 IOAPIC_map_GSI (IRQ_to_GSI (mp_ISA_bus_id, KEYBOARD_IRQ),
0234 KEYBOARD_VECTOR, 0xFF00000000000800LL);
0235 set_vector_handler (KEYBOARD_VECTOR, kbd_irq_handler);
0236 }
0237 return TRUE;
0238 }
0239
0240
0241 void
0242 keyboard_8042_next (key_event *e)
0243 {
0244 circular_remove (&keyb_buffer, (void *)e);
0245 }
0246
0247 #include "module/header.h"
0248
0249 static const struct module_ops mod_ops = {
0250 .init = init_keyboard_8042
0251 };
0252
0253 DEF_MODULE (input___kb8042, "Keyboard (i8042) driver", &mod_ops, {});
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264