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>
This commit is contained in:
Nico Huber
2020-07-18 15:20:00 +02:00
committed by Patrick Georgi
parent be842cb72d
commit 5e0db58533
5 changed files with 15 additions and 33 deletions

View File

@@ -60,7 +60,7 @@ static const u32 vga_colors[] = {
(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 void corebootfb_set_cursor(unsigned int x, unsigned int y)
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);

View File

@@ -45,8 +45,10 @@ static struct rect screen;
* 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 @@ static inline void set_pixel(struct vector *coord, uint32_t color)
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 @@ static int cbgfx_init(void)
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 @@ int clear_screen(const struct rgb_color *rgb)
* 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++)