Index | Thread | Search

From:
Klemens Nanni <kn@openbsd.org>
Subject:
Re: amd64/efiboot: add mach fwsetup
To:
Jonathan Matthew <jonathan@d14n.org>, tech@openbsd.org
Date:
Sun, 17 Aug 2025 09:40:24 +0000

Download raw body.

Thread
08.08.2025 10:21, Jonathan Matthew пишет:
> 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?

Helpful and works on my Intel T14 gen3.

OK kn with efiboot/conf.c version[] bumped.

> 
> 
> 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));
>