diff options
author | Nico Huber <nico.huber@secunet.com> | 2019-12-05 13:49:19 +0100 |
---|---|---|
committer | Nico Huber <nico.h@gmx.de> | 2020-04-20 10:09:59 +0000 |
commit | e6b0a32cb305f8f201d93ba41215ba9e976c7698 (patch) | |
tree | 4a5d50c488e5781825f1dc333cef8346c427346f /payloads/libpayload/drivers/serial/8250.c | |
parent | b81147cb56cb7265d1584491e37accdb2f2f61d7 (diff) |
libpayload: Make 8250 UART driver relocation safe
`lib_sysinfo->serial` is a virtual pointer into coreboot tables.
It's not valid across relocation. Accessing the wrong value during
relocation of FILO resulted in a hang with DEBUG_SEGMENT and UART
console enabled. Work around that by caching the whole table entry
locally.
An alternative would be to revise `sysinfo`, to contain no virtual
pointers to anything outside the payload.
Change-Id: I03adaf57b83a177316d7778f7e06df8eb6f9158e
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37513
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Reto Buerki <reet@codelabs.ch>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Diffstat (limited to 'payloads/libpayload/drivers/serial/8250.c')
-rw-r--r-- | payloads/libpayload/drivers/serial/8250.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/payloads/libpayload/drivers/serial/8250.c b/payloads/libpayload/drivers/serial/8250.c index 9502d4b147..4a7cc01a0a 100644 --- a/payloads/libpayload/drivers/serial/8250.c +++ b/payloads/libpayload/drivers/serial/8250.c @@ -31,7 +31,9 @@ #include <libpayload-config.h> #include <libpayload.h> -#define IOBASE lib_sysinfo.serial->baseaddr +static struct cb_serial cb_serial; + +#define IOBASE cb_serial.baseaddr #define MEMBASE (phys_to_virt(IOBASE)) static int serial_hardware_is_present = 0; @@ -39,14 +41,14 @@ static int serial_is_mem_mapped = 0; static uint8_t serial_read_reg(int offset) { - offset *= lib_sysinfo.serial->regwidth; + offset *= cb_serial.regwidth; #if CONFIG(LP_IO_ADDRESS_SPACE) if (!serial_is_mem_mapped) return inb(IOBASE + offset); else #endif - if (lib_sysinfo.serial->regwidth == 4) + if (cb_serial.regwidth == 4) return readl(MEMBASE + offset) & 0xff; else return readb(MEMBASE + offset); @@ -54,14 +56,14 @@ static uint8_t serial_read_reg(int offset) static void serial_write_reg(uint8_t val, int offset) { - offset *= lib_sysinfo.serial->regwidth; + offset *= cb_serial.regwidth; #if CONFIG(LP_IO_ADDRESS_SPACE) if (!serial_is_mem_mapped) outb(val, IOBASE + offset); else #endif - if (lib_sysinfo.serial->regwidth == 4) + if (cb_serial.regwidth == 4) writel(val & 0xff, MEMBASE + offset); else writeb(val, MEMBASE + offset); @@ -108,11 +110,7 @@ static struct console_output_driver consout = { void serial_init(void) { - if (!lib_sysinfo.serial) - return; - - serial_is_mem_mapped = - (lib_sysinfo.serial->type == CB_SERIAL_TYPE_MEMORY_MAPPED); + serial_is_mem_mapped = (cb_serial.type == CB_SERIAL_TYPE_MEMORY_MAPPED); if (!serial_is_mem_mapped) { #if CONFIG(LP_IO_ADDRESS_SPACE) @@ -130,15 +128,16 @@ void serial_init(void) #if CONFIG(LP_SERIAL_SET_SPEED) serial_hardware_init(CONFIG_LP_SERIAL_BAUD_RATE, 8, 0, 1); #endif + serial_hardware_is_present = 1; } void serial_console_init(void) { if (!lib_sysinfo.serial) return; + cb_serial = *lib_sysinfo.serial; serial_init(); - serial_hardware_is_present = 1; console_add_input_driver(&consin); console_add_output_driver(&consout); |