--- src/add-ons/kernel/bus_managers/ps2/ps2_common.c | 12 ++++-- src/add-ons/kernel/bus_managers/ps2/ps2_common.h | 2 + src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c | 37 ++++++++++++++++++-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_common.c b/src/add-ons/kernel/bus_managers/ps2/ps2_common.c index 49c5677..19ce13c 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.c +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.c @@ -18,6 +18,7 @@ isa_module_info *gIsa = NULL; +emergency_module_info *gEmergency = NULL; bool gActiveMultiplexingEnabled = false; sem_id gControllerSem; @@ -299,10 +300,6 @@ ps2_interrupt(void* cookie) TRACE("ps2: ps2_interrupt ctrl 0x%02x, data 0x%02x (keyb)\n", ctrl, data); dev = &ps2_device[PS2_DEVICE_KEYB]; error = (ctrl & 0xC0) != 0; - - // TODO: remove me again; let us drop into the kernel debugger with F12 - if (data == 88) - panic("keyboard requested halt.\n"); } dev->history[1] = dev->history[0]; @@ -328,6 +325,9 @@ ps2_init(void) if (status < B_OK) return status; + /* Don't care if it could be loaded or not... */ + get_module(B_EMERGENCY_MODULE_NAME, (module_info **)&gEmergency); + gControllerSem = create_sem(1, "ps/2 keyb ctrl"); ps2_flush(); @@ -396,6 +396,8 @@ err2: ps2_dev_exit(); err1: delete_sem(gControllerSem); + if (gEmergency) + put_module(B_EMERGENCY_MODULE_NAME); put_module(B_ISA_MODULE_NAME); TRACE("ps2: init failed!\n"); return B_ERROR; @@ -411,5 +413,7 @@ ps2_uninit(void) ps2_service_exit(); ps2_dev_exit(); delete_sem(gControllerSem); + if (gEmergency) + put_module(B_EMERGENCY_MODULE_NAME); put_module(B_ISA_MODULE_NAME); } diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_common.h b/src/add-ons/kernel/bus_managers/ps2/ps2_common.h index 39eaa5a..8df0eda 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_common.h +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_common.h @@ -18,6 +18,7 @@ #include <Drivers.h> #include <KernelExport.h> #include <OS.h> +#include <emergency.h> #include "ps2_defs.h" #include "ps2_dev.h" @@ -39,6 +40,7 @@ // global variables extern isa_module_info *gIsa; +extern emergency_module_info *gEmergency; extern device_hooks gKeyboardDeviceHooks; extern device_hooks gMouseDeviceHooks; diff --git a/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c b/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c index 2c9e0fc..7b22d09 100644 --- a/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c +++ b/src/add-ons/kernel/bus_managers/ps2/ps2_keyboard.c @@ -16,6 +16,8 @@ #include <string.h> +#include "debugger_keymaps.h" + #define KEY_BUFFER_SIZE 100 // we will buffer 100 key strokes before we start dropping them @@ -34,6 +36,7 @@ static int32 sKeyboardOpenMask; static sem_id sKeyboardSem; static struct packet_buffer *sKeyBuffer; static bool sIsExtended = false; +static int32 sShiftState = 0; static int32 sKeyboardRepeatRate; static bigtime_t sKeyboardRepeatDelay; @@ -116,15 +119,43 @@ keyboard_handle_int(ps2_dev *dev) if (sIsExtended) { scancode |= 0x80; sIsExtended = false; + } else { + int32 mask = 0; + switch (scancode) { + case 0x2a: mask = 1; break; /* LShift */ + case 0x36: mask = 2; break; /* RShift */ + case 0x58: mask = 4; break; /* F12 */ + } + + if (keyInfo.is_keydown) + atomic_or(&sShiftState, mask); + else + atomic_and(&sShiftState, ~mask); } keyInfo.timestamp = dev->history[0].time; keyInfo.scancode = scancode; - if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, sizeof(keyInfo)) == 0) { - // If there is no space left in the buffer, we drop this key stroke. We avoid - // dropping old key strokes, to not destroy what already was typed. + if ((sShiftState & 0x07) == 0x04 && scancode == 0x58) { + /* TODO: remove me again; let us drop into the kernel debugger with F12 */ + panic("keyboard requested halt.\n"); + sShiftState = 0; /* break code not seen by ps2 int handler */ return B_HANDLED_INTERRUPT; + } else { + if (((sShiftState & 0x07) > 4)) { + /* (LShift || RShift) && F12 && other key */ + if ((scancode != 0x58) && keyInfo.is_keydown && gEmergency) + gEmergency->emergency_key(kUnshiftedKeymap[scancode]); + return B_HANDLED_INTERRUPT; + } else { + if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, sizeof(keyInfo)) + == 0) { + /* If there is no space left in the buffer, we drop this key + * stroke. We avoid dropping old key strokes, to not destroy + * what already was typed. */ + return B_HANDLED_INTERRUPT; + } + } } release_sem_etc(sKeyboardSem, 1, B_DO_NOT_RESCHEDULE); -- 1.5.4.2