The BOCHS_DEBUG_HACK definition now only enables support for the bochs
debug output - to activate it, you now have to enable it in the kernel
settings file ("bochs_debug_output true").
Reimplemented the serial output so that it's flexible towards the base
port at run time.
Implemented support for kernel settings "serial_debug_port" (which can
now also be an index in the BIOS provided serial ports list), and
"serial_debug_speed".
That also means that you can finally use the same kernel executable
under BeOS Bochs and on a real system without any restrictions.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10642 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,17 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2002-2004, The Haiku Team. All rights reserved.
|
* Copyright 2002-2005, Axel Dörfler, [email protected]
|
||||||
** Distributed under the terms of the Haiku License.
|
* Copyright 2001, Rob Judd <[email protected]>
|
||||||
**
|
* Copyright 2002, Marcus Overhagen <[email protected]>
|
||||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
* Distributed under the terms of the Haiku License.
|
||||||
** Distributed under the terms of the NewOS License.
|
*
|
||||||
*/
|
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
|
* Distributed under the terms of the NewOS License.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
** Modified 2001/09/05 by Rob Judd<[email protected]>
|
|
||||||
** Modified 2002/09/28 by Marcus Overhagen <[email protected]>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <kernel.h>
|
#include <KernelExport.h>
|
||||||
|
#include <driver_settings.h>
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <arch/dbg_console.h>
|
#include <arch/dbg_console.h>
|
||||||
@@ -19,23 +18,44 @@
|
|||||||
#include <boot/stage2.h>
|
#include <boot/stage2.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* define this only if not used as compile parameter
|
|
||||||
* setting it to 1 will disable serial debug and
|
/* If you've enabled Bochs debug output in the kernel driver
|
||||||
* redirect it to Bochs
|
* settings and has defined this, serial debug output will be
|
||||||
|
* disabled and redirected to Bochs.
|
||||||
|
* Define this only if not used as compile parameter.
|
||||||
*/
|
*/
|
||||||
// #define BOCHS_DEBUG_HACK 0
|
// #define BOCHS_DEBUG_HACK 0
|
||||||
|
|
||||||
// Select between COM1 and COM2 for debug output
|
|
||||||
#define USE_COM1 1
|
|
||||||
|
|
||||||
static const int dbg_baud_rate = 115200;
|
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
|
||||||
|
|
||||||
|
#if BOCHS_DEBUG_HACK
|
||||||
|
static bool sBochsOutput = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
char
|
char
|
||||||
arch_dbg_con_read(void)
|
arch_dbg_con_read(void)
|
||||||
{
|
{
|
||||||
#if BOCHS_DEBUG_HACK
|
#if BOCHS_DEBUG_HACK
|
||||||
|
if (sBochsOutput) {
|
||||||
/* 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
|
||||||
*/
|
*/
|
||||||
@@ -77,37 +97,31 @@ arch_dbg_con_read(void)
|
|||||||
}
|
}
|
||||||
} while (!ascii);
|
} while (!ascii);
|
||||||
return ascii;
|
return ascii;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_COM1
|
while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x1) == 0)
|
||||||
while ((in8(0x3fd) & 1) == 0)
|
|
||||||
;
|
;
|
||||||
return in8(0x3f8);
|
|
||||||
#else
|
return in8(sSerialBasePort + SERIAL_RECEIVE_BUFFER);
|
||||||
while ((in8(0x2fd) & 1) == 0)
|
|
||||||
;
|
|
||||||
return in8(0x2f8);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_arch_dbg_con_putch(const char c)
|
put_char(const char c)
|
||||||
{
|
{
|
||||||
#if BOCHS_DEBUG_HACK
|
#if BOCHS_DEBUG_HACK
|
||||||
|
if (sBochsOutput) {
|
||||||
out8(c, 0xe9);
|
out8(c, 0xe9);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_COM1
|
// wait until the transmitter empty bit is set
|
||||||
while ((in8(0x3fd) & 0x20) == 0)
|
while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x20) == 0)
|
||||||
;
|
;
|
||||||
out8(c, 0x3f8);
|
|
||||||
#else // COM2
|
out8(c, sSerialBasePort + SERIAL_TRANSMIT_BUFFER);
|
||||||
while ((in8(0x2fd) & 0x20) == 0)
|
|
||||||
;
|
|
||||||
out8(c, 0x2f8);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,10 +129,10 @@ char
|
|||||||
arch_dbg_con_putch(const char c)
|
arch_dbg_con_putch(const char c)
|
||||||
{
|
{
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
_arch_dbg_con_putch('\r');
|
put_char('\r');
|
||||||
_arch_dbg_con_putch('\n');
|
put_char('\n');
|
||||||
} else if (c != '\r')
|
} else if (c != '\r')
|
||||||
_arch_dbg_con_putch(c);
|
put_char(c);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -147,20 +161,77 @@ arch_dbg_con_early_boot_message(const char *string)
|
|||||||
status_t
|
status_t
|
||||||
arch_dbg_con_init(kernel_args *args)
|
arch_dbg_con_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
short divisor = 115200 / dbg_baud_rate;
|
uint16 divisor = (uint16)(115200 / kSerialBaudRate);
|
||||||
|
|
||||||
#if USE_COM1
|
// only use the port if we could find one, else use the standard port
|
||||||
out8(0x80, 0x3fb); /* set up to load divisor latch */
|
if (args->platform_args.serial_base_ports[0] != 0)
|
||||||
out8(divisor & 0xf, 0x3f8); /* LSB */
|
sSerialBasePort = args->platform_args.serial_base_ports[0];
|
||||||
out8(divisor >> 8, 0x3f9); /* MSB */
|
|
||||||
out8(3, 0x3fb); /* 8N1 */
|
|
||||||
#else // COM2
|
|
||||||
out8(0x80, 0x2fb); /* set up to load divisor latch */
|
|
||||||
out8(divisor & 0xf, 0x2f8); /* LSB */
|
|
||||||
out8(divisor >> 8, 0x2f9); /* MSB */
|
|
||||||
out8(3, 0x2fb); /* 8N1 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
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 */
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
arch_dbg_con_init_settings(kernel_args *args)
|
||||||
|
{
|
||||||
|
uint32 baudRate = kSerialBaudRate;
|
||||||
|
uint16 basePort = sSerialBasePort;
|
||||||
|
uint16 divisor;
|
||||||
|
void *handle;
|
||||||
|
|
||||||
|
// get debug settings
|
||||||
|
handle = load_driver_settings("kernel");
|
||||||
|
if (handle != NULL) {
|
||||||
|
const char *value;
|
||||||
|
|
||||||
|
#ifdef BOCHS_DEBUG_HACK
|
||||||
|
sBochsOutput = get_driver_boolean_parameter(handle, "bochs_debug_output", false, false);
|
||||||
|
#endif
|
||||||
|
value = get_driver_parameter(handle, "serial_debug_port", NULL, NULL);
|
||||||
|
if (value != NULL) {
|
||||||
|
int32 number = strtol(value, NULL, 0);
|
||||||
|
if (number < MAX_SERIAL_PORTS) {
|
||||||
|
// use as index into port array
|
||||||
|
if (args->platform_args.serial_base_ports[number] != 0)
|
||||||
|
basePort = args->platform_args.serial_base_ports[number];
|
||||||
|
} else {
|
||||||
|
// use as port number directly
|
||||||
|
basePort = number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value = get_driver_parameter(handle, "serial_debug_speed", NULL, NULL);
|
||||||
|
if (value != NULL) {
|
||||||
|
int32 number = strtol(value, NULL, 0);
|
||||||
|
switch (number) {
|
||||||
|
case 9600:
|
||||||
|
case 19200:
|
||||||
|
case 38400:
|
||||||
|
case 57600:
|
||||||
|
case 115200:
|
||||||
|
//case 230400:
|
||||||
|
baudRate = number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unload_driver_settings(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sSerialBasePort == basePort && baudRate == kSerialBaudRate)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
sSerialBasePort = basePort;
|
||||||
|
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 */
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user