Reviewed-by: Eric Dong <eric.d...@intel.com> -----Original Message----- From: Ni, Ruiyu Sent: Friday, May 29, 2015 5:46 PM To: edk2-devel@lists.sourceforge.net Cc: Ni, Ruiyu; Dong, Eric Subject: [Patch] MdeModulePkg: Provide EfiBootManagerRegisterBootDescriptionHandler
This API can be used for platform to customize the boot description other than using core provided boot description. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <ruiyu...@intel.com> CC: Eric Dong <eric.d...@intel.com> --- MdeModulePkg/Include/Library/UefiBootManagerLib.h | 30 ++++ MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c | 162 ++++++++++++++++----- .../Library/UefiBootManagerLib/InternalBm.h | 7 + 3 files changed, 160 insertions(+), 39 deletions(-) diff --git a/MdeModulePkg/Include/Library/UefiBootManagerLib.h b/MdeModulePkg/Include/Library/UefiBootManagerLib.h index 032c437..5538d90 100644 --- a/MdeModulePkg/Include/Library/UefiBootManagerLib.h +++ b/MdeModulePkg/Include/Library/UefiBootManagerLib.h @@ -440,6 +440,36 @@ EfiBootManagerRegisterLegacyBootSupport ( EFI_BOOT_MANAGER_LEGACY_BOOT LegacyBoot ); +/** + Return the platform provided boot option description for the controller. + + @param Handle Controller handle. + @param DefaultDescription Default boot description provided by core. + + @return The callee allocated description string + or NULL if the handler wants to use DefaultDescription. +**/ +typedef +CHAR16 * +(EFIAPI *EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER) ( + IN EFI_HANDLE Handle, + IN CONST CHAR16 *DefaultDescription + ); + +/** + Register the platform provided boot description handler. + + @param Handler The platform provided boot description handler + + @retval EFI_SUCCESS The handler was registered successfully. + @retval EFI_ALREADY_STARTED The handler was already registered. + @retval EFI_OUT_OF_RESOURCES There is not enough resource to perform the registration. +**/ +EFI_STATUS +EFIAPI +EfiBootManagerRegisterBootDescriptionHandler ( + IN EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER Handler + ); // // Boot Manager connect and disconnect library functions diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c index efac6d5..2d3d57b 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c @@ -25,6 +25,8 @@ CHAR16 mBmUefiPrefix[] = L"UEFI "; EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION mBmRefreshLegacyBootOption = NULL; EFI_BOOT_MANAGER_LEGACY_BOOT mBmLegacyBoot = NULL; +LIST_ENTRY mPlatformBootDescriptionHandlers = +INITIALIZE_LIST_HEAD_VARIABLE (mPlatformBootDescriptionHandlers); + /// /// This GUID is used for an EFI Variable that stores the front device pathes /// for a partial device path that starts with the HD node. @@ -641,9 +643,10 @@ BmGetMiscDescription ( IN EFI_HANDLE Handle ) { - EFI_STATUS Status; - CHAR16 *Description; - EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_STATUS Status; + CHAR16 *Description; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; switch (BmDevicePathType (DevicePathFromHandle (Handle))) { case BmAcpiFloppyBoot: @@ -677,21 +680,128 @@ BmGetMiscDescription ( } break; + case BmMessageNetworkBoot: + Description = L"Network"; + break; + default: - Description = L"Misc Device"; + Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **) &Fs); + if (!EFI_ERROR (Status)) { + Description = L"Non-Block Boot Device"; + } else { + Description = L"Misc Device"; + } break; } return AllocateCopyPool (StrSize (Description), Description); } -BM_GET_BOOT_DESCRIPTION mBmGetBootDescription[] = { +/** + Register the platform provided boot description handler. + + @param Handler The platform provided boot description handler + + @retval EFI_SUCCESS The handler was registered successfully. + @retval EFI_ALREADY_STARTED The handler was already registered. + @retval EFI_OUT_OF_RESOURCES There is not enough resource to perform the registration. +**/ +EFI_STATUS +EFIAPI +EfiBootManagerRegisterBootDescriptionHandler ( + IN EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER Handler + ) +{ + LIST_ENTRY *Link; + BM_BOOT_DESCRIPTION_ENTRY *Entry; + + for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers) + ; !IsNull (&mPlatformBootDescriptionHandlers, Link) + ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link) + ) { + Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE); + if (Entry->Handler == Handler) { + return EFI_ALREADY_STARTED; + } + } + + Entry = AllocatePool (sizeof (BM_BOOT_DESCRIPTION_ENTRY)); if (Entry + == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Entry->Signature = BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE; + Entry->Handler = Handler; + InsertTailList (&mPlatformBootDescriptionHandlers, &Entry->Link); + return EFI_SUCCESS; +} + +BM_GET_BOOT_DESCRIPTION mBmBootDescriptionHandlers[] = { BmGetUsbDescription, BmGetDescriptionFromDiskInfo, BmGetMiscDescription }; /** + Return the boot description for the controller. + + @param Handle Controller handle. + + @return The description string. +**/ +CHAR16 * +BmGetBootDescription ( + IN EFI_HANDLE Handle + ) +{ + LIST_ENTRY *Link; + BM_BOOT_DESCRIPTION_ENTRY *Entry; + CHAR16 *Description; + CHAR16 *DefaultDescription; + CHAR16 *Temp; + UINTN Index; + + // + // Firstly get the default boot description // DefaultDescription = + NULL; for (Index = 0; Index < sizeof (mBmBootDescriptionHandlers) / + sizeof (mBmBootDescriptionHandlers[0]); Index++) { + DefaultDescription = mBmBootDescriptionHandlers[Index] (Handle); + if (DefaultDescription != NULL) { + // + // Avoid description confusion between UEFI & Legacy boot option by adding "UEFI " prefix + // ONLY for core provided boot description handler. + // + Temp = AllocatePool (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)); + ASSERT (Temp != NULL); + StrCpy (Temp, mBmUefiPrefix); + StrCat (Temp, DefaultDescription); + FreePool (DefaultDescription); + DefaultDescription = Temp; + break; + } + } + ASSERT (DefaultDescription != NULL); + + // + // Secondly query platform for the better boot description // for ( + Link = GetFirstNode (&mPlatformBootDescriptionHandlers) + ; !IsNull (&mPlatformBootDescriptionHandlers, Link) + ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link) + ) { + Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE); + Description = Entry->Handler (Handle, DefaultDescription); + if (Description != NULL) { + FreePool (DefaultDescription); + return Description; + } + } + + return DefaultDescription; +} + +/** Check whether a USB device match the specified USB WWID device path. This function follows "Load Option Processing" behavior in UEFI specification. @@ -1755,16 +1865,12 @@ BmEnumerateBootOptions ( { EFI_STATUS Status; EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; - UINT16 NonBlockNumber; UINTN HandleCount; EFI_HANDLE *Handles; EFI_BLOCK_IO_PROTOCOL *BlkIo; UINTN Removable; UINTN Index; - UINTN FunctionIndex; - CHAR16 *Temp; - CHAR16 *DescriptionPtr; - CHAR16 Description[30]; + CHAR16 *Description; ASSERT (BootOptionCount != NULL); @@ -1807,28 +1913,7 @@ BmEnumerateBootOptions ( continue; } - DescriptionPtr = NULL; - for (FunctionIndex = 0; FunctionIndex < sizeof (mBmGetBootDescription) / sizeof (mBmGetBootDescription[0]); FunctionIndex++) { - DescriptionPtr = mBmGetBootDescription[FunctionIndex] (Handles[Index]); - if (DescriptionPtr != NULL) { - break; - } - } - - if (DescriptionPtr == NULL) { - continue; - } - - // - // Avoid description confusion between UEFI & Legacy boot option by adding "UEFI " prefix - // - Temp = AllocatePool (StrSize (DescriptionPtr) + sizeof (mBmUefiPrefix)); - ASSERT (Temp != NULL); - StrCpy (Temp, mBmUefiPrefix); - StrCat (Temp, DescriptionPtr); - FreePool (DescriptionPtr); - DescriptionPtr = Temp; - + Description = BmGetBootDescription (Handles[Index]); BootOptions = ReallocatePool ( sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), @@ -1841,14 +1926,14 @@ BmEnumerateBootOptions ( LoadOptionNumberUnassigned, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, - DescriptionPtr, + Description, DevicePathFromHandle (Handles[Index]), NULL, 0 ); ASSERT_EFI_ERROR (Status); - FreePool (DescriptionPtr); + FreePool (Description); } } @@ -1859,7 +1944,6 @@ BmEnumerateBootOptions ( // // Parse simple file system not based on block io // - NonBlockNumber = 0; gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, @@ -1879,8 +1963,7 @@ BmEnumerateBootOptions ( // continue; } - UnicodeSPrint (Description, sizeof (Description), NonBlockNumber > 0 ? L"%s %d" : L"%s", L"UEFI Non-Block Boot Device", NonBlockNumber); - + Description = BmGetBootDescription (Handles[Index]); BootOptions = ReallocatePool ( sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), @@ -1899,6 +1982,7 @@ BmEnumerateBootOptions ( 0 ); ASSERT_EFI_ERROR (Status); + FreePool (Description); } if (HandleCount != 0) { @@ -1917,8 +2001,7 @@ BmEnumerateBootOptions ( ); for (Index = 0; Index < HandleCount; Index++) { - UnicodeSPrint (Description, sizeof (Description), Index > 0 ? L"%s %d" : L"%s", L"UEFI Network", Index); - + Description = BmGetBootDescription (Handles[Index]); BootOptions = ReallocatePool ( sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), @@ -1937,6 +2020,7 @@ BmEnumerateBootOptions ( 0 ); ASSERT_EFI_ERROR (Status); + FreePool (Description); } if (HandleCount != 0) { diff --git a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h index 8e8534d..9baba86 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h +++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h @@ -123,6 +123,13 @@ ForEachVariable ( VOID *Context ); +#define BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE SIGNATURE_32 ('b', 'm', +'d', 'h') typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER Handler; } +BM_BOOT_DESCRIPTION_ENTRY; + /** Repair all the controllers according to the Driver Health status queried. **/ -- 1.9.5.msysgit.1 ------------------------------------------------------------------------------ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel