Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <[email protected]>
Cc: Eric Dong <[email protected]>
---
MdeModulePkg/Include/Library/UefiBootManagerLib.h | 1 +
.../Library/UefiBootManagerLib/BmLoadOption.c | 130 ++++++++++++++++++---
.../Library/UefiBootManagerLib/InternalBm.h | 3 +-
.../UefiBootManagerLib/UefiBootManagerLib.inf | 1 +
4 files changed, 118 insertions(+), 17 deletions(-)
diff --git a/MdeModulePkg/Include/Library/UefiBootManagerLib.h
b/MdeModulePkg/Include/Library/UefiBootManagerLib.h
index 5538d90..1b04a8c 100644
--- a/MdeModulePkg/Include/Library/UefiBootManagerLib.h
+++ b/MdeModulePkg/Include/Library/UefiBootManagerLib.h
@@ -30,6 +30,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 fbd7830..454fe20 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
@@ -18,14 +18,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
};
/**
@@ -153,8 +155,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.
@@ -166,12 +169,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) ||
@@ -232,6 +237,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,
@@ -548,6 +564,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;
@@ -579,6 +596,19 @@ EfiBootManagerDeleteLoadOptionVariable (
if (OptionOrder != NULL) {
FreePool (OptionOrder);
}
+ } else {
+ ASSERT (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;
@@ -675,7 +705,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.
@@ -918,6 +949,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.
@@ -937,16 +1024,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) {
//
@@ -987,8 +1076,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;
@@ -1116,7 +1213,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 7f52b13..3fc9cc7 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
+++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
@@ -41,6 +41,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED.
#include <Protocol/BootLogo.h>
#include <Protocol/DriverHealth.h>
#include <Protocol/FormBrowser2.h>
+#include <Protocol/VariableLock.h>
#include <Guid/ZeroGuid.h>
#include <Guid/MemoryTypeInformation.h>
@@ -101,7 +102,7 @@ CHAR16 *
IN EFI_HANDLE Handle
);
-#define BM_OPTION_NAME_LEN sizeof ("SysPrep####")
+#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 a2c6441..f1f6246 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
--
1.9.5.msysgit.1
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel