diff options
author | Michael Brown | 2011-03-29 22:35:06 +0200 |
---|---|---|
committer | Michael Brown | 2011-03-29 23:08:05 +0200 |
commit | fc7239bdc8384d02a190723ef4e030d6ef2620a9 (patch) | |
tree | 83a0360ea913f062f7053d4853b228f789519552 /src/interface/efi/efi_init.c | |
parent | [forcedeth] Remove software unicast MAC address filter (diff) | |
download | ipxe-fc7239bdc8384d02a190723ef4e030d6ef2620a9.tar.gz ipxe-fc7239bdc8384d02a190723ef4e030d6ef2620a9.tar.xz ipxe-fc7239bdc8384d02a190723ef4e030d6ef2620a9.zip |
[efi] Ensure that all drivers are shut down before the OS boots
Reported-by: Itay Gazit <itayg@mellanox.co.il>
Suggested-by: Michael R Turner <mikeyt@us.ibm.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface/efi/efi_init.c')
-rw-r--r-- | src/interface/efi/efi_init.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/interface/efi/efi_init.c b/src/interface/efi/efi_init.c index 029bc06f..6c7b4955 100644 --- a/src/interface/efi/efi_init.c +++ b/src/interface/efi/efi_init.c @@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/efi/efi.h> #include <ipxe/efi/Protocol/LoadedImage.h> #include <ipxe/uuid.h> +#include <ipxe/init.h> /** Image handle passed to entry point */ EFI_HANDLE efi_image_handle; @@ -36,6 +37,21 @@ EFI_SYSTEM_TABLE *efi_systab; static EFI_GUID efi_loaded_image_protocol_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID; +/** Event used to signal shutdown */ +static EFI_EVENT efi_shutdown_event; + +/** + * Shut down in preparation for booting an OS. + * + * This hook gets called at ExitBootServices time in order to make + * sure that everything is properly shut down before the OS takes + * over. + */ +static EFIAPI void efi_shutdown_hook ( EFI_EVENT event __unused, + void *context __unused ) { + shutdown_boot(); +} + /** * Look up EFI configuration table * @@ -129,5 +145,18 @@ EFI_STATUS efi_init ( EFI_HANDLE image_handle, } } + /* EFI is perfectly capable of gracefully shutting down any + * loaded devices if it decides to fall back to a legacy boot. + * For no particularly comprehensible reason, it doesn't + * bother doing so when ExitBootServices() is called. + */ + if ( ( efirc = bs->CreateEvent ( EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_CALLBACK, efi_shutdown_hook, + NULL, &efi_shutdown_event ) ) != 0 ) { + DBGC ( systab, "EFI could not create ExitBootServices event: " + "%s\n", efi_strerror ( efirc ) ); + return efirc; + } + return 0; } |