Download raw body.
amd64/efiboot: add mach fwsetup
Since UEFI 2.4 (released 2013) there has been a mechanism for system
software to tell the machine to boot into the firmware setup interface,
described here:
https://uefi.org/specs/UEFI/2.11/08_Services_Runtime_Services.html#exchanging-information-between-the-os-and-firmware
The diff below adds a 'mach fwsetup' command to amd64 efiboot that implements
this, so you can get into the firmware interface even if you can't hit F12
in the precise millisecond you need to in the normal boot process.
It's not a required feature, so on some machines (mostly servers as far as
I can tell) it'll just print an error message.
ok?
Index: boot/boot.8
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/boot/boot.8,v
diff -u -p -u -p -r1.36 boot.8
--- boot/boot.8 5 Nov 2024 09:42:48 -0000 1.36
+++ boot/boot.8 8 Aug 2025 07:08:09 -0000
@@ -236,6 +236,8 @@ Set the I/O base address for the serial
.It Nm diskinfo
Prints a list of hard disks installed on your system including:
BIOS device number, and the BIOS geometry.
+.It Nm fwsetup
+On EFI systems, reboot into the firmware user interface, if supported.
.It Ic gop Op Ar mode
On
.Xr efifb 4
Index: efiboot/cmd_i386.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/cmd_i386.c,v
diff -u -p -u -p -r1.2 cmd_i386.c
--- efiboot/cmd_i386.c 25 Apr 2024 18:31:49 -0000 1.2
+++ efiboot/cmd_i386.c 8 Aug 2025 07:08:09 -0000
@@ -65,6 +65,7 @@ const struct cmd_table cmd_machine[] = {
#ifdef IDLE_POWEROFF
{ "idle", CMDT_CMD, Xidle_efi },
#endif
+ { "fwsetup", CMDT_CMD, Xfwsetup_efi },
{ NULL, 0 }
};
Index: efiboot/efiboot.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
diff -u -p -u -p -r1.42 efiboot.c
--- efiboot/efiboot.c 25 Apr 2024 18:31:49 -0000 1.42
+++ efiboot/efiboot.c 8 Aug 2025 07:08:09 -0000
@@ -40,6 +40,8 @@
#define KERN_LOADSPACE_SIZE (64 * 1024 * 1024)
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 1ULL
+
EFI_SYSTEM_TABLE *ST;
EFI_BOOT_SERVICES *BS;
EFI_RUNTIME_SERVICES *RS;
@@ -1243,3 +1245,41 @@ Xidle_efi(void)
return 0;
}
#endif /* IDLE_POWEROFF */
+
+int
+Xfwsetup_efi(void)
+{
+ UINT64 osind;
+ UINTN osind_size = sizeof(osind);
+ UINT32 osind_attrs = 0x1 | 0x2 | 0x4;
+ EFI_GUID global = EFI_GLOBAL_VARIABLE;
+ EFI_STATUS status;
+
+ status = RS->GetVariable(L"OsIndicationsSupported", &global, NULL,
+ &osind_size, &osind);
+ if (status == EFI_NOT_FOUND) {
+ printf("not supported on this machine.\n");
+ return -1;
+ } else if (status != EFI_SUCCESS) {
+ printf("%s: %d\n", __func__, status);
+ return -1;
+ }
+
+ if ((osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) == 0) {
+ printf("not supported on this machine.\n");
+ return -1;
+ }
+
+ osind = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
+ status = RS->SetVariable(L"OsIndications", &global, osind_attrs,
+ sizeof(osind), &osind);
+ if (status != EFI_SUCCESS) {
+ printf("%s: %d\n", __func__, status);
+ return -1;
+ }
+
+ RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ for (;;)
+ continue;
+ return 0;
+}
Index: efiboot/efiboot.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.h,v
diff -u -p -u -p -r1.6 efiboot.h
--- efiboot/efiboot.h 25 Apr 2024 18:31:49 -0000 1.6
+++ efiboot/efiboot.h 8 Aug 2025 07:08:09 -0000
@@ -40,6 +40,7 @@ int Xpoweroff_efi(void);
#ifdef IDLE_POWEROFF
int Xidle_efi(void);
#endif
+int Xfwsetup_efi(void);
extern void (*run_i386)(u_long, u_long, int, int, int, int, int, int, int, int)
__attribute__ ((noreturn));
amd64/efiboot: add mach fwsetup