Nico Huber would like Julius Werner and Reto Buerki to review this change.

View Change

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;
}

To view, visit change 37478. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I4b8434af69e0526f78523ae61981a15abb1295b0
Gerrit-Change-Number: 37478
Gerrit-PatchSet: 1
Gerrit-Owner: Nico Huber <nico.h@gmx.de>
Gerrit-Reviewer: Julius Werner <jwerner@chromium.org>
Gerrit-Reviewer: Reto Buerki <reet@codelabs.ch>
Gerrit-MessageType: newchange