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.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17547 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Ruiyu Ni
2015-06-02 09:03:38 +00:00
committed by niruiyu
parent 4e5220964b
commit f41c71d26a
3 changed files with 160 additions and 39 deletions

View File

@ -440,6 +440,36 @@ EfiBootManagerRegisterLegacyBootSupport (
EFI_BOOT_MANAGER_LEGACY_BOOT LegacyBoot 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 // Boot Manager connect and disconnect library functions

View File

@ -25,6 +25,8 @@ CHAR16 mBmUefiPrefix[] = L"UEFI ";
EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION mBmRefreshLegacyBootOption = NULL; EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION mBmRefreshLegacyBootOption = NULL;
EFI_BOOT_MANAGER_LEGACY_BOOT mBmLegacyBoot = 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 /// 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. /// for a partial device path that starts with the HD node.
@ -641,9 +643,10 @@ BmGetMiscDescription (
IN EFI_HANDLE Handle IN EFI_HANDLE Handle
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
CHAR16 *Description; CHAR16 *Description;
EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_BLOCK_IO_PROTOCOL *BlockIo;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
switch (BmDevicePathType (DevicePathFromHandle (Handle))) { switch (BmDevicePathType (DevicePathFromHandle (Handle))) {
case BmAcpiFloppyBoot: case BmAcpiFloppyBoot:
@ -677,20 +680,127 @@ BmGetMiscDescription (
} }
break; break;
case BmMessageNetworkBoot:
Description = L"Network";
break;
default: 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; break;
} }
return AllocateCopyPool (StrSize (Description), Description); 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, BmGetUsbDescription,
BmGetDescriptionFromDiskInfo, BmGetDescriptionFromDiskInfo,
BmGetMiscDescription 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 Check whether a USB device match the specified USB WWID device path. This
function follows "Load Option Processing" behavior in UEFI specification. function follows "Load Option Processing" behavior in UEFI specification.
@ -1755,16 +1865,12 @@ BmEnumerateBootOptions (
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
UINT16 NonBlockNumber;
UINTN HandleCount; UINTN HandleCount;
EFI_HANDLE *Handles; EFI_HANDLE *Handles;
EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_BLOCK_IO_PROTOCOL *BlkIo;
UINTN Removable; UINTN Removable;
UINTN Index; UINTN Index;
UINTN FunctionIndex; CHAR16 *Description;
CHAR16 *Temp;
CHAR16 *DescriptionPtr;
CHAR16 Description[30];
ASSERT (BootOptionCount != NULL); ASSERT (BootOptionCount != NULL);
@ -1807,28 +1913,7 @@ BmEnumerateBootOptions (
continue; continue;
} }
DescriptionPtr = NULL; Description = BmGetBootDescription (Handles[Index]);
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;
BootOptions = ReallocatePool ( BootOptions = ReallocatePool (
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
@ -1841,14 +1926,14 @@ BmEnumerateBootOptions (
LoadOptionNumberUnassigned, LoadOptionNumberUnassigned,
LoadOptionTypeBoot, LoadOptionTypeBoot,
LOAD_OPTION_ACTIVE, LOAD_OPTION_ACTIVE,
DescriptionPtr, Description,
DevicePathFromHandle (Handles[Index]), DevicePathFromHandle (Handles[Index]),
NULL, NULL,
0 0
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
FreePool (DescriptionPtr); FreePool (Description);
} }
} }
@ -1859,7 +1944,6 @@ BmEnumerateBootOptions (
// //
// Parse simple file system not based on block io // Parse simple file system not based on block io
// //
NonBlockNumber = 0;
gBS->LocateHandleBuffer ( gBS->LocateHandleBuffer (
ByProtocol, ByProtocol,
&gEfiSimpleFileSystemProtocolGuid, &gEfiSimpleFileSystemProtocolGuid,
@ -1879,8 +1963,7 @@ BmEnumerateBootOptions (
// //
continue; 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 ( BootOptions = ReallocatePool (
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
@ -1899,6 +1982,7 @@ BmEnumerateBootOptions (
0 0
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
FreePool (Description);
} }
if (HandleCount != 0) { if (HandleCount != 0) {
@ -1917,8 +2001,7 @@ BmEnumerateBootOptions (
); );
for (Index = 0; Index < HandleCount; Index++) { 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 ( BootOptions = ReallocatePool (
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),
sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),
@ -1937,6 +2020,7 @@ BmEnumerateBootOptions (
0 0
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
FreePool (Description);
} }
if (HandleCount != 0) { if (HandleCount != 0) {

View File

@ -123,6 +123,13 @@ ForEachVariable (
VOID *Context 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. Repair all the controllers according to the Driver Health status queried.
**/ **/