libpayload: Consolidate io vs. mem mapped serial into accessor functions
This way we won't have two copies of the hardware init function, and three copies of the putchar, havechar, and getchar functions. Change-Id: Ifda7fec5d582244b0e163ee93ffeedeb28ce48da Signed-off-by: Gabe Black <gabeblack@google.com> Reviewed-on: http://review.coreboot.org/2657 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
d267987083
commit
1c1171208f
|
@ -32,68 +32,61 @@
|
||||||
#include <libpayload.h>
|
#include <libpayload.h>
|
||||||
|
|
||||||
#define IOBASE lib_sysinfo.serial->baseaddr
|
#define IOBASE lib_sysinfo.serial->baseaddr
|
||||||
#define MEMBASE (phys_to_virt(lib_sysinfo.serial->baseaddr))
|
#define MEMBASE (phys_to_virt(IOBASE))
|
||||||
#define DIVISOR(x) (115200 / x)
|
|
||||||
|
|
||||||
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 uint8_t serial_read_reg(int offset)
|
||||||
static void serial_io_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits)
|
|
||||||
{
|
{
|
||||||
unsigned char reg;
|
if (serial_is_mem_mapped)
|
||||||
|
return readb(MEMBASE + offset);
|
||||||
/* Disable interrupts. */
|
else
|
||||||
outb(0, port + 0x01);
|
return inb(IOBASE + offset);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* Restore the previous value of the divisor.
|
|
||||||
* And set 8 bits per character */
|
|
||||||
outb((reg & ~0x80) | 3, port + 0x03);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serial_mem_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits)
|
static void serial_write_reg(uint8_t val, int offset)
|
||||||
|
{
|
||||||
|
if (serial_is_mem_mapped)
|
||||||
|
writeb(val, MEMBASE + offset);
|
||||||
|
else
|
||||||
|
outb(val, IOBASE + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_SET_SPEED
|
||||||
|
static void serial_hardware_init(int speed, int word_bits,
|
||||||
|
int parity, int stop_bits)
|
||||||
{
|
{
|
||||||
unsigned char reg;
|
unsigned char reg;
|
||||||
|
|
||||||
/* We will assume 8n1 for now. Does anyone use anything else these days? */
|
|
||||||
|
|
||||||
/* Disable interrupts. */
|
/* Disable interrupts. */
|
||||||
writeb(0, MEMBASE + 0x01);
|
serial_write_reg(0, 0x01);
|
||||||
|
|
||||||
/* Assert RTS and DTR. */
|
/* Assert RTS and DTR. */
|
||||||
writeb(3, MEMBASE + 0x04);
|
serial_write_reg(3, 0x04);
|
||||||
|
|
||||||
/* Set the divisor latch. */
|
/* Set the divisor latch. */
|
||||||
reg = readb(MEMBASE + 0x03);
|
reg = serial_read_reg(0x03);
|
||||||
writeb(reg | 0x80, MEMBASE + 0x03);
|
serial_write_reg(reg | 0x80, 0x03);
|
||||||
|
|
||||||
/* Write the divisor. */
|
/* Write the divisor. */
|
||||||
writeb(DIVISOR(speed) & 0xFF, MEMBASE);
|
uint16_t divisor = 115200 / speed;
|
||||||
writeb(DIVISOR(speed) >> 8 & 0xFF, MEMBASE + 1);
|
serial_write_reg(divisor & 0xFF, 0x00);
|
||||||
|
serial_write_reg(divisor >> 8, 0x01);
|
||||||
|
|
||||||
/* Restore the previous value of the divisor.
|
/* Restore the previous value of the divisor.
|
||||||
* And set 8 bits per character */
|
* And set 8 bits per character */
|
||||||
writeb((reg & ~0x80) | 3, MEMBASE + 0x03);
|
serial_write_reg((reg & ~0x80) | 3, 0x03);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct console_input_driver consin = {
|
static struct console_input_driver consin = {
|
||||||
.havekey = serial_havechar,
|
.havekey = &serial_havechar,
|
||||||
.getchar = serial_getchar
|
.getchar = &serial_getchar
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct console_output_driver consout = {
|
static struct console_output_driver consout = {
|
||||||
.putchar = serial_putchar
|
.putchar = &serial_putchar
|
||||||
};
|
};
|
||||||
|
|
||||||
void serial_init(void)
|
void serial_init(void)
|
||||||
|
@ -101,94 +94,44 @@ void serial_init(void)
|
||||||
if (!lib_sysinfo.serial)
|
if (!lib_sysinfo.serial)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
serial_is_mem_mapped =
|
||||||
|
(lib_sysinfo.serial->type == CB_SERIAL_TYPE_MEMORY_MAPPED);
|
||||||
|
|
||||||
|
if (!serial_is_mem_mapped && (inb(IOBASE + 0x05) == 0xFF) &&
|
||||||
|
(inb(IOBASE + 0x06) == 0xFF)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_hardware_is_present = 1;
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_SET_SPEED
|
#ifdef CONFIG_SERIAL_SET_SPEED
|
||||||
if (lib_sysinfo.serial->type == CB_SERIAL_TYPE_MEMORY_MAPPED)
|
serial_hardware_init(CONFIG_SERIAL_BAUD_RATE, 8, 0, 1);
|
||||||
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
|
#endif
|
||||||
console_add_input_driver(&consin);
|
console_add_input_driver(&consin);
|
||||||
console_add_output_driver(&consout);
|
console_add_output_driver(&consout);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void serial_putchar(unsigned int c)
|
void serial_putchar(unsigned int c)
|
||||||
{
|
{
|
||||||
if (!lib_sysinfo.serial)
|
if (!serial_hardware_is_present)
|
||||||
return;
|
return;
|
||||||
|
while ((serial_read_reg(0x05) & 0x20) == 0) ;
|
||||||
if (lib_sysinfo.serial->type == CB_SERIAL_TYPE_MEMORY_MAPPED)
|
serial_write_reg(c, 0x00);
|
||||||
serial_mem_putchar(c);
|
|
||||||
else
|
|
||||||
serial_io_putchar(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int serial_havechar(void)
|
int serial_havechar(void)
|
||||||
{
|
{
|
||||||
if (!lib_sysinfo.serial)
|
if (!serial_hardware_is_present)
|
||||||
return 0;
|
return 0;
|
||||||
|
return serial_read_reg(0x05) & 0x01;
|
||||||
if (lib_sysinfo.ser_base)
|
|
||||||
return serial_mem_havechar();
|
|
||||||
else
|
|
||||||
return serial_io_havechar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int serial_getchar(void)
|
int serial_getchar(void)
|
||||||
{
|
{
|
||||||
if (!lib_sysinfo.serial)
|
if (!serial_hardware_is_present)
|
||||||
return -1;
|
return -1;
|
||||||
|
while (!serial_havechar()) ;
|
||||||
if (lib_sysinfo.ser_base)
|
return serial_read_reg(0x00);
|
||||||
return serial_mem_getchar();
|
|
||||||
else
|
|
||||||
return serial_io_getchar();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These are thinly veiled vt100 functions used by curses */
|
/* These are thinly veiled vt100 functions used by curses */
|
||||||
|
@ -214,7 +157,7 @@ int serial_getchar(void)
|
||||||
|
|
||||||
static void serial_putcmd(const char *str)
|
static void serial_putcmd(const char *str)
|
||||||
{
|
{
|
||||||
while(*str)
|
while (*str)
|
||||||
serial_putchar(*(str++));
|
serial_putchar(*(str++));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue