Copied the x86 debug console functions to x86_64.
Note that this is only temporary so that I have serial output from the kernel, the x86 and x86_64 versions will be merged later.
This commit is contained in:
@@ -30,6 +30,8 @@ arch_cpu_init_percpu(kernel_args *args, int cpu)
|
|||||||
status_t
|
status_t
|
||||||
arch_cpu_init(kernel_args *args)
|
arch_cpu_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
|
dprintf("not implemented...\n");
|
||||||
|
while (1);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,74 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2002-2009, Axel Dörfler, [email protected]
|
||||||
|
* Copyright 2001, Rob Judd <[email protected]>
|
||||||
|
* Copyright 2002, Marcus Overhagen <[email protected]>
|
||||||
* Copyright 2012, Alex Smith, [email protected].
|
* Copyright 2012, Alex Smith, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
|
* Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <debug.h>
|
#include <KernelExport.h>
|
||||||
|
#include <driver_settings.h>
|
||||||
|
#include <int.h>
|
||||||
|
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <arch/debug_console.h>
|
#include <arch/debug_console.h>
|
||||||
|
#include <boot/stage2.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
enum serial_register_offsets {
|
||||||
|
SERIAL_TRANSMIT_BUFFER = 0,
|
||||||
|
SERIAL_RECEIVE_BUFFER = 0,
|
||||||
|
SERIAL_DIVISOR_LATCH_LOW = 0,
|
||||||
|
SERIAL_DIVISOR_LATCH_HIGH = 1,
|
||||||
|
SERIAL_FIFO_CONTROL = 2,
|
||||||
|
SERIAL_LINE_CONTROL = 3,
|
||||||
|
SERIAL_MODEM_CONTROL = 4,
|
||||||
|
SERIAL_LINE_STATUS = 5,
|
||||||
|
SERIAL_MODEM_STATUS = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const uint32 kSerialBaudRate = 115200;
|
||||||
|
static uint16 sSerialBasePort = 0x3f8;
|
||||||
|
// COM1 is the default debug output port
|
||||||
|
|
||||||
|
static spinlock sSerialOutputSpinlock = B_SPINLOCK_INITIALIZER;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_serial_port(uint16 basePort, uint32 baudRate)
|
||||||
|
{
|
||||||
|
sSerialBasePort = basePort;
|
||||||
|
|
||||||
|
uint16 divisor = (uint16)(115200 / baudRate);
|
||||||
|
|
||||||
|
out8(0x80, sSerialBasePort + SERIAL_LINE_CONTROL); /* set divisor latch access bit */
|
||||||
|
out8(divisor & 0xf, sSerialBasePort + SERIAL_DIVISOR_LATCH_LOW);
|
||||||
|
out8(divisor >> 8, sSerialBasePort + SERIAL_DIVISOR_LATCH_HIGH);
|
||||||
|
out8(3, sSerialBasePort + SERIAL_LINE_CONTROL); /* 8N1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
put_char(const char c)
|
||||||
|
{
|
||||||
|
// wait until the transmitter empty bit is set
|
||||||
|
while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x20) == 0)
|
||||||
|
asm volatile ("pause;");
|
||||||
|
|
||||||
|
out8(c, sSerialBasePort + SERIAL_TRANSMIT_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -43,43 +104,109 @@ arch_debug_blue_screen_getchar(void)
|
|||||||
int
|
int
|
||||||
arch_debug_serial_try_getchar(void)
|
arch_debug_serial_try_getchar(void)
|
||||||
{
|
{
|
||||||
return -1;
|
uint8 lineStatus = in8(sSerialBasePort + SERIAL_LINE_STATUS);
|
||||||
|
if (lineStatus == 0xff) {
|
||||||
|
// The "data available" bit is set, but also all error bits. Likely we
|
||||||
|
// don't have a valid I/O port.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((lineStatus & 0x1) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return in8(sSerialBasePort + SERIAL_RECEIVE_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char
|
char
|
||||||
arch_debug_serial_getchar(void)
|
arch_debug_serial_getchar(void)
|
||||||
{
|
{
|
||||||
while(true)
|
while (true) {
|
||||||
|
uint8 lineStatus = in8(sSerialBasePort + SERIAL_LINE_STATUS);
|
||||||
|
if (lineStatus == 0xff) {
|
||||||
|
// The "data available" bit is set, but also all error bits. Likely
|
||||||
|
// we don't have a valid I/O port.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((lineStatus & 0x1) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
PAUSE();
|
PAUSE();
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
return in8(sSerialBasePort + SERIAL_RECEIVE_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_arch_debug_serial_putchar(const char c)
|
||||||
|
{
|
||||||
|
if (c == '\n') {
|
||||||
|
put_char('\r');
|
||||||
|
put_char('\n');
|
||||||
|
} else if (c != '\r')
|
||||||
|
put_char(c);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
arch_debug_serial_putchar(const char c)
|
arch_debug_serial_putchar(const char c)
|
||||||
{
|
{
|
||||||
|
cpu_status state = 0;
|
||||||
|
if (!debug_debugger_running()) {
|
||||||
|
state = disable_interrupts();
|
||||||
|
acquire_spinlock(&sSerialOutputSpinlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
_arch_debug_serial_putchar(c);
|
||||||
|
|
||||||
|
if (!debug_debugger_running()) {
|
||||||
|
release_spinlock(&sSerialOutputSpinlock);
|
||||||
|
restore_interrupts(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arch_debug_serial_puts(const char *s)
|
arch_debug_serial_puts(const char *s)
|
||||||
{
|
{
|
||||||
|
cpu_status state = 0;
|
||||||
|
if (!debug_debugger_running()) {
|
||||||
|
state = disable_interrupts();
|
||||||
|
acquire_spinlock(&sSerialOutputSpinlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*s != '\0') {
|
||||||
|
_arch_debug_serial_putchar(*s);
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!debug_debugger_running()) {
|
||||||
|
release_spinlock(&sSerialOutputSpinlock);
|
||||||
|
restore_interrupts(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arch_debug_serial_early_boot_message(const char *string)
|
arch_debug_serial_early_boot_message(const char *string)
|
||||||
{
|
{
|
||||||
|
// this function will only be called in fatal situations
|
||||||
|
// ToDo: also enable output via text console?!
|
||||||
|
arch_debug_console_init(NULL);
|
||||||
|
arch_debug_serial_puts(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
arch_debug_console_init(kernel_args *args)
|
arch_debug_console_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
|
// only use the port if we could find one, else use the standard port
|
||||||
|
if (args != NULL && args->platform_args.serial_base_ports[0] != 0)
|
||||||
|
sSerialBasePort = args->platform_args.serial_base_ports[0];
|
||||||
|
|
||||||
|
init_serial_port(sSerialBasePort, kSerialBaudRate);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,8 +78,6 @@ static int32 main2(void *);
|
|||||||
extern "C" int
|
extern "C" int
|
||||||
_start(kernel_args *bootKernelArgs, int currentCPU)
|
_start(kernel_args *bootKernelArgs, int currentCPU)
|
||||||
{
|
{
|
||||||
while (1) {}
|
|
||||||
|
|
||||||
if (bootKernelArgs->kernel_args_size != sizeof(kernel_args)
|
if (bootKernelArgs->kernel_args_size != sizeof(kernel_args)
|
||||||
|| bootKernelArgs->version != CURRENT_KERNEL_ARGS_VERSION) {
|
|| bootKernelArgs->version != CURRENT_KERNEL_ARGS_VERSION) {
|
||||||
// This is something we cannot handle right now - release kernels
|
// This is something we cannot handle right now - release kernels
|
||||||
|
|||||||
Reference in New Issue
Block a user