Skip to content

Commit bc5d1e4

Browse files
programmerlexiMintsuki
authored andcommitted
lib/bli: implement timeout control
1 parent 9c3ead9 commit bc5d1e4

File tree

3 files changed

+98
-6
lines changed

3 files changed

+98
-6
lines changed

common/lib/bli.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,28 @@ void uint64_to_decwstr(uint64_t value, wchar_t *buf) {
4141
buf[i] = '\0';
4242
}
4343

44+
bool decwstr_to_size(const wchar_t *buf, size_t buf_size, size_t *value) {
45+
size_t i = 0;
46+
size_t tmp = 0;
47+
48+
if (buf == NULL) {
49+
return false;
50+
}
51+
52+
while (i * 2 < buf_size && buf[i]) {
53+
wchar_t c = buf[i];
54+
if (!(c >= L'0' && c <= L'9')) {
55+
return false;
56+
}
57+
tmp = tmp * 10 + (c - L'0');
58+
i++;
59+
}
60+
61+
*value = tmp;
62+
63+
return true;
64+
}
65+
4466
void bli_set_loader_time(wchar_t *variable, uint64_t time) {
4567
if (time == 0)
4668
return;
@@ -67,6 +89,15 @@ void init_bli(void) {
6789
sizeof(LIMINE_BRAND),
6890
LIMINE_BRAND);
6991

92+
uint64_t features = (1 << 0) | // Timeout control
93+
(1 << 1) | // Oneshot timeout control
94+
(1 << 13); // menu-disabled support
95+
gRT->SetVariable(L"LoaderFeatures",
96+
&bli_vendor_guid,
97+
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
98+
sizeof(features),
99+
&features);
100+
70101
char part_uuid_str[37];
71102
guid_to_string(&boot_volume->part_guid, part_uuid_str);
72103

@@ -87,4 +118,46 @@ void bli_on_boot(void) {
87118
bli_set_loader_time(L"LoaderTimeExecUSec", rdtsc_usec());
88119
}
89120

121+
static bool handle_timeout(wchar_t *variable, bool erase, size_t *timeout, bool *skip_timeout) {
122+
wchar_t timeout_buf[256];
123+
UINTN getvar_size = sizeof(timeout_buf) - 2;
124+
uint32_t attrs;
125+
if (gRT->GetVariable(variable,
126+
&bli_vendor_guid,
127+
&attrs,
128+
&getvar_size,
129+
timeout_buf) == 0 && getvar_size > 0) {
130+
if (erase) {
131+
gRT->SetVariable(variable, &bli_vendor_guid,
132+
attrs,
133+
0, NULL);
134+
}
135+
if (getvar_size == 24 && memcmp(timeout_buf, L"menu-force",24) == 0) {
136+
*skip_timeout = true;
137+
return true;
138+
}
139+
if ((getvar_size == 24 && memcmp(timeout_buf, L"menu-hidden",24) == 0) || (getvar_size == 28 && memcmp(timeout_buf, L"menu-disabled",28) == 0)) {
140+
// TODO: menu-hidden should enable quiet & set timeout >= 1
141+
*timeout = 0;
142+
return true;
143+
}
144+
size_t t;
145+
if (!decwstr_to_size(timeout_buf, getvar_size, &t)) {
146+
return false;
147+
}
148+
*timeout = t;
149+
return true;
150+
}
151+
return false;
152+
153+
}
154+
155+
bool bli_update_oneshot_timeout(size_t *timeout, bool *skip_timeout) {
156+
return handle_timeout(L"LoaderConfigTimeoutOneShot", true, timeout, skip_timeout);
157+
}
158+
159+
bool bli_update_timeout(size_t *timeout, bool *skip_timeout) {
160+
return handle_timeout(L"LoaderConfigTimeout", false, timeout, skip_timeout);
161+
}
162+
90163
#endif

common/lib/bli.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
void init_bli(void);
77
void bli_on_boot(void);
8+
bool bli_update_oneshot_timeout(size_t *timeout, bool *skip_timeout);
9+
bool bli_update_timeout(size_t *timeout, bool *skip_timeout);
810

911
#endif
1012

common/menu.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <stdnoreturn.h>
55
#include <config.h>
66
#include <menu.h>
7+
#include <lib/bli.h>
78
#include <lib/print.h>
89
#include <lib/misc.h>
910
#include <lib/libc.h>
@@ -1187,13 +1188,29 @@ noreturn void _menu(bool first_run) {
11871188
}
11881189

11891190
size_t timeout = 5;
1190-
char *timeout_config = config_get_value(NULL, 0, "TIMEOUT");
1191-
if (timeout_config != NULL) {
1192-
if (!strcmp(timeout_config, "no"))
1193-
skip_timeout = true;
1194-
else
1195-
timeout = strtoui(timeout_config, NULL, 10);
1191+
1192+
bool has_timeout = false;
1193+
1194+
#if defined (UEFI)
1195+
has_timeout = bli_update_oneshot_timeout(&timeout, &skip_timeout);
1196+
#endif
1197+
1198+
if (!has_timeout) {
1199+
char *timeout_config = config_get_value(NULL, 0, "TIMEOUT");
1200+
if (timeout_config != NULL) {
1201+
has_timeout = true;
1202+
if (!strcmp(timeout_config, "no"))
1203+
skip_timeout = true;
1204+
else
1205+
timeout = strtoui(timeout_config, NULL, 10);
1206+
}
1207+
}
1208+
1209+
#if defined (UEFI)
1210+
if (!has_timeout) {
1211+
has_timeout = bli_update_timeout(&timeout, &skip_timeout);
11961212
}
1213+
#endif
11971214

11981215
#if defined(UEFI)
11991216
bool reboot_to_firmware_supported = reboot_to_fw_ui_supported();

0 commit comments

Comments
 (0)