* 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:
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006, Axel Dörfler, [email protected]
|
* Copyright 2002-2006, Axel Dörfler, [email protected]
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
@@ -18,7 +18,9 @@ struct kernel_args;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int arch_debug_blue_screen_try_getchar(void);
|
||||||
char arch_debug_blue_screen_getchar(void);
|
char arch_debug_blue_screen_getchar(void);
|
||||||
|
int arch_debug_serial_try_getchar(void);
|
||||||
char arch_debug_serial_getchar(void);
|
char arch_debug_serial_getchar(void);
|
||||||
void arch_debug_serial_putchar(char c);
|
void arch_debug_serial_putchar(char c);
|
||||||
void arch_debug_serial_puts(const char *s);
|
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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -23,6 +23,28 @@ static int32 sDebuggerCommandAdded = 0;
|
|||||||
|
|
||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
#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
|
static int
|
||||||
debug_process_transfer(int argc, char **argv)
|
debug_process_transfer(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -42,9 +64,38 @@ debug_process_transfer(int argc, char **argv)
|
|||||||
if (length == 0)
|
if (length == 0)
|
||||||
return 5;
|
return 5;
|
||||||
|
|
||||||
Transfer transfer(pipe);
|
static uint8 transferBuffer[sizeof(DebugTransfer)]
|
||||||
transfer.SetData(data, length);
|
__attribute__((aligned(16)));
|
||||||
return ((UHCI *)pipe->GetBusManager())->ProcessDebugTransfer(&transfer);
|
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
|
#endif
|
||||||
|
|
||||||
@@ -672,73 +723,102 @@ UHCI::SubmitTransfer(Transfer *transfer)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
UHCI::ProcessDebugTransfer(Transfer *transfer)
|
UHCI::StartDebugTransfer(DebugTransfer *transfer)
|
||||||
{
|
{
|
||||||
uhci_td *firstDescriptor = NULL;
|
transfer->firstDescriptor = NULL;
|
||||||
uhci_qh *transferQueue = NULL;
|
transfer->transferQueue = NULL;
|
||||||
status_t result = CreateFilledTransfer(transfer, &firstDescriptor,
|
status_t result = CreateFilledTransfer(transfer, &transfer->firstDescriptor,
|
||||||
&transferQueue);
|
&transfer->transferQueue);
|
||||||
if (result < B_OK)
|
if (result < B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
fQueues[UHCI_DEBUG_QUEUE]->AppendTransfer(transferQueue, false);
|
fQueues[UHCI_DEBUG_QUEUE]->AppendTransfer(transfer->transferQueue, false);
|
||||||
|
|
||||||
while (true) {
|
return B_OK;
|
||||||
bool transferOK = false;
|
}
|
||||||
bool transferError = false;
|
|
||||||
uhci_td *descriptor = firstDescriptor;
|
|
||||||
|
|
||||||
while (descriptor) {
|
|
||||||
uint32 status = descriptor->status;
|
|
||||||
if (status & TD_STATUS_ACTIVE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (status & TD_ERROR_MASK) {
|
status_t
|
||||||
transferError = true;
|
UHCI::CheckDebugTransfer(DebugTransfer *transfer, bool &_stillPending)
|
||||||
break;
|
{
|
||||||
}
|
bool transferOK = false;
|
||||||
|
bool transferError = false;
|
||||||
|
uhci_td *descriptor = transfer->firstDescriptor;
|
||||||
|
|
||||||
if ((descriptor->link_phy & TD_TERMINATE)
|
while (descriptor) {
|
||||||
|| uhci_td_actual_length(descriptor)
|
uint32 status = descriptor->status;
|
||||||
< uhci_td_maximum_length(descriptor)) {
|
if (status & TD_STATUS_ACTIVE)
|
||||||
transferOK = true;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptor = (uhci_td *)descriptor->link_log;
|
if (status & TD_ERROR_MASK) {
|
||||||
|
transferError = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!transferOK && !transferError) {
|
if ((descriptor->link_phy & TD_TERMINATE)
|
||||||
spin(200);
|
|| uhci_td_actual_length(descriptor)
|
||||||
continue;
|
< uhci_td_maximum_length(descriptor)) {
|
||||||
|
transferOK = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transferOK) {
|
descriptor = (uhci_td *)descriptor->link_log;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
UHCI::AddTo(Stack *stack)
|
||||||
{
|
{
|
||||||
#ifdef TRACE_USB
|
#ifdef TRACE_USB
|
||||||
set_dprintf_enabled(true);
|
set_dprintf_enabled(true);
|
||||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
load_driver_symbols("uhci");
|
load_driver_symbols("uhci");
|
||||||
#endif
|
#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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
struct pci_info;
|
struct pci_info;
|
||||||
struct pci_module_info;
|
struct pci_module_info;
|
||||||
class UHCIRootHub;
|
class UHCIRootHub;
|
||||||
|
class DebugTransfer;
|
||||||
|
|
||||||
|
|
||||||
class Queue {
|
class Queue {
|
||||||
@@ -97,7 +98,11 @@ public:
|
|||||||
|
|
||||||
status_t Start();
|
status_t Start();
|
||||||
virtual status_t SubmitTransfer(Transfer *transfer);
|
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);
|
virtual status_t CancelQueuedTransfers(Pipe *pipe, bool force);
|
||||||
status_t CancelQueuedIsochronousTransfers(Pipe *pipe, bool force);
|
status_t CancelQueuedIsochronousTransfers(Pipe *pipe, bool force);
|
||||||
status_t SubmitRequest(Transfer *transfer);
|
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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -176,6 +176,9 @@ enter_debugger(void)
|
|||||||
static void
|
static void
|
||||||
exit_debugger(void)
|
exit_debugger(void)
|
||||||
{
|
{
|
||||||
|
// make sure a possibly pending transfer is canceled
|
||||||
|
evaluate_debug_command("uhci_process_transfer cancel");
|
||||||
|
|
||||||
sUseUSBKeyboard = false;
|
sUseUSBKeyboard = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,11 +198,12 @@ debugger_getchar(void)
|
|||||||
if (!sUseUSBKeyboard)
|
if (!sUseUSBKeyboard)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
while (sBufferedCharCount == 0) {
|
if (sBufferedCharCount == 0) {
|
||||||
set_debug_variable("_usbPipe", (uint64)sUSBPipe);
|
set_debug_variable("_usbPipe", (uint64)sUSBPipe);
|
||||||
set_debug_variable("_usbTransferData", (uint64)sUSBTransferData);
|
set_debug_variable("_usbTransferData", (uint64)sUSBTransferData);
|
||||||
set_debug_variable("_usbTransferLength", (uint64)sUSBTransferLength);
|
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;
|
bool phantomState = true;
|
||||||
for (size_t i = 2; i < sUSBTransferLength; i++) {
|
for (size_t i = 2; i < sUSBTransferLength; i++) {
|
||||||
@@ -210,7 +214,7 @@ debugger_getchar(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (phantomState)
|
if (phantomState)
|
||||||
continue;
|
return -1;
|
||||||
|
|
||||||
uint8 modifiers = 0;
|
uint8 modifiers = 0;
|
||||||
for (uint32 i = 0; i < 8; i++) {
|
for (uint32 i = 0; i < 8; i++) {
|
||||||
@@ -272,6 +276,9 @@ debugger_getchar(void)
|
|||||||
sLastTransferData[i] = sUSBTransferData[i];
|
sLastTransferData[i] = sUSBTransferData[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sBufferedCharCount == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
int result = sBufferedChars[sBufferReadIndex++];
|
int result = sBufferedChars[sBufferReadIndex++];
|
||||||
sBufferReadIndex %= sBufferSize;
|
sBufferReadIndex %= sBufferSize;
|
||||||
sBufferedCharCount--;
|
sBufferedCharCount--;
|
||||||
@@ -302,7 +309,7 @@ static struct debugger_module_info sModuleInfo = {
|
|||||||
&debugger_getchar
|
&debugger_getchar
|
||||||
};
|
};
|
||||||
|
|
||||||
module_info *modules[] = {
|
module_info *modules[] = {
|
||||||
(module_info *)&sModuleInfo,
|
(module_info *)&sModuleInfo,
|
||||||
NULL
|
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
|
char
|
||||||
arch_debug_blue_screen_getchar(void)
|
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
|
char
|
||||||
arch_debug_serial_getchar(void)
|
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
|
char
|
||||||
arch_debug_blue_screen_getchar(void)
|
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
|
char
|
||||||
arch_debug_serial_getchar(void)
|
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
|
char
|
||||||
arch_debug_blue_screen_getchar(void)
|
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
|
char
|
||||||
arch_debug_serial_getchar(void)
|
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
|
char
|
||||||
arch_debug_blue_screen_getchar(void)
|
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
|
char
|
||||||
arch_debug_serial_getchar(void)
|
arch_debug_serial_getchar(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -166,8 +166,8 @@ arch_debug_install_interrupt_handlers(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char
|
int
|
||||||
arch_debug_blue_screen_getchar(void)
|
arch_debug_blue_screen_try_getchar(void)
|
||||||
{
|
{
|
||||||
/* polling the keyboard, similar to code in keyboard
|
/* polling the keyboard, similar to code in keyboard
|
||||||
* driver, but without using an interrupt
|
* driver, but without using an interrupt
|
||||||
@@ -194,105 +194,126 @@ arch_debug_blue_screen_getchar(void)
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
uint8 status = in8(PS2_PORT_CTRL);
|
||||||
uint8 status = in8(PS2_PORT_CTRL);
|
|
||||||
|
|
||||||
if ((status & PS2_STATUS_OUTPUT_BUFFER_FULL) == 0) {
|
if ((status & PS2_STATUS_OUTPUT_BUFFER_FULL) == 0) {
|
||||||
// no data in keyboard buffer
|
// no data in keyboard buffer
|
||||||
spin(200);
|
return -1;
|
||||||
continue;
|
}
|
||||||
|
|
||||||
|
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);
|
case LEFT_CONTROL:
|
||||||
key = in8(PS2_PORT_DATA);
|
controlPressed = true;
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (status & PS2_STATUS_AUX_DATA) {
|
case LEFT_ALT:
|
||||||
// we read mouse data, ignore it
|
altPressed = true;
|
||||||
continue;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
if (key & 0x80) {
|
// start escape sequence for cursor movement
|
||||||
// key up
|
case CURSOR_UP:
|
||||||
switch (key & ~0x80) {
|
special = 0x80 | 'A';
|
||||||
case LEFT_SHIFT:
|
return '\x1b';
|
||||||
case RIGHT_SHIFT:
|
case CURSOR_DOWN:
|
||||||
shiftPressed = false;
|
special = 0x80 | 'B';
|
||||||
break;
|
return '\x1b';
|
||||||
case LEFT_CONTROL:
|
case CURSOR_RIGHT:
|
||||||
controlPressed = false;
|
special = 0x80 | 'C';
|
||||||
break;
|
return '\x1b';
|
||||||
case LEFT_ALT:
|
case CURSOR_LEFT:
|
||||||
altPressed = false;
|
special = 0x80 | 'D';
|
||||||
break;
|
return '\x1b';
|
||||||
}
|
case CURSOR_HOME:
|
||||||
} else {
|
special = 0x80 | 'H';
|
||||||
// key down
|
return '\x1b';
|
||||||
switch (key) {
|
case CURSOR_END:
|
||||||
case LEFT_SHIFT:
|
special = 0x80 | 'F';
|
||||||
case RIGHT_SHIFT:
|
return '\x1b';
|
||||||
shiftPressed = true;
|
case PAGE_UP:
|
||||||
break;
|
special = 0x80 | '5';
|
||||||
|
special2 = '~';
|
||||||
case LEFT_CONTROL:
|
return '\x1b';
|
||||||
controlPressed = true;
|
case PAGE_DOWN:
|
||||||
break;
|
special = 0x80 | '6';
|
||||||
|
special2 = '~';
|
||||||
case LEFT_ALT:
|
return '\x1b';
|
||||||
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';
|
|
||||||
|
|
||||||
|
|
||||||
case DELETE:
|
case DELETE:
|
||||||
if (controlPressed && altPressed)
|
if (controlPressed && altPressed)
|
||||||
arch_cpu_shutdown(true);
|
arch_cpu_shutdown(true);
|
||||||
|
|
||||||
special = 0x80 | '3';
|
special = 0x80 | '3';
|
||||||
special2 = '~';
|
special2 = '~';
|
||||||
return '\x1b';
|
return '\x1b';
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (controlPressed) {
|
if (controlPressed) {
|
||||||
char c = kShiftedKeymap[key];
|
char c = kShiftedKeymap[key];
|
||||||
if (c >= 'A' && c <= 'Z')
|
if (c >= 'A' && c <= 'Z')
|
||||||
return 0x1f & c;
|
return 0x1f & c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (altPressed)
|
if (altPressed)
|
||||||
return kAltedKeymap[key];
|
return kAltedKeymap[key];
|
||||||
|
|
||||||
return shiftPressed
|
return shiftPressed
|
||||||
? kShiftedKeymap[key] : kUnshiftedKeymap[key];
|
? 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
|
char
|
||||||
blue_screen_getchar(void)
|
blue_screen_getchar(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ bool blue_screen_paging_enabled(void);
|
|||||||
void blue_screen_set_paging(bool enabled);
|
void blue_screen_set_paging(bool enabled);
|
||||||
|
|
||||||
void blue_screen_clear_screen(void);
|
void blue_screen_clear_screen(void);
|
||||||
|
int blue_screen_try_getchar(void);
|
||||||
char blue_screen_getchar(void);
|
char blue_screen_getchar(void);
|
||||||
void blue_screen_putchar(char c);
|
void blue_screen_putchar(char c);
|
||||||
void blue_screen_puts(const char *text);
|
void blue_screen_puts(const char *text);
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ static bool sSyslogOutputEnabled = true;
|
|||||||
static bool sBlueScreenEnabled = false;
|
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 sSerialInputEnabled = false;
|
|
||||||
static bool sBlueScreenOutput = true;
|
static bool sBlueScreenOutput = true;
|
||||||
static bool sEmergencyKeysEnabled = true;
|
static bool sEmergencyKeysEnabled = true;
|
||||||
static spinlock sSpinlock = B_SPINLOCK_INITIALIZER;
|
static spinlock sSpinlock = B_SPINLOCK_INITIALIZER;
|
||||||
@@ -474,7 +473,8 @@ read_line(char* buffer, int32 maxLength,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 8: // backspace
|
case 8: // backspace (CTRL-H)
|
||||||
|
case 0x7f: // backspace (xterm)
|
||||||
if (position > 0) {
|
if (position > 0) {
|
||||||
kputs("\x1b[1D"); // move to the left one
|
kputs("\x1b[1D"); // move to the left one
|
||||||
position--;
|
position--;
|
||||||
@@ -681,22 +681,30 @@ read_line(char* buffer, int32 maxLength,
|
|||||||
char
|
char
|
||||||
kgetc(void)
|
kgetc(void)
|
||||||
{
|
{
|
||||||
if (sSerialInputEnabled)
|
while (true) {
|
||||||
return arch_debug_serial_getchar();
|
// check serial input
|
||||||
|
int c = arch_debug_serial_try_getchar();
|
||||||
|
if (c >= 0)
|
||||||
|
return (char)c;
|
||||||
|
|
||||||
// give the kernel debugger modules a chance first
|
// check blue screen input
|
||||||
for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
|
if (sBlueScreenOutput) {
|
||||||
if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_getchar) {
|
c = blue_screen_try_getchar();
|
||||||
int getChar = sDebuggerModules[i]->debugger_getchar();
|
if (c >= 0)
|
||||||
if (getChar >= 0)
|
return (char)c;
|
||||||
return (char)getChar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
static int
|
||||||
cmd_switch_cpu(int argc, char** argv)
|
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 "
|
"Dumps the whole syslog buffer, or, if -k is specified, only "
|
||||||
"the part that hasn't been sent yet.\n", 0);
|
"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;
|
return B_OK;
|
||||||
|
|
||||||
err2:
|
err2:
|
||||||
|
|||||||
Reference in New Issue
Block a user