* Added an emergency key mechanism to the kernel, inspired by Jan Klötzke's
patch from about a year ago (I couldn't use any code of his yet, though, but there are a few things left). The emergency keys are triggered by pressing Alt-SysReq + key. * By default, only Alt-SysReq+'d' is used as a means to deliberately enter the kernel debugger. F12 belongs to userland again, now :-) * Debugger add-ons now have another optional method to implement their own emergency keys - 'd' for the debugger cannot be overridden, though. * The mechanism can be turned off via a new kernel setting, so it's not that easy anymore to "crash" Haiku if you don't want to. * Right now, the PS/2 driver, and the pre-input_server in-kernel debugger keyboard mini-driver support this, USB not yet. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31660 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8ef9253a59
commit
c755ecfe96
@ -50,5 +50,8 @@
|
|||||||
# (system shutdown, battery info, ...)
|
# (system shutdown, battery info, ...)
|
||||||
# default is off
|
# default is off
|
||||||
|
|
||||||
|
#emergency_keys false
|
||||||
|
# Disables emergency keys (ie. Alt-SysReq+*), enabled by default
|
||||||
|
|
||||||
#acpi true
|
#acpi true
|
||||||
# ACPI support, off by default
|
# ACPI support, off by default
|
||||||
|
@ -28,7 +28,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ASSERT_ALWAYS(x) \
|
#define ASSERT_ALWAYS(x) \
|
||||||
do { if (!(x)) { panic("ASSERT FAILED (%s:%d): %s\n", __FILE__, __LINE__, #x); } } while (0)
|
do { \
|
||||||
|
if (!(x)) { \
|
||||||
|
panic("ASSERT FAILED (%s:%d): %s\n", __FILE__, __LINE__, #x); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define ASSERT_ALWAYS_PRINT(x, format...) \
|
#define ASSERT_ALWAYS_PRINT(x, format...) \
|
||||||
do { \
|
do { \
|
||||||
@ -66,10 +70,13 @@ struct debugger_module_info {
|
|||||||
void (*enter_debugger)(void);
|
void (*enter_debugger)(void);
|
||||||
void (*exit_debugger)(void);
|
void (*exit_debugger)(void);
|
||||||
|
|
||||||
// io hooks
|
// I/O hooks
|
||||||
int (*debugger_puts)(const char *str, int32 length);
|
int (*debugger_puts)(const char *str, int32 length);
|
||||||
int (*debugger_getchar)(void);
|
int (*debugger_getchar)(void);
|
||||||
// TODO: add hooks for tunnelling gdb ?
|
// TODO: add hooks for tunnelling gdb ?
|
||||||
|
|
||||||
|
// Misc. hooks
|
||||||
|
bool (*emergency_key_pressed)(char key);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct debugger_demangle_module_info {
|
struct debugger_demangle_module_info {
|
||||||
@ -113,7 +120,8 @@ extern void debug_stop_screen_debug_output(void);
|
|||||||
extern void debug_set_page_fault_info(addr_t faultAddress, addr_t pc,
|
extern void debug_set_page_fault_info(addr_t faultAddress, addr_t pc,
|
||||||
uint32 flags);
|
uint32 flags);
|
||||||
extern debug_page_fault_info* debug_get_page_fault_info();
|
extern debug_page_fault_info* debug_get_page_fault_info();
|
||||||
extern void debug_trap_cpu_in_kdl(bool returnIfHandedOver);
|
extern void debug_trap_cpu_in_kdl(bool returnIfHandedOver);
|
||||||
|
extern bool debug_emergency_key_pressed(char key);
|
||||||
|
|
||||||
extern char kgetc(void);
|
extern char kgetc(void);
|
||||||
extern void kputs(const char *string);
|
extern void kputs(const char *string);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2007 Haiku, Inc.
|
* Copyright 2004-2009 Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors (in chronological order):
|
* Authors (in chronological order):
|
||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
/*! PS/2 bus manager */
|
/*! PS/2 bus manager */
|
||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "ps2_common.h"
|
#include "ps2_common.h"
|
||||||
@ -277,32 +278,33 @@ ps2_interrupt(void* cookie)
|
|||||||
return B_UNHANDLED_INTERRUPT;
|
return B_UNHANDLED_INTERRUPT;
|
||||||
|
|
||||||
if (atomic_get(&sIgnoreInterrupts)) {
|
if (atomic_get(&sIgnoreInterrupts)) {
|
||||||
TRACE("ps2: ps2_interrupt ignoring, ctrl 0x%02x (%s)\n", ctrl, (ctrl & PS2_STATUS_AUX_DATA) ? "aux" : "keyb");
|
TRACE("ps2: ps2_interrupt ignoring, ctrl 0x%02x (%s)\n", ctrl,
|
||||||
|
(ctrl & PS2_STATUS_AUX_DATA) ? "aux" : "keyb");
|
||||||
return B_HANDLED_INTERRUPT;
|
return B_HANDLED_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = ps2_read_data();
|
data = ps2_read_data();
|
||||||
|
|
||||||
if (ctrl & PS2_STATUS_AUX_DATA) {
|
if ((ctrl & PS2_STATUS_AUX_DATA) != 0) {
|
||||||
uint8 idx;
|
uint8 idx;
|
||||||
if (gActiveMultiplexingEnabled) {
|
if (gActiveMultiplexingEnabled) {
|
||||||
idx = ctrl >> 6;
|
idx = ctrl >> 6;
|
||||||
error = (ctrl & 0x04) != 0;
|
error = (ctrl & 0x04) != 0;
|
||||||
TRACE("ps2: ps2_interrupt ctrl 0x%02x, data 0x%02x (mouse %d)\n", ctrl, data, idx);
|
TRACE("ps2: ps2_interrupt ctrl 0x%02x, data 0x%02x (mouse %d)\n",
|
||||||
|
ctrl, data, idx);
|
||||||
} else {
|
} else {
|
||||||
idx = 0;
|
idx = 0;
|
||||||
error = (ctrl & 0xC0) != 0;
|
error = (ctrl & 0xC0) != 0;
|
||||||
TRACE("ps2: ps2_interrupt ctrl 0x%02x, data 0x%02x (aux)\n", ctrl, data);
|
TRACE("ps2: ps2_interrupt ctrl 0x%02x, data 0x%02x (aux)\n", ctrl,
|
||||||
|
data);
|
||||||
}
|
}
|
||||||
dev = &ps2_device[PS2_DEVICE_MOUSE + idx];
|
dev = &ps2_device[PS2_DEVICE_MOUSE + idx];
|
||||||
} else {
|
} else {
|
||||||
TRACE("ps2: ps2_interrupt ctrl 0x%02x, data 0x%02x (keyb)\n", ctrl, data);
|
TRACE("ps2: ps2_interrupt ctrl 0x%02x, data 0x%02x (keyb)\n", ctrl,
|
||||||
|
data);
|
||||||
|
|
||||||
dev = &ps2_device[PS2_DEVICE_KEYB];
|
dev = &ps2_device[PS2_DEVICE_KEYB];
|
||||||
error = (ctrl & 0xC0) != 0;
|
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];
|
dev->history[1] = dev->history[0];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2007 Haiku, Inc.
|
* Copyright 2004-2009 Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors (in chronological order):
|
* Authors (in chronological order):
|
||||||
@ -10,11 +10,16 @@
|
|||||||
|
|
||||||
/*! PS/2 keyboard device driver */
|
/*! PS/2 keyboard device driver */
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
#include <debugger_keymaps.h>
|
||||||
|
|
||||||
#include "ps2_service.h"
|
#include "ps2_service.h"
|
||||||
#include "kb_mouse_driver.h"
|
#include "kb_mouse_driver.h"
|
||||||
#include "packet_buffer.h"
|
#include "packet_buffer.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define KEY_BUFFER_SIZE 100
|
#define KEY_BUFFER_SIZE 100
|
||||||
// we will buffer 100 key strokes before we start dropping them
|
// we will buffer 100 key strokes before we start dropping them
|
||||||
@ -26,7 +31,11 @@ enum {
|
|||||||
} leds_status;
|
} leds_status;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EXTENDED_KEY = 0xe0,
|
EXTENDED_KEY = 0xe0,
|
||||||
|
|
||||||
|
LEFT_ALT_KEY = 0x38,
|
||||||
|
RIGHT_ALT_KEY = 0xb8,
|
||||||
|
SYS_REQ_KEY = 0x54
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -35,8 +44,9 @@ static sem_id sKeyboardSem;
|
|||||||
static struct packet_buffer *sKeyBuffer;
|
static struct packet_buffer *sKeyBuffer;
|
||||||
static bool sIsExtended = false;
|
static bool sIsExtended = false;
|
||||||
|
|
||||||
static int32 sKeyboardRepeatRate;
|
static int32 sKeyboardRepeatRate;
|
||||||
static bigtime_t sKeyboardRepeatDelay;
|
static bigtime_t sKeyboardRepeatDelay;
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
set_leds(led_info *ledInfo)
|
set_leds(led_info *ledInfo)
|
||||||
@ -52,7 +62,8 @@ set_leds(led_info *ledInfo)
|
|||||||
if (ledInfo->caps_lock)
|
if (ledInfo->caps_lock)
|
||||||
leds |= LED_CAPS;
|
leds |= LED_CAPS;
|
||||||
|
|
||||||
return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_KEYBOARD_SET_LEDS, &leds, 1, NULL, 0);
|
return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB],
|
||||||
|
PS2_CMD_KEYBOARD_SET_LEDS, &leds, 1, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -84,13 +95,20 @@ set_typematic(int32 rate, bigtime_t delay)
|
|||||||
else
|
else
|
||||||
value |= 0 << 5;
|
value |= 0 << 5;
|
||||||
|
|
||||||
return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_KEYBOARD_SET_TYPEMATIC, &value, 1, NULL, 0);
|
return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB],
|
||||||
|
PS2_CMD_KEYBOARD_SET_TYPEMATIC, &value, 1, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32
|
static int32
|
||||||
keyboard_handle_int(ps2_dev *dev)
|
keyboard_handle_int(ps2_dev *dev)
|
||||||
{
|
{
|
||||||
|
enum emergency_keys {
|
||||||
|
EMERGENCY_LEFT_ALT = 0x01,
|
||||||
|
EMERGENCY_RIGHT_ALT = 0x02,
|
||||||
|
EMERGENCY_SYS_REQ = 0x04,
|
||||||
|
};
|
||||||
|
static int emergencyKeyStatus = 0;
|
||||||
at_kbd_io keyInfo;
|
at_kbd_io keyInfo;
|
||||||
uint8 scancode = dev->history[0].data;
|
uint8 scancode = dev->history[0].data;
|
||||||
|
|
||||||
@ -107,7 +125,7 @@ keyboard_handle_int(ps2_dev *dev)
|
|||||||
|
|
||||||
// TRACE("scancode: %x\n", scancode);
|
// TRACE("scancode: %x\n", scancode);
|
||||||
|
|
||||||
if (scancode & 0x80) {
|
if ((scancode & 0x80) != 0) {
|
||||||
keyInfo.is_keydown = false;
|
keyInfo.is_keydown = false;
|
||||||
scancode &= 0x7f;
|
scancode &= 0x7f;
|
||||||
} else
|
} else
|
||||||
@ -118,12 +136,33 @@ keyboard_handle_int(ps2_dev *dev)
|
|||||||
sIsExtended = false;
|
sIsExtended = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle emergency keys
|
||||||
|
if (scancode == LEFT_ALT_KEY || scancode == RIGHT_ALT_KEY) {
|
||||||
|
// left or right alt-key pressed
|
||||||
|
if (keyInfo.is_keydown) {
|
||||||
|
emergencyKeyStatus |= scancode == LEFT_ALT_KEY
|
||||||
|
? EMERGENCY_LEFT_ALT : EMERGENCY_RIGHT_ALT;
|
||||||
|
} else {
|
||||||
|
emergencyKeyStatus &= ~(scancode == LEFT_ALT_KEY
|
||||||
|
? EMERGENCY_LEFT_ALT : EMERGENCY_RIGHT_ALT);
|
||||||
|
}
|
||||||
|
} else if (scancode == SYS_REQ_KEY) {
|
||||||
|
if (keyInfo.is_keydown)
|
||||||
|
emergencyKeyStatus |= EMERGENCY_SYS_REQ;
|
||||||
|
else
|
||||||
|
emergencyKeyStatus &= EMERGENCY_SYS_REQ;
|
||||||
|
} else if (emergencyKeyStatus > EMERGENCY_SYS_REQ
|
||||||
|
&& debug_emergency_key_pressed(kUnshiftedKeymap[scancode]))
|
||||||
|
return B_HANDLED_INTERRUPT;
|
||||||
|
|
||||||
keyInfo.timestamp = dev->history[0].time;
|
keyInfo.timestamp = dev->history[0].time;
|
||||||
keyInfo.scancode = scancode;
|
keyInfo.scancode = scancode;
|
||||||
|
|
||||||
if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, sizeof(keyInfo)) == 0) {
|
if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo,
|
||||||
// If there is no space left in the buffer, we drop this key stroke. We avoid
|
sizeof(keyInfo)) == 0) {
|
||||||
// dropping old key strokes, to not destroy what already was typed.
|
// 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;
|
return B_HANDLED_INTERRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,11 +189,14 @@ read_keyboard_packet(at_kbd_io *packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packet_buffer_read(sKeyBuffer, (uint8 *)packet, sizeof(*packet)) == 0) {
|
if (packet_buffer_read(sKeyBuffer, (uint8 *)packet, sizeof(*packet)) == 0) {
|
||||||
TRACE("ps2: read_keyboard_packet, Error reading packet: %s\n", strerror(status));
|
TRACE("ps2: read_keyboard_packet, Error reading packet: %s\n",
|
||||||
|
strerror(status));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("ps2: read_keyboard_packet: scancode: %x, keydown: %s\n", packet->scancode, packet->is_keydown ? "true" : "false");
|
TRACE("ps2: read_keyboard_packet: scancode: %x, keydown: %s\n",
|
||||||
|
packet->scancode, packet->is_keydown ? "true" : "false");
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,13 +226,16 @@ probe_keyboard(void)
|
|||||||
// return B_ERROR;
|
// return B_ERROR;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_RESET, NULL, 0, &data, 1);
|
status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_RESET, NULL,
|
||||||
|
0, &data, 1);
|
||||||
if (status != B_OK || data != 0xaa) {
|
if (status != B_OK || data != 0xaa) {
|
||||||
INFO("ps2: keyboard reset failed, status 0x%08lx, data 0x%02x\n", status, data);
|
INFO("ps2: keyboard reset failed, status 0x%08lx, data 0x%02x\n",
|
||||||
|
status, data);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// default settings after keyboard reset: delay = 0x01 (500 ms), rate = 0x0b (10.9 chr/sec)
|
// default settings after keyboard reset: delay = 0x01 (500 ms),
|
||||||
|
// rate = 0x0b (10.9 chr/sec)
|
||||||
sKeyboardRepeatRate = ((31 - 0x0b) * 280) / 31 + 20;
|
sKeyboardRepeatRate = ((31 - 0x0b) * 280) / 31 + 20;
|
||||||
sKeyboardRepeatDelay = 500000;
|
sKeyboardRepeatDelay = 500000;
|
||||||
|
|
||||||
@ -328,24 +373,29 @@ keyboard_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
case KB_SET_KEY_REPEATING:
|
case KB_SET_KEY_REPEATING:
|
||||||
{
|
{
|
||||||
TRACE("ps2: ioctl KB_SET_KEY_REPEATING\n");
|
TRACE("ps2: ioctl KB_SET_KEY_REPEATING\n");
|
||||||
// 0xFA (Set All Keys Typematic/Make/Break) - Keyboard responds with "ack" (0xFA).
|
// 0xFA (Set All Keys Typematic/Make/Break) - Keyboard responds
|
||||||
return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xfa, NULL, 0, NULL, 0);
|
// with "ack" (0xFA).
|
||||||
|
return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xfa, NULL, 0,
|
||||||
|
NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
case KB_SET_KEY_NONREPEATING:
|
case KB_SET_KEY_NONREPEATING:
|
||||||
{
|
{
|
||||||
TRACE("ps2: ioctl KB_SET_KEY_NONREPEATING\n");
|
TRACE("ps2: ioctl KB_SET_KEY_NONREPEATING\n");
|
||||||
// 0xF8 (Set All Keys Make/Break) - Keyboard responds with "ack" (0xFA).
|
// 0xF8 (Set All Keys Make/Break) - Keyboard responds with "ack"
|
||||||
return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xf8, NULL, 0, NULL, 0);
|
// (0xFA).
|
||||||
|
return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xf8, NULL, 0,
|
||||||
|
NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
case KB_SET_KEY_REPEAT_RATE:
|
case KB_SET_KEY_REPEAT_RATE:
|
||||||
{
|
{
|
||||||
int32 key_repeat_rate;
|
int32 key_repeat_rate;
|
||||||
TRACE("ps2: ioctl KB_SET_KEY_REPEAT_RATE\n");
|
TRACE("ps2: ioctl KB_SET_KEY_REPEAT_RATE\n");
|
||||||
if (user_memcpy(&key_repeat_rate, buffer, sizeof(key_repeat_rate)) < B_OK)
|
if (user_memcpy(&key_repeat_rate, buffer, sizeof(key_repeat_rate))
|
||||||
|
!= B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
if (set_typematic(key_repeat_rate, sKeyboardRepeatDelay) < B_OK)
|
if (set_typematic(key_repeat_rate, sKeyboardRepeatDelay) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
sKeyboardRepeatRate = key_repeat_rate;
|
sKeyboardRepeatRate = key_repeat_rate;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -354,16 +404,18 @@ keyboard_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
case KB_GET_KEY_REPEAT_RATE:
|
case KB_GET_KEY_REPEAT_RATE:
|
||||||
{
|
{
|
||||||
TRACE("ps2: ioctl KB_GET_KEY_REPEAT_RATE\n");
|
TRACE("ps2: ioctl KB_GET_KEY_REPEAT_RATE\n");
|
||||||
return user_memcpy(buffer, &sKeyboardRepeatRate, sizeof(sKeyboardRepeatRate));
|
return user_memcpy(buffer, &sKeyboardRepeatRate,
|
||||||
|
sizeof(sKeyboardRepeatRate));
|
||||||
}
|
}
|
||||||
|
|
||||||
case KB_SET_KEY_REPEAT_DELAY:
|
case KB_SET_KEY_REPEAT_DELAY:
|
||||||
{
|
{
|
||||||
bigtime_t key_repeat_delay;
|
bigtime_t key_repeat_delay;
|
||||||
TRACE("ps2: ioctl KB_SET_KEY_REPEAT_DELAY\n");
|
TRACE("ps2: ioctl KB_SET_KEY_REPEAT_DELAY\n");
|
||||||
if (user_memcpy(&key_repeat_delay, buffer, sizeof(key_repeat_delay)) < B_OK)
|
if (user_memcpy(&key_repeat_delay, buffer, sizeof(key_repeat_delay))
|
||||||
|
!= B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
if (set_typematic(sKeyboardRepeatRate, key_repeat_delay) < B_OK)
|
if (set_typematic(sKeyboardRepeatRate, key_repeat_delay) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
sKeyboardRepeatDelay = key_repeat_delay;
|
sKeyboardRepeatDelay = key_repeat_delay;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -373,7 +425,8 @@ keyboard_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
case KB_GET_KEY_REPEAT_DELAY:
|
case KB_GET_KEY_REPEAT_DELAY:
|
||||||
{
|
{
|
||||||
TRACE("ps2: ioctl KB_GET_KEY_REPEAT_DELAY\n");
|
TRACE("ps2: ioctl KB_GET_KEY_REPEAT_DELAY\n");
|
||||||
return user_memcpy(buffer, &sKeyboardRepeatDelay, sizeof(sKeyboardRepeatDelay));
|
return user_memcpy(buffer, &sKeyboardRepeatDelay,
|
||||||
|
sizeof(sKeyboardRepeatDelay));
|
||||||
}
|
}
|
||||||
|
|
||||||
case KB_GET_KEYBOARD_ID:
|
case KB_GET_KEYBOARD_ID:
|
||||||
@ -389,6 +442,7 @@ keyboard_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
device_hooks gKeyboardDeviceHooks = {
|
device_hooks gKeyboardDeviceHooks = {
|
||||||
keyboard_open,
|
keyboard_open,
|
||||||
keyboard_close,
|
keyboard_close,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de
|
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de
|
||||||
* Copyright 2001, Rob Judd <judd@ob-wan.com>
|
* Copyright 2001, Rob Judd <judd@ob-wan.com>
|
||||||
* Copyright 2002, Marcus Overhagen <marcus@overhagen.de>
|
* Copyright 2002, Marcus Overhagen <marcus@overhagen.de>
|
||||||
* Distributed under the terms of the Haiku License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
* Distributed under the terms of the NewOS License.
|
* Distributed under the terms of the NewOS License.
|
||||||
@ -52,6 +52,7 @@ enum keycodes {
|
|||||||
LEFT_CONTROL = 29,
|
LEFT_CONTROL = 29,
|
||||||
|
|
||||||
LEFT_ALT = 56,
|
LEFT_ALT = 56,
|
||||||
|
RIGHT_ALT = 58,
|
||||||
|
|
||||||
CURSOR_LEFT = 75,
|
CURSOR_LEFT = 75,
|
||||||
CURSOR_RIGHT = 77,
|
CURSOR_RIGHT = 77,
|
||||||
@ -62,8 +63,8 @@ enum keycodes {
|
|||||||
PAGE_UP = 73,
|
PAGE_UP = 73,
|
||||||
PAGE_DOWN = 81,
|
PAGE_DOWN = 81,
|
||||||
|
|
||||||
BREAK = 198, // TODO: >= 128 can't be valid
|
|
||||||
DELETE = 83,
|
DELETE = 83,
|
||||||
|
SYS_REQ = 84,
|
||||||
F12 = 88,
|
F12 = 88,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,7 +109,8 @@ static int32
|
|||||||
debug_keyboard_interrupt(void *data)
|
debug_keyboard_interrupt(void *data)
|
||||||
{
|
{
|
||||||
static bool controlPressed = false;
|
static bool controlPressed = false;
|
||||||
static bool altPressed;
|
static bool altPressed = false;
|
||||||
|
static bool sysReqPressed = false;
|
||||||
uint8 key;
|
uint8 key;
|
||||||
|
|
||||||
key = in8(PS2_PORT_DATA);
|
key = in8(PS2_PORT_DATA);
|
||||||
@ -117,8 +119,10 @@ debug_keyboard_interrupt(void *data)
|
|||||||
if (key & 0x80) {
|
if (key & 0x80) {
|
||||||
if (key == LEFT_CONTROL)
|
if (key == LEFT_CONTROL)
|
||||||
controlPressed = false;
|
controlPressed = false;
|
||||||
if (key == LEFT_ALT)
|
else if (key == LEFT_ALT)
|
||||||
altPressed = false;
|
altPressed = false;
|
||||||
|
else if (key == SYS_REQ)
|
||||||
|
sysReqPressed = false;
|
||||||
|
|
||||||
return B_HANDLED_INTERRUPT;
|
return B_HANDLED_INTERRUPT;
|
||||||
}
|
}
|
||||||
@ -129,22 +133,22 @@ debug_keyboard_interrupt(void *data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LEFT_ALT:
|
case LEFT_ALT:
|
||||||
|
case RIGHT_ALT:
|
||||||
altPressed = true;
|
altPressed = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SYS_REQ:
|
||||||
|
sysReqPressed = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case DELETE:
|
case DELETE:
|
||||||
if (controlPressed && altPressed)
|
if (controlPressed && altPressed)
|
||||||
arch_cpu_shutdown(true);
|
arch_cpu_shutdown(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* the following code has two possibilities because of issues
|
default:
|
||||||
* with BeBochs & BeOS (all special keys don't map to anything
|
if (altPressed && sysReqPressed)
|
||||||
* useful, and SYS_REQ does a screen dump in BeOS).
|
debug_emergency_key_pressed(kUnshiftedKeymap[key]);
|
||||||
* ToDo: remove these key functions some day...
|
|
||||||
*/
|
|
||||||
case F12:
|
|
||||||
case BREAK:
|
|
||||||
panic("Keyboard Requested Halt\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
@ -63,6 +63,7 @@ static bool sBlueScreenEnabled = false;
|
|||||||
// must always be false on startup
|
// must always be false on startup
|
||||||
static bool sDebugScreenEnabled = false;
|
static bool sDebugScreenEnabled = false;
|
||||||
static bool sBlueScreenOutput = true;
|
static bool sBlueScreenOutput = true;
|
||||||
|
static bool sEmergencyKeysEnabled = true;
|
||||||
static spinlock sSpinlock = B_SPINLOCK_INITIALIZER;
|
static spinlock sSpinlock = B_SPINLOCK_INITIALIZER;
|
||||||
static int32 sDebuggerOnCPU = -1;
|
static int32 sDebuggerOnCPU = -1;
|
||||||
|
|
||||||
@ -1239,6 +1240,8 @@ debug_init_post_vm(kernel_args* args)
|
|||||||
"syslog_debug_output", sSyslogOutputEnabled, sSyslogOutputEnabled);
|
"syslog_debug_output", sSyslogOutputEnabled, sSyslogOutputEnabled);
|
||||||
sBlueScreenOutput = get_driver_boolean_parameter(handle,
|
sBlueScreenOutput = get_driver_boolean_parameter(handle,
|
||||||
"bluescreen", true, true);
|
"bluescreen", true, true);
|
||||||
|
sEmergencyKeysEnabled = get_driver_boolean_parameter(handle,
|
||||||
|
"emergency_keys", sEmergencyKeysEnabled, sEmergencyKeysEnabled);
|
||||||
|
|
||||||
unload_driver_settings(handle);
|
unload_driver_settings(handle);
|
||||||
}
|
}
|
||||||
@ -1350,6 +1353,30 @@ debug_trap_cpu_in_kdl(bool returnIfHandedOver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
debug_emergency_key_pressed(char key)
|
||||||
|
{
|
||||||
|
if (!sEmergencyKeysEnabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (key == 'd') {
|
||||||
|
kernel_debugger("Keyboard Requested Halt.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast to the kernel debugger modules
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
|
||||||
|
if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) {
|
||||||
|
if (sDebuggerModules[i]->emergency_key_pressed(key))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - public API
|
// #pragma mark - public API
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user