loader.efi: fix console output after BS off

When Boot Services (BS) are switched off, we can not use BS
functions any more. Since drawn console does implement our own
Blt(), we can use it to draw the console.

However, SimpleTextOutput protocol based console output must be
blocked.

Tested by inserting printf() after ExitBootServices() call.

MFC after:	1 week
This commit is contained in:
Toomas Soome 2021-09-03 00:17:32 +03:00
parent cc2d08d388
commit 4c7a3a70e0
2 changed files with 26 additions and 10 deletions

View File

@ -751,12 +751,15 @@ gfxfb_blt(void *BltBuffer, GFXFB_BLT_OPERATION BltOperation,
#if defined(EFI)
EFI_STATUS status;
EFI_GRAPHICS_OUTPUT *gop = gfx_state.tg_private;
extern int boot_services_gone;
EFI_TPL tpl;
/*
* We assume Blt() does work, if not, we will need to build
* exception list case by case.
*/
if (gop != NULL) {
if (gop != NULL && boot_services_gone == 0) {
tpl = BS->RaiseTPL(TPL_NOTIFY);
switch (BltOperation) {
case GfxFbBltVideoFill:
status = gop->Blt(gop, BltBuffer, EfiBltVideoFill,
@ -803,6 +806,7 @@ gfxfb_blt(void *BltBuffer, GFXFB_BLT_OPERATION BltOperation,
break;
}
BS->RestoreTPL(tpl);
return (rv);
}
#endif
@ -1040,20 +1044,12 @@ void
gfx_fb_cursor(void *arg, const teken_pos_t *p)
{
teken_gfx_t *state = arg;
#if defined(EFI)
EFI_TPL tpl;
tpl = BS->RaiseTPL(TPL_NOTIFY);
#endif
/* Switch cursor off in old location and back on in new. */
if (state->tg_cursor_visible) {
gfx_fb_cursor_draw(state, &state->tg_cursor, false);
gfx_fb_cursor_draw(state, p, true);
}
#if defined(EFI)
BS->RestoreTPL(tpl);
#endif
}
void

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <framebuffer.h>
#include "bootstrap.h"
extern int boot_services_gone;
extern EFI_GUID gop_guid;
static EFI_GUID simple_input_ex_guid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
static SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
@ -176,6 +177,9 @@ efi_text_cursor(void *arg, const teken_pos_t *p)
teken_gfx_t *state = arg;
UINTN col, row;
if (boot_services_gone)
return;
row = p->tp_row;
if (p->tp_row >= state->tg_tp.tp_row)
row = state->tg_tp.tp_row - 1;
@ -234,6 +238,9 @@ efi_text_putchar(void *s, const teken_pos_t *p, teken_char_t c,
EFI_STATUS status;
int idx;
if (boot_services_gone)
return;
idx = p->tp_col + p->tp_row * state->tg_tp.tp_col;
if (idx >= state->tg_tp.tp_col * state->tg_tp.tp_row)
return;
@ -251,6 +258,9 @@ efi_text_fill(void *arg, const teken_rect_t *r, teken_char_t c,
teken_gfx_t *state = arg;
teken_pos_t p;
if (boot_services_gone)
return;
if (state->tg_cursor_visible)
conout->EnableCursor(conout, FALSE);
for (p.tp_row = r->tr_begin.tp_row; p.tp_row < r->tr_end.tp_row;
@ -303,6 +313,9 @@ efi_text_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p)
int nrow, ncol, x, y; /* Has to be signed - >= 0 comparison */
bool scroll = false;
if (boot_services_gone)
return;
/*
* Copying is a little tricky. We must make sure we do it in
* correct order, to make sure we don't overwrite our own data.
@ -356,6 +369,9 @@ efi_text_param(void *arg, int cmd, unsigned int value)
{
teken_gfx_t *state = arg;
if (boot_services_gone)
return;
switch (cmd) {
case TP_SETLOCALCURSOR:
/*
@ -730,6 +746,9 @@ efi_term_emu(int c)
int t, i;
EFI_STATUS status;
if (boot_services_gone)
return;
switch (esc) {
case 0:
switch (c) {
@ -839,7 +858,8 @@ efi_term_emu(int c)
break;
}
#else
efi_cons_rawputchar(c);
if (!boot_services_gone)
efi_cons_rawputchar(c);
#endif
}