From: Ruiyu Ni Date: Tue, 17 Nov 2015 10:11:44 +0000 (+0000) Subject: MdeModulePkg: Add Platform recovery support X-Git-Tag: edk2-stable201903~8574 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=780e05caecb89bb1be8a4deefb6392384e46594d MdeModulePkg: Add Platform recovery support Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Reviewed-by: Sunny Wang git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18859 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Include/Library/UefiBootManagerLib.h b/MdeModulePkg/Include/Library/UefiBootManagerLib.h index 54a67130f3..afb4271e3d 100644 --- a/MdeModulePkg/Include/Library/UefiBootManagerLib.h +++ b/MdeModulePkg/Include/Library/UefiBootManagerLib.h @@ -31,6 +31,7 @@ typedef enum { LoadOptionTypeDriver, LoadOptionTypeSysPrep, LoadOptionTypeBoot, + LoadOptionTypePlatformRecovery, LoadOptionTypeMax } EFI_BOOT_MANAGER_LOAD_OPTION_TYPE; diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c index 6fcd23b6ab..999647cfac 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c @@ -19,14 +19,16 @@ GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mBmLoadOptionName[] = { L"Driver", L"SysPrep", - L"Boot" + L"Boot", + L"PlatformRecovery" }; GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mBmLoadOptionOrderName[] = { EFI_DRIVER_ORDER_VARIABLE_NAME, EFI_SYS_PREP_ORDER_VARIABLE_NAME, - EFI_BOOT_ORDER_VARIABLE_NAME + EFI_BOOT_ORDER_VARIABLE_NAME, + NULL // PlatformRecovery#### doesn't have associated *Order variable }; /** @@ -154,8 +156,9 @@ BmGetFreeOptionNumber ( } /** - Create the Boot####, Driver####, SysPrep####, variable from the load option. - + Create the Boot####, Driver####, SysPrep####, PlatformRecovery#### variable + from the load option. + @param LoadOption Pointer to the load option. @retval EFI_SUCCESS The variable was created. @@ -167,12 +170,14 @@ EfiBootManagerLoadOptionToVariable ( IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Option ) { + EFI_STATUS Status; UINTN VariableSize; UINT8 *Variable; UINT8 *Ptr; CHAR16 OptionName[BM_OPTION_NAME_LEN]; CHAR16 *Description; CHAR16 NullChar; + EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; UINT32 VariableAttributes; if ((Option->OptionNumber == LoadOptionNumberUnassigned) || @@ -233,6 +238,17 @@ structure. UnicodeSPrint (OptionName, sizeof (OptionName), L"%s%04x", mBmLoadOptionName[Option->OptionType], Option->OptionNumber); VariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE; + if (Option->OptionType == LoadOptionTypePlatformRecovery) { + // + // Lock the PlatformRecovery#### + // + Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock); + if (!EFI_ERROR (Status)) { + Status = VariableLock->RequestToLock (VariableLock, OptionName, &gEfiGlobalVariableGuid); + ASSERT_EFI_ERROR (Status); + } + VariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; + } return gRT->SetVariable ( OptionName, @@ -550,6 +566,7 @@ EfiBootManagerDeleteLoadOptionVariable ( UINTN OptionOrderSize; EFI_STATUS Status; UINTN Index; + CHAR16 OptionName[BM_OPTION_NAME_LEN]; if (((UINT32) OptionType >= LoadOptionTypeMax) || (OptionNumber >= LoadOptionNumberMax)) { return EFI_INVALID_PARAMETER; @@ -581,6 +598,18 @@ EfiBootManagerDeleteLoadOptionVariable ( if (OptionOrder != NULL) { FreePool (OptionOrder); } + } else if (OptionType == LoadOptionTypePlatformRecovery) { + // + // PlatformRecovery#### doesn't have assiciated PlatformRecoveryOrder, remove the PlatformRecovery#### itself. + // + UnicodeSPrint (OptionName, sizeof (OptionName), L"%s%04x", mBmLoadOptionName[OptionType], OptionNumber); + Status = gRT->SetVariable ( + OptionName, + &gEfiGlobalVariableGuid, + 0, + 0, + NULL + ); } return Status; @@ -677,7 +706,8 @@ BmStrSizeEx ( } /** - Validate the Boot####, Driver####, SysPrep#### variable (VendorGuid/Name) + Validate the Boot####, Driver####, SysPrep#### and PlatformRecovery#### + variable (VendorGuid/Name) @param Variable The variable data. @param VariableSize The variable size. @@ -920,6 +950,62 @@ EfiBootManagerVariableToLoadOption ( return EfiBootManagerVariableToLoadOptionEx (VariableName, &gEfiGlobalVariableGuid, Option); } +typedef struct { + EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType; + EFI_GUID *Guid; + EFI_BOOT_MANAGER_LOAD_OPTION *Options; + UINTN OptionCount; +} BM_COLLECT_LOAD_OPTIONS_PARAM; + +/** + Visitor function to collect the Platform Recovery load options or OS Recovery + load options from NV storage. + + @param Name Variable name. + @param Guid Variable GUID. + @param Context The same context passed to BmForEachVariable. +**/ +VOID +BmCollectLoadOptions ( + IN CHAR16 *Name, + IN EFI_GUID *Guid, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType; + UINT16 OptionNumber; + EFI_BOOT_MANAGER_LOAD_OPTION Option; + UINTN Index; + BM_COLLECT_LOAD_OPTIONS_PARAM *Param; + + Param = (BM_COLLECT_LOAD_OPTIONS_PARAM *) Context; + + if (CompareGuid (Guid, Param->Guid) && ( + Param->OptionType == LoadOptionTypePlatformRecovery && + BmIsValidLoadOptionVariableName (Name, &OptionType, &OptionNumber) && + OptionType == LoadOptionTypePlatformRecovery + )) { + Status = EfiBootManagerVariableToLoadOptionEx (Name, Guid, &Option); + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < Param->OptionCount; Index++) { + if (Param->Options[Index].OptionNumber > Option.OptionNumber) { + break; + } + } + Param->Options = ReallocatePool ( + Param->OptionCount * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION), + (Param->OptionCount + 1) * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION), + Param->Options + ); + ASSERT (Param->Options != NULL); + CopyMem (&Param->Options[Index + 1], &Param->Options[Index], (Param->OptionCount - Index) * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION)); + CopyMem (&Param->Options[Index], &Option, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION)); + Param->OptionCount++; + } + } +} + /** Returns an array of load options based on the EFI variable L"BootOrder"/L"DriverOrder" and the L"Boot####"/L"Driver####" variables impled by it. @@ -939,16 +1025,18 @@ EfiBootManagerGetLoadOptions ( IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType ) { - EFI_STATUS Status; - UINT16 *OptionOrder; - UINTN OptionOrderSize; - UINTN Index; - UINTN OptionIndex; - EFI_BOOT_MANAGER_LOAD_OPTION *Options; - CHAR16 OptionName[BM_OPTION_NAME_LEN]; - UINT16 OptionNumber; + EFI_STATUS Status; + UINT16 *OptionOrder; + UINTN OptionOrderSize; + UINTN Index; + UINTN OptionIndex; + EFI_BOOT_MANAGER_LOAD_OPTION *Options; + CHAR16 OptionName[BM_OPTION_NAME_LEN]; + UINT16 OptionNumber; + BM_COLLECT_LOAD_OPTIONS_PARAM Param; *OptionCount = 0; + Options = NULL; if (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep || LoadOptionType == LoadOptionTypeBoot) { // @@ -989,8 +1077,16 @@ EfiBootManagerGetLoadOptions ( *OptionCount = OptionIndex; } - } else { - return NULL; + } else if (LoadOptionType == LoadOptionTypePlatformRecovery) { + Param.OptionType = LoadOptionTypePlatformRecovery; + Param.Options = NULL; + Param.OptionCount = 0; + Param.Guid = &gEfiGlobalVariableGuid; + + BmForEachVariable (BmCollectLoadOptions, (VOID *) &Param); + + *OptionCount = Param.OptionCount; + Options = Param.Options; } return Options; @@ -1118,7 +1214,8 @@ BmIsLoadOptionPeHeaderValid ( if ((Type == LoadOptionTypeDriver && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) || (Type == LoadOptionTypeDriver && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) || (Type == LoadOptionTypeSysPrep && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) || - (Type == LoadOptionTypeBoot && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) + (Type == LoadOptionTypeBoot && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) || + (Type == LoadOptionTypePlatformRecovery && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) ) { return TRUE; } diff --git a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h index 862811e7b5..6a888fa35e 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h +++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h @@ -42,6 +42,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include @@ -102,7 +103,10 @@ CHAR16 * IN EFI_HANDLE Handle ); -#define BM_OPTION_NAME_LEN sizeof ("SysPrep####") +// +// PlatformRecovery#### is the load option with the longest name +// +#define BM_OPTION_NAME_LEN sizeof ("PlatformRecovery####") extern CHAR16 *mBmLoadOptionName[]; /** diff --git a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf index a2c6441dbe..f1f6246b11 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf +++ b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf @@ -101,6 +101,7 @@ gEfiDevicePathProtocolGuid ## CONSUMES gEfiBootLogoProtocolGuid ## CONSUMES gEfiSimpleTextInputExProtocolGuid ## CONSUMES + gEdkiiVariableLockProtocolGuid ## CONSUMES gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES gEfiUsbIoProtocolGuid ## SOMETIMES_CONSUMES gEfiDiskInfoProtocolGuid ## SOMETIMES_CONSUMES