Hello Julius Werner, Reto Buerki,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/37478
to review the following change.
Change subject: libpayload: Cache physical cbmem console address ......................................................................
libpayload: Cache physical cbmem console address
Same as with other consoles and drivers that cache an address outside the payload (e.g. video/corebootfb), we should store the physical address, so we can derive the virtual address on demand. This makes it save to use the address across relocations.
Fixes the default build of FILO, tested with Qemu/i440FX and Qemu/Q35.
Change-Id: I4b8434af69e0526f78523ae61981a15abb1295b0 Signed-off-by: Nico Huber nico.h@gmx.de --- M payloads/libpayload/drivers/cbmem_console.c 1 file changed, 17 insertions(+), 12 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/78/37478/1
diff --git a/payloads/libpayload/drivers/cbmem_console.c b/payloads/libpayload/drivers/cbmem_console.c index 9435e1c..35a8d3a 100644 --- a/payloads/libpayload/drivers/cbmem_console.c +++ b/payloads/libpayload/drivers/cbmem_console.c @@ -39,7 +39,7 @@ #define CURSOR_MASK ((1 << 28) - 1) #define OVERFLOW (1 << 31)
-static struct cbmem_console *cbmem_console_p; +static uintptr_t cbmem_console_p;
static struct console_output_driver cbmem_console_driver = { @@ -48,27 +48,32 @@
static void do_write(const void *buffer, size_t count) { - memcpy(cbmem_console_p->body + (cbmem_console_p->cursor & CURSOR_MASK), - buffer, count); - cbmem_console_p->cursor += count; + struct cbmem_console *const cbmem_con = phys_to_virt(cbmem_console_p); + + memcpy(cbmem_con->body + (cbmem_con->cursor & CURSOR_MASK), buffer, count); + cbmem_con->cursor += count; }
void cbmem_console_init(void) { - cbmem_console_p = lib_sysinfo.cbmem_cons; - if (cbmem_console_p && cbmem_console_p->size) + /* We might have been called before relocation (like FILO does). So + just keep the physical address which won't break on relocation. */ + cbmem_console_p = virt_to_phys(lib_sysinfo.cbmem_cons); + + struct cbmem_console *const cbmem_con = phys_to_virt(cbmem_console_p); + if (cbmem_console_p && cbmem_con->size) console_add_output_driver(&cbmem_console_driver); }
void cbmem_console_write(const void *buffer, size_t count) { - while ((cbmem_console_p->cursor & CURSOR_MASK) + count >= - cbmem_console_p->size) { - size_t still_fits = cbmem_console_p->size - - (cbmem_console_p->cursor & CURSOR_MASK); + struct cbmem_console *const cbmem_con = phys_to_virt(cbmem_console_p); + + while ((cbmem_con->cursor & CURSOR_MASK) + count >= cbmem_con->size) { + size_t still_fits = cbmem_con->size - (cbmem_con->cursor & CURSOR_MASK); do_write(buffer, still_fits); - cbmem_console_p->cursor &= ~CURSOR_MASK; - cbmem_console_p->cursor |= OVERFLOW; + cbmem_con->cursor &= ~CURSOR_MASK; + cbmem_con->cursor |= OVERFLOW; buffer += still_fits; count -= still_fits; }