@@ -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+
4466void 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
0 commit comments