mirror of
https://github.com/ipxe/ipxe
synced 2026-02-28 03:11:18 +03:00
[efi] Add ability to reboot to firmware setup menu
Add the ability to reboot to the firmware setup menu (if supported) by setting the relevant value in the OsIndications variable. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -38,12 +38,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
struct reboot_options {
|
struct reboot_options {
|
||||||
/** Perform a warm reboot */
|
/** Perform a warm reboot */
|
||||||
int warm;
|
int warm;
|
||||||
|
/** Reboot to firmware setup */
|
||||||
|
int setup;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** "reboot" option list */
|
/** "reboot" option list */
|
||||||
static struct option_descriptor reboot_opts[] = {
|
static struct option_descriptor reboot_opts[] = {
|
||||||
OPTION_DESC ( "warm", 'w', no_argument,
|
OPTION_DESC ( "warm", 'w', no_argument,
|
||||||
struct reboot_options, warm, parse_flag ),
|
struct reboot_options, warm, parse_flag ),
|
||||||
|
OPTION_DESC ( "setup", 's', no_argument,
|
||||||
|
struct reboot_options, setup, parse_flag ),
|
||||||
};
|
};
|
||||||
|
|
||||||
/** "reboot" command descriptor */
|
/** "reboot" command descriptor */
|
||||||
@@ -69,6 +73,8 @@ static int reboot_exec ( int argc, char **argv ) {
|
|||||||
/* Reboot system */
|
/* Reboot system */
|
||||||
if ( opts.warm )
|
if ( opts.warm )
|
||||||
flags |= REBOOT_WARM;
|
flags |= REBOOT_WARM;
|
||||||
|
if ( opts.setup )
|
||||||
|
flags |= REBOOT_SETUP;
|
||||||
reboot ( flags );
|
reboot ( flags );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
void reboot ( int flags );
|
void reboot ( int flags );
|
||||||
|
|
||||||
#define REBOOT_WARM 0x00000001 /**< Perform a warm reboot */
|
#define REBOOT_WARM 0x00000001 /**< Perform a warm reboot */
|
||||||
|
#define REBOOT_SETUP 0x00000002 /**< Reboot to firmware setup */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Power off system
|
* Power off system
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
#include <ipxe/efi/efi.h>
|
#include <ipxe/efi/efi.h>
|
||||||
|
#include <ipxe/efi/Guid/GlobalVariable.h>
|
||||||
#include <ipxe/reboot.h>
|
#include <ipxe/reboot.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +43,28 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
*/
|
*/
|
||||||
static void efi_reboot ( int flags ) {
|
static void efi_reboot ( int flags ) {
|
||||||
EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
|
EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
|
||||||
|
static CHAR16 wname[] = EFI_OS_INDICATIONS_VARIABLE_NAME;
|
||||||
|
UINT64 osind;
|
||||||
|
UINT32 attrs;
|
||||||
EFI_RESET_TYPE type;
|
EFI_RESET_TYPE type;
|
||||||
|
EFI_STATUS efirc;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Request boot to firmware setup, if applicable */
|
||||||
|
if ( flags & REBOOT_SETUP ) {
|
||||||
|
osind = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
|
||||||
|
attrs = ( EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_RUNTIME_ACCESS |
|
||||||
|
EFI_VARIABLE_NON_VOLATILE );
|
||||||
|
if ( ( efirc = rs->SetVariable ( wname, &efi_global_variable,
|
||||||
|
attrs, sizeof ( osind ),
|
||||||
|
&osind ) ) != 0 ) {
|
||||||
|
rc = -EEFI ( efirc );
|
||||||
|
DBGC ( efi_systab, "EFI could not set %ls: %s\n",
|
||||||
|
wname, strerror ( rc ) );
|
||||||
|
/* Continue to reboot anyway */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Use runtime services to reset system */
|
/* Use runtime services to reset system */
|
||||||
type = ( ( flags & REBOOT_WARM ) ? EfiResetWarm : EfiResetCold );
|
type = ( ( flags & REBOOT_WARM ) ? EfiResetWarm : EfiResetCold );
|
||||||
|
|||||||
Reference in New Issue
Block a user