Hello Julius Werner,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/43578
to review the following change.
Change subject: libpayload: Cache copy of `cb_framebuffer` struct ......................................................................
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 --- 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(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/78/43578/1
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 54d3dfa..0f96658 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) @@ -229,7 +231,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)); } @@ -243,12 +245,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) { @@ -507,7 +506,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 03300b5..b592413 100644 --- a/payloads/libpayload/include/sysinfo.h +++ b/payloads/libpayload/include/sysinfo.h @@ -79,7 +79,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
Julius Werner has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/43578 )
Change subject: libpayload: Cache copy of `cb_framebuffer` struct ......................................................................
Patch Set 1: Code-Review+2
(1 comment)
https://review.coreboot.org/c/coreboot/+/43578/1/payloads/libpayload/drivers... File payloads/libpayload/drivers/video/corebootfb.c:
https://review.coreboot.org/c/coreboot/+/43578/1/payloads/libpayload/drivers... PS1, Line 229: fbinfo = lib_sysinfo.framebuffer; nit: no real reason to copy here anymore either, right? could just be a pointer (maybe #define fbinfo (lib_sysinfo.framebuffer) if you don't want to touch so much of the file).
Nico Huber has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/43578 )
Change subject: libpayload: Cache copy of `cb_framebuffer` struct ......................................................................
Patch Set 2:
(1 comment)
https://review.coreboot.org/c/coreboot/+/43578/1/payloads/libpayload/drivers... File payloads/libpayload/drivers/video/corebootfb.c:
https://review.coreboot.org/c/coreboot/+/43578/1/payloads/libpayload/drivers... PS1, Line 229: fbinfo = lib_sysinfo.framebuffer;
nit: no real reason to copy here anymore either, right? could just be a pointer (maybe #define fbinf […]
We modify some fields below (for centering). I guess it's better to keep that local. So the `lib_sysinfo.framebuffer` always has the actual coreboot fb info.
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/43578 )
Change subject: libpayload: Cache copy of `cb_framebuffer` struct ......................................................................
Patch Set 2: Code-Review+2
Patrick Georgi has submitted this change. ( https://review.coreboot.org/c/coreboot/+/43578 )
Change subject: libpayload: Cache copy of `cb_framebuffer` struct ......................................................................
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(-)
Approvals: build bot (Jenkins): Verified Julius Werner: Looks good to me, approved Angel Pons: Looks good to me, approved
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