* Added arch_debug_blue_screen_try_getchar() and arch_debug_serial_try_getchar()
which don't wait for a character, but return -1 when no character is available ATM. Implemented correctly for x86 only. * Changed the semantics of the debugger_module_info::debugger_getchar() hook. It is supposed to return immediately now. * Adjusted usb_keyboard accordingly. Hacked UHCI's debug_process_transfer() to achieve that. It does now start, check, or cancel a transfer. Split UHCI::ProcessDebugTransfer() into StartDebugTransfer(), and CheckDebugTransfer() accordingly, and also added a CancelDebugTransfer(). The latter seems to have issues. Michael, please have a look. I have no clue what I'm doing. :-) * Adjusted kgetc() to poll all possible inputs using the new functions/semantics. This allows to use any input (USB, PS/2, serial) in KDL. * Removed the no longer needed "serial_input" command. * read_line(): Also support 0x7f as backspace code. That's what xterm sends. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42126 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
21d6b8e2c7
commit
8bcc50c336
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
@ -18,7 +18,9 @@ struct kernel_args;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int arch_debug_blue_screen_try_getchar(void);
|
||||
char arch_debug_blue_screen_getchar(void);
|
||||
int arch_debug_serial_try_getchar(void);
|
||||
char arch_debug_serial_getchar(void);
|
||||
void arch_debug_serial_putchar(char c);
|
||||
void arch_debug_serial_puts(const char *s);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2006, Haiku Inc. All rights reserved.
|
||||
* Copyright 2004-2011, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -23,6 +23,28 @@ static int32 sDebuggerCommandAdded = 0;
|
||||
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
|
||||
|
||||
class DebugTransfer : public Transfer {
|
||||
public:
|
||||
DebugTransfer(Pipe *pipe)
|
||||
:
|
||||
Transfer(pipe)
|
||||
{
|
||||
}
|
||||
|
||||
uhci_td *firstDescriptor;
|
||||
uhci_qh *transferQueue;
|
||||
};
|
||||
|
||||
|
||||
/*! The function is an evil hack to allow <tt> <kdebug>usb_keyboard </tt> to
|
||||
execute transfers.
|
||||
When invoked the first time, a new transfer is started, each time the
|
||||
function is called afterwards, it is checked whether the transfer is already
|
||||
completed. If called with argv[1] == "cancel" the function cancels a
|
||||
possibly pending transfer.
|
||||
*/
|
||||
static int
|
||||
debug_process_transfer(int argc, char **argv)
|
||||
{
|
||||
@ -42,9 +64,38 @@ debug_process_transfer(int argc, char **argv)
|
||||
if (length == 0)
|
||||
return 5;
|
||||
|
||||
Transfer transfer(pipe);
|
||||
transfer.SetData(data, length);
|
||||
return ((UHCI *)pipe->GetBusManager())->ProcessDebugTransfer(&transfer);
|
||||
static uint8 transferBuffer[sizeof(DebugTransfer)]
|
||||
__attribute__((aligned(16)));
|
||||
static DebugTransfer* transfer;
|
||||
|
||||
UHCI *bus = (UHCI *)pipe->GetBusManager();
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "cancel") == 0) {
|
||||
if (transfer != NULL) {
|
||||
bus->CancelDebugTransfer(transfer);
|
||||
transfer = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (transfer != NULL) {
|
||||
bool stillPending;
|
||||
status_t error = bus->CheckDebugTransfer(transfer, stillPending);
|
||||
if (!stillPending)
|
||||
transfer = NULL;
|
||||
|
||||
return error == B_OK ? 0 : 6;
|
||||
}
|
||||
|
||||
transfer = new(transferBuffer) DebugTransfer(pipe);
|
||||
transfer->SetData(data, length);
|
||||
|
||||
if (bus->StartDebugTransfer(transfer) != B_OK) {
|
||||
transfer = NULL;
|
||||
return 7;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -672,73 +723,102 @@ UHCI::SubmitTransfer(Transfer *transfer)
|
||||
|
||||
|
||||
status_t
|
||||
UHCI::ProcessDebugTransfer(Transfer *transfer)
|
||||
UHCI::StartDebugTransfer(DebugTransfer *transfer)
|
||||
{
|
||||
uhci_td *firstDescriptor = NULL;
|
||||
uhci_qh *transferQueue = NULL;
|
||||
status_t result = CreateFilledTransfer(transfer, &firstDescriptor,
|
||||
&transferQueue);
|
||||
transfer->firstDescriptor = NULL;
|
||||
transfer->transferQueue = NULL;
|
||||
status_t result = CreateFilledTransfer(transfer, &transfer->firstDescriptor,
|
||||
&transfer->transferQueue);
|
||||
if (result < B_OK)
|
||||
return result;
|
||||
|
||||
fQueues[UHCI_DEBUG_QUEUE]->AppendTransfer(transferQueue, false);
|
||||
fQueues[UHCI_DEBUG_QUEUE]->AppendTransfer(transfer->transferQueue, false);
|
||||
|
||||
while (true) {
|
||||
bool transferOK = false;
|
||||
bool transferError = false;
|
||||
uhci_td *descriptor = firstDescriptor;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
while (descriptor) {
|
||||
uint32 status = descriptor->status;
|
||||
if (status & TD_STATUS_ACTIVE)
|
||||
break;
|
||||
|
||||
if (status & TD_ERROR_MASK) {
|
||||
transferError = true;
|
||||
break;
|
||||
}
|
||||
status_t
|
||||
UHCI::CheckDebugTransfer(DebugTransfer *transfer, bool &_stillPending)
|
||||
{
|
||||
bool transferOK = false;
|
||||
bool transferError = false;
|
||||
uhci_td *descriptor = transfer->firstDescriptor;
|
||||
|
||||
if ((descriptor->link_phy & TD_TERMINATE)
|
||||
|| uhci_td_actual_length(descriptor)
|
||||
< uhci_td_maximum_length(descriptor)) {
|
||||
transferOK = true;
|
||||
break;
|
||||
}
|
||||
while (descriptor) {
|
||||
uint32 status = descriptor->status;
|
||||
if (status & TD_STATUS_ACTIVE)
|
||||
break;
|
||||
|
||||
descriptor = (uhci_td *)descriptor->link_log;
|
||||
if (status & TD_ERROR_MASK) {
|
||||
transferError = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!transferOK && !transferError) {
|
||||
spin(200);
|
||||
continue;
|
||||
if ((descriptor->link_phy & TD_TERMINATE)
|
||||
|| uhci_td_actual_length(descriptor)
|
||||
< uhci_td_maximum_length(descriptor)) {
|
||||
transferOK = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (transferOK) {
|
||||
size_t actualLength = 0;
|
||||
uint8 lastDataToggle = 0;
|
||||
if (transfer->TransferPipe()->Direction() == Pipe::In) {
|
||||
// data to read out
|
||||
iovec *vector = transfer->Vector();
|
||||
size_t vectorCount = transfer->VectorCount();
|
||||
|
||||
actualLength = ReadDescriptorChain(firstDescriptor,
|
||||
vector, vectorCount, &lastDataToggle);
|
||||
} else {
|
||||
// read the actual length that was sent
|
||||
actualLength = ReadActualLength(firstDescriptor,
|
||||
&lastDataToggle);
|
||||
}
|
||||
|
||||
transfer->TransferPipe()->SetDataToggle(lastDataToggle == 0);
|
||||
}
|
||||
|
||||
fQueues[UHCI_DEBUG_QUEUE]->RemoveTransfer(transferQueue, false);
|
||||
FreeDescriptorChain(firstDescriptor);
|
||||
FreeTransferQueue(transferQueue);
|
||||
return transferOK ? B_OK : B_IO_ERROR;
|
||||
descriptor = (uhci_td *)descriptor->link_log;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
if (!transferOK && !transferError) {
|
||||
spin(200);
|
||||
_stillPending = true;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (transferOK) {
|
||||
size_t actualLength = 0;
|
||||
uint8 lastDataToggle = 0;
|
||||
if (transfer->TransferPipe()->Direction() == Pipe::In) {
|
||||
// data to read out
|
||||
iovec *vector = transfer->Vector();
|
||||
size_t vectorCount = transfer->VectorCount();
|
||||
|
||||
actualLength = ReadDescriptorChain(transfer->firstDescriptor,
|
||||
vector, vectorCount, &lastDataToggle);
|
||||
} else {
|
||||
// read the actual length that was sent
|
||||
actualLength = ReadActualLength(transfer->firstDescriptor,
|
||||
&lastDataToggle);
|
||||
}
|
||||
|
||||
transfer->TransferPipe()->SetDataToggle(lastDataToggle == 0);
|
||||
}
|
||||
|
||||
fQueues[UHCI_DEBUG_QUEUE]->RemoveTransfer(transfer->transferQueue, false);
|
||||
FreeDescriptorChain(transfer->firstDescriptor);
|
||||
FreeTransferQueue(transfer->transferQueue);
|
||||
_stillPending = false;
|
||||
return transferOK ? B_OK : B_IO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UHCI::CancelDebugTransfer(DebugTransfer *transfer)
|
||||
{
|
||||
// clear the active bit so the descriptors are canceled
|
||||
uhci_td *descriptor = transfer->firstDescriptor;
|
||||
while (descriptor) {
|
||||
descriptor->status &= ~TD_STATUS_ACTIVE;
|
||||
descriptor = (uhci_td *)descriptor->link_log;
|
||||
}
|
||||
|
||||
transfer->Finished(B_CANCELED, 0);
|
||||
|
||||
// dequeue and free resources
|
||||
fQueues[UHCI_DEBUG_QUEUE]->RemoveTransfer(transfer->transferQueue, false);
|
||||
FreeDescriptorChain(transfer->firstDescriptor);
|
||||
FreeTransferQueue(transfer->transferQueue);
|
||||
// TODO: [bonefish] The Free*() calls cause "PMA: provided address resulted
|
||||
// in invalid index" to be printed, so apparently something is not right.
|
||||
// Though I have not clue what. This is the same cleanup code as in
|
||||
// CheckDebugTransfer() that should undo the CreateFilledTransfer() from
|
||||
// StartDebugTransfer().
|
||||
}
|
||||
|
||||
|
||||
@ -1832,7 +1912,7 @@ status_t
|
||||
UHCI::AddTo(Stack *stack)
|
||||
{
|
||||
#ifdef TRACE_USB
|
||||
set_dprintf_enabled(true);
|
||||
set_dprintf_enabled(true);
|
||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
load_driver_symbols("uhci");
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2006, Haiku Inc. All rights reserved.
|
||||
* Copyright 2004-2011, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -24,6 +24,7 @@
|
||||
struct pci_info;
|
||||
struct pci_module_info;
|
||||
class UHCIRootHub;
|
||||
class DebugTransfer;
|
||||
|
||||
|
||||
class Queue {
|
||||
@ -97,7 +98,11 @@ public:
|
||||
|
||||
status_t Start();
|
||||
virtual status_t SubmitTransfer(Transfer *transfer);
|
||||
status_t ProcessDebugTransfer(Transfer *transfer);
|
||||
status_t StartDebugTransfer(DebugTransfer *transfer);
|
||||
status_t CheckDebugTransfer(DebugTransfer *transfer,
|
||||
bool &_stillPending);
|
||||
void CancelDebugTransfer(
|
||||
DebugTransfer *transfer);
|
||||
virtual status_t CancelQueuedTransfers(Pipe *pipe, bool force);
|
||||
status_t CancelQueuedIsochronousTransfers(Pipe *pipe, bool force);
|
||||
status_t SubmitRequest(Transfer *transfer);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku Inc. All rights reserved.
|
||||
* Copyright 2009-2011, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -176,6 +176,9 @@ enter_debugger(void)
|
||||
static void
|
||||
exit_debugger(void)
|
||||
{
|
||||
// make sure a possibly pending transfer is canceled
|
||||
evaluate_debug_command("uhci_process_transfer cancel");
|
||||
|
||||
sUseUSBKeyboard = false;
|
||||
}
|
||||
|
||||
@ -195,11 +198,12 @@ debugger_getchar(void)
|
||||
if (!sUseUSBKeyboard)
|
||||
return -1;
|
||||
|
||||
while (sBufferedCharCount == 0) {
|
||||
if (sBufferedCharCount == 0) {
|
||||
set_debug_variable("_usbPipe", (uint64)sUSBPipe);
|
||||
set_debug_variable("_usbTransferData", (uint64)sUSBTransferData);
|
||||
set_debug_variable("_usbTransferLength", (uint64)sUSBTransferLength);
|
||||
evaluate_debug_command("uhci_process_transfer");
|
||||
if (evaluate_debug_command("uhci_process_transfer") != 0)
|
||||
return -1;
|
||||
|
||||
bool phantomState = true;
|
||||
for (size_t i = 2; i < sUSBTransferLength; i++) {
|
||||
@ -210,7 +214,7 @@ debugger_getchar(void)
|
||||
}
|
||||
|
||||
if (phantomState)
|
||||
continue;
|
||||
return -1;
|
||||
|
||||
uint8 modifiers = 0;
|
||||
for (uint32 i = 0; i < 8; i++) {
|
||||
@ -272,6 +276,9 @@ debugger_getchar(void)
|
||||
sLastTransferData[i] = sUSBTransferData[i];
|
||||
}
|
||||
|
||||
if (sBufferedCharCount == 0)
|
||||
return -1;
|
||||
|
||||
int result = sBufferedChars[sBufferReadIndex++];
|
||||
sBufferReadIndex %= sBufferSize;
|
||||
sBufferedCharCount--;
|
||||
@ -302,7 +309,7 @@ static struct debugger_module_info sModuleInfo = {
|
||||
&debugger_getchar
|
||||
};
|
||||
|
||||
module_info *modules[] = {
|
||||
module_info *modules[] = {
|
||||
(module_info *)&sModuleInfo,
|
||||
NULL
|
||||
};
|
||||
|
@ -31,6 +31,14 @@ arch_debug_install_interrupt_handlers(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_blue_screen_try_getchar(void)
|
||||
{
|
||||
// TODO: Implement correctly!
|
||||
return arch_debug_blue_screen_getchar();
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_blue_screen_getchar(void)
|
||||
{
|
||||
@ -38,6 +46,14 @@ arch_debug_blue_screen_getchar(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_serial_try_getchar(void)
|
||||
{
|
||||
// TODO: Implement correctly!
|
||||
return arch_debug_serial_getchar();
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_serial_getchar(void)
|
||||
{
|
||||
|
@ -31,6 +31,14 @@ arch_debug_install_interrupt_handlers(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_blue_screen_try_getchar(void)
|
||||
{
|
||||
// TODO: Implement correctly!
|
||||
return arch_debug_blue_screen_getchar();
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_blue_screen_getchar(void)
|
||||
{
|
||||
@ -38,6 +46,14 @@ arch_debug_blue_screen_getchar(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_serial_try_getchar(void)
|
||||
{
|
||||
// TODO: Implement correctly!
|
||||
return arch_debug_serial_getchar();
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_serial_getchar(void)
|
||||
{
|
||||
|
@ -31,6 +31,14 @@ arch_debug_install_interrupt_handlers(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_blue_screen_try_getchar(void)
|
||||
{
|
||||
#warning IMPLEMENT arch_debug_blue_screen_try_getchar
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_blue_screen_getchar(void)
|
||||
{
|
||||
@ -39,6 +47,14 @@ arch_debug_blue_screen_getchar(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_serial_try_getchar(void)
|
||||
{
|
||||
#warning IMPLEMENT arch_debug_serial_try_getchar
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_serial_getchar(void)
|
||||
{
|
||||
|
@ -28,6 +28,14 @@ arch_debug_install_interrupt_handlers(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_blue_screen_try_getchar(void)
|
||||
{
|
||||
// TODO: Implement correctly!
|
||||
return arch_debug_blue_screen_getchar();
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_blue_screen_getchar(void)
|
||||
{
|
||||
@ -35,6 +43,14 @@ arch_debug_blue_screen_getchar(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_serial_try_getchar(void)
|
||||
{
|
||||
// TODO: Implement correctly!
|
||||
return arch_debug_serial_getchar();
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_serial_getchar(void)
|
||||
{
|
||||
|
@ -166,8 +166,8 @@ arch_debug_install_interrupt_handlers(void)
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_blue_screen_getchar(void)
|
||||
int
|
||||
arch_debug_blue_screen_try_getchar(void)
|
||||
{
|
||||
/* polling the keyboard, similar to code in keyboard
|
||||
* driver, but without using an interrupt
|
||||
@ -194,105 +194,126 @@ arch_debug_blue_screen_getchar(void)
|
||||
return key;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
uint8 status = in8(PS2_PORT_CTRL);
|
||||
uint8 status = in8(PS2_PORT_CTRL);
|
||||
|
||||
if ((status & PS2_STATUS_OUTPUT_BUFFER_FULL) == 0) {
|
||||
// no data in keyboard buffer
|
||||
spin(200);
|
||||
continue;
|
||||
if ((status & PS2_STATUS_OUTPUT_BUFFER_FULL) == 0) {
|
||||
// no data in keyboard buffer
|
||||
return -1;
|
||||
}
|
||||
|
||||
key = in8(PS2_PORT_DATA);
|
||||
|
||||
if (status & PS2_STATUS_AUX_DATA) {
|
||||
// we read mouse data, ignore it
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (key & 0x80) {
|
||||
// key up
|
||||
switch (key & ~0x80) {
|
||||
case LEFT_SHIFT:
|
||||
case RIGHT_SHIFT:
|
||||
shiftPressed = false;
|
||||
return -1;
|
||||
case LEFT_CONTROL:
|
||||
controlPressed = false;
|
||||
return -1;
|
||||
case LEFT_ALT:
|
||||
altPressed = false;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// key down
|
||||
switch (key) {
|
||||
case LEFT_SHIFT:
|
||||
case RIGHT_SHIFT:
|
||||
shiftPressed = true;
|
||||
return -1;
|
||||
|
||||
spin(200);
|
||||
key = in8(PS2_PORT_DATA);
|
||||
case LEFT_CONTROL:
|
||||
controlPressed = true;
|
||||
return -1;
|
||||
|
||||
if (status & PS2_STATUS_AUX_DATA) {
|
||||
// we read mouse data, ignore it
|
||||
continue;
|
||||
}
|
||||
case LEFT_ALT:
|
||||
altPressed = true;
|
||||
return -1;
|
||||
|
||||
if (key & 0x80) {
|
||||
// key up
|
||||
switch (key & ~0x80) {
|
||||
case LEFT_SHIFT:
|
||||
case RIGHT_SHIFT:
|
||||
shiftPressed = false;
|
||||
break;
|
||||
case LEFT_CONTROL:
|
||||
controlPressed = false;
|
||||
break;
|
||||
case LEFT_ALT:
|
||||
altPressed = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// key down
|
||||
switch (key) {
|
||||
case LEFT_SHIFT:
|
||||
case RIGHT_SHIFT:
|
||||
shiftPressed = true;
|
||||
break;
|
||||
|
||||
case LEFT_CONTROL:
|
||||
controlPressed = true;
|
||||
break;
|
||||
|
||||
case LEFT_ALT:
|
||||
altPressed = true;
|
||||
break;
|
||||
|
||||
// start escape sequence for cursor movement
|
||||
case CURSOR_UP:
|
||||
special = 0x80 | 'A';
|
||||
return '\x1b';
|
||||
case CURSOR_DOWN:
|
||||
special = 0x80 | 'B';
|
||||
return '\x1b';
|
||||
case CURSOR_RIGHT:
|
||||
special = 0x80 | 'C';
|
||||
return '\x1b';
|
||||
case CURSOR_LEFT:
|
||||
special = 0x80 | 'D';
|
||||
return '\x1b';
|
||||
case CURSOR_HOME:
|
||||
special = 0x80 | 'H';
|
||||
return '\x1b';
|
||||
case CURSOR_END:
|
||||
special = 0x80 | 'F';
|
||||
return '\x1b';
|
||||
case PAGE_UP:
|
||||
special = 0x80 | '5';
|
||||
special2 = '~';
|
||||
return '\x1b';
|
||||
case PAGE_DOWN:
|
||||
special = 0x80 | '6';
|
||||
special2 = '~';
|
||||
return '\x1b';
|
||||
// start escape sequence for cursor movement
|
||||
case CURSOR_UP:
|
||||
special = 0x80 | 'A';
|
||||
return '\x1b';
|
||||
case CURSOR_DOWN:
|
||||
special = 0x80 | 'B';
|
||||
return '\x1b';
|
||||
case CURSOR_RIGHT:
|
||||
special = 0x80 | 'C';
|
||||
return '\x1b';
|
||||
case CURSOR_LEFT:
|
||||
special = 0x80 | 'D';
|
||||
return '\x1b';
|
||||
case CURSOR_HOME:
|
||||
special = 0x80 | 'H';
|
||||
return '\x1b';
|
||||
case CURSOR_END:
|
||||
special = 0x80 | 'F';
|
||||
return '\x1b';
|
||||
case PAGE_UP:
|
||||
special = 0x80 | '5';
|
||||
special2 = '~';
|
||||
return '\x1b';
|
||||
case PAGE_DOWN:
|
||||
special = 0x80 | '6';
|
||||
special2 = '~';
|
||||
return '\x1b';
|
||||
|
||||
|
||||
case DELETE:
|
||||
if (controlPressed && altPressed)
|
||||
arch_cpu_shutdown(true);
|
||||
case DELETE:
|
||||
if (controlPressed && altPressed)
|
||||
arch_cpu_shutdown(true);
|
||||
|
||||
special = 0x80 | '3';
|
||||
special2 = '~';
|
||||
return '\x1b';
|
||||
special = 0x80 | '3';
|
||||
special2 = '~';
|
||||
return '\x1b';
|
||||
|
||||
default:
|
||||
if (controlPressed) {
|
||||
char c = kShiftedKeymap[key];
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return 0x1f & c;
|
||||
}
|
||||
default:
|
||||
if (controlPressed) {
|
||||
char c = kShiftedKeymap[key];
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return 0x1f & c;
|
||||
}
|
||||
|
||||
if (altPressed)
|
||||
return kAltedKeymap[key];
|
||||
if (altPressed)
|
||||
return kAltedKeymap[key];
|
||||
|
||||
return shiftPressed
|
||||
? kShiftedKeymap[key] : kUnshiftedKeymap[key];
|
||||
}
|
||||
return shiftPressed
|
||||
? kShiftedKeymap[key] : kUnshiftedKeymap[key];
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
arch_debug_blue_screen_getchar(void)
|
||||
{
|
||||
while (true) {
|
||||
int c = arch_debug_blue_screen_try_getchar();
|
||||
if (c >= 0)
|
||||
return (char)c;
|
||||
|
||||
PAUSE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_debug_serial_try_getchar(void)
|
||||
{
|
||||
if ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x1) == 0)
|
||||
return -1;
|
||||
|
||||
return in8(sSerialBasePort + SERIAL_RECEIVE_BUFFER);
|
||||
}
|
||||
|
||||
|
||||
|
@ -659,6 +659,13 @@ blue_screen_clear_screen(void)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
blue_screen_try_getchar(void)
|
||||
{
|
||||
return arch_debug_blue_screen_try_getchar();
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
blue_screen_getchar(void)
|
||||
{
|
||||
|
@ -20,6 +20,7 @@ bool blue_screen_paging_enabled(void);
|
||||
void blue_screen_set_paging(bool enabled);
|
||||
|
||||
void blue_screen_clear_screen(void);
|
||||
int blue_screen_try_getchar(void);
|
||||
char blue_screen_getchar(void);
|
||||
void blue_screen_putchar(char c);
|
||||
void blue_screen_puts(const char *text);
|
||||
|
@ -90,7 +90,6 @@ static bool sSyslogOutputEnabled = true;
|
||||
static bool sBlueScreenEnabled = false;
|
||||
// must always be false on startup
|
||||
static bool sDebugScreenEnabled = false;
|
||||
static bool sSerialInputEnabled = false;
|
||||
static bool sBlueScreenOutput = true;
|
||||
static bool sEmergencyKeysEnabled = true;
|
||||
static spinlock sSpinlock = B_SPINLOCK_INITIALIZER;
|
||||
@ -474,7 +473,8 @@ read_line(char* buffer, int32 maxLength,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8: // backspace
|
||||
case 8: // backspace (CTRL-H)
|
||||
case 0x7f: // backspace (xterm)
|
||||
if (position > 0) {
|
||||
kputs("\x1b[1D"); // move to the left one
|
||||
position--;
|
||||
@ -681,22 +681,30 @@ read_line(char* buffer, int32 maxLength,
|
||||
char
|
||||
kgetc(void)
|
||||
{
|
||||
if (sSerialInputEnabled)
|
||||
return arch_debug_serial_getchar();
|
||||
while (true) {
|
||||
// check serial input
|
||||
int c = arch_debug_serial_try_getchar();
|
||||
if (c >= 0)
|
||||
return (char)c;
|
||||
|
||||
// give the kernel debugger modules a chance first
|
||||
for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
|
||||
if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_getchar) {
|
||||
int getChar = sDebuggerModules[i]->debugger_getchar();
|
||||
if (getChar >= 0)
|
||||
return (char)getChar;
|
||||
// check blue screen input
|
||||
if (sBlueScreenOutput) {
|
||||
c = blue_screen_try_getchar();
|
||||
if (c >= 0)
|
||||
return (char)c;
|
||||
}
|
||||
|
||||
// give the kernel debugger modules a chance
|
||||
for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
|
||||
if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_getchar) {
|
||||
int getChar = sDebuggerModules[i]->debugger_getchar();
|
||||
if (getChar >= 0)
|
||||
return (char)getChar;
|
||||
}
|
||||
}
|
||||
|
||||
PAUSE();
|
||||
}
|
||||
|
||||
if (sBlueScreenOutput)
|
||||
return blue_screen_getchar();
|
||||
|
||||
return arch_debug_serial_getchar();
|
||||
}
|
||||
|
||||
|
||||
@ -1136,16 +1144,6 @@ cmd_dump_syslog(int argc, char** argv)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmd_serial_input(int argc, char** argv)
|
||||
{
|
||||
sSerialInputEnabled = !sSerialInputEnabled;
|
||||
kprintf("Serial input is turned %s now.\n",
|
||||
sSerialInputEnabled ? "on" : "off");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmd_switch_cpu(int argc, char** argv)
|
||||
{
|
||||
@ -1413,9 +1411,6 @@ syslog_init_post_vm(struct kernel_args* args)
|
||||
"Dumps the whole syslog buffer, or, if -k is specified, only "
|
||||
"the part that hasn't been sent yet.\n", 0);
|
||||
|
||||
add_debugger_command("serial_input", &cmd_serial_input,
|
||||
"Enable or disable serial input");
|
||||
|
||||
return B_OK;
|
||||
|
||||
err2:
|
||||
|
Loading…
Reference in New Issue
Block a user