Patrick Georgi submitted this change.

View Change

Approvals: build bot (Jenkins): Verified Julius Werner: Looks good to me, approved Angel Pons: Looks good to me, approved
libpayload: Cache copy of `cb_framebuffer` struct

Our AArch64 code supports dynamic framebuffer allocation which
makes it necessary to change the framebuffer information during
runtime. Having a pointer inside `libsysinfo` made a mess of it
as the pointer would either refer to the original struct inside
the coreboot table or to a new struct inside payload space. The
latter would be unaffected by a relocation of the payload.

Instead of the pointer, we'll always keep a copy of the whole
struct, which can be altered on demand without affecting the
coreboot table. To align the `video/graphics` driver with the
console driver, we also replace `fbaddr` with a macro `FB` that
calls phys_to_virt().

Change-Id: I3edc09cdb502a71516c1ee71457c1f8dcd01c119
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/43578
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Julius Werner <jwerner@chromium.org>
---
M payloads/libpayload/arch/arm64/mmu.c
M payloads/libpayload/drivers/video/corebootfb.c
M payloads/libpayload/drivers/video/graphics.c
M payloads/libpayload/include/sysinfo.h
M payloads/libpayload/libc/coreboot.c
5 files changed, 15 insertions(+), 33 deletions(-)

diff --git a/payloads/libpayload/arch/arm64/mmu.c b/payloads/libpayload/arch/arm64/mmu.c
index 1fa9ced..cb0081b 100644
--- a/payloads/libpayload/arch/arm64/mmu.c
+++ b/payloads/libpayload/arch/arm64/mmu.c
@@ -625,14 +625,10 @@
static void mmu_add_fb_range(struct mmu_ranges *mmu_ranges)
{
struct mmu_memrange *fb_range;
- static struct cb_framebuffer modified_fb;
- struct cb_framebuffer *framebuffer = lib_sysinfo.framebuffer;
+ struct cb_framebuffer *framebuffer = &lib_sysinfo.framebuffer;
uint32_t fb_size;

/* Check whether framebuffer is needed */
- if (framebuffer == NULL)
- return;
-
fb_size = framebuffer->bytes_per_line * framebuffer->y_resolution;
if (!fb_size)
return;
@@ -652,16 +648,7 @@
if (fb_range == NULL)
mmu_error();

- /*
- * Set framebuffer address. However, one needs to use a freshly
- * allocated framebuffer structure because the one in the coreboot
- * table is part of a checksum calculation. Therefore, one cannot
- * modify a field without recomputing the necessary checksum
- * calcuation.
- */
- modified_fb = *framebuffer;
- modified_fb.physical_address = fb_range->base;
- lib_sysinfo.framebuffer = &modified_fb;
+ framebuffer->physical_address = fb_range->base;
}

/*
diff --git a/payloads/libpayload/drivers/video/corebootfb.c b/payloads/libpayload/drivers/video/corebootfb.c
index c21665d..1865ad3 100644
--- a/payloads/libpayload/drivers/video/corebootfb.c
+++ b/payloads/libpayload/drivers/video/corebootfb.c
@@ -60,7 +60,7 @@
(0xFF << 16) | (0xFF << 8) | 0xFF,
};

-struct cb_framebuffer fbinfo;
+static struct cb_framebuffer fbinfo;
static unsigned short *chars;

/* Shorthand for up-to-date virtual framebuffer address */
@@ -223,13 +223,10 @@

static int corebootfb_init(void)
{
- if (lib_sysinfo.framebuffer == NULL)
+ if (!lib_sysinfo.framebuffer.physical_address)
return -1;

- fbinfo = *lib_sysinfo.framebuffer;
-
- if (fbinfo.physical_address == 0)
- return -1;
+ fbinfo = lib_sysinfo.framebuffer;

font_init(fbinfo.x_resolution);

diff --git a/payloads/libpayload/drivers/video/graphics.c b/payloads/libpayload/drivers/video/graphics.c
index 21f520c..2d2ea03 100644
--- a/payloads/libpayload/drivers/video/graphics.c
+++ b/payloads/libpayload/drivers/video/graphics.c
@@ -45,8 +45,10 @@
* Framebuffer is assumed to assign a higher coordinate (larger x, y) to
* a higher address
*/
-static struct cb_framebuffer *fbinfo;
-static uint8_t *fbaddr;
+static const struct cb_framebuffer *fbinfo;
+
+/* Shorthand for up-to-date virtual framebuffer address */
+#define FB ((unsigned char *)phys_to_virt(fbinfo->physical_address))

#define LOG(x...) printf("CBGFX: " x)
#define PIVOT_H_MASK (PIVOT_H_LEFT|PIVOT_H_CENTER|PIVOT_H_RIGHT)
@@ -296,7 +298,7 @@
break;
}

- uint8_t * const pixel = fbaddr + rcoord.y * bpl + rcoord.x * bpp / 8;
+ uint8_t * const pixel = FB + rcoord.y * bpl + rcoord.x * bpp / 8;
for (i = 0; i < bpp / 8; i++)
pixel[i] = (color >> (i * 8));
}
@@ -310,12 +312,9 @@
if (initialized)
return 0;

- fbinfo = lib_sysinfo.framebuffer;
- if (!fbinfo)
- return CBGFX_ERROR_FRAMEBUFFER_INFO;
+ fbinfo = &lib_sysinfo.framebuffer;

- fbaddr = phys_to_virt((uint8_t *)(uintptr_t)(fbinfo->physical_address));
- if (!fbaddr)
+ if (!fbinfo->physical_address)
return CBGFX_ERROR_FRAMEBUFFER_ADDR;

switch (fbinfo->orientation) {
@@ -627,7 +626,7 @@
* We assume that for 32bpp the high byte gets ignored anyway. */
if ((((color >> 8) & 0xff) == (color & 0xff)) && (bpp == 16 ||
(((color >> 16) & 0xff) == (color & 0xff)))) {
- memset(fbaddr, color & 0xff, fbinfo->y_resolution * bpl);
+ memset(FB, color & 0xff, fbinfo->y_resolution * bpl);
} else {
for (p.y = 0; p.y < screen.size.height; p.y++)
for (p.x = 0; p.x < screen.size.width; p.x++)
diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h
index 188b2c3..303e08e 100644
--- a/payloads/libpayload/include/sysinfo.h
+++ b/payloads/libpayload/include/sysinfo.h
@@ -81,7 +81,7 @@

char *cb_version;

- struct cb_framebuffer *framebuffer;
+ struct cb_framebuffer framebuffer;

int num_gpios;
struct cb_gpio gpios[SYSINFO_MAX_GPIOS];
diff --git a/payloads/libpayload/libc/coreboot.c b/payloads/libpayload/libc/coreboot.c
index 5ecdd51..43d9df4 100644
--- a/payloads/libpayload/libc/coreboot.c
+++ b/payloads/libpayload/libc/coreboot.c
@@ -186,8 +186,7 @@
#if CONFIG(LP_COREBOOT_VIDEO_CONSOLE)
static void cb_parse_framebuffer(void *ptr, struct sysinfo_t *info)
{
- /* ptr points to a coreboot table entry and is already virtual */
- info->framebuffer = ptr;
+ info->framebuffer = *(struct cb_framebuffer *)ptr;
}
#endif


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

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I3edc09cdb502a71516c1ee71457c1f8dcd01c119
Gerrit-Change-Number: 43578
Gerrit-PatchSet: 3
Gerrit-Owner: Nico Huber <nico.h@gmx.de>
Gerrit-Reviewer: Felix Singer <felixsinger@posteo.net>
Gerrit-Reviewer: Angel Pons <th3fanbus@gmail.com>
Gerrit-Reviewer: Julius Werner <jwerner@chromium.org>
Gerrit-Reviewer: Patrick Georgi <pgeorgi@google.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter@users.sourceforge.net>
Gerrit-MessageType: merged