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