summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/drivers/serial.c155
1 files changed, 49 insertions, 106 deletions
diff --git a/payloads/libpayload/drivers/serial.c b/payloads/libpayload/drivers/serial.c
index cd00a13204..0d26750941 100644
--- a/payloads/libpayload/drivers/serial.c
+++ b/payloads/libpayload/drivers/serial.c
@@ -32,68 +32,61 @@
#include <libpayload.h>
#define IOBASE lib_sysinfo.serial->baseaddr
-#define MEMBASE (phys_to_virt(lib_sysinfo.serial->baseaddr))
-#define DIVISOR(x) (115200 / x)
+#define MEMBASE (phys_to_virt(IOBASE))
-static int serial_io_hardware_is_present = 1;
+static int serial_hardware_is_present = 0;
+static int serial_is_mem_mapped = 0;
-#ifdef CONFIG_SERIAL_SET_SPEED
-static void serial_io_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits)
+static uint8_t serial_read_reg(int offset)
{
- unsigned char reg;
-
- /* Disable interrupts. */
- outb(0, port + 0x01);
-
- /* Assert RTS and DTR. */
- outb(3, port + 0x04);
-
- /* Set the divisor latch. */
- reg = inb(port + 0x03);
- outb(reg | 0x80, port + 0x03);
-
- /* Write the divisor. */
- outb(DIVISOR(speed) & 0xFF, port);
- outb(DIVISOR(speed) >> 8 & 0xFF, port + 1);
+ if (serial_is_mem_mapped)
+ return readb(MEMBASE + offset);
+ else
+ return inb(IOBASE + offset);
+}
- /* Restore the previous value of the divisor.
- * And set 8 bits per character */
- outb((reg & ~0x80) | 3, port + 0x03);
+static void serial_write_reg(uint8_t val, int offset)
+{
+ if (serial_is_mem_mapped)
+ writeb(val, MEMBASE + offset);
+ else
+ outb(val, IOBASE + offset);
}
-static void serial_mem_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits)
+#ifdef CONFIG_SERIAL_SET_SPEED
+static void serial_hardware_init(int speed, int word_bits,
+ int parity, int stop_bits)
{
unsigned char reg;
- /* We will assume 8n1 for now. Does anyone use anything else these days? */
-
/* Disable interrupts. */
- writeb(0, MEMBASE + 0x01);
+ serial_write_reg(0, 0x01);
/* Assert RTS and DTR. */
- writeb(3, MEMBASE + 0x04);
+ serial_write_reg(3, 0x04);
/* Set the divisor latch. */
- reg = readb(MEMBASE + 0x03);
- writeb(reg | 0x80, MEMBASE + 0x03);
+ reg = serial_read_reg(0x03);
+ serial_write_reg(reg | 0x80, 0x03);
/* Write the divisor. */
- writeb(DIVISOR(speed) & 0xFF, MEMBASE);
- writeb(DIVISOR(speed) >> 8 & 0xFF, MEMBASE + 1);
+ uint16_t divisor = 115200 / speed;
+ serial_write_reg(divisor & 0xFF, 0x00);
+ serial_write_reg(divisor >> 8, 0x01);
/* Restore the previous value of the divisor.
* And set 8 bits per character */
- writeb((reg & ~0x80) | 3, MEMBASE + 0x03);
+ serial_write_reg((reg & ~0x80) | 3, 0x03);
}
#endif
static struct console_input_driver consin = {
- .havekey = serial_havechar,
- .getchar = serial_getchar
+ .havekey = &serial_havechar,
+ .getchar = &serial_getchar
};
static struct console_output_driver consout = {
- .putchar = serial_putchar
+ .putchar = &serial_putchar
};
void serial_init(void)
@@ -101,94 +94,44 @@ void serial_init(void)
if (!lib_sysinfo.serial)
return;
-#ifdef CONFIG_SERIAL_SET_SPEED
- if (lib_sysinfo.serial->type == CB_SERIAL_TYPE_MEMORY_MAPPED)
- serial_mem_hardware_init(IOBASE, CONFIG_SERIAL_BAUD_RATE, 8, 0, 1);
- else
- serial_io_hardware_init(IOBASE, CONFIG_SERIAL_BAUD_RATE, 8, 0, 1);
-#endif
- console_add_input_driver(&consin);
- console_add_output_driver(&consout);
+ serial_is_mem_mapped =
+ (lib_sysinfo.serial->type == CB_SERIAL_TYPE_MEMORY_MAPPED);
- /* check to see if there's actually serial port h/w */
- if (lib_sysinfo.ser_ioport) {
- if( (inb(IOBASE + 0x05)==0xFF) && (inb(IOBASE + 0x06)==0xFF) )
- serial_io_hardware_is_present = 0;
+ if (!serial_is_mem_mapped && (inb(IOBASE + 0x05) == 0xFF) &&
+ (inb(IOBASE + 0x06) == 0xFF)) {
+ return;
}
-}
-
-static void serial_io_putchar(unsigned int c)
-{
- c &= 0xff;
- while ((inb(IOBASE + 0x05) & 0x20) == 0) ;
- outb(c, IOBASE);
-}
-static int serial_io_havechar(void)
-{
- if ( !serial_io_hardware_is_present )
- return 0;
- return inb(IOBASE + 0x05) & 0x01;
-}
-
-static int serial_io_getchar(void)
-{
- if ( !serial_io_hardware_is_present )
- return -1;
- while (!serial_io_havechar()) ;
- return (int)inb(IOBASE);
-}
+ serial_hardware_is_present = 1;
-static void serial_mem_putchar(unsigned int c)
-{
- c &= 0xff;
- while ((readb(MEMBASE + 0x05) & 0x20) == 0) ;
- writeb(c, MEMBASE);
-}
-
-static int serial_mem_havechar(void)
-{
- return readb(MEMBASE + 0x05) & 0x01;
-}
-
-static int serial_mem_getchar(void)
-{
- while (!serial_mem_havechar()) ;
- return (int)readb(MEMBASE);
+#ifdef CONFIG_SERIAL_SET_SPEED
+ serial_hardware_init(CONFIG_SERIAL_BAUD_RATE, 8, 0, 1);
+#endif
+ console_add_input_driver(&consin);
+ console_add_output_driver(&consout);
}
-
void serial_putchar(unsigned int c)
{
- if (!lib_sysinfo.serial)
+ if (!serial_hardware_is_present)
return;
-
- if (lib_sysinfo.serial->type == CB_SERIAL_TYPE_MEMORY_MAPPED)
- serial_mem_putchar(c);
- else
- serial_io_putchar(c);
+ while ((serial_read_reg(0x05) & 0x20) == 0) ;
+ serial_write_reg(c, 0x00);
}
int serial_havechar(void)
{
- if (!lib_sysinfo.serial)
+ if (!serial_hardware_is_present)
return 0;
-
- if (lib_sysinfo.ser_base)
- return serial_mem_havechar();
- else
- return serial_io_havechar();
+ return serial_read_reg(0x05) & 0x01;
}
int serial_getchar(void)
{
- if (!lib_sysinfo.serial)
+ if (!serial_hardware_is_present)
return -1;
-
- if (lib_sysinfo.ser_base)
- return serial_mem_getchar();
- else
- return serial_io_getchar();
+ while (!serial_havechar()) ;
+ return serial_read_reg(0x00);
}
/* These are thinly veiled vt100 functions used by curses */
@@ -214,7 +157,7 @@ int serial_getchar(void)
static void serial_putcmd(const char *str)
{
- while(*str)
+ while (*str)
serial_putchar(*(str++));
}