[FREELDR:UEFI] Fix broken boot menu countdown (#8714)

The UEFI boot menu countdown was broken for two reasons:

- StallExecutionProcessor and UefiHwIdle were empty stubs, so the countdown
  had no actual delay and no proper idle, it ran instantly without waiting
  KbHit used ReadKeyStroke to poll for input, which consumed the keystroke
  before GetCh could read it.

This fixes both: StallExecutionProcessor and UefiHwIdle now have real
implementations using BootServices->Stall and a timer event.

KbHit is changed to use CheckEvent(WaitForKey) which polls availability
without consuming the key.

CORE-11954
This commit is contained in:
Ahmed Arif
2026-03-08 19:40:15 +01:00
committed by GitHub
parent 8a2864dd11
commit dc9ee34478
3 changed files with 45 additions and 18 deletions

View File

@@ -16,12 +16,6 @@ DriveMapGetBiosDriveNumber(PCSTR DeviceName)
}
#endif
VOID
StallExecutionProcessor(ULONG Microseconds)
{
}
VOID
UefiVideoGetFontsFromFirmware(PULONG RomFontPointers)
{
@@ -46,9 +40,3 @@ UefiPcBeep(VOID)
{
/* Not possible on UEFI, for now */
}
VOID
UefiHwIdle(VOID)
{
}

View File

@@ -17,7 +17,6 @@ static unsigned CurrentCursorY = 0;
static UCHAR CurrentAttr = ATTR(COLOR_GRAY, COLOR_BLACK);
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
static EFI_INPUT_KEY Key;
static BOOLEAN ExtendedKey = FALSE;
static char ExtendedScanCode = 0;
@@ -121,12 +120,15 @@ ConvertToBiosExtValue(UCHAR KeyIn)
BOOLEAN
UefiConsKbHit(VOID)
{
return (GlobalSystemTable->ConIn->ReadKeyStroke(GlobalSystemTable->ConIn, &Key) != EFI_NOT_READY);
return (GlobalSystemTable->BootServices->CheckEvent(
GlobalSystemTable->ConIn->WaitForKey) == EFI_SUCCESS);
}
int
UefiConsGetCh(VOID)
{
EFI_INPUT_KEY Key;
EFI_STATUS Status;
UCHAR KeyOutput = 0;
/* If an extended key press was detected the last time we were called
@@ -137,6 +139,10 @@ UefiConsGetCh(VOID)
return ExtendedScanCode;
}
Status = GlobalSystemTable->ConIn->ReadKeyStroke(GlobalSystemTable->ConIn, &Key);
if (EFI_ERROR(Status))
return 0;
if (Key.UnicodeChar != 0)
{
KeyOutput = Key.UnicodeChar;
@@ -147,9 +153,5 @@ UefiConsGetCh(VOID)
ExtendedScanCode = ConvertToBiosExtValue(Key.ScanCode);
KeyOutput = KEY_EXTENDED;
}
/* UEFI will stack input requests, we have to clear it */
Key.UnicodeChar = 0;
Key.ScanCode = 0;
return KeyOutput;
}

View File

@@ -25,9 +25,46 @@ extern ULONG VramSize;
extern PCM_FRAMEBUF_DEVICE_DATA FrameBufferData;
BOOLEAN AcpiPresent = FALSE;
static EFI_EVENT IdleTimerEvent = NULL;
/* FUNCTIONS *****************************************************************/
VOID
StallExecutionProcessor(ULONG Microseconds)
{
GlobalSystemTable->BootServices->Stall(Microseconds);
}
VOID
UefiHwIdle(VOID)
{
UINTN Index;
EFI_STATUS Status;
EFI_BOOT_SERVICES *BootServices = GlobalSystemTable->BootServices;
/* Keep one timer event around and arm it each idle tick */
if (IdleTimerEvent == NULL)
{
Status = BootServices->CreateEvent(EVT_TIMER,
TPL_APPLICATION,
NULL,
NULL,
&IdleTimerEvent);
if (EFI_ERROR(Status))
{
StallExecutionProcessor(10000); /* 10 ms fallback */
return;
}
}
/* Set a 10ms (100,000 * 100ns) relative timer */
Status = BootServices->SetTimer(IdleTimerEvent, TimerRelative, 100000);
if (!EFI_ERROR(Status))
Status = BootServices->WaitForEvent(1, &IdleTimerEvent, &Index);
if (EFI_ERROR(Status))
StallExecutionProcessor(10000); /* 10 ms fallback */
}
BOOLEAN IsAcpiPresent(VOID)
{
return AcpiPresent;