summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarcus <marcus>2003-09-19 17:49:59 +0000
committermarcus <marcus>2003-09-19 17:49:59 +0000
commitf1e5076de4234fa7f71a1f6d8801b8f8ee60b726 (patch)
tree4040a1ffda2c181e0d373dc1e23b9d7971a07ceb
parentb6f88d4911cc9b17022f5e763cd04343a05ef241 (diff)
laden/
2003-09-19 Marcus Brinkmann <marcus@gnu.org> * Makefile.am (laden_CFLAGS): Add -I$(top_srcdir)/libc-parts. * output.c: Include <stdlib.h> and <string.h>. * output.h (struct output_driver): Add CFG argument to INIT function. (output_init): Make NAME argument const, rename it to DRIVER. * output.c (output_init): Likewise. Only check if the prefix of DRIVER is a driver name. Then skip a trailing comma and pass the remainder via the new variable DRIVER_CFG to the init function of the driver. * output-vga.c (vga_init): Add CFG argument. * output-serial.c: New file by Daniel Wagner <wagi@gmx.de>. wortel/ 2003-09-19 Marcus Brinkmann <marcus@gnu.org> * Makefile.am (wortel_CFLAGS): Add -I$(top_srcdir)/libc-parts. * output.c: Include <stdlib.h> and <string.h>. * output.h (struct output_driver): Add CFG argument to INIT function. (output_init): Make NAME argument const, rename it to DRIVER. * output.c (output_init): Likewise. Only check if the prefix of DRIVER is a driver name. Then skip a trailing comma and pass the remainder via the new variable DRIVER_CFG to the init function of the driver. * output-vga.c (vga_init): Add CFG argument. * output-serial.c: New file by Daniel Wagner <wagi@gmx.de>.
-rw-r--r--AUTHORS4
-rw-r--r--laden/ChangeLog14
-rw-r--r--laden/Makefile.am5
-rw-r--r--laden/README19
-rw-r--r--laden/ia32-output.c2
-rw-r--r--laden/output-serial.c158
-rw-r--r--laden/output-vga.c2
-rw-r--r--laden/output.c25
-rw-r--r--laden/output.h15
-rw-r--r--physmem/zalloc.c2
-rw-r--r--wortel/Makefile.am5
-rw-r--r--wortel/README34
-rw-r--r--wortel/ia32-output.c2
-rw-r--r--wortel/output-serial.c159
-rw-r--r--wortel/output-vga.c2
-rw-r--r--wortel/output.c22
-rw-r--r--wortel/output.h15
17 files changed, 454 insertions, 31 deletions
diff --git a/AUTHORS b/AUTHORS
index 4251ca2..ce60489 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -7,3 +7,7 @@ Johan Rydberg <jrydberg@night.trouble.net>
The zone allocator physmem/zalloc.h, physmem/zalloc.c was originally
written by:
Neal H Walfield <neal@walfield.org>
+
+The serial output driver for laden and wortel (laden/output-serial.c,
+wortel/output-serial.c) was written by:
+Daniel Wagner <wagi@gmx.ch>
diff --git a/laden/ChangeLog b/laden/ChangeLog
index fbbd212..2568a5a 100644
--- a/laden/ChangeLog
+++ b/laden/ChangeLog
@@ -1,3 +1,17 @@
+2003-09-19 Marcus Brinkmann <marcus@gnu.org>
+
+ * Makefile.am (laden_CFLAGS): Add -I$(top_srcdir)/libc-parts.
+ * output.c: Include <stdlib.h> and <string.h>.
+ * output.h (struct output_driver): Add CFG argument to INIT
+ function.
+ (output_init): Make NAME argument const, rename it to DRIVER.
+ * output.c (output_init): Likewise. Only check if the prefix of
+ DRIVER is a driver name. Then skip a trailing comma and pass the
+ remainder via the new variable DRIVER_CFG to the init function of
+ the driver.
+ * output-vga.c (vga_init): Add CFG argument.
+ * output-serial.c: New file by Daniel Wagner <wagi@gmx.de>.
+
2003-07-26 Marcus Brinkmann <marcus@gnu.org>
* Initial check-in.
diff --git a/laden/Makefile.am b/laden/Makefile.am
index 4c9e9a1..09d1048 100644
--- a/laden/Makefile.am
+++ b/laden/Makefile.am
@@ -20,12 +20,13 @@
if ARCH_IA32
ARCH_SOURCES = multiboot.h ia32-crt0.S ia32-cmain.c \
- ia32-output.c output-vga.c ia32-shutdown.c
+ ia32-output.c output-vga.c output-serial.c ia32-shutdown.c
endif
noinst_PROGRAMS = laden
-laden_CFLAGS = -I$(srcdir) -I$(top_srcdir)/include $(AM_CFLAGS)
+laden_CFLAGS = -I$(srcdir) -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libc-parts $(AM_CFLAGS)
laden_SOURCES = $(ARCH_SOURCES) \
output.h output.c output-none.c \
diff --git a/laden/README b/laden/README
index 945ebe1..da490f4 100644
--- a/laden/README
+++ b/laden/README
@@ -35,6 +35,23 @@ The available output drivers are architecture specific (see below for
details). You can suppress all output by using the output driver
"none", which is available on all architectures.
+Some drivers support options. You list the options you want to use
+directly following the driver name, separated by commas. For example,
+to specify COM2 and a baud rate of 9600, you would use the option "-o
+serial,uart2,speed=9600". Note that spaces are not allowed (as spaces
+separate the arguments to laden). Which options are recognized
+depends on the driver.
+
+Serial output
+-------------
+
+The serial output driver supports options to configure the serial
+port. The following options are recognized:
+
+uart1 Select UART1 (aka COM1).
+uart2 Select UART2 (aka COM2).
+speed=BAUD Set the baud rate to BAUD. Possible values are 50 to 115200.
+
Architecture Specific Notes
===========================
@@ -51,4 +68,4 @@ addresses so that the programs do not overlap.
The boot info field in the KIP will be set to the multiboot
information structure.
-On this architecture laden supports VGA output.
+On this architecture, laden supports VGA and serial output.
diff --git a/laden/ia32-output.c b/laden/ia32-output.c
index 88c45cc..f4ad778 100644
--- a/laden/ia32-output.c
+++ b/laden/ia32-output.c
@@ -26,12 +26,14 @@
extern struct output_driver vga_output;
+extern struct output_driver serial_output;
extern struct output_driver no_output;
/* A list of all output drivers, terminated with a null pointer. */
struct output_driver *output_drivers[] =
{
&vga_output,
+ &serial_output,
&no_output,
0
};
diff --git a/laden/output-serial.c b/laden/output-serial.c
new file mode 100644
index 0000000..9b5e2e7
--- /dev/null
+++ b/laden/output-serial.c
@@ -0,0 +1,158 @@
+/* output-serial.c - A serial port output driver.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Daniel Wagner.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/io.h>
+#include <string.h>
+#include <errno.h>
+
+#include "output.h"
+
+
+/* The base I/O ports for the serial device ports COM1 and COM2. */
+#define UART1_BASE 0x3f8
+#define UART2_BASE 0x2f8
+
+/* The selected base port. */
+static unsigned short int uart_base = UART1_BASE;
+
+/* The data register. */
+#define UART_DR (uart_base + 0)
+
+/* The interrupt enable and ID registers. */
+#define UART_IER (uart_base + 1)
+#define UART_IIR (uart_base + 2)
+
+/* The line and modem control and status registers. */
+#define UART_LCR (uart_base + 3)
+#define UART_MCR (uart_base + 4)
+#define UART_LSR (uart_base + 5)
+#define UART_LSR_THRE (1 << 5)
+#define UART_MSR (uart_base + 6)
+
+
+/* Baudrate divisor LSB and MSB registers. */
+#define UART_LSB (uart_base + 0)
+#define UART_MSB (uart_base + 1)
+
+/* The default speed setting. */
+#define UART_SPEED_MAX 115200
+#define UART_SPEED_MIN 50
+#define UART_SPEED_DEFAULT UART_SPEED_MAX
+
+
+static void
+serial_init (const char *driver_cfg)
+{
+ static const char delimiters[] = ",";
+ /* Twice the desired UART speed, to allow for .5 values. */
+ unsigned int uart_speed = 2 * UART_SPEED_DEFAULT;
+ unsigned int divider;
+ volatile int busy_wait_var;
+
+ if (driver_cfg)
+ {
+ char *cfg = strdupa (driver_cfg);
+ char *token = strtok (cfg, delimiters);
+
+ while (token)
+ {
+ if (!strcmp (token, "uart1"))
+ uart_base = UART1_BASE;
+ if (!strcmp (token, "uart2"))
+ uart_base = UART2_BASE;
+ if (!strncmp (token, "speed=", 6))
+ {
+ char *tail;
+ unsigned long new_speed;
+
+ errno = 0;
+ new_speed = strtoul (&token[6], &tail, 0);
+
+ /* Allow .5 for speeds like 134.5. */
+ new_speed <<= 1;
+ if (tail[0] == '.' && tail[1] == '5')
+ {
+ new_speed++;
+ tail += 2;
+ }
+ if (!errno && !*tail
+ && new_speed > UART_SPEED_MIN && new_speed < UART_SPEED_MAX)
+ uart_speed = new_speed;
+ }
+ token = strtok (NULL, delimiters);
+ }
+ }
+
+ /* Parity bit. */
+ outb (UART_LCR, 0x80);
+
+ /* FIXME: Wait a bit. Would be nice to have a real sleep function. */
+ for (busy_wait_var = 0; busy_wait_var < 1000000; busy_wait_var++);
+
+ /* Set baud rate. */
+ divider = (2 * UART_SPEED_MAX) / uart_speed;
+ outb ((divider >> 0) & 0xff, UART_LSB);
+ outb ((divider >> 8) & 0xff, UART_MSB);
+
+ /* Set 8,N,1. */
+ outb (0x03, UART_LCR);
+
+ /* Disable interrupts. */
+ outb (0x00, UART_IER);
+
+ /* Enable FIFOs. */
+ outb (0x07, UART_IIR);
+
+ /* Enable RX interrupts. */
+ outb (0x01, UART_IER);
+
+ inb (UART_IER);
+ inb (UART_IIR);
+ inb (UART_LCR);
+ inb (UART_MCR);
+ inb (UART_LSR);
+ inb (UART_MSR);
+}
+
+
+static void
+serial_putchar (int chr)
+{
+ while (!(inb (UART_LSR) & UART_LSR_THRE))
+ ;
+
+ outb (chr, UART_DR);
+
+ if (chr == '\n')
+ serial_putchar ('\r');
+}
+
+
+struct output_driver serial_output =
+ {
+ "serial",
+ serial_init,
+ 0, /* deinit */
+ serial_putchar
+ };
diff --git a/laden/output-vga.c b/laden/output-vga.c
index 82234e5..0826618 100644
--- a/laden/output-vga.c
+++ b/laden/output-vga.c
@@ -80,7 +80,7 @@ static char *video;
static void
-vga_init (void)
+vga_init (const char *cfg)
{
unsigned int pos = vga_get_cursor_pos ();
col = pos % VGA_COLUMNS;
diff --git a/laden/output.c b/laden/output.c
index 8d40cb1..f6f4a59 100644
--- a/laden/output.c
+++ b/laden/output.c
@@ -22,7 +22,9 @@
#include <config.h>
#endif
+#include <stdlib.h>
#include <stdarg.h>
+#include <string.h>
#include "output.h"
@@ -40,23 +42,32 @@ static struct output_driver *output;
putchar or any other output routine. Returns 0 if NAME is not a
valid output driver name, otherwise 1 on success. */
int
-output_init (char *name)
+output_init (const char *driver)
{
+ const char *driver_cfg = NULL;
+
if (output)
{
output_deinit ();
output = 0;
}
- if (name)
+ if (driver)
{
struct output_driver **out = &output_drivers[0];
while (*out)
{
- if (!strcmp (name, (*out)->name))
+ unsigned int name_len = strlen ((*out)->name);
+ if (!strncmp (driver, (*out)->name, name_len))
{
- output = *out;
- break;
+ const char *cfg = driver + name_len;
+ if (!*cfg || *cfg == ',')
+ {
+ if (*cfg)
+ driver_cfg = cfg + 1;
+ output = *out;
+ break;
+ }
}
out++;
}
@@ -67,7 +78,7 @@ output_init (char *name)
output = output_drivers[0];
if (output->init)
- (*output->init) ();
+ (*output->init) (driver_cfg);
return 1;
}
@@ -251,6 +262,8 @@ printf (const char *fmt, ...)
break;
case 'p':
+ putchar ('0');
+ putchar ('x');
print_nr ((unsigned int) va_arg (ap, void *), 16);
p++;
break;
diff --git a/laden/output.h b/laden/output.h
index c8d1e24..5ab13fa 100644
--- a/laden/output.h
+++ b/laden/output.h
@@ -31,7 +31,7 @@ struct output_driver
const char *name;
/* Initialize the output device. */
- void (*init) (void);
+ void (*init) (const char *cfg);
/* Deinitialize the output device. */
void (*deinit) (void);
@@ -47,16 +47,20 @@ struct output_driver
extern struct output_driver *output_drivers[];
-/* Activate the output driver NAME or the default one if NAME is a
+/* Activate the output driver DRIVER or the default one if DRIVER is a
null pointer. Must be called once at startup, before calling
- putchar or any other output routine. Returns 0 if NAME is not a
- valid output driver name, otherwise 1 on success. */
-int output_init (char *name);
+ putchar or any other output routine. DRIVER has the pattern
+ NAME[,CONFIG...], for example "serial,uart2,speed=9600". Returns 0
+ if DRIVER is not a valid output driver specification, otherwise 1
+ on success. */
+int output_init (const char *driver);
+
/* Deactivate the output driver. Must be called after the last time
putchar or any other output routine is called. */
void output_deinit (void);
+
/* Print the single character CHR on the output device. */
int putchar (int chr);
@@ -67,6 +71,7 @@ int printf (const char *fmt, ...);
/* True if debug mode is enabled. */
extern int output_debug;
+
/* Print a debug message. */
#define debug(...) do { if (output_debug) printf (__VA_ARGS__); } while (0)
diff --git a/physmem/zalloc.c b/physmem/zalloc.c
index e03e7ac..4f2acd4 100644
--- a/physmem/zalloc.c
+++ b/physmem/zalloc.c
@@ -205,8 +205,6 @@ zfree (l4_word_t block, l4_word_t size)
? block_align : size_align)
- L4_MIN_PAGE_SHIFT;
- printf ("block align: %u size_align: %u zone_nr: %u\n",
- block_align, size_align, zone_nr);
add_block ((struct block *) block, zone_nr);
block += ZONE_SIZE (zone_nr);
diff --git a/wortel/Makefile.am b/wortel/Makefile.am
index 48d8f72..4dffa96 100644
--- a/wortel/Makefile.am
+++ b/wortel/Makefile.am
@@ -20,12 +20,13 @@
if ARCH_IA32
ARCH_SOURCES = multiboot.h ia32-crt0.S ia32-cmain.c \
- ia32-output.c output-vga.c ia32-shutdown.c
+ ia32-output.c output-vga.c output-serial.c ia32-shutdown.c
endif
noinst_PROGRAMS = wortel
-wortel_CFLAGS = -I$(srcdir) -I$(top_srcdir)/include $(AM_CFLAGS)
+wortel_CFLAGS = -I$(srcdir) -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libc-parts $(AM_CFLAGS)
wortel_SOURCES = $(ARCH_SOURCES) \
output.h output.c output-none.c \
diff --git a/wortel/README b/wortel/README
index 6dc0af8..9601417 100644
--- a/wortel/README
+++ b/wortel/README
@@ -7,3 +7,37 @@ booting up the system and wrapping privileged L4 operations.
For now, only a rudimentary part of the loader is written, and the
only useful thing wortel can do is to start the dummy physmem server
for a small demonstration.
+
+
+OUTPUT
+======
+
+The available output drivers are architecture specific (see below for
+details). You can suppress all output by using the output driver
+"none", which is available on all architectures.
+
+Some drivers support options. You list the options you want to use
+directly following the driver name, separated by commas. For example,
+to specify COM2 and a baud rate of 9600, you would use the option "-o
+serial,uart2,speed=9600". Note that spaces are not allowed (as spaces
+separate the arguments to wortel). Which options are recognized
+depends on the driver.
+
+Serial output
+-------------
+
+The serial output driver supports options to configure the serial
+port. The following options are recognized:
+
+uart1 Select UART1 (aka COM1).
+uart2 Select UART2 (aka COM2).
+speed=BAUD Set the baud rate to BAUD. Possible values are 50 to 115200.
+
+
+Architecture Specific Notes
+===========================
+
+ia32
+----
+
+On this architecture, wortel supports VGA and serial output.
diff --git a/wortel/ia32-output.c b/wortel/ia32-output.c
index 88c45cc..f4ad778 100644
--- a/wortel/ia32-output.c
+++ b/wortel/ia32-output.c
@@ -26,12 +26,14 @@
extern struct output_driver vga_output;
+extern struct output_driver serial_output;
extern struct output_driver no_output;
/* A list of all output drivers, terminated with a null pointer. */
struct output_driver *output_drivers[] =
{
&vga_output,
+ &serial_output,
&no_output,
0
};
diff --git a/wortel/output-serial.c b/wortel/output-serial.c
new file mode 100644
index 0000000..91c6914
--- /dev/null
+++ b/wortel/output-serial.c
@@ -0,0 +1,159 @@
+/* output-serial.c - A serial port output driver.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Written by Daniel Wagner.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/io.h>
+#include <string.h>
+#include <errno.h>
+
+#include <l4/ipc.h>
+
+#include "output.h"
+
+
+/* The base I/O ports for the serial device ports COM1 and COM2. */
+#define UART1_BASE 0x3f8
+#define UART2_BASE 0x2f8
+
+/* The selected base port. */
+static unsigned short int uart_base = UART1_BASE;
+
+/* The data register. */
+#define UART_DR (uart_base + 0)
+
+/* The interrupt enable and ID registers. */
+#define UART_IER (uart_base + 1)
+#define UART_IIR (uart_base + 2)
+
+/* The line and modem control and status registers. */
+#define UART_LCR (uart_base + 3)
+#define UART_MCR (uart_base + 4)
+#define UART_LSR (uart_base + 5)
+#define UART_LSR_THRE (1 << 5)
+#define UART_MSR (uart_base + 6)
+
+
+/* Baudrate divisor LSB and MSB registers. */
+#define UART_LSB (uart_base + 0)
+#define UART_MSB (uart_base + 1)
+
+/* The default speed setting. */
+#define UART_SPEED_MAX 115200
+#define UART_SPEED_MIN 50
+#define UART_SPEED_DEFAULT UART_SPEED_MAX
+
+
+static void
+serial_init (const char *driver_cfg)
+{
+ static const char delimiters[] = ",";
+ /* Twice the desired UART speed, to allow for .5 values. */
+ unsigned int uart_speed = 2 * UART_SPEED_DEFAULT;
+ unsigned int divider;
+
+ if (driver_cfg)
+ {
+ char *cfg = strdupa (driver_cfg);
+ char *token = strtok (cfg, delimiters);
+
+ while (token)
+ {
+ if (!strcmp (token, "uart1"))
+ uart_base = UART1_BASE;
+ if (!strcmp (token, "uart2"))
+ uart_base = UART2_BASE;
+ if (!strncmp (token, "speed=", 6))
+ {
+ char *tail;
+ unsigned long new_speed;
+
+ errno = 0;
+ new_speed = strtoul (&token[6], &tail, 0);
+
+ /* Allow .5 for speeds like 134.5. */
+ new_speed <<= 1;
+ if (tail[0] == '.' && tail[1] == '5')
+ {
+ new_speed++;
+ tail += 2;
+ }
+ if (!errno && !*tail
+ && new_speed > UART_SPEED_MIN && new_speed < UART_SPEED_MAX)
+ uart_speed = new_speed;
+ }
+ token = strtok (NULL, delimiters);
+ }
+ }
+
+ /* Parity bit. */
+ outb (UART_LCR, 0x80);
+
+ /* FIXME: How long do we have to wait? */
+ l4_sleep (l4_time_period (L4_WORD_C (100000)));
+
+ /* Set baud rate. */
+ divider = (2 * UART_SPEED_MAX) / uart_speed;
+ outb ((divider >> 0) & 0xff, UART_LSB);
+ outb ((divider >> 8) & 0xff, UART_MSB);
+
+ /* Set 8,N,1. */
+ outb (0x03, UART_LCR);
+
+ /* Disable interrupts. */
+ outb (0x00, UART_IER);
+
+ /* Enable FIFOs. */
+ outb (0x07, UART_IIR);
+
+ /* Enable RX interrupts. */
+ outb (0x01, UART_IER);
+
+ inb (UART_IER);
+ inb (UART_IIR);
+ inb (UART_LCR);
+ inb (UART_MCR);
+ inb (UART_LSR);
+ inb (UART_MSR);
+}
+
+
+static void
+serial_putchar (int chr)
+{
+ while (!(inb (UART_LSR) & UART_LSR_THRE))
+ ;
+
+ outb (chr, UART_DR);
+
+ if (chr == '\n')
+ serial_putchar ('\r');
+}
+
+
+struct output_driver serial_output =
+ {
+ "serial",
+ serial_init,
+ 0, /* deinit */
+ serial_putchar
+ };
diff --git a/wortel/output-vga.c b/wortel/output-vga.c
index 82234e5..0826618 100644
--- a/wortel/output-vga.c
+++ b/wortel/output-vga.c
@@ -80,7 +80,7 @@ static char *video;
static void
-vga_init (void)
+vga_init (const char *cfg)
{
unsigned int pos = vga_get_cursor_pos ();
col = pos % VGA_COLUMNS;
diff --git a/wortel/output.c b/wortel/output.c
index 1da9826..f6f4a59 100644
--- a/wortel/output.c
+++ b/wortel/output.c
@@ -22,6 +22,7 @@
#include <config.h>
#endif
+#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
@@ -41,23 +42,32 @@ static struct output_driver *output;
putchar or any other output routine. Returns 0 if NAME is not a
valid output driver name, otherwise 1 on success. */
int
-output_init (char *name)
+output_init (const char *driver)
{
+ const char *driver_cfg = NULL;
+
if (output)
{
output_deinit ();
output = 0;
}
- if (name)
+ if (driver)
{
struct output_driver **out = &output_drivers[0];
while (*out)
{
- if (!strcmp (name, (*out)->name))
+ unsigned int name_len = strlen ((*out)->name);
+ if (!strncmp (driver, (*out)->name, name_len))
{
- output = *out;
- break;
+ const char *cfg = driver + name_len;
+ if (!*cfg || *cfg == ',')
+ {
+ if (*cfg)
+ driver_cfg = cfg + 1;
+ output = *out;
+ break;
+ }
}
out++;
}
@@ -68,7 +78,7 @@ output_init (char *name)
output = output_drivers[0];
if (output->init)
- (*output->init) ();
+ (*output->init) (driver_cfg);
return 1;
}
diff --git a/wortel/output.h b/wortel/output.h
index c8d1e24..5ab13fa 100644
--- a/wortel/output.h
+++ b/wortel/output.h
@@ -31,7 +31,7 @@ struct output_driver
const char *name;
/* Initialize the output device. */
- void (*init) (void);
+ void (*init) (const char *cfg);
/* Deinitialize the output device. */
void (*deinit) (void);
@@ -47,16 +47,20 @@ struct output_driver
extern struct output_driver *output_drivers[];
-/* Activate the output driver NAME or the default one if NAME is a
+/* Activate the output driver DRIVER or the default one if DRIVER is a
null pointer. Must be called once at startup, before calling
- putchar or any other output routine. Returns 0 if NAME is not a
- valid output driver name, otherwise 1 on success. */
-int output_init (char *name);
+ putchar or any other output routine. DRIVER has the pattern
+ NAME[,CONFIG...], for example "serial,uart2,speed=9600". Returns 0
+ if DRIVER is not a valid output driver specification, otherwise 1
+ on success. */
+int output_init (const char *driver);
+
/* Deactivate the output driver. Must be called after the last time
putchar or any other output routine is called. */
void output_deinit (void);
+
/* Print the single character CHR on the output device. */
int putchar (int chr);
@@ -67,6 +71,7 @@ int printf (const char *fmt, ...);
/* True if debug mode is enabled. */
extern int output_debug;
+
/* Print a debug message. */
#define debug(...) do { if (output_debug) printf (__VA_ARGS__); } while (0)