Move low-level hardware writing from output.c to new file hw/serialio.c.
Avoid hardware specific code in output.c. This will reduce the amount of change needed to output.c as support for more serial hardware is added. This patch also renames some functions to improve the naming scheme. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
3ecdc492ce
commit
4cd522e673
4
Makefile
4
Makefile
|
@ -29,7 +29,7 @@ IASL:=iasl
|
|||
SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \
|
||||
serial.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \
|
||||
fw/smp.c \
|
||||
hw/pci.c hw/timer.c hw/rtc.c hw/dma.c hw/pic.c hw/ps2port.c \
|
||||
hw/pci.c hw/timer.c hw/rtc.c hw/dma.c hw/pic.c hw/ps2port.c hw/serialio.c \
|
||||
hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c hw/usb-xhci.c \
|
||||
hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \
|
||||
hw/blockcmd.c hw/floppy.c hw/ata.c hw/ramdisk.c \
|
||||
|
@ -201,7 +201,7 @@ $(OUT)bios.bin.elf: $(OUT)rom.o $(OUT)bios.bin.prep
|
|||
################ VGA build rules
|
||||
|
||||
# VGA src files
|
||||
SRCVGA=src/output.c src/string.c src/hw/pci.c \
|
||||
SRCVGA=src/output.c src/string.c src/hw/pci.c src/hw/serialio.c \
|
||||
vgasrc/vgabios.c vgasrc/vgafb.c vgasrc/vgafonts.c vgasrc/vbe.c \
|
||||
vgasrc/stdvga.c vgasrc/stdvgamodes.c vgasrc/stdvgaio.c \
|
||||
vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodevga.c
|
||||
|
|
|
@ -743,7 +743,7 @@ int BootSequence VARLOW = -1;
|
|||
void VISIBLE32FLAT
|
||||
handle_18(void)
|
||||
{
|
||||
debug_serial_preinit();
|
||||
debug_preinit();
|
||||
debug_enter(NULL, DEBUG_HDL_18);
|
||||
int seq = BootSequence + 1;
|
||||
BootSequence = seq;
|
||||
|
@ -754,7 +754,7 @@ handle_18(void)
|
|||
void VISIBLE32FLAT
|
||||
handle_19(void)
|
||||
{
|
||||
debug_serial_preinit();
|
||||
debug_preinit();
|
||||
debug_enter(NULL, DEBUG_HDL_19);
|
||||
BootSequence = 0;
|
||||
do_boot(0);
|
||||
|
|
|
@ -202,7 +202,7 @@ fail:
|
|||
return;
|
||||
}
|
||||
|
||||
void debug_cbmem(char c)
|
||||
void coreboot_debug_putc(char c)
|
||||
{
|
||||
if (!CONFIG_DEBUG_COREBOOT)
|
||||
return;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "config.h"
|
||||
#include "hw/serialio.h" // DebugOutputPort
|
||||
#include "malloc.h" // memalign_high
|
||||
#include "memmap.h" // add_e820
|
||||
#include "output.h" // dprintf
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
// Low-level serial (and serial-like) device access.
|
||||
//
|
||||
// Copyright (C) 2008-1013 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
#include "config.h" // CONFIG_DEBUG_SERIAL
|
||||
#include "fw/paravirt.h" // RunningOnQEMU
|
||||
#include "output.h" // dprintf
|
||||
#include "serialio.h" // serial_debug_preinit
|
||||
#include "x86.h" // outb
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Serial port debug output
|
||||
****************************************************************/
|
||||
|
||||
#define DEBUG_TIMEOUT 100000
|
||||
|
||||
// Setup the debug serial port for output.
|
||||
void
|
||||
serial_debug_preinit(void)
|
||||
{
|
||||
if (!CONFIG_DEBUG_SERIAL)
|
||||
return;
|
||||
// setup for serial logging: 8N1
|
||||
u8 oldparam, newparam = 0x03;
|
||||
oldparam = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR);
|
||||
outb(newparam, CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR);
|
||||
// Disable irqs
|
||||
u8 oldier, newier = 0;
|
||||
oldier = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER);
|
||||
outb(newier, CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER);
|
||||
|
||||
if (oldparam != newparam || oldier != newier)
|
||||
dprintf(1, "Changing serial settings was %x/%x now %x/%x\n"
|
||||
, oldparam, oldier, newparam, newier);
|
||||
}
|
||||
|
||||
// Write a character to the serial port.
|
||||
static void
|
||||
serial_debug(char c)
|
||||
{
|
||||
if (!CONFIG_DEBUG_SERIAL)
|
||||
return;
|
||||
int timeout = DEBUG_TIMEOUT;
|
||||
while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x20) != 0x20)
|
||||
if (!timeout--)
|
||||
// Ran out of time.
|
||||
return;
|
||||
outb(c, CONFIG_DEBUG_SERIAL_PORT+SEROFF_DATA);
|
||||
}
|
||||
|
||||
void
|
||||
serial_debug_putc(char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
serial_debug('\r');
|
||||
serial_debug(c);
|
||||
}
|
||||
|
||||
// Make sure all serial port writes have been completely sent.
|
||||
void
|
||||
serial_debug_flush(void)
|
||||
{
|
||||
if (!CONFIG_DEBUG_SERIAL)
|
||||
return;
|
||||
int timeout = DEBUG_TIMEOUT;
|
||||
while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x60) != 0x60)
|
||||
if (!timeout--)
|
||||
// Ran out of time.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* QEMU debug port
|
||||
****************************************************************/
|
||||
|
||||
u16 DebugOutputPort VARFSEG = 0x402;
|
||||
|
||||
// Write a character to the special debugging port.
|
||||
void
|
||||
qemu_debug_putc(char c)
|
||||
{
|
||||
if (CONFIG_DEBUG_IO && runningOnQEMU())
|
||||
// Send character to debug port.
|
||||
outb(c, GET_GLOBAL(DebugOutputPort));
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef __SERIALIO_H
|
||||
#define __SERIALIO_H
|
||||
|
||||
#include "types.h" // u16
|
||||
|
||||
#define PORT_LPT2 0x0278
|
||||
#define PORT_SERIAL4 0x02e8
|
||||
#define PORT_SERIAL2 0x02f8
|
||||
|
@ -18,4 +20,10 @@
|
|||
#define SEROFF_LSR 5
|
||||
#define SEROFF_MSR 6
|
||||
|
||||
void serial_debug_preinit(void);
|
||||
void serial_debug_putc(char c);
|
||||
void serial_debug_flush(void);
|
||||
extern u16 DebugOutputPort;
|
||||
void qemu_debug_putc(char c);
|
||||
|
||||
#endif // serialio.h
|
||||
|
|
|
@ -45,7 +45,7 @@ __callrom(struct rom_header *rom, u16 offset, u16 bdf)
|
|||
farcall16big(&br);
|
||||
finish_preempt();
|
||||
|
||||
debug_serial_preinit();
|
||||
debug_preinit();
|
||||
}
|
||||
|
||||
// Execute a given option rom at the standard entry vector.
|
||||
|
|
103
src/output.c
103
src/output.c
|
@ -1,6 +1,6 @@
|
|||
// Raw screen writing and debug output code.
|
||||
//
|
||||
// Copyright (C) 2008,2009 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2008-2013 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
||||
|
||||
|
@ -10,8 +10,7 @@
|
|||
#include "bregs.h" // struct bregs
|
||||
#include "config.h" // CONFIG_*
|
||||
#include "biosvar.h" // GET_GLOBAL
|
||||
#include "fw/paravirt.h" // PlatformRunningOn
|
||||
#include "hw/serialio.h" // SEROFF_IER
|
||||
#include "hw/serialio.h" // serial_debug_putc
|
||||
#include "malloc.h" // malloc_tmp
|
||||
#include "output.h" // dprintf
|
||||
#include "stacks.h" // call16_int
|
||||
|
@ -27,81 +26,41 @@ struct putcinfo {
|
|||
* Debug output
|
||||
****************************************************************/
|
||||
|
||||
#define DEBUG_TIMEOUT 100000
|
||||
|
||||
u16 DebugOutputPort VARFSEG = 0x402;
|
||||
|
||||
// Setup debugging port(s).
|
||||
void
|
||||
debug_serial_preinit(void)
|
||||
debug_preinit(void)
|
||||
{
|
||||
if (!CONFIG_DEBUG_SERIAL)
|
||||
return;
|
||||
// setup for serial logging: 8N1
|
||||
u8 oldparam, newparam = 0x03;
|
||||
oldparam = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR);
|
||||
outb(newparam, CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR);
|
||||
// Disable irqs
|
||||
u8 oldier, newier = 0;
|
||||
oldier = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER);
|
||||
outb(newier, CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER);
|
||||
|
||||
if (oldparam != newparam || oldier != newier)
|
||||
dprintf(1, "Changing serial settings was %x/%x now %x/%x\n"
|
||||
, oldparam, oldier, newparam, newier);
|
||||
}
|
||||
|
||||
// Write a character to the serial port.
|
||||
static void
|
||||
debug_serial(char c)
|
||||
{
|
||||
if (!CONFIG_DEBUG_SERIAL)
|
||||
return;
|
||||
int timeout = DEBUG_TIMEOUT;
|
||||
while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x20) != 0x20)
|
||||
if (!timeout--)
|
||||
// Ran out of time.
|
||||
return;
|
||||
outb(c, CONFIG_DEBUG_SERIAL_PORT+SEROFF_DATA);
|
||||
}
|
||||
|
||||
// Make sure all serial port writes have been completely sent.
|
||||
static void
|
||||
debug_serial_flush(void)
|
||||
{
|
||||
if (!CONFIG_DEBUG_SERIAL)
|
||||
return;
|
||||
int timeout = DEBUG_TIMEOUT;
|
||||
while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x60) != 0x60)
|
||||
if (!timeout--)
|
||||
// Ran out of time.
|
||||
return;
|
||||
serial_debug_preinit();
|
||||
}
|
||||
|
||||
// Write a character to debug port(s).
|
||||
static void
|
||||
putc_debug(struct putcinfo *action, char c)
|
||||
debug_putc(struct putcinfo *action, char c)
|
||||
{
|
||||
if (! CONFIG_DEBUG_LEVEL)
|
||||
return;
|
||||
if (CONFIG_DEBUG_IO && runningOnQEMU())
|
||||
// Send character to debug port.
|
||||
outb(c, GET_GLOBAL(DebugOutputPort));
|
||||
qemu_debug_putc(c);
|
||||
if (!MODESEGMENT)
|
||||
debug_cbmem(c);
|
||||
if (c == '\n')
|
||||
debug_serial('\r');
|
||||
debug_serial(c);
|
||||
coreboot_debug_putc(c);
|
||||
serial_debug_putc(c);
|
||||
}
|
||||
|
||||
// In segmented mode just need a dummy variable (putc_debug is always
|
||||
// Flush any pending output to debug port(s).
|
||||
static void
|
||||
debug_flush(void)
|
||||
{
|
||||
serial_debug_flush();
|
||||
}
|
||||
|
||||
// In segmented mode just need a dummy variable (debug_putc is always
|
||||
// used anyway), and in 32bit flat mode need a pointer to the 32bit
|
||||
// instance of putc_debug().
|
||||
// instance of debug_putc().
|
||||
#if MODE16
|
||||
static struct putcinfo debuginfo VAR16;
|
||||
#elif MODESEGMENT
|
||||
static struct putcinfo debuginfo VAR32SEG;
|
||||
#else
|
||||
static struct putcinfo debuginfo = { putc_debug };
|
||||
static struct putcinfo debuginfo = { debug_putc };
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -123,16 +82,16 @@ screenc(char c)
|
|||
|
||||
// Handle a character from a printf request.
|
||||
static void
|
||||
putc_screen(struct putcinfo *action, char c)
|
||||
screen_putc(struct putcinfo *action, char c)
|
||||
{
|
||||
if (ScreenAndDebug)
|
||||
putc_debug(&debuginfo, c);
|
||||
debug_putc(&debuginfo, c);
|
||||
if (c == '\n')
|
||||
screenc('\r');
|
||||
screenc(c);
|
||||
}
|
||||
|
||||
static struct putcinfo screeninfo = { putc_screen };
|
||||
static struct putcinfo screeninfo = { screen_putc };
|
||||
|
||||
|
||||
/****************************************************************
|
||||
|
@ -145,7 +104,7 @@ putc(struct putcinfo *action, char c)
|
|||
{
|
||||
if (MODESEGMENT) {
|
||||
// Only debugging output supported in segmented mode.
|
||||
putc_debug(action, c);
|
||||
debug_putc(action, c);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -348,7 +307,7 @@ panic(const char *fmt, ...)
|
|||
va_start(args, fmt);
|
||||
bvprintf(&debuginfo, fmt, args);
|
||||
va_end(args);
|
||||
debug_serial_flush();
|
||||
debug_flush();
|
||||
}
|
||||
|
||||
// XXX - use PANIC PORT.
|
||||
|
@ -365,10 +324,10 @@ __dprintf(const char *fmt, ...)
|
|||
struct thread_info *cur = getCurThread();
|
||||
if (cur != &MainThread) {
|
||||
// Show "thread id" for this debug message.
|
||||
putc_debug(&debuginfo, '|');
|
||||
debug_putc(&debuginfo, '|');
|
||||
puthex(&debuginfo, (u32)cur, 8);
|
||||
putc_debug(&debuginfo, '|');
|
||||
putc_debug(&debuginfo, ' ');
|
||||
debug_putc(&debuginfo, '|');
|
||||
debug_putc(&debuginfo, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,7 +335,7 @@ __dprintf(const char *fmt, ...)
|
|||
va_start(args, fmt);
|
||||
bvprintf(&debuginfo, fmt, args);
|
||||
va_end(args);
|
||||
debug_serial_flush();
|
||||
debug_flush();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -388,7 +347,7 @@ printf(const char *fmt, ...)
|
|||
bvprintf(&screeninfo, fmt, args);
|
||||
va_end(args);
|
||||
if (ScreenAndDebug)
|
||||
debug_serial_flush();
|
||||
debug_flush();
|
||||
}
|
||||
|
||||
|
||||
|
@ -479,7 +438,7 @@ hexdump(const void *d, int len)
|
|||
d+=4;
|
||||
}
|
||||
putc(&debuginfo, '\n');
|
||||
debug_serial_flush();
|
||||
debug_flush();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -503,7 +462,7 @@ __debug_isr(const char *fname)
|
|||
{
|
||||
puts_cs(&debuginfo, fname);
|
||||
putc(&debuginfo, '\n');
|
||||
debug_serial_flush();
|
||||
debug_flush();
|
||||
}
|
||||
|
||||
// Function called on handler startup.
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
#include "types.h" // u32
|
||||
|
||||
// output.c
|
||||
extern u16 DebugOutputPort;
|
||||
void debug_serial_preinit(void);
|
||||
void debug_preinit(void);
|
||||
void panic(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2))) __noreturn;
|
||||
void printf(const char *fmt, ...)
|
||||
|
|
|
@ -317,7 +317,7 @@ handle_post(void)
|
|||
if (!CONFIG_QEMU && !CONFIG_COREBOOT)
|
||||
return;
|
||||
|
||||
debug_serial_preinit();
|
||||
debug_preinit();
|
||||
dprintf(1, "Start bios (version %s)\n", VERSION);
|
||||
|
||||
// Check if we are running under Xen.
|
||||
|
|
|
@ -25,7 +25,7 @@ void VISIBLE16
|
|||
handle_resume(void)
|
||||
{
|
||||
ASSERT16();
|
||||
debug_serial_preinit();
|
||||
debug_preinit();
|
||||
int status = rtc_read(CMOS_RESET_CODE);
|
||||
rtc_write(CMOS_RESET_CODE, 0);
|
||||
dprintf(1, "In resume (status=%d)\n", status);
|
||||
|
|
|
@ -78,7 +78,7 @@ void *find_acpi_rsdp(void);
|
|||
// fw/coreboot.c
|
||||
extern const char *CBvendor, *CBpart;
|
||||
struct cbfs_file;
|
||||
void debug_cbmem(char c);
|
||||
void coreboot_debug_putc(char c);
|
||||
void cbfs_run_payload(struct cbfs_file *file);
|
||||
void coreboot_platform_setup(void);
|
||||
void cbfs_payload_setup(void);
|
||||
|
|
|
@ -1283,7 +1283,7 @@ int HaveRunInit VAR16;
|
|||
void VISIBLE16
|
||||
vga_post(struct bregs *regs)
|
||||
{
|
||||
debug_serial_preinit();
|
||||
debug_preinit();
|
||||
dprintf(1, "Start SeaVGABIOS (version %s)\n", VERSION);
|
||||
debug_enter(regs, DEBUG_VGA_POST);
|
||||
|
||||
|
|
Loading…
Reference in New Issue