Fix BDS limitation of two "EFI DVD/CDROM" options appear after plug two CD-ROM.
authorgikidy <gikidy@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 11 Jun 2009 08:35:53 +0000 (08:35 +0000)
committergikidy <gikidy@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 11 Jun 2009 08:35:53 +0000 (08:35 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8530 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Include/Library/GenericBdsLib.h
IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h

index f7224f60c88a07e28a965cdf6344ee0d6091d8f3..c1cc82de2bba23b8597287c11cd24860db4614cc 100644 (file)
@@ -768,6 +768,26 @@ SetupResetReminder (
   VOID\r
   );\r
 \r
+\r
+//\r
+// Define the boot option default description \r
+// NOTE: This is not defined in UEFI spec.\r
+//\r
+#define DESCRIPTION_FLOPPY        L"EFI Floppy"\r
+#define DESCRIPTION_FLOPPY_NUM    L"EFI Floppy %d"\r
+#define DESCRIPTION_DVD           L"EFI DVD/CDROM"\r
+#define DESCRIPTION_DVD_NUM       L"EFI DVD/CDROM %d"\r
+#define DESCRIPTION_USB           L"EFI USB Device"\r
+#define DESCRIPTION_USB_NUM       L"EFI USB Device %d"\r
+#define DESCRIPTION_SCSI          L"EFI SCSI Device"\r
+#define DESCRIPTION_SCSI_NUM      L"EFI SCSI Device %d"\r
+#define DESCRIPTION_MISC          L"EFI Misc Device"\r
+#define DESCRIPTION_MISC_NUM      L"EFI Misc Device %d"\r
+#define DESCRIPTION_NETWORK       L"EFI Network"\r
+#define DESCRIPTION_NETWORK_NUM   L"EFI Network %d"       \r
+#define DESCRIPTION_NON_BLOCK     L"EFI Non-Block Boot Device"\r
+#define DESCRIPTION_NON_BLOCK_NUM L"EFI Non-Block Boot Device %d"\r
+\r
 //\r
 // Define the boot type which to classify the boot option type\r
 // Different boot option type could have different boot behavior\r
@@ -785,6 +805,7 @@ SetupResetReminder (
 #define  BDS_EFI_MESSAGE_ATAPI_BOOT       0x0301 // Type 03; Sub-Type 01\r
 #define  BDS_EFI_MESSAGE_SCSI_BOOT        0x0302 // Type 03; Sub-Type 02\r
 #define  BDS_EFI_MESSAGE_USB_DEVICE_BOOT  0x0305 // Type 03; Sub-Type 05\r
+#define  BDS_EFI_MESSAGE_SATA_BOOT        0x0318 // Type 03; Sub-Type 18\r
 #define  BDS_EFI_MESSAGE_MISC_BOOT        0x03FF\r
 //\r
 // Media boot type\r
@@ -881,7 +902,30 @@ BdsLibIsValidEFIBootOptDevicePath (
   IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,\r
   IN BOOLEAN                      CheckMedia\r
   );\r
-  \r
+\r
+/**\r
+  Check whether the Device path in a boot option point to a valid bootable device,\r
+  And if CheckMedia is true, check the device is ready to boot now.\r
+  If Description is not NULL and the device path point to a fixed BlockIo\r
+  device, check the description whether conflict with other auto-created\r
+  boot options.\r
+\r
+  @param  DevPath     the Device path in a boot option\r
+  @param  CheckMedia  if true, check the device is ready to boot now.\r
+  @param  Description the description in a boot option\r
+\r
+  @retval TRUE        the Device path  is valid\r
+  @retval FALSE       the Device path  is invalid .\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+BdsLibIsValidEFIBootOptDevicePathExt (\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,\r
+  IN BOOLEAN                      CheckMedia,\r
+  IN CHAR16                       *Description\r
+  );\r
+\r
 /**\r
   For a bootable Device path, return its boot type.\r
 \r
index 3a9530ec27ad366c9218e44579199f980c6eeb2c..b2c29424f26427ab1ba5bcd043a5de022d9dad55 100644 (file)
@@ -756,8 +756,7 @@ BdsLibDeleteOptionFromHandle (
 \r
 \r
 /**\r
-  Delete all invalid EFI boot options. The probable invalid boot option could\r
-  be Removable media or Network boot device.\r
+  Delete all invalid EFI boot options.\r
 \r
   @retval EFI_SUCCESS            Delete all invalid boot option success\r
   @retval EFI_NOT_FOUND          Variable "BootOrder" is not found\r
@@ -780,6 +779,7 @@ BdsDeleteAllInvalidEfiBootOption (
   UINT16                    BootOption[BOOT_OPTION_MAX_CHAR];\r
   EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;\r
   UINT8                     *TempPtr;\r
+  CHAR16                    *Description;\r
 \r
   Status        = EFI_SUCCESS;\r
   BootOrder     = NULL;\r
@@ -812,6 +812,7 @@ BdsDeleteAllInvalidEfiBootOption (
 \r
     TempPtr = BootOptionVar;\r
     TempPtr += sizeof (UINT32) + sizeof (UINT16);\r
+    Description = (CHAR16 *) TempPtr;\r
     TempPtr += StrSize ((CHAR16 *) TempPtr);\r
     OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;\r
 \r
@@ -825,7 +826,7 @@ BdsDeleteAllInvalidEfiBootOption (
       continue;\r
     }\r
 \r
-    if (!BdsLibIsValidEFIBootOptDevicePath (OptionDevicePath, FALSE)) {\r
+    if (!BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) {\r
       //\r
       // Delete this invalid boot option "Boot####"\r
       //\r
@@ -871,9 +872,41 @@ BdsDeleteAllInvalidEfiBootOption (
 \r
 \r
 /**\r
-  This function will enumerate all possible boot device in the system,\r
-  it will only execute once of every boot.\r
-\r
+  For EFI boot option, BDS separate them as six types:\r
+  1. Network - The boot option points to the SimpleNetworkProtocol device. \r
+               Bds will try to automatically create this type boot option when enumerate.\r
+  2. Shell   - The boot option points to internal flash shell. \r
+               Bds will try to automatically create this type boot option when enumerate.\r
+  3. Removable BlockIo      - The boot option only points to the removable media\r
+                              device, like USB flash disk, DVD, Floppy etc.\r
+                              These device should contain a *removable* blockIo\r
+                              protocol in their device handle.\r
+                              Bds will try to automatically create this type boot option \r
+                              when enumerate.\r
+  4. Fixed BlockIo          - The boot option only points to a Fixed blockIo device, \r
+                              like HardDisk.\r
+                              These device should contain a *fixed* blockIo\r
+                              protocol in their device handle.\r
+                              BDS will skip fixed blockIo devices, and NOT\r
+                              automatically create boot option for them. But BDS \r
+                              will help to delete those fixed blockIo boot option, \r
+                              whose description rule conflict with other auto-created\r
+                              boot options.\r
+  5. Non-BlockIo Simplefile - The boot option points to a device whose handle \r
+                              has SimpleFileSystem Protocol, but has no blockio\r
+                              protocol. These devices do not offer blockIo\r
+                              protocol, but BDS still can get the \r
+                              \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem\r
+                              Protocol.\r
+  6. File    - The boot option points to a file. These boot options are usually \r
+               created by user manually or OS loader. BDS will not delete or modify\r
+               these boot options.        \r
+    \r
+  This function will enumerate all possible boot device in the system, and\r
+  automatically create boot options for Network, Shell, Removable BlockIo, \r
+  and Non-BlockIo Simplefile devices.\r
+  It will only excute once of every boot.\r
+  \r
   @param  BdsBootOptionList      The header of the link list which indexed all\r
                                  current boot options\r
 \r
@@ -974,19 +1007,23 @@ BdsLibEnumerateAllBootOption (
     switch (DevicePathType) {\r
     case BDS_EFI_ACPI_FLOPPY_BOOT:\r
       if (FloppyNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Floppy");\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_FLOPPY);\r
       } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Floppy %d", FloppyNumber);\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_FLOPPY_NUM, FloppyNumber);\r
       }\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       FloppyNumber++;\r
       break;\r
-\r
+    \r
+    //\r
+    // Assume a removable SATA device should be the DVD/CD device\r
+    //\r
     case BDS_EFI_MESSAGE_ATAPI_BOOT:\r
+    case BDS_EFI_MESSAGE_SATA_BOOT:\r
       if (CdromNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI DVD/CDROM");\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_DVD);\r
       } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI DVD/CDROM %d", CdromNumber);\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_DVD_NUM, CdromNumber);\r
       }\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       CdromNumber++;\r
@@ -994,9 +1031,9 @@ BdsLibEnumerateAllBootOption (
 \r
     case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:\r
       if (UsbNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI USB Device");\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_USB);\r
       } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI USB Device %d", UsbNumber);\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_USB_NUM, UsbNumber);\r
       }\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       UsbNumber++;\r
@@ -1004,9 +1041,9 @@ BdsLibEnumerateAllBootOption (
 \r
     case BDS_EFI_MESSAGE_SCSI_BOOT:\r
       if (UsbNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI SCSI Device");\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_SCSI);\r
       } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI SCSI Device %d", UsbNumber);\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_SCSI_NUM, UsbNumber);\r
       }\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       UsbNumber++;\r
@@ -1014,9 +1051,9 @@ BdsLibEnumerateAllBootOption (
 \r
     case BDS_EFI_MESSAGE_MISC_BOOT:\r
       if (MiscNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Misc Device");\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_MISC);\r
       } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Misc Device %d", MiscNumber);\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_MISC_NUM, MiscNumber);\r
       }\r
       BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);\r
       MiscNumber++;\r
@@ -1080,9 +1117,9 @@ BdsLibEnumerateAllBootOption (
       BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);\r
     } else {\r
       if (NonBlockNumber == 0) {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device");\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_NON_BLOCK);\r
       } else {\r
-        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device %d", NonBlockNumber);\r
+        UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_NON_BLOCK_NUM, NonBlockNumber);\r
       }\r
       BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer);\r
       NonBlockNumber++;\r
@@ -1105,9 +1142,9 @@ BdsLibEnumerateAllBootOption (
         );\r
   for (Index = 0; Index < NumberSimpleNetworkHandles; Index++) {\r
     if (Index == 0) {\r
-      UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Network");\r
+      UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_NETWORK);\r
     } else {\r
-      UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Network %d", Index);\r
+      UnicodeSPrint (Buffer, sizeof (Buffer), DESCRIPTION_NETWORK_NUM, Index);\r
     }\r
     BdsLibBuildOptionFromHandle (SimpleNetworkHandles[Index], BdsBootOptionList, Buffer);\r
   }\r
@@ -1597,6 +1634,8 @@ BdsGetBootTypeFromDevicePath (
           return BDS_EFI_MESSAGE_USB_DEVICE_BOOT;\r
         } else if (DevicePathSubType(TempDevicePath) == MSG_SCSI_DP) {\r
           return BDS_EFI_MESSAGE_SCSI_BOOT;\r
+        } else if (DevicePathSubType(TempDevicePath) == MSG_SATA_DP) {\r
+          return BDS_EFI_MESSAGE_SATA_BOOT;\r
         }\r
         return BDS_EFI_MESSAGE_MISC_BOOT;\r
       default:\r
@@ -1608,6 +1647,41 @@ BdsGetBootTypeFromDevicePath (
   return BDS_EFI_UNSUPPORT;\r
 }\r
 \r
+\r
+/** \r
+  Check whether the descriptionis is conflict with the description reserved for\r
+  auto-created boot options.\r
+\r
+  @param  Description  The Description in a boot option\r
+  \r
+  @retval TRUE    The description is conflict with the description reserved for\r
+                  auto-created boot options.\r
+  @retval FALSE   The description is not conflict with the description reserved.\r
+  \r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CheckDescritptionConflict (\r
+  IN CHAR16                       *Description\r
+  )\r
+{\r
+  if (Description == NULL) {\r
+    return FALSE;  \r
+  }\r
+  if ((CompareMem (Description, DESCRIPTION_FLOPPY, StrLen (DESCRIPTION_FLOPPY) * sizeof (CHAR16)) == 0)  ||\r
+      (CompareMem (Description, DESCRIPTION_DVD, StrLen (DESCRIPTION_DVD) * sizeof (CHAR16)) == 0)        ||\r
+      (CompareMem (Description, DESCRIPTION_USB, StrLen (DESCRIPTION_USB) * sizeof (CHAR16)) == 0)        ||\r
+      (CompareMem (Description, DESCRIPTION_SCSI, StrLen (DESCRIPTION_SCSI) * sizeof (CHAR16)) == 0)      ||\r
+      (CompareMem (Description, DESCRIPTION_MISC, StrLen (DESCRIPTION_MISC) * sizeof (CHAR16)) == 0)      ||\r
+      (CompareMem (Description, DESCRIPTION_NETWORK, StrLen (DESCRIPTION_NETWORK) * sizeof (CHAR16)) == 0)||\r
+      (CompareMem (Description, DESCRIPTION_NON_BLOCK, StrLen (DESCRIPTION_NON_BLOCK) * sizeof (CHAR16)) == 0)) { \r
+     return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+\r
 /**\r
   Check whether the Device path in a boot option point to a valid bootable device,\r
   And if CheckMedia is true, check the device is ready to boot now.\r
@@ -1625,6 +1699,32 @@ BdsLibIsValidEFIBootOptDevicePath (
   IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,\r
   IN BOOLEAN                      CheckMedia\r
   )\r
+{\r
+  return BdsLibIsValidEFIBootOptDevicePathExt (DevPath, CheckMedia, NULL);\r
+}\r
+\r
+/**\r
+  Check whether the Device path in a boot option point to a valid bootable device,\r
+  And if CheckMedia is true, check the device is ready to boot now.\r
+  If Description is not NULL and the device path point to a fixed BlockIo\r
+  device, check the description whether conflict with other auto-created\r
+  boot options.\r
+\r
+  @param  DevPath     the Device path in a boot option\r
+  @param  CheckMedia  if true, check the device is ready to boot now.\r
+  @param  Description the description in a boot option\r
+\r
+  @retval TRUE        the Device path  is valid\r
+  @retval FALSE       the Device path  is invalid .\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+BdsLibIsValidEFIBootOptDevicePathExt (\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,\r
+  IN BOOLEAN                      CheckMedia,\r
+  IN CHAR16                       *Description\r
+  )\r
 {\r
   EFI_STATUS                Status;\r
   EFI_HANDLE                Handle;\r
@@ -1704,7 +1804,9 @@ BdsLibIsValidEFIBootOptDevicePath (
   }\r
   \r
   //\r
-  // If the boot option point to a blockIO device, no matter whether or not it is a removeable device, it is a valid EFI boot option\r
+  // If the boot option point to a blockIO device:\r
+  // if it is a removable blockIo device, it is valid.\r
+  // if it is a fixed blockIo device, check its description confliction. \r
   //\r
   TempDevicePath = DevPath;\r
   Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);\r
@@ -1725,6 +1827,20 @@ BdsLibIsValidEFIBootOptDevicePath (
   if (!EFI_ERROR (Status)) {\r
     Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);\r
     if (!EFI_ERROR (Status)) {\r
+      if (!BlockIo->Media->RemovableMedia) {\r
+        //\r
+        // For the Fixed block devices, check its description whether conflict\r
+        // with other auto-created boot options. BDS permit a boot option point to \r
+        // Fixed block device, but not permit it use the description reserved for\r
+        // auto-created boot options.\r
+        // The check is to cover the bug, that replace a removable BlockIo device\r
+        // with a fixed BlockIo device at the same port, but the removable device's\r
+        // boot option can not be automatically deleted.\r
+        //\r
+        if (CheckDescritptionConflict (Description)) {\r
+           return FALSE; \r
+        }\r
+      }      \r
       if (CheckMedia) {\r
         //\r
         // Test if it is ready to boot now\r
index 208b975ade5cdc7dbaa265dccecd5706558aa9b2..a850743643b5e76a97799b9572b565da8c3cf3fd 100644 (file)
@@ -112,4 +112,21 @@ BdsLibGetImageHeader (
   OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr\r
   );\r
 \r
+/** \r
+  Check whether the descriptionis is conflict with the description reserved for\r
+  auto-created boot options.\r
+\r
+  @param  Description  The Description in a boot option\r
+  \r
+  @retval TRUE    The description is conflict with the description reserved for\r
+                  auto-created boot options.\r
+  @retval FALSE   The description is not conflict with the description reserved.\r
+  \r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CheckDescritptionConflict (\r
+  IN CHAR16                       *Description\r
+  );\r
+\r
 #endif // _BDS_LIB_H_\r