MdeModulePkg: Provide EfiBootManagerRegisterBootDescriptionHandler
authorRuiyu Ni <ruiyu.ni@intel.com>
Tue, 2 Jun 2015 09:03:38 +0000 (09:03 +0000)
committerniruiyu <niruiyu@Edk2>
Tue, 2 Jun 2015 09:03:38 +0000 (09:03 +0000)
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

MdeModulePkg/Include/Library/UefiBootManagerLib.h
MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h

index 032c437..5538d90 100644 (file)
@@ -440,6 +440,36 @@ EfiBootManagerRegisterLegacyBootSupport (
   EFI_BOOT_MANAGER_LEGACY_BOOT                  LegacyBoot\r
   );\r
 \r
+/**\r
+  Return the platform provided boot option description for the controller.\r
+\r
+  @param Handle                Controller handle.\r
+  @param DefaultDescription    Default boot description provided by core.\r
+\r
+  @return  The callee allocated description string\r
+           or NULL if the handler wants to use DefaultDescription.\r
+**/\r
+typedef\r
+CHAR16 *\r
+(EFIAPI *EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER) (\r
+  IN EFI_HANDLE                  Handle,\r
+  IN CONST CHAR16                *DefaultDescription\r
+  );\r
+\r
+/**\r
+  Register the platform provided boot description handler.\r
+\r
+  @param Handler  The platform provided boot description handler\r
+\r
+  @retval EFI_SUCCESS          The handler was registered successfully.\r
+  @retval EFI_ALREADY_STARTED  The handler was already registered.\r
+  @retval EFI_OUT_OF_RESOURCES There is not enough resource to perform the registration.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiBootManagerRegisterBootDescriptionHandler (\r
+  IN EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER  Handler\r
+  );\r
 \r
 //\r
 // Boot Manager connect and disconnect library functions\r
index efac6d5..2d3d57b 100644 (file)
@@ -25,6 +25,8 @@ CHAR16       mBmUefiPrefix[] = L"UEFI ";
 EFI_BOOT_MANAGER_REFRESH_LEGACY_BOOT_OPTION  mBmRefreshLegacyBootOption = NULL;\r
 EFI_BOOT_MANAGER_LEGACY_BOOT                 mBmLegacyBoot              = NULL;\r
 \r
+LIST_ENTRY mPlatformBootDescriptionHandlers = INITIALIZE_LIST_HEAD_VARIABLE (mPlatformBootDescriptionHandlers);\r
+\r
 ///\r
 /// This GUID is used for an EFI Variable that stores the front device pathes\r
 /// for a partial device path that starts with the HD node.\r
@@ -641,9 +643,10 @@ BmGetMiscDescription (
   IN EFI_HANDLE                  Handle\r
   )\r
 {\r
-  EFI_STATUS                     Status;\r
-  CHAR16                         *Description;\r
-  EFI_BLOCK_IO_PROTOCOL          *BlockIo;\r
+  EFI_STATUS                      Status;\r
+  CHAR16                          *Description;\r
+  EFI_BLOCK_IO_PROTOCOL           *BlockIo;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;\r
 \r
   switch (BmDevicePathType (DevicePathFromHandle (Handle))) {\r
   case BmAcpiFloppyBoot:\r
@@ -677,20 +680,127 @@ BmGetMiscDescription (
     }\r
     break;\r
 \r
+  case BmMessageNetworkBoot:\r
+    Description = L"Network";\r
+    break;\r
+\r
   default:\r
-    Description = L"Misc Device";\r
+    Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **) &Fs);\r
+    if (!EFI_ERROR (Status)) {\r
+      Description = L"Non-Block Boot Device";\r
+    } else {\r
+      Description = L"Misc Device";\r
+    }\r
     break;\r
   }\r
 \r
   return AllocateCopyPool (StrSize (Description), Description);\r
 }\r
 \r
-BM_GET_BOOT_DESCRIPTION mBmGetBootDescription[] = {\r
+/**\r
+  Register the platform provided boot description handler.\r
+\r
+  @param Handler  The platform provided boot description handler\r
+\r
+  @retval EFI_SUCCESS          The handler was registered successfully.\r
+  @retval EFI_ALREADY_STARTED  The handler was already registered.\r
+  @retval EFI_OUT_OF_RESOURCES There is not enough resource to perform the registration.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiBootManagerRegisterBootDescriptionHandler (\r
+  IN EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER  Handler\r
+  )\r
+{\r
+  LIST_ENTRY                                    *Link;\r
+  BM_BOOT_DESCRIPTION_ENTRY                    *Entry;\r
+\r
+  for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers)\r
+      ; !IsNull (&mPlatformBootDescriptionHandlers, Link)\r
+      ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link)\r
+      ) {\r
+    Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE);\r
+    if (Entry->Handler == Handler) {\r
+      return EFI_ALREADY_STARTED;\r
+    }\r
+  }\r
+\r
+  Entry = AllocatePool (sizeof (BM_BOOT_DESCRIPTION_ENTRY));\r
+  if (Entry == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Entry->Signature = BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE;\r
+  Entry->Handler   = Handler;\r
+  InsertTailList (&mPlatformBootDescriptionHandlers, &Entry->Link);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+BM_GET_BOOT_DESCRIPTION mBmBootDescriptionHandlers[] = {\r
   BmGetUsbDescription,\r
   BmGetDescriptionFromDiskInfo,\r
   BmGetMiscDescription\r
 };\r
 \r
+/**\r
+  Return the boot description for the controller.\r
+\r
+  @param Handle                Controller handle.\r
+\r
+  @return  The description string.\r
+**/\r
+CHAR16 *\r
+BmGetBootDescription (\r
+  IN EFI_HANDLE                  Handle\r
+  )\r
+{\r
+  LIST_ENTRY                     *Link;\r
+  BM_BOOT_DESCRIPTION_ENTRY      *Entry;\r
+  CHAR16                         *Description;\r
+  CHAR16                         *DefaultDescription;\r
+  CHAR16                         *Temp;\r
+  UINTN                          Index;\r
+\r
+  //\r
+  // Firstly get the default boot description\r
+  //\r
+  DefaultDescription = NULL;\r
+  for (Index = 0; Index < sizeof (mBmBootDescriptionHandlers) / sizeof (mBmBootDescriptionHandlers[0]); Index++) {\r
+    DefaultDescription = mBmBootDescriptionHandlers[Index] (Handle);\r
+    if (DefaultDescription != NULL) {\r
+      //\r
+      // Avoid description confusion between UEFI & Legacy boot option by adding "UEFI " prefix\r
+      // ONLY for core provided boot description handler.\r
+      //\r
+      Temp = AllocatePool (StrSize (DefaultDescription) + sizeof (mBmUefiPrefix)); \r
+      ASSERT (Temp != NULL);\r
+      StrCpy (Temp, mBmUefiPrefix);\r
+      StrCat (Temp, DefaultDescription);\r
+      FreePool (DefaultDescription);\r
+      DefaultDescription = Temp;\r
+      break;\r
+    }\r
+  }\r
+  ASSERT (DefaultDescription != NULL);\r
+\r
+  //\r
+  // Secondly query platform for the better boot description\r
+  //\r
+  for ( Link = GetFirstNode (&mPlatformBootDescriptionHandlers)\r
+      ; !IsNull (&mPlatformBootDescriptionHandlers, Link)\r
+      ; Link = GetNextNode (&mPlatformBootDescriptionHandlers, Link)\r
+      ) {\r
+    Entry = CR (Link, BM_BOOT_DESCRIPTION_ENTRY, Link, BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE);\r
+    Description = Entry->Handler (Handle, DefaultDescription);\r
+    if (Description != NULL) {\r
+      FreePool (DefaultDescription);\r
+      return Description;\r
+    }\r
+  }\r
+\r
+  return DefaultDescription;\r
+}\r
+\r
 /**\r
   Check whether a USB device match the specified USB WWID device path. This\r
   function follows "Load Option Processing" behavior in UEFI specification.\r
@@ -1755,16 +1865,12 @@ BmEnumerateBootOptions (
 {\r
   EFI_STATUS                            Status;\r
   EFI_BOOT_MANAGER_LOAD_OPTION          *BootOptions;\r
-  UINT16                                NonBlockNumber;\r
   UINTN                                 HandleCount;\r
   EFI_HANDLE                            *Handles;\r
   EFI_BLOCK_IO_PROTOCOL                 *BlkIo;\r
   UINTN                                 Removable;\r
   UINTN                                 Index;\r
-  UINTN                                 FunctionIndex;\r
-  CHAR16                                *Temp;\r
-  CHAR16                                *DescriptionPtr;\r
-  CHAR16                                Description[30];\r
+  CHAR16                                *Description;\r
 \r
   ASSERT (BootOptionCount != NULL);\r
 \r
@@ -1807,28 +1913,7 @@ BmEnumerateBootOptions (
         continue;\r
       }\r
 \r
-      DescriptionPtr = NULL;\r
-      for (FunctionIndex = 0; FunctionIndex < sizeof (mBmGetBootDescription) / sizeof (mBmGetBootDescription[0]); FunctionIndex++) {\r
-        DescriptionPtr = mBmGetBootDescription[FunctionIndex] (Handles[Index]);\r
-        if (DescriptionPtr != NULL) {\r
-          break;\r
-        }\r
-      }\r
-\r
-      if (DescriptionPtr == NULL) {\r
-        continue;\r
-      }\r
-\r
-      //\r
-      // Avoid description confusion between UEFI & Legacy boot option by adding "UEFI " prefix\r
-      //\r
-      Temp = AllocatePool (StrSize (DescriptionPtr) + sizeof (mBmUefiPrefix)); \r
-      ASSERT (Temp != NULL);\r
-      StrCpy (Temp, mBmUefiPrefix);\r
-      StrCat (Temp, DescriptionPtr);\r
-      FreePool (DescriptionPtr);\r
-      DescriptionPtr = Temp;\r
-\r
+      Description = BmGetBootDescription (Handles[Index]);\r
       BootOptions = ReallocatePool (\r
                       sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),\r
                       sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),\r
@@ -1841,14 +1926,14 @@ BmEnumerateBootOptions (
                  LoadOptionNumberUnassigned,\r
                  LoadOptionTypeBoot,\r
                  LOAD_OPTION_ACTIVE,\r
-                 DescriptionPtr,\r
+                 Description,\r
                  DevicePathFromHandle (Handles[Index]),\r
                  NULL,\r
                  0\r
                  );\r
       ASSERT_EFI_ERROR (Status);\r
 \r
-      FreePool (DescriptionPtr);\r
+      FreePool (Description);\r
     }\r
   }\r
 \r
@@ -1859,7 +1944,6 @@ BmEnumerateBootOptions (
   //\r
   // Parse simple file system not based on block io\r
   //\r
-  NonBlockNumber = 0;\r
   gBS->LocateHandleBuffer (\r
          ByProtocol,\r
          &gEfiSimpleFileSystemProtocolGuid,\r
@@ -1879,8 +1963,7 @@ BmEnumerateBootOptions (
       //\r
       continue;\r
     }\r
-    UnicodeSPrint (Description, sizeof (Description), NonBlockNumber > 0 ? L"%s %d" : L"%s", L"UEFI Non-Block Boot Device", NonBlockNumber);\r
-    \r
+    Description = BmGetBootDescription (Handles[Index]);\r
     BootOptions = ReallocatePool (\r
                     sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),\r
                     sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),\r
@@ -1899,6 +1982,7 @@ BmEnumerateBootOptions (
                0\r
                );\r
     ASSERT_EFI_ERROR (Status);\r
+    FreePool (Description);\r
   }\r
 \r
   if (HandleCount != 0) {\r
@@ -1917,8 +2001,7 @@ BmEnumerateBootOptions (
          );\r
   for (Index = 0; Index < HandleCount; Index++) {\r
 \r
-    UnicodeSPrint (Description, sizeof (Description), Index > 0 ? L"%s %d" : L"%s", L"UEFI Network", Index);\r
-\r
+    Description = BmGetBootDescription (Handles[Index]);\r
     BootOptions = ReallocatePool (\r
                     sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount),\r
                     sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1),\r
@@ -1937,6 +2020,7 @@ BmEnumerateBootOptions (
                0\r
                );\r
     ASSERT_EFI_ERROR (Status);\r
+    FreePool (Description);\r
   }\r
 \r
   if (HandleCount != 0) {\r
index 8e8534d..9baba86 100644 (file)
@@ -123,6 +123,13 @@ ForEachVariable (
   VOID                        *Context\r
   );\r
 \r
+#define BM_BOOT_DESCRIPTION_ENTRY_SIGNATURE SIGNATURE_32 ('b', 'm', 'd', 'h')\r
+typedef struct {\r
+  UINT32                                    Signature;\r
+  LIST_ENTRY                                Link;\r
+  EFI_BOOT_MANAGER_BOOT_DESCRIPTION_HANDLER Handler;\r
+} BM_BOOT_DESCRIPTION_ENTRY;\r
+\r
 /**\r
   Repair all the controllers according to the Driver Health status queried.\r
 **/\r