]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
OvmfPkg/PlatformBootManagerLib: eliminate unchecked PcdSetXX() calls
[mirror_edk2.git] / OvmfPkg / Library / PlatformBootManagerLib / BdsPlatform.c
index 912c5ed1ece40f39f27eec8a796d315e54fda540..29ce21282595acc8e38a82f6f12fc75661e437cc 100644 (file)
@@ -15,6 +15,7 @@
 #include "BdsPlatform.h"\r
 #include <Guid/XenInfo.h>\r
 #include <Guid/RootBridgesConnectedEventGroup.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
 \r
 \r
 //\r
@@ -149,6 +150,134 @@ PlatformRegisterFvBootOption (
   EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
 }\r
 \r
+/**\r
+  Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options\r
+  whose device paths do not resolve exactly to an FvFile in the system.\r
+\r
+  This removes any boot options that point to binaries built into the firmware\r
+  and have become stale due to any of the following:\r
+  - DXEFV's base address or size changed (historical),\r
+  - DXEFV's FvNameGuid changed,\r
+  - the FILE_GUID of the pointed-to binary changed,\r
+  - the referenced binary is no longer built into the firmware.\r
+\r
+  EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only\r
+  avoids exact duplicates.\r
+**/\r
+VOID\r
+RemoveStaleFvFileOptions (\r
+  VOID\r
+  )\r
+{\r
+  EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
+  UINTN                        BootOptionCount;\r
+  UINTN                        Index;\r
+\r
+  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,\r
+                  LoadOptionTypeBoot);\r
+\r
+  for (Index = 0; Index < BootOptionCount; ++Index) {\r
+    EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;\r
+    EFI_STATUS               Status;\r
+    EFI_HANDLE               FvHandle;\r
+\r
+    //\r
+    // If the device path starts with neither MemoryMapped(...) nor Fv(...),\r
+    // then keep the boot option.\r
+    //\r
+    Node1 = BootOptions[Index].FilePath;\r
+    if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&\r
+          DevicePathSubType (Node1) == HW_MEMMAP_DP) &&\r
+        !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&\r
+          DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // If the second device path node is not FvFile(...), then keep the boot\r
+    // option.\r
+    //\r
+    Node2 = NextDevicePathNode (Node1);\r
+    if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||\r
+        DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Locate the Firmware Volume2 protocol instance that is denoted by the\r
+    // boot option. If this lookup fails (i.e., the boot option references a\r
+    // firmware volume that doesn't exist), then we'll proceed to delete the\r
+    // boot option.\r
+    //\r
+    SearchNode = Node1;\r
+    Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,\r
+                    &SearchNode, &FvHandle);\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // The firmware volume was found; now let's see if it contains the FvFile\r
+      // identified by GUID.\r
+      //\r
+      EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol;\r
+      MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;\r
+      UINTN                             BufferSize;\r
+      EFI_FV_FILETYPE                   FoundType;\r
+      EFI_FV_FILE_ATTRIBUTES            FileAttributes;\r
+      UINT32                            AuthenticationStatus;\r
+\r
+      Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid,\r
+                      (VOID **)&FvProtocol);\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;\r
+      //\r
+      // Buffer==NULL means we request metadata only: BufferSize, FoundType,\r
+      // FileAttributes.\r
+      //\r
+      Status = FvProtocol->ReadFile (\r
+                             FvProtocol,\r
+                             &FvFileNode->FvFileName, // NameGuid\r
+                             NULL,                    // Buffer\r
+                             &BufferSize,\r
+                             &FoundType,\r
+                             &FileAttributes,\r
+                             &AuthenticationStatus\r
+                             );\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // The FvFile was found. Keep the boot option.\r
+        //\r
+        continue;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Delete the boot option.\r
+    //\r
+    Status = EfiBootManagerDeleteLoadOptionVariable (\r
+               BootOptions[Index].OptionNumber, LoadOptionTypeBoot);\r
+    DEBUG_CODE (\r
+      CHAR16 *DevicePathString;\r
+\r
+      DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,\r
+                           FALSE, FALSE);\r
+      DEBUG ((\r
+        EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE,\r
+        "%a: removing stale Boot#%04x %s: %r\n",\r
+        __FUNCTION__,\r
+        (UINT32)BootOptions[Index].OptionNumber,\r
+        DevicePathString == NULL ? L"<unavailable>" : DevicePathString,\r
+        Status\r
+        ));\r
+      if (DevicePathString != NULL) {\r
+        FreePool (DevicePathString);\r
+      }\r
+      );\r
+  }\r
+\r
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
+}\r
+\r
 VOID\r
 PlatformRegisterOptionsAndKeys (\r
   VOID\r
@@ -213,7 +342,7 @@ PlatformBootManagerBeforeConsole (
 \r
 Routine Description:\r
 \r
-  Platform Bds init. Incude the platform firmware vendor, revision\r
+  Platform Bds init. Include the platform firmware vendor, revision\r
   and so crc check.\r
 \r
 Arguments:\r
@@ -224,8 +353,9 @@ Returns:
 \r
 --*/\r
 {\r
-  EFI_HANDLE Handle;\r
-  EFI_STATUS Status;\r
+  EFI_HANDLE    Handle;\r
+  EFI_STATUS    Status;\r
+  RETURN_STATUS PcdStatus;\r
 \r
   DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));\r
   InstallDevicePathCallback ();\r
@@ -265,7 +395,9 @@ Returns:
   ASSERT_EFI_ERROR (Status);\r
 \r
   PlatformInitializeConsole (gPlatformConsole);\r
-  PcdSet16 (PcdPlatformBootTimeOut, GetFrontPageTimeoutFromQemu ());\r
+  PcdStatus = PcdSet16S (PcdPlatformBootTimeOut,\r
+                GetFrontPageTimeoutFromQemu ());\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
   PlatformRegisterOptionsAndKeys ();\r
 }\r
@@ -437,7 +569,7 @@ GetGopDevicePath (
   }\r
 \r
   //\r
-  // Try to connect this handle, so that GOP dirver could start on this\r
+  // Try to connect this handle, so that GOP driver could start on this\r
   // device and create child handles with GraphicsOutput Protocol installed\r
   // on them, then we get device paths of these child handles and select\r
   // them as possible console device.\r
@@ -469,7 +601,7 @@ GetGopDevicePath (
         // In current implementation, we only enable one of the child handles\r
         // as console device, i.e. sotre one of the child handle's device\r
         // path to variable "ConOut"\r
-        // In futhure, we could select all child handles to be console device\r
+        // In future, we could select all child handles to be console device\r
         //\r
 \r
         *GopDevicePath = TempDevicePath;\r
@@ -489,7 +621,7 @@ GetGopDevicePath (
 }\r
 \r
 EFI_STATUS\r
-PreparePciVgaDevicePath (\r
+PreparePciDisplayDevicePath (\r
   IN EFI_HANDLE                DeviceHandle\r
   )\r
 /*++\r
@@ -739,14 +871,14 @@ DetectAndPreparePlatformPciDevicePath (
   }\r
 \r
   //\r
-  // Here we decide which VGA device to enable in PCI bus\r
+  // Here we decide which display device to enable in PCI bus\r
   //\r
-  if (IS_PCI_VGA (Pci)) {\r
+  if (IS_PCI_DISPLAY (Pci)) {\r
     //\r
     // Add them to ConOut.\r
     //\r
-    DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));\r
-    PreparePciVgaDevicePath (Handle);\r
+    DEBUG ((EFI_D_INFO, "Found PCI display device\n"));\r
+    PreparePciDisplayDevicePath (Handle);\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -786,7 +918,7 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  PlatformConsole         - Predfined platform default console device array.\r
+  PlatformConsole         - Predefined platform default console device array.\r
 --*/\r
 {\r
   UINTN                              Index;\r
@@ -807,7 +939,7 @@ Arguments:
 \r
     //\r
     // Have chance to connect the platform default console,\r
-    // the platform default console is the minimue device group\r
+    // the platform default console is the minimum device group\r
     // the platform should support\r
     //\r
     for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
@@ -1126,8 +1258,8 @@ ConnectRecursivelyIfPciMassStorage (
   This notification function is invoked when the\r
   EMU Variable FVB has been changed.\r
 \r
-  @param  Event                 The event that occured\r
-  @param  Context               For EFI compatiblity.  Not used.\r
+  @param  Event                 The event that occurred\r
+  @param  Context               For EFI compatibility.  Not used.\r
 \r
 **/\r
 VOID\r
@@ -1152,6 +1284,7 @@ VisitingFileSystemInstance (
 {\r
   EFI_STATUS      Status;\r
   STATIC BOOLEAN  ConnectedToFileSystem = FALSE;\r
+  RETURN_STATUS   PcdStatus;\r
 \r
   if (ConnectedToFileSystem) {\r
     return EFI_ALREADY_STARTED;\r
@@ -1171,7 +1304,9 @@ VisitingFileSystemInstance (
       NULL,\r
       &mEmuVariableEventReg\r
       );\r
-  PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);\r
+  PcdStatus = PcdSet64S (PcdEmuVariableEvent,\r
+                (UINT64)(UINTN) mEmuVariableEvent);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1198,7 +1333,7 @@ PlatformBdsConnectSequence (
 \r
 Routine Description:\r
 \r
-  Connect with predeined platform connect sequence,\r
+  Connect with predefined platform connect sequence,\r
   the OEM/IBV can customize with their own connect sequence.\r
 \r
 Arguments:\r
@@ -1280,7 +1415,7 @@ PlatformBootManagerAfterConsole (
 \r
 Routine Description:\r
 \r
-  The function will excute with as the platform policy, current policy\r
+  The function will execute with as the platform policy, current policy\r
   is driven by boot mode. IBV/OEM can customize this code for their specific\r
   policy action.\r
 \r
@@ -1316,13 +1451,7 @@ Routine Description:
   //\r
   // Logo show\r
   //\r
-  BootLogoEnableLogo (\r
-    ImageFormatBmp,                          // ImageFormat\r
-    PcdGetPtr (PcdLogoFile),                 // Logo\r
-    EdkiiPlatformLogoDisplayAttributeCenter, // Attribute\r
-    0,                                       // OffsetX\r
-    0                                        // OffsetY\r
-    );\r
+  BootLogoEnableLogo ();\r
 \r
   //\r
   // Perform some platform specific connect sequence\r
@@ -1343,6 +1472,7 @@ Routine Description:
     PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE\r
     );\r
 \r
+  RemoveStaleFvFileOptions ();\r
   SetBootOrderFromQemu ();\r
 }\r
 \r
@@ -1350,8 +1480,8 @@ Routine Description:
   This notification function is invoked when an instance of the\r
   EFI_DEVICE_PATH_PROTOCOL is produced.\r
 \r
-  @param  Event                 The event that occured\r
-  @param  Context               For EFI compatiblity.  Not used.\r
+  @param  Event                 The event that occurred\r
+  @param  Context               For EFI compatibility.  Not used.\r
 \r
 **/\r
 VOID\r