lib/term: Reuse a framebuffer for UEFI fallback term if boot services exited instead of bailing out
diff --git a/common/lib/fb.c b/common/lib/fb.c
index 5d6f32e1..0db34500 100644
--- a/common/lib/fb.c
+++ b/common/lib/fb.c
@@ -6,6 +6,9 @@
#include <drivers/gop.h>
#include <mm/pmm.h>
+struct fb_info *fb_fbs;
+size_t fb_fbs_count = 0;
+
void fb_init(struct fb_info **ret, size_t *_fbs_count,
uint64_t target_width, uint64_t target_height, uint16_t target_bpp) {
#if defined (BIOS)
@@ -24,6 +27,9 @@ void fb_init(struct fb_info **ret, size_t *_fbs_count,
#elif defined (UEFI)
init_gop(ret, _fbs_count, target_width, target_height, target_bpp);
#endif
+
+ fb_fbs = *ret;
+ fb_fbs_count = *_fbs_count;
}
void fb_clear(struct fb_info *fb) {
diff --git a/common/lib/fb.h b/common/lib/fb.h
index 79542d61..fea4e28a 100644
--- a/common/lib/fb.h
+++ b/common/lib/fb.h
@@ -32,6 +32,9 @@ struct fb_info {
struct fb_info *mode_list;
};
+extern struct fb_info *fb_fbs;
+extern size_t fb_fbs_count;
+
void fb_init(struct fb_info **ret, size_t *_fbs_count,
uint64_t target_width, uint64_t target_height, uint16_t target_bpp);
diff --git a/common/lib/term.c b/common/lib/term.c
index d3111c29..fc547643 100644
--- a/common/lib/term.c
+++ b/common/lib/term.c
@@ -4,6 +4,7 @@
#include <lib/term.h>
#include <lib/real.h>
#include <lib/misc.h>
+#include <lib/fb.h>
#include <mm/pmm.h>
#include <drivers/vga_textmode.h>
#include <flanterm/backends/fb.h>
@@ -226,16 +227,16 @@ static bool dummy_handle(void) {
void term_fallback(void) {
term_notready();
-#if defined (UEFI)
- if (!efi_boot_services_exited) {
-#endif
+ terms = ext_mem_alloc(sizeof(void *));
+ terms_i = 1;
- terms = ext_mem_alloc(sizeof(void *));
- terms_i = 1;
+ terms[0] = ext_mem_alloc(sizeof(struct flanterm_context));
- terms[0] = ext_mem_alloc(sizeof(struct flanterm_context));
+ struct flanterm_context *term = terms[0];
- struct flanterm_context *term = terms[0];
+#if defined (UEFI)
+ if (!efi_boot_services_exited) {
+#endif
fallback_clear(NULL, true);
@@ -277,6 +278,32 @@ void term_fallback(void) {
term->set_text_fg_default(term);
term->set_text_bg_default(term);
+ } else {
+ if (fb_fbs_count == 0) {
+ goto fail;
+ }
+
+ terms[0] = flanterm_fb_init(ext_mem_alloc, pmm_free,
+ (void *)(uintptr_t)fb_fbs[0].framebuffer_addr, fb_fbs[0].framebuffer_width,
+ fb_fbs[0].framebuffer_height, fb_fbs[0].framebuffer_pitch,
+ fb_fbs[0].red_mask_size, fb_fbs[0].red_mask_shift,
+ fb_fbs[0].green_mask_size, fb_fbs[0].green_mask_shift,
+ fb_fbs[0].blue_mask_size, fb_fbs[0].blue_mask_shift,
+ NULL,
+ NULL, NULL,
+ NULL, NULL,
+ NULL, NULL,
+ NULL, 0, 0, 1,
+ 0, 0,
+ 0
+ );
}
+
+ return;
+
+fail:
+ pmm_free(terms[0], sizeof(struct flanterm_context));
+ pmm_free(terms, sizeof(void *));
+ terms_i = 0;
#endif
}
