git: 221376db0cb7 - main - loader.efi: to preserve heap space, use AllocatePages() for shadow_fb

From: Toomas Soome <tsoome_at_FreeBSD.org>
Date: Wed, 22 Dec 2021 11:56:10 UTC
The branch main has been updated by tsoome:

URL: https://cgit.FreeBSD.org/src/commit/?id=221376db0cb77035e325baf8b54d6224925b41f8

commit 221376db0cb77035e325baf8b54d6224925b41f8
Author:     Toomas Soome <tsoome@FreeBSD.org>
AuthorDate: 2021-12-17 13:10:05 +0000
Commit:     Toomas Soome <tsoome@FreeBSD.org>
CommitDate: 2021-12-22 09:39:28 +0000

    loader.efi: to preserve heap space, use AllocatePages() for shadow_fb
    
    shadow FB size could be rather large and depends on resolution,
    instead of using heap, allocate dedicated space outside of heap.
    
    Reviewed by: manu
    Differential Revision: https://reviews.freebsd.org/D33600
    MFC after: 2 weeks
---
 stand/common/gfx_fb.h          |  1 +
 stand/efi/loader/framebuffer.c | 13 +++++++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/stand/common/gfx_fb.h b/stand/common/gfx_fb.h
index e55f6fc13fe5..f5747e065daf 100644
--- a/stand/common/gfx_fb.h
+++ b/stand/common/gfx_fb.h
@@ -217,6 +217,7 @@ typedef struct teken_gfx {
 	struct vt_font	tg_font;
 	struct gen_fb	tg_fb;
 	uint32_t	*tg_shadow_fb;		/* units of 4 bytes */
+	size_t		tg_shadow_sz;		/* units of pages */
 	teken_funcs_t	*tg_functions;
 	void		*tg_private;
 } teken_gfx_t;
diff --git a/stand/efi/loader/framebuffer.c b/stand/efi/loader/framebuffer.c
index 0a00b3645b36..d5504c9cff35 100644
--- a/stand/efi/loader/framebuffer.c
+++ b/stand/efi/loader/framebuffer.c
@@ -634,9 +634,18 @@ efi_find_framebuffer(teken_gfx_t *gfx_state)
 	gfx_state->tg_fb.fb_bpp = fls(efifb.fb_mask_red | efifb.fb_mask_green |
 	    efifb.fb_mask_blue | efifb.fb_mask_reserved);
 
-	free(gfx_state->tg_shadow_fb);
-	gfx_state->tg_shadow_fb = malloc(efifb.fb_height * efifb.fb_width *
+	if (gfx_state->tg_shadow_fb != NULL)
+		BS->FreePages((EFI_PHYSICAL_ADDRESS)gfx_state->tg_shadow_fb,
+		    gfx_state->tg_shadow_sz);
+	gfx_state->tg_shadow_sz =
+	    EFI_SIZE_TO_PAGES(efifb.fb_height * efifb.fb_width *
 	    sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+	status = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData,
+	    gfx_state->tg_shadow_sz,
+	    (EFI_PHYSICAL_ADDRESS *)&gfx_state->tg_shadow_fb);
+	if (status != EFI_SUCCESS)
+		gfx_state->tg_shadow_fb = NULL;
+
 	return (0);
 }