From 73760b20583b09d53cbfa3af2dd341d85e434b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 3 Nov 2004 03:02:34 +0000 Subject: [PATCH] Moved serial interface code into separate file. serial_init() is now called from start(). Changed the way the serial debug output is served: instead of having the console node to dump everything to serial, too, only dprintf() triggers serial output now. dprintf() is now silent unless in debug mode; serial output could be enabled separetely, though (currently only at build time). There is no need to disable serial output while the menu is running. Removed unnecessary grist from the Jamfile. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9756 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/boot/platform/bios_ia32/Jamfile | 29 ++--- .../boot/platform/bios_ia32/console.cpp | 104 +---------------- src/kernel/boot/platform/bios_ia32/debug.c | 13 ++- src/kernel/boot/platform/bios_ia32/menu.cpp | 3 - src/kernel/boot/platform/bios_ia32/mmu.cpp | 2 +- src/kernel/boot/platform/bios_ia32/serial.cpp | 106 ++++++++++++++++++ src/kernel/boot/platform/bios_ia32/serial.h | 27 +++++ src/kernel/boot/platform/bios_ia32/start.c | 2 + 8 files changed, 165 insertions(+), 121 deletions(-) create mode 100644 src/kernel/boot/platform/bios_ia32/serial.cpp create mode 100644 src/kernel/boot/platform/bios_ia32/serial.h diff --git a/src/kernel/boot/platform/bios_ia32/Jamfile b/src/kernel/boot/platform/bios_ia32/Jamfile index 9ace82e181..f5037129a1 100644 --- a/src/kernel/boot/platform/bios_ia32/Jamfile +++ b/src/kernel/boot/platform/bios_ia32/Jamfile @@ -8,19 +8,20 @@ UsePrivateHeaders [ FDirName storage ] ; SubDirC++Flags -fno-rtti ; KernelMergeObject boot_platform_bios_ia32.o : - <$(SOURCE_GRIST)>shell.S - <$(SOURCE_GRIST)>start.c - <$(SOURCE_GRIST)>debug.c - <$(SOURCE_GRIST)>bios.S - <$(SOURCE_GRIST)>console.cpp - <$(SOURCE_GRIST)>devices.cpp - <$(SOURCE_GRIST)>keyboard.cpp - <$(SOURCE_GRIST)>menu.cpp - <$(SOURCE_GRIST)>mmu.cpp - <$(SOURCE_GRIST)>cpu.cpp - <$(SOURCE_GRIST)>smp_boot.c - <$(SOURCE_GRIST)>smp_trampoline.S - <$(SOURCE_GRIST)>support.S - <$(SOURCE_GRIST)>video.cpp + shell.S + start.c + debug.c + bios.S + console.cpp + serial.cpp + devices.cpp + keyboard.cpp + menu.cpp + mmu.cpp + cpu.cpp + smp_boot.c + smp_trampoline.S + support.S + video.cpp : -fno-pic ; diff --git a/src/kernel/boot/platform/bios_ia32/console.cpp b/src/kernel/boot/platform/bios_ia32/console.cpp index 809fe56a25..4072fd6eea 100644 --- a/src/kernel/boot/platform/bios_ia32/console.cpp +++ b/src/kernel/boot/platform/bios_ia32/console.cpp @@ -4,13 +4,13 @@ */ +#include "console.h" + #include -#include #include -#include #include -#include "console.h" +#include class Console : public ConsoleNode { @@ -21,110 +21,16 @@ class Console : public ConsoleNode { virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize); }; -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 *sScreenBase = (uint16 *)0xb8000; static uint32 sScreenWidth = 80; static uint32 sScreenHeight = 25; static uint32 sScreenOffset = 0; static uint16 sColor = 0x0f00; -static int32 sSerialEnabled = 0; -static uint16 sSerialBasePort = 0x3f8; - static Console sInput, sOutput; FILE *stdin, *stdout, *stderr; -// serial debug output - - -static void -serial_putc(char c) -{ - // wait until the transmitter empty bit is set - while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x20) == 0) - ; - - out8(c, sSerialBasePort + SERIAL_TRANSMIT_BUFFER); -} - - -static void -serial_puts(const char *string, size_t size) -{ - while (size-- != 0) { - char c = string[0]; - - if (c == '\n') { - serial_putc('\r'); - serial_putc('\n'); - } else if (c != '\r') - serial_putc(c); - - string++; - } -} - - -extern "C" void -serial_disable(void) -{ -#if ENABLE_SERIAL - sSerialEnabled = 0; -#else - sSerialEnabled--; -#endif -} - - -extern "C" void -serial_enable(void) -{ - sSerialEnabled++; -} - - -static void -serial_init(void) -{ - // copy the base ports of the optional 4 serial ports to the kernel args - // 0x0000:0x0400 is the location of that information in the BIOS data segment - uint16 *ports = (uint16 *)0x400; - memcpy(gKernelArgs.platform_args.serial_base_ports, ports, sizeof(uint16) * MAX_SERIAL_PORTS); - - // only use the port if we could find one, else use the standard port - if (gKernelArgs.platform_args.serial_base_ports[0] != 0) - sSerialBasePort = gKernelArgs.platform_args.serial_base_ports[0]; - - uint16 divisor = uint16(115200 / kSerialBaudRate); - - 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 */ - -#ifdef ENABLE_SERIAL - serial_enable(); -#endif -} - - -// #pragma mark - - - static void scroll_up() { @@ -160,9 +66,6 @@ Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer, size_t bufferS { const char *string = (const char *)buffer; - if (sSerialEnabled > 0) - serial_puts(string, bufferSize); - if (gKernelArgs.frame_buffer.enabled) return bufferSize; @@ -231,7 +134,6 @@ console_init(void) { // ToDo: make screen size changeable via stage2_args - serial_init(); console_clear_screen(); // enable stdio functionality diff --git a/src/kernel/boot/platform/bios_ia32/debug.c b/src/kernel/boot/platform/bios_ia32/debug.c index 5dc557a692..c7a5998f65 100644 --- a/src/kernel/boot/platform/bios_ia32/debug.c +++ b/src/kernel/boot/platform/bios_ia32/debug.c @@ -1,9 +1,11 @@ /* ** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. -** Distributed under the terms of the OpenBeOS License. +** Distributed under the terms of the Haiku License. */ +#include "serial.h" + #include #include #include @@ -34,10 +36,17 @@ panic(const char *format, ...) void dprintf(const char *format, ...) { + char buffer[512]; va_list list; + int length; va_start(list, format); - vprintf(format, list); + length = vsnprintf(buffer, sizeof(buffer), format, list); va_end(list); + + serial_puts(buffer, length); + + if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) + fprintf(stderr, "%s", buffer); } diff --git a/src/kernel/boot/platform/bios_ia32/menu.cpp b/src/kernel/boot/platform/bios_ia32/menu.cpp index b1eccdc0c7..9a6c63ddd1 100644 --- a/src/kernel/boot/platform/bios_ia32/menu.cpp +++ b/src/kernel/boot/platform/bios_ia32/menu.cpp @@ -468,12 +468,9 @@ void platform_run_menu(Menu *menu) { platform_switch_to_text_mode(); - serial_disable(); - // no serial output while we're playing on the console run_menu(menu); - serial_enable(); platform_switch_to_logo(); } diff --git a/src/kernel/boot/platform/bios_ia32/mmu.cpp b/src/kernel/boot/platform/bios_ia32/mmu.cpp index 2aa53a3d75..57fc82bfb8 100644 --- a/src/kernel/boot/platform/bios_ia32/mmu.cpp +++ b/src/kernel/boot/platform/bios_ia32/mmu.cpp @@ -38,7 +38,7 @@ //#define TRACE_MMU #ifdef TRACE_MMU -# define TRACE(x) printf x +# define TRACE(x) dprintf x #else # define TRACE(x) ; #endif diff --git a/src/kernel/boot/platform/bios_ia32/serial.cpp b/src/kernel/boot/platform/bios_ia32/serial.cpp new file mode 100644 index 0000000000..6faaae2dd5 --- /dev/null +++ b/src/kernel/boot/platform/bios_ia32/serial.cpp @@ -0,0 +1,106 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the Haiku License. +*/ + + +#include "serial.h" + +#include +#include +#include + +#include + + +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 int32 sSerialEnabled = 0; +static uint16 sSerialBasePort = 0x3f8; + + +static void +serial_putc(char c) +{ + // wait until the transmitter empty bit is set + while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x20) == 0) + ; + + out8(c, sSerialBasePort + SERIAL_TRANSMIT_BUFFER); +} + + +extern "C" void +serial_puts(const char *string, size_t size) +{ + if (sSerialEnabled <= 0) + return; + + while (size-- != 0) { + char c = string[0]; + + if (c == '\n') { + serial_putc('\r'); + serial_putc('\n'); + } else if (c != '\r') + serial_putc(c); + + string++; + } +} + + +extern "C" void +serial_disable(void) +{ +#if ENABLE_SERIAL + sSerialEnabled = 0; +#else + sSerialEnabled--; +#endif +} + + +extern "C" void +serial_enable(void) +{ + sSerialEnabled++; +} + + +extern "C" void +serial_init(void) +{ + // copy the base ports of the optional 4 serial ports to the kernel args + // 0x0000:0x0400 is the location of that information in the BIOS data segment + uint16 *ports = (uint16 *)0x400; + memcpy(gKernelArgs.platform_args.serial_base_ports, ports, sizeof(uint16) * MAX_SERIAL_PORTS); + + // only use the port if we could find one, else use the standard port + if (gKernelArgs.platform_args.serial_base_ports[0] != 0) + sSerialBasePort = gKernelArgs.platform_args.serial_base_ports[0]; + + uint16 divisor = uint16(115200 / kSerialBaudRate); + + 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 */ + +#ifdef ENABLE_SERIAL + serial_enable(); +#endif +} + diff --git a/src/kernel/boot/platform/bios_ia32/serial.h b/src/kernel/boot/platform/bios_ia32/serial.h new file mode 100644 index 0000000000..9ae022c468 --- /dev/null +++ b/src/kernel/boot/platform/bios_ia32/serial.h @@ -0,0 +1,27 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the Haiku License. +*/ +#ifndef SERIAL_H +#define SERIAL_H + + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +extern void serial_init(void); + +extern void serial_puts(const char *string, size_t size); + +extern void serial_disable(void); +extern void serial_enable(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SERIAL_H */ diff --git a/src/kernel/boot/platform/bios_ia32/start.c b/src/kernel/boot/platform/bios_ia32/start.c index 3af4b16757..a9359554fd 100644 --- a/src/kernel/boot/platform/bios_ia32/start.c +++ b/src/kernel/boot/platform/bios_ia32/start.c @@ -4,6 +4,7 @@ */ +#include "serial.h" #include "console.h" #include "cpu.h" #include "mmu.h" @@ -113,6 +114,7 @@ _start(void) args.heap_size = HEAP_SIZE; + serial_init(); console_init(); cpu_init(); mmu_init();