/** @file\r
Load option library functions which relate with creating and processing load options.\r
\r
-Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
CHAR16 *mBmLoadOptionName[] = {\r
L"Driver",\r
L"SysPrep",\r
- L"Boot"\r
+ L"Boot",\r
+ L"PlatformRecovery"\r
};\r
\r
GLOBAL_REMOVE_IF_UNREFERENCED\r
CHAR16 *mBmLoadOptionOrderName[] = {\r
EFI_DRIVER_ORDER_VARIABLE_NAME,\r
EFI_SYS_PREP_ORDER_VARIABLE_NAME,\r
- EFI_BOOT_ORDER_VARIABLE_NAME\r
+ EFI_BOOT_ORDER_VARIABLE_NAME,\r
+ NULL // PlatformRecovery#### doesn't have associated *Order variable\r
};\r
\r
/**\r
}\r
\r
/**\r
- Create the Boot####, Driver####, SysPrep####, variable from the load option.\r
- \r
+ Create the Boot####, Driver####, SysPrep####, PlatformRecovery#### variable\r
+ from the load option.\r
+\r
@param LoadOption Pointer to the load option.\r
\r
@retval EFI_SUCCESS The variable was created.\r
IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Option\r
)\r
{\r
+ EFI_STATUS Status;\r
UINTN VariableSize;\r
UINT8 *Variable;\r
UINT8 *Ptr;\r
CHAR16 OptionName[BM_OPTION_NAME_LEN];\r
CHAR16 *Description;\r
CHAR16 NullChar;\r
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;\r
UINT32 VariableAttributes;\r
\r
if ((Option->OptionNumber == LoadOptionNumberUnassigned) ||\r
UnicodeSPrint (OptionName, sizeof (OptionName), L"%s%04x", mBmLoadOptionName[Option->OptionType], Option->OptionNumber);\r
\r
VariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
+ if (Option->OptionType == LoadOptionTypePlatformRecovery) {\r
+ //\r
+ // Lock the PlatformRecovery####\r
+ //\r
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = VariableLock->RequestToLock (VariableLock, OptionName, &gEfiGlobalVariableGuid);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ VariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
+ }\r
\r
return gRT->SetVariable (\r
OptionName,\r
{\r
UINT16 *OptionOrder;\r
UINTN OptionOrderSize;\r
- EFI_STATUS Status;\r
UINTN Index;\r
+ CHAR16 OptionName[BM_OPTION_NAME_LEN];\r
\r
if (((UINT32) OptionType >= LoadOptionTypeMax) || (OptionNumber >= LoadOptionNumberMax)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Status = EFI_NOT_FOUND;\r
-\r
if (OptionType == LoadOptionTypeDriver || OptionType == LoadOptionTypeSysPrep || OptionType == LoadOptionTypeBoot) {\r
//\r
- // If the associated *Order exists, just remove the reference in *Order.\r
+ // If the associated *Order exists, firstly remove the reference in *Order for\r
+ // Driver####, SysPrep#### and Boot####.\r
//\r
GetEfiGlobalVariable2 (mBmLoadOptionOrderName[OptionType], (VOID **) &OptionOrder, &OptionOrderSize);\r
ASSERT ((OptionOrder != NULL && OptionOrderSize != 0) || (OptionOrder == NULL && OptionOrderSize == 0));\r
if (OptionOrder[Index] == OptionNumber) {\r
OptionOrderSize -= sizeof (UINT16);\r
CopyMem (&OptionOrder[Index], &OptionOrder[Index + 1], OptionOrderSize - Index * sizeof (UINT16));\r
- Status = gRT->SetVariable (\r
- mBmLoadOptionOrderName[OptionType],\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- OptionOrderSize,\r
- OptionOrder\r
- );\r
+ gRT->SetVariable (\r
+ mBmLoadOptionOrderName[OptionType],\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ OptionOrderSize,\r
+ OptionOrder\r
+ );\r
break;\r
}\r
}\r
}\r
}\r
\r
- return Status;\r
-}\r
-\r
-/**\r
- Convert a single character to number.\r
- It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'\r
-\r
- @param Char The input char which need to convert to int.\r
-**/\r
-UINTN\r
-BmCharToUint (\r
- IN CHAR16 Char\r
- )\r
-{\r
- if ((Char >= L'0') && (Char <= L'9')) {\r
- return (UINTN) (Char - L'0');\r
- }\r
-\r
- if ((Char >= L'A') && (Char <= L'F')) {\r
- return (UINTN) (Char - L'A' + 0xA);\r
- }\r
-\r
- ASSERT (FALSE);\r
- return (UINTN) -1;\r
+ //\r
+ // Remove the Driver####, SysPrep####, Boot#### or PlatformRecovery#### itself.\r
+ //\r
+ UnicodeSPrint (OptionName, sizeof (OptionName), L"%s%04x", mBmLoadOptionName[OptionType], OptionNumber);\r
+ return gRT->SetVariable (\r
+ OptionName,\r
+ &gEfiGlobalVariableGuid,\r
+ 0,\r
+ 0,\r
+ NULL\r
+ );\r
}\r
\r
/**\r
}\r
\r
/**\r
- Validate the Boot####, Driver####, SysPrep#### variable (VendorGuid/Name)\r
+ Validate the Boot####, Driver####, SysPrep#### and PlatformRecovery####\r
+ variable (VendorGuid/Name)\r
\r
@param Variable The variable data.\r
@param VariableSize The variable size.\r
return EfiBootManagerVariableToLoadOptionEx (VariableName, &gEfiGlobalVariableGuid, Option);\r
}\r
\r
+typedef struct {\r
+ EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType;\r
+ EFI_GUID *Guid;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION *Options;\r
+ UINTN OptionCount;\r
+} BM_COLLECT_LOAD_OPTIONS_PARAM;\r
+\r
+/**\r
+ Visitor function to collect the Platform Recovery load options or OS Recovery\r
+ load options from NV storage.\r
+\r
+ @param Name Variable name.\r
+ @param Guid Variable GUID.\r
+ @param Context The same context passed to BmForEachVariable.\r
+**/\r
+VOID\r
+BmCollectLoadOptions (\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *Guid,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType;\r
+ UINT16 OptionNumber;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION Option;\r
+ UINTN Index;\r
+ BM_COLLECT_LOAD_OPTIONS_PARAM *Param;\r
+\r
+ Param = (BM_COLLECT_LOAD_OPTIONS_PARAM *) Context;\r
+\r
+ if (CompareGuid (Guid, Param->Guid) && (\r
+ Param->OptionType == LoadOptionTypePlatformRecovery &&\r
+ BmIsValidLoadOptionVariableName (Name, &OptionType, &OptionNumber) &&\r
+ OptionType == LoadOptionTypePlatformRecovery\r
+ )) {\r
+ Status = EfiBootManagerVariableToLoadOptionEx (Name, Guid, &Option);\r
+ if (!EFI_ERROR (Status)) {\r
+ for (Index = 0; Index < Param->OptionCount; Index++) {\r
+ if (Param->Options[Index].OptionNumber > Option.OptionNumber) {\r
+ break;\r
+ }\r
+ }\r
+ Param->Options = ReallocatePool (\r
+ Param->OptionCount * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION),\r
+ (Param->OptionCount + 1) * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION),\r
+ Param->Options\r
+ );\r
+ ASSERT (Param->Options != NULL);\r
+ CopyMem (&Param->Options[Index + 1], &Param->Options[Index], (Param->OptionCount - Index) * sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));\r
+ CopyMem (&Param->Options[Index], &Option, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));\r
+ Param->OptionCount++;\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Returns an array of load options based on the EFI variable\r
L"BootOrder"/L"DriverOrder" and the L"Boot####"/L"Driver####" variables impled by it.\r
IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT16 *OptionOrder;\r
- UINTN OptionOrderSize;\r
- UINTN Index;\r
- UINTN OptionIndex;\r
- EFI_BOOT_MANAGER_LOAD_OPTION *Options;\r
- CHAR16 OptionName[BM_OPTION_NAME_LEN];\r
- UINT16 OptionNumber;\r
+ EFI_STATUS Status;\r
+ UINT16 *OptionOrder;\r
+ UINTN OptionOrderSize;\r
+ UINTN Index;\r
+ UINTN OptionIndex;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION *Options;\r
+ CHAR16 OptionName[BM_OPTION_NAME_LEN];\r
+ UINT16 OptionNumber;\r
+ BM_COLLECT_LOAD_OPTIONS_PARAM Param;\r
\r
*OptionCount = 0;\r
+ Options = NULL;\r
\r
if (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep || LoadOptionType == LoadOptionTypeBoot) {\r
//\r
*OptionCount = OptionIndex;\r
}\r
\r
- } else {\r
- return NULL;\r
+ } else if (LoadOptionType == LoadOptionTypePlatformRecovery) {\r
+ Param.OptionType = LoadOptionTypePlatformRecovery;\r
+ Param.Options = NULL;\r
+ Param.OptionCount = 0;\r
+ Param.Guid = &gEfiGlobalVariableGuid;\r
+\r
+ BmForEachVariable (BmCollectLoadOptions, (VOID *) &Param);\r
+\r
+ *OptionCount = Param.OptionCount;\r
+ Options = Param.Options;\r
}\r
\r
return Options;\r
if ((Type == LoadOptionTypeDriver && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
(Type == LoadOptionTypeDriver && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ||\r
(Type == LoadOptionTypeSysPrep && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) ||\r
- (Type == LoadOptionTypeBoot && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)\r
+ (Type == LoadOptionTypeBoot && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) ||\r
+ (Type == LoadOptionTypePlatformRecovery && Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)\r
) {\r
return TRUE;\r
}\r