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
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
if (OptionOrder != NULL) {\r
FreePool (OptionOrder);\r
}\r
+ } else if (OptionType == LoadOptionTypePlatformRecovery) {\r
+ //\r
+ // PlatformRecovery#### doesn't have assiciated PlatformRecoveryOrder, remove the PlatformRecovery#### itself.\r
+ //\r
+ UnicodeSPrint (OptionName, sizeof (OptionName), L"%s%04x", mBmLoadOptionName[OptionType], OptionNumber);\r
+ Status = gRT->SetVariable (\r
+ OptionName,\r
+ &gEfiGlobalVariableGuid,\r
+ 0,\r
+ 0,\r
+ NULL\r
+ );\r
}\r
\r
return Status;\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