]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Add Platform recovery support
authorRuiyu Ni <ruiyu.ni@intel.com>
Tue, 17 Nov 2015 10:11:44 +0000 (10:11 +0000)
committerniruiyu <niruiyu@Edk2>
Tue, 17 Nov 2015 10:11:44 +0000 (10:11 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Sunny Wang <sunnywang@hpe.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18859 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Include/Library/UefiBootManagerLib.h
MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c
MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h
MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf

index 54a67130f315cfe261a182871284dc3da34346ee..afb4271e3d4d6dfefcdf6ea60ab2ccfb693a86de 100644 (file)
@@ -31,6 +31,7 @@ typedef enum {
   LoadOptionTypeDriver,\r
   LoadOptionTypeSysPrep,\r
   LoadOptionTypeBoot,\r
   LoadOptionTypeDriver,\r
   LoadOptionTypeSysPrep,\r
   LoadOptionTypeBoot,\r
+  LoadOptionTypePlatformRecovery,\r
   LoadOptionTypeMax\r
 } EFI_BOOT_MANAGER_LOAD_OPTION_TYPE;\r
 \r
   LoadOptionTypeMax\r
 } EFI_BOOT_MANAGER_LOAD_OPTION_TYPE;\r
 \r
index 6fcd23b6aba337adb26922a0b3f606ddf88eef08..999647cfac198eb141bc0a866f21551dd843c844 100644 (file)
@@ -19,14 +19,16 @@ GLOBAL_REMOVE_IF_UNREFERENCED
   CHAR16 *mBmLoadOptionName[] = {\r
     L"Driver",\r
     L"SysPrep",\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
   };\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
@@ -154,8 +156,9 @@ BmGetFreeOptionNumber (
 }\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
   @param  LoadOption      Pointer to the load option.\r
 \r
   @retval EFI_SUCCESS     The variable was created.\r
@@ -167,12 +170,14 @@ EfiBootManagerLoadOptionToVariable (
   IN CONST EFI_BOOT_MANAGER_LOAD_OPTION     *Option\r
   )\r
 {\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
   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
   UINT32                           VariableAttributes;\r
 \r
   if ((Option->OptionNumber == LoadOptionNumberUnassigned) ||\r
@@ -233,6 +238,17 @@ structure.
   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
   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
   return gRT->SetVariable (\r
                 OptionName,\r
@@ -550,6 +566,7 @@ EfiBootManagerDeleteLoadOptionVariable (
   UINTN                             OptionOrderSize;\r
   EFI_STATUS                        Status;\r
   UINTN                             Index;\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
   if (((UINT32) OptionType >= LoadOptionTypeMax) || (OptionNumber >= LoadOptionNumberMax)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -581,6 +598,18 @@ EfiBootManagerDeleteLoadOptionVariable (
     if (OptionOrder != NULL) {\r
       FreePool (OptionOrder);\r
     }\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
   return Status;\r
@@ -677,7 +706,8 @@ BmStrSizeEx (
 }\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
 \r
   @param  Variable              The variable data.\r
   @param  VariableSize          The variable size.\r
@@ -920,6 +950,62 @@ EfiBootManagerVariableToLoadOption (
   return EfiBootManagerVariableToLoadOptionEx (VariableName, &gEfiGlobalVariableGuid, Option);\r
 }\r
 \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
 /**\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
@@ -939,16 +1025,18 @@ EfiBootManagerGetLoadOptions (
   IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE  LoadOptionType\r
   )\r
 {\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
 \r
   *OptionCount = 0;\r
+  Options      = NULL;\r
 \r
   if (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep || LoadOptionType == LoadOptionTypeBoot) {\r
     //\r
 \r
   if (LoadOptionType == LoadOptionTypeDriver || LoadOptionType == LoadOptionTypeSysPrep || LoadOptionType == LoadOptionTypeBoot) {\r
     //\r
@@ -989,8 +1077,16 @@ EfiBootManagerGetLoadOptions (
       *OptionCount = OptionIndex;\r
     }\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
   }\r
 \r
   return Options;\r
@@ -1118,7 +1214,8 @@ BmIsLoadOptionPeHeaderValid (
         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
         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
             ) {\r
           return TRUE;\r
         }\r
index 862811e7b5c132ba254c8678960aa4fd75794838..6a888fa35e14c6f33c15d8bb9197ca624d8a6701 100644 (file)
@@ -42,6 +42,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/BootLogo.h>\r
 #include <Protocol/DriverHealth.h>\r
 #include <Protocol/FormBrowser2.h>\r
 #include <Protocol/BootLogo.h>\r
 #include <Protocol/DriverHealth.h>\r
 #include <Protocol/FormBrowser2.h>\r
+#include <Protocol/VariableLock.h>\r
 \r
 #include <Guid/ZeroGuid.h>\r
 #include <Guid/MemoryTypeInformation.h>\r
 \r
 #include <Guid/ZeroGuid.h>\r
 #include <Guid/MemoryTypeInformation.h>\r
@@ -102,7 +103,10 @@ CHAR16 *
   IN EFI_HANDLE          Handle\r
   );\r
 \r
   IN EFI_HANDLE          Handle\r
   );\r
 \r
-#define BM_OPTION_NAME_LEN                          sizeof ("SysPrep####")\r
+//\r
+// PlatformRecovery#### is the load option with the longest name\r
+//\r
+#define BM_OPTION_NAME_LEN                          sizeof ("PlatformRecovery####")\r
 extern CHAR16  *mBmLoadOptionName[];\r
 \r
 /**\r
 extern CHAR16  *mBmLoadOptionName[];\r
 \r
 /**\r
index a2c6441dbea1f758546fbe1feb339f7eb7094835..f1f6246b110779ca7dbdfc840f71447fab17f26b 100644 (file)
   gEfiDevicePathProtocolGuid                    ## CONSUMES\r
   gEfiBootLogoProtocolGuid                      ## CONSUMES\r
   gEfiSimpleTextInputExProtocolGuid             ## CONSUMES\r
   gEfiDevicePathProtocolGuid                    ## CONSUMES\r
   gEfiBootLogoProtocolGuid                      ## CONSUMES\r
   gEfiSimpleTextInputExProtocolGuid             ## CONSUMES\r
+  gEdkiiVariableLockProtocolGuid                ## CONSUMES\r
   gEfiGraphicsOutputProtocolGuid                ## SOMETIMES_CONSUMES\r
   gEfiUsbIoProtocolGuid                         ## SOMETIMES_CONSUMES\r
   gEfiDiskInfoProtocolGuid                      ## SOMETIMES_CONSUMES\r
   gEfiGraphicsOutputProtocolGuid                ## SOMETIMES_CONSUMES\r
   gEfiUsbIoProtocolGuid                         ## SOMETIMES_CONSUMES\r
   gEfiDiskInfoProtocolGuid                      ## SOMETIMES_CONSUMES\r