]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / BootGraphicsResourceTableDxe / BootGraphicsResourceTableDxe.c
index 6a7165a954897068e4c4b0da3018445eec953755..d16872e145779f8ac92367072703f39c11ea3626 100644 (file)
@@ -1,24 +1,19 @@
 /** @file\r
   This module install ACPI Boot Graphics Resource Table (BGRT).\r
 \r
-  Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2016, Microsoft Corporation<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 **/\r
 \r
 #include <Uefi.h>\r
 \r
 #include <IndustryStandard/Acpi.h>\r
-#include <IndustryStandard/Bmp.h>\r
 \r
 #include <Protocol/AcpiTable.h>\r
 #include <Protocol/GraphicsOutput.h>\r
 #include <Protocol/BootLogo.h>\r
+#include <Protocol/BootLogo2.h>\r
 \r
 #include <Guid/EventGroup.h>\r
 \r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/PcdLib.h>\r
+#include <Library/SafeIntLib.h>\r
+#include <Library/BmpSupportLib.h>\r
+\r
+/**\r
+  Update information of logo image drawn on screen.\r
+\r
+  @param[in] This          The pointer to the Boot Logo protocol 2 instance.\r
+  @param[in] BltBuffer     The BLT buffer for logo drawn on screen. If BltBuffer\r
+                           is set to NULL, it indicates that logo image is no\r
+                           longer on the screen.\r
+  @param[in] DestinationX  X coordinate of destination for the BltBuffer.\r
+  @param[in] DestinationY  Y coordinate of destination for the BltBuffer.\r
+  @param[in] Width         Width of rectangle in BltBuffer in pixels.\r
+  @param[in] Height        Hight of rectangle in BltBuffer in pixels.\r
+\r
+  @retval EFI_SUCCESS            The boot logo information was updated.\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.\r
+  @retval EFI_OUT_OF_RESOURCES   The logo information was not updated due to\r
+                                 insufficient memory resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetBootLogo (\r
+  IN EFI_BOOT_LOGO_PROTOCOL         *This,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer       OPTIONAL,\r
+  IN UINTN                          DestinationX,\r
+  IN UINTN                          DestinationY,\r
+  IN UINTN                          Width,\r
+  IN UINTN                          Height\r
+  );\r
+\r
+/**\r
+  Update information of logo image drawn on screen.\r
+\r
+  @param[in] This          The pointer to the Boot Logo protocol 2 instance.\r
+  @param[in] BltBuffer     The BLT buffer for logo drawn on screen. If BltBuffer\r
+                           is set to NULL, it indicates that logo image is no\r
+                           longer on the screen.\r
+  @param[in] DestinationX  X coordinate of destination for the BltBuffer.\r
+  @param[in] DestinationY  Y coordinate of destination for the BltBuffer.\r
+  @param[in] Width         Width of rectangle in BltBuffer in pixels.\r
+  @param[in] Height        Hight of rectangle in BltBuffer in pixels.\r
+\r
+  @retval EFI_SUCCESS            The boot logo information was updated.\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.\r
+  @retval EFI_OUT_OF_RESOURCES   The logo information was not updated due to\r
+                                 insufficient memory resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetBootLogo2 (\r
+  IN EDKII_BOOT_LOGO2_PROTOCOL      *This,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer       OPTIONAL,\r
+  IN UINTN                          DestinationX,\r
+  IN UINTN                          DestinationY,\r
+  IN UINTN                          Width,\r
+  IN UINTN                          Height\r
+  );\r
+\r
+/**\r
+  Get the location of the boot logo on the screen.\r
+\r
+  @param[in]  This          The pointer to the Boot Logo Protocol 2 instance\r
+  @param[out] BltBuffer     Returns pointer to the GOP BLT buffer that was\r
+                            previously registered with SetBootLogo2(). The\r
+                            buffer returned must not be modified or freed.\r
+  @param[out] DestinationX  Returns the X start position of the GOP BLT buffer\r
+                            that was previously registered with SetBootLogo2().\r
+  @param[out] DestinationY  Returns the Y start position of the GOP BLT buffer\r
+                            that was previously registered with SetBootLogo2().\r
+  @param[out] Width         Returns the width of the GOP BLT buffer\r
+                            that was previously registered with SetBootLogo2().\r
+  @param[out] Height        Returns the height of the GOP BLT buffer\r
+                            that was previously registered with SetBootLogo2().\r
+\r
+  @retval EFI_SUCCESS            The location of the boot logo was returned.\r
+  @retval EFI_NOT_READY          The boot logo has not been set.\r
+  @retval EFI_INVALID_PARAMETER  BltBuffer is NULL.\r
+  @retval EFI_INVALID_PARAMETER  DestinationX is NULL.\r
+  @retval EFI_INVALID_PARAMETER  DestinationY is NULL.\r
+  @retval EFI_INVALID_PARAMETER  Width is NULL.\r
+  @retval EFI_INVALID_PARAMETER  Height is NULL.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetBootLogo2 (\r
+  IN  EDKII_BOOT_LOGO2_PROTOCOL      *This,\r
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  **BltBuffer,\r
+  OUT UINTN                          *DestinationX,\r
+  OUT UINTN                          *DestinationY,\r
+  OUT UINTN                          *Width,\r
+  OUT UINTN                          *Height\r
+  );\r
 \r
 //\r
-// Module globals.\r
+// Boot Logo Protocol Handle\r
 //\r
-EFI_EVENT  mBootGraphicsReadyToBootEvent;\r
-UINTN      mBootGraphicsResourceTableKey = 0;\r
+EFI_HANDLE  mBootLogoHandle = NULL;\r
 \r
-EFI_HANDLE                     mBootLogoHandle = NULL;\r
-BOOLEAN                        mIsLogoValid = FALSE;\r
-EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *mLogoBltBuffer = NULL;\r
-UINTN                          mLogoDestX = 0;\r
-UINTN                          mLogoDestY = 0;\r
-UINTN                          mLogoWidth = 0;\r
-UINTN                          mLogoHeight = 0;\r
+//\r
+// Boot Logo Protocol Instance\r
+//\r
+EFI_BOOT_LOGO_PROTOCOL  mBootLogoProtocolTemplate = {\r
+  SetBootLogo\r
+};\r
 \r
-BMP_IMAGE_HEADER  mBmpImageHeaderTemplate = {\r
-  'B',    // CharB\r
-  'M',    // CharM\r
-  0,      // Size will be updated at runtime\r
-  {0, 0}, // Reserved\r
-  sizeof (BMP_IMAGE_HEADER), // ImageOffset\r
-  sizeof (BMP_IMAGE_HEADER) - OFFSET_OF (BMP_IMAGE_HEADER, HeaderSize), // HeaderSize\r
-  0,      // PixelWidth will be updated at runtime\r
-  0,      // PixelHeight will be updated at runtime\r
-  1,      // Planes\r
-  24,     // BitPerPixel\r
-  0,      // CompressionType\r
-  0,      // ImageSize will be updated at runtime\r
-  0,      // XPixelsPerMeter\r
-  0,      // YPixelsPerMeter\r
-  0,      // NumberOfColors\r
-  0       // ImportantColors\r
+///\r
+/// Boot Logo 2 Protocol instance\r
+///\r
+EDKII_BOOT_LOGO2_PROTOCOL mBootLogo2ProtocolTemplate = {\r
+  SetBootLogo2,\r
+  GetBootLogo2\r
 };\r
 \r
-BOOLEAN  mAcpiBgrtInstalled = FALSE;\r
-BOOLEAN  mAcpiBgrtStatusChanged = FALSE;\r
-BOOLEAN  mAcpiBgrtBufferChanged = FALSE;\r
+EFI_EVENT                      mBootGraphicsReadyToBootEvent;\r
+UINTN                          mBootGraphicsResourceTableKey = 0;\r
+BOOLEAN                        mIsLogoValid = FALSE;\r
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *mLogoBltBuffer = NULL;\r
+UINTN                          mLogoDestX  = 0;\r
+UINTN                          mLogoDestY  = 0;\r
+UINTN                          mLogoWidth  = 0;\r
+UINTN                          mLogoHeight = 0;\r
+BOOLEAN                        mAcpiBgrtInstalled     = FALSE;\r
+BOOLEAN                        mAcpiBgrtStatusChanged = FALSE;\r
+BOOLEAN                        mAcpiBgrtBufferChanged = FALSE;\r
 \r
+//\r
+// ACPI Boot Graphics Resource Table template\r
+//\r
 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate = {\r
   {\r
     EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,\r
@@ -116,40 +202,52 @@ SetBootLogo (
   IN UINTN                             DestinationY,\r
   IN UINTN                             Width,\r
   IN UINTN                             Height\r
-  );\r
-\r
-EFI_BOOT_LOGO_PROTOCOL  mBootLogoProtocolTemplate = { SetBootLogo };\r
+  )\r
+{\r
+  //\r
+  // Call same service in Boot Logo 2 Protocol\r
+  //\r
+  return SetBootLogo2 (\r
+           &mBootLogo2ProtocolTemplate,\r
+           BltBuffer,\r
+           DestinationX,\r
+           DestinationY,\r
+           Width,\r
+           Height\r
+           );\r
+}\r
 \r
 /**\r
   Update information of logo image drawn on screen.\r
 \r
-  @param  This           The pointer to the Boot Logo protocol instance.\r
-  @param  BltBuffer      The BLT buffer for logo drawn on screen. If BltBuffer\r
-                         is set to NULL, it indicates that logo image is no\r
-                         longer on the screen.\r
-  @param  DestinationX   X coordinate of destination for the BltBuffer.\r
-  @param  DestinationY   Y coordinate of destination for the BltBuffer.\r
-  @param  Width          Width of rectangle in BltBuffer in pixels.\r
-  @param  Height         Hight of rectangle in BltBuffer in pixels.\r
-\r
-  @retval EFI_SUCCESS             The boot logo information was updated.\r
-  @retval EFI_INVALID_PARAMETER   One of the parameters has an invalid value.\r
-  @retval EFI_OUT_OF_RESOURCES    The logo information was not updated due to\r
-                                  insufficient memory resources.\r
-\r
+  @param[in] This          The pointer to the Boot Logo protocol 2 instance.\r
+  @param[in] BltBuffer     The BLT buffer for logo drawn on screen. If BltBuffer\r
+                           is set to NULL, it indicates that logo image is no\r
+                           longer on the screen.\r
+  @param[in] DestinationX  X coordinate of destination for the BltBuffer.\r
+  @param[in] DestinationY  Y coordinate of destination for the BltBuffer.\r
+  @param[in] Width         Width of rectangle in BltBuffer in pixels.\r
+  @param[in] Height        Hight of rectangle in BltBuffer in pixels.\r
+\r
+  @retval EFI_SUCCESS            The boot logo information was updated.\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.\r
+  @retval EFI_OUT_OF_RESOURCES   The logo information was not updated due to\r
+                                 insufficient memory resources.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-SetBootLogo (\r
-  IN EFI_BOOT_LOGO_PROTOCOL            *This,\r
-  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL     *BltBuffer       OPTIONAL,\r
-  IN UINTN                             DestinationX,\r
-  IN UINTN                             DestinationY,\r
-  IN UINTN                             Width,\r
-  IN UINTN                             Height\r
+SetBootLogo2 (\r
+  IN EDKII_BOOT_LOGO2_PROTOCOL      *This,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  *BltBuffer       OPTIONAL,\r
+  IN UINTN                          DestinationX,\r
+  IN UINTN                          DestinationY,\r
+  IN UINTN                          Width,\r
+  IN UINTN                          Height\r
   )\r
 {\r
-  UINT64                        BufferSize;\r
+  EFI_STATUS  Status;\r
+  UINTN       BufferSize;\r
+  UINT32      Result32;\r
 \r
   if (BltBuffer == NULL) {\r
     mIsLogoValid = FALSE;\r
@@ -157,103 +255,180 @@ SetBootLogo (
     return EFI_SUCCESS;\r
   }\r
 \r
+  //\r
+  // Width and height are not allowed to be zero.\r
+  //\r
   if (Width == 0 || Height == 0) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
-  mAcpiBgrtBufferChanged = TRUE;\r
-  if (mLogoBltBuffer != NULL) {\r
-    FreePool (mLogoBltBuffer);\r
-    mLogoBltBuffer = NULL;\r
+\r
+  //\r
+  // Verify destination, width, and height do not overflow 32-bit values.\r
+  // The Boot Graphics Resource Table only has 32-bit fields for these values.\r
+  //\r
+  Status = SafeUintnToUint32 (DestinationX, &Result32);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+  Status = SafeUintnToUint32 (DestinationY, &Result32);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  Status = SafeUintnToUint32 (Width, &Result32);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  Status = SafeUintnToUint32 (Height, &Result32);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   //\r
-  // Ensure the Height * Width doesn't overflow\r
+  // Ensure the Height * Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) does\r
+  // not overflow UINTN\r
   //\r
-  if (Height > DivU64x64Remainder ((UINTN) ~0, Width, NULL)) {\r
+  Status = SafeUintnMult (\r
+             Width,\r
+             Height,\r
+             &BufferSize\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  Status = SafeUintnMult (\r
+             BufferSize,\r
+             sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),\r
+             &BufferSize\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
-  BufferSize = MultU64x64 (Width, Height);\r
-  \r
+\r
   //\r
-  // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
+  // Update state\r
   //\r
-  if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
-    return EFI_UNSUPPORTED;\r
+  mAcpiBgrtBufferChanged = TRUE;\r
+\r
+  //\r
+  // Free old logo buffer\r
+  //\r
+  if (mLogoBltBuffer != NULL) {\r
+    FreePool (mLogoBltBuffer);\r
+    mLogoBltBuffer = NULL;\r
   }\r
 \r
-  mLogoBltBuffer = AllocateCopyPool (\r
-                     (UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),\r
-                     BltBuffer\r
-                     );\r
+  //\r
+  // Allocate new logo buffer\r
+  //\r
+  mLogoBltBuffer = AllocateCopyPool (BufferSize, BltBuffer);\r
   if (mLogoBltBuffer == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  mLogoDestX = DestinationX;\r
-  mLogoDestY = DestinationY;\r
-  mLogoWidth = Width;\r
-  mLogoHeight = Height;\r
+\r
+  mLogoDestX   = DestinationX;\r
+  mLogoDestY   = DestinationY;\r
+  mLogoWidth   = Width;\r
+  mLogoHeight  = Height;\r
   mIsLogoValid = TRUE;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  This function calculates and updates an UINT8 checksum.\r
-\r
-  @param[in]  Buffer          Pointer to buffer to checksum.\r
-  @param[in]  Size            Number of bytes to checksum.\r
-\r
+  Get the location of the boot logo on the screen.\r
+\r
+  @param[in]  This          The pointer to the Boot Logo Protocol 2 instance\r
+  @param[out] BltBuffer     Returns pointer to the GOP BLT buffer that was\r
+                            previously registered with SetBootLogo2(). The\r
+                            buffer returned must not be modified or freed.\r
+  @param[out] DestinationX  Returns the X start position of the GOP BLT buffer\r
+                            that was previously registered with SetBootLogo2().\r
+  @param[out] DestinationY  Returns the Y start position of the GOP BLT buffer\r
+                            that was previously registered with SetBootLogo2().\r
+  @param[out] Width         Returns the width of the GOP BLT buffer\r
+                            that was previously registered with SetBootLogo2().\r
+  @param[out] Height        Returns the height of the GOP BLT buffer\r
+                            that was previously registered with SetBootLogo2().\r
+\r
+  @retval EFI_SUCCESS            The location of the boot logo was returned.\r
+  @retval EFI_NOT_READY          The boot logo has not been set.\r
+  @retval EFI_INVALID_PARAMETER  BltBuffer is NULL.\r
+  @retval EFI_INVALID_PARAMETER  DestinationX is NULL.\r
+  @retval EFI_INVALID_PARAMETER  DestinationY is NULL.\r
+  @retval EFI_INVALID_PARAMETER  Width is NULL.\r
+  @retval EFI_INVALID_PARAMETER  Height is NULL.\r
 **/\r
-VOID\r
-BgrtAcpiTableChecksum (\r
-  IN UINT8      *Buffer,\r
-  IN UINTN      Size\r
+EFI_STATUS\r
+EFIAPI\r
+GetBootLogo2 (\r
+  IN  EDKII_BOOT_LOGO2_PROTOCOL      *This,\r
+  OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL  **BltBuffer,\r
+  OUT UINTN                          *DestinationX,\r
+  OUT UINTN                          *DestinationY,\r
+  OUT UINTN                          *Width,\r
+  OUT UINTN                          *Height\r
   )\r
 {\r
-  UINTN ChecksumOffset;\r
-\r
-  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);\r
+  //\r
+  // If the boot logo has not been set with SetBootLogo() or SetBootLogo() was\r
+  // called with a NULL BltBuffer then the boot logo is not valid and\r
+  // EFI_NOT_READY is returned.\r
+  //\r
+  if (mLogoBltBuffer == NULL) {\r
+    DEBUG ((DEBUG_ERROR, "Request to get boot logo location before boot logo has been set.\n"));\r
+    return EFI_NOT_READY;\r
+  }\r
 \r
   //\r
-  // Set checksum to 0 first.\r
+  // Make sure none of the boot logo location parameters are NULL.\r
   //\r
-  Buffer[ChecksumOffset] = 0;\r
+  if (BltBuffer == NULL || DestinationX == NULL || DestinationY == NULL ||\r
+      Width == NULL || Height == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
   //\r
-  // Update checksum value.\r
+  // Boot logo is valid.  Return values from module globals.\r
   //\r
-  Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);\r
+  *BltBuffer    = mLogoBltBuffer;\r
+  *DestinationX = mLogoDestX;\r
+  *DestinationY = mLogoDestY;\r
+  *Width        = mLogoWidth;\r
+  *Height       = mLogoHeight;\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Install Boot Graphics Resource Table to ACPI table.\r
+  Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
+  install the Boot Graphics Resource Table.\r
 \r
-  @return Status code.\r
+  @param[in]  Event   The Event that is being processed.\r
+  @param[in]  Context The Event Context.\r
 \r
 **/\r
-EFI_STATUS\r
-InstallBootGraphicsResourceTable (\r
-  VOID\r
+VOID\r
+EFIAPI\r
+BgrtReadyToBootEventNotify (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_ACPI_TABLE_PROTOCOL       *AcpiTableProtocol;\r
-  UINT8                         *ImageBuffer;\r
-  UINTN                         PaddingSize;\r
-  UINTN                         BmpSize;\r
-  UINTN                         OrigBmpSize;\r
-  UINT8                         *Image;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPixel;\r
-  UINTN                         Col;\r
-  UINTN                         Row;\r
+  EFI_STATUS               Status;\r
+  EFI_ACPI_TABLE_PROTOCOL  *AcpiTableProtocol;\r
+  VOID                     *ImageBuffer;\r
+  UINT32                   BmpSize;\r
 \r
   //\r
   // Get ACPI Table protocol.\r
   //\r
-  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiAcpiTableProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &AcpiTableProtocol\r
+                  );\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    return;\r
   }\r
 \r
   //\r
@@ -264,109 +439,85 @@ InstallBootGraphicsResourceTable (
       //\r
       // Nothing has changed\r
       //\r
-      return EFI_SUCCESS;\r
+      return;\r
     } else {\r
       //\r
-      // If BGRT data change happens. Uninstall Orignal AcpiTable first\r
+      // If BGRT data change happens, then uninstall orignal AcpiTable first\r
       //\r
       Status = AcpiTableProtocol->UninstallAcpiTable (\r
                                     AcpiTableProtocol,\r
                                     mBootGraphicsResourceTableKey\r
                                     );\r
       if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      } \r
+        return;\r
+      }\r
     }\r
   } else {\r
     //\r
-    // Check whether Logo exist.\r
+    // Check whether Logo exists\r
     //\r
-    if ( mLogoBltBuffer == NULL) {\r
-      return EFI_NOT_FOUND;\r
+    if (mLogoBltBuffer == NULL) {\r
+      return;\r
     }\r
   }\r
 \r
   if (mAcpiBgrtBufferChanged) {\r
     //\r
-    // reserve original BGRT buffer size\r
+    // Free the old BMP image buffer\r
     //\r
-    OrigBmpSize = mBmpImageHeaderTemplate.ImageSize + sizeof (BMP_IMAGE_HEADER);\r
-    //\r
-    // Free orignal BMP memory \r
-    // \r
-    if (mBootGraphicsResourceTableTemplate.ImageAddress) {\r
-      gBS->FreePages(mBootGraphicsResourceTableTemplate.ImageAddress, EFI_SIZE_TO_PAGES(OrigBmpSize));\r
+    ImageBuffer = (UINT8 *)(UINTN)mBootGraphicsResourceTableTemplate.ImageAddress;\r
+    if (ImageBuffer != NULL) {\r
+      FreePool (ImageBuffer);\r
     }\r
 \r
     //\r
-    // Allocate memory for BMP file.\r
+    // Convert GOP Blt buffer to BMP image.  Pass in ImageBuffer set to NULL\r
+    // so the BMP image is allocated by TranslateGopBltToBmp().\r
     //\r
-    PaddingSize = mLogoWidth & 0x3;\r
-\r
-    //\r
-    // First check mLogoWidth * 3 + PaddingSize doesn't overflow\r
-    //\r
-    if (mLogoWidth > (((UINT32) ~0) - PaddingSize) / 3 ) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
-    //\r
-    // Second check (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER) doesn't overflow\r
-    //\r
-    if (mLogoHeight > (((UINT32) ~0) - sizeof (BMP_IMAGE_HEADER)) / (mLogoWidth * 3 + PaddingSize)) {\r
-      return EFI_UNSUPPORTED;\r
+    ImageBuffer = NULL;\r
+    Status = TranslateGopBltToBmp (\r
+               mLogoBltBuffer,\r
+               (UINT32)mLogoHeight,\r
+               (UINT32)mLogoWidth,\r
+               &ImageBuffer,\r
+               &BmpSize\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
     }\r
 \r
     //\r
-    // The image should be stored in EfiBootServicesData, allowing the system to reclaim the memory\r
-    //\r
-    BmpSize = (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER);\r
-    ImageBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BmpSize));\r
-    if (ImageBuffer == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    ZeroMem (ImageBuffer, BmpSize);\r
-\r
-    mBmpImageHeaderTemplate.Size = (UINT32) BmpSize;\r
-    mBmpImageHeaderTemplate.ImageSize = (UINT32) BmpSize - sizeof (BMP_IMAGE_HEADER);\r
-    mBmpImageHeaderTemplate.PixelWidth = (UINT32) mLogoWidth;\r
-    mBmpImageHeaderTemplate.PixelHeight = (UINT32) mLogoHeight;\r
-    CopyMem (ImageBuffer, &mBmpImageHeaderTemplate, sizeof (BMP_IMAGE_HEADER));\r
-    \r
-    //\r
-    // Convert BLT buffer to BMP file.\r
+    // Free the logo buffer\r
     //\r
-    Image = ImageBuffer + sizeof (BMP_IMAGE_HEADER);\r
-    for (Row = 0; Row < mLogoHeight; Row++) {\r
-    BltPixel = &mLogoBltBuffer[(mLogoHeight - Row - 1) * mLogoWidth];\r
-\r
-    for (Col = 0; Col < mLogoWidth; Col++) {\r
-      *Image++ = BltPixel->Blue;\r
-      *Image++ = BltPixel->Green;\r
-      *Image++ = BltPixel->Red;\r
-      BltPixel++;\r
-    }\r
-\r
-      //\r
-      // Padding for 4 byte alignment.\r
-      //\r
-      Image += PaddingSize;\r
-    }\r
     FreePool (mLogoBltBuffer);\r
     mLogoBltBuffer = NULL;\r
 \r
-    mBootGraphicsResourceTableTemplate.ImageAddress = (UINT64) (UINTN) ImageBuffer;\r
-    mBootGraphicsResourceTableTemplate.ImageOffsetX = (UINT32) mLogoDestX;\r
-    mBootGraphicsResourceTableTemplate.ImageOffsetY = (UINT32) mLogoDestY;\r
+    //\r
+    // Update BMP image fields of the Boot Graphics Resource Table\r
+    //\r
+    mBootGraphicsResourceTableTemplate.ImageAddress = (UINT64)(UINTN)ImageBuffer;\r
+    mBootGraphicsResourceTableTemplate.ImageOffsetX = (UINT32)mLogoDestX;\r
+    mBootGraphicsResourceTableTemplate.ImageOffsetY = (UINT32)mLogoDestY;\r
   }\r
 \r
-  mBootGraphicsResourceTableTemplate.Status = (UINT8) (mIsLogoValid ? EFI_ACPI_5_0_BGRT_STATUS_VALID : EFI_ACPI_5_0_BGRT_STATUS_INVALID);\r
+  //\r
+  // Update Status field of Boot Graphics Resource Table\r
+  //\r
+  if (mIsLogoValid) {\r
+    mBootGraphicsResourceTableTemplate.Status = EFI_ACPI_5_0_BGRT_STATUS_VALID;\r
+  } else {\r
+    mBootGraphicsResourceTableTemplate.Status = EFI_ACPI_5_0_BGRT_STATUS_INVALID;\r
+  }\r
 \r
   //\r
-  // Update Checksum.\r
+  // Update Checksum of Boot Graphics Resource Table\r
   //\r
-  BgrtAcpiTableChecksum ((UINT8 *) &mBootGraphicsResourceTableTemplate, sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE));\r
+  mBootGraphicsResourceTableTemplate.Header.Checksum = 0;\r
+  mBootGraphicsResourceTableTemplate.Header.Checksum =\r
+    CalculateCheckSum8 (\r
+      (UINT8 *)&mBootGraphicsResourceTableTemplate,\r
+      sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE)\r
+      );\r
 \r
   //\r
   // Publish Boot Graphics Resource Table.\r
@@ -378,32 +529,12 @@ InstallBootGraphicsResourceTable (
                                 &mBootGraphicsResourceTableKey\r
                                 );\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    return;\r
   }\r
 \r
-  mAcpiBgrtInstalled = TRUE;\r
+  mAcpiBgrtInstalled     = TRUE;\r
   mAcpiBgrtStatusChanged = FALSE;\r
   mAcpiBgrtBufferChanged = FALSE;\r
-  \r
-  return Status;\r
-}\r
-\r
-/**\r
-  Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
-  install the Boot Graphics Resource Table.\r
-\r
-  @param[in]  Event   The Event that is being processed.\r
-  @param[in]  Context The Event Context.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BgrtReadyToBootEventNotify (\r
-  IN EFI_EVENT        Event,\r
-  IN VOID             *Context\r
-  )\r
-{\r
-  InstallBootGraphicsResourceTable ();\r
 }\r
 \r
 /**\r
@@ -419,31 +550,37 @@ BgrtReadyToBootEventNotify (
 EFI_STATUS\r
 EFIAPI\r
 BootGraphicsDxeEntryPoint (\r
-  IN EFI_HANDLE          ImageHandle,\r
-  IN EFI_SYSTEM_TABLE    *SystemTable\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  UINT64      OemTableId;\r
+  EFI_STATUS                   Status;\r
+  EFI_ACPI_DESCRIPTION_HEADER  *Header;\r
 \r
+  //\r
+  // Update Header fields of Boot Graphics Resource Table from PCDs\r
+  //\r
+  Header = &mBootGraphicsResourceTableTemplate.Header;\r
+  ZeroMem (Header->OemId, sizeof (Header->OemId));\r
   CopyMem (\r
-    mBootGraphicsResourceTableTemplate.Header.OemId,\r
+    Header->OemId,\r
     PcdGetPtr (PcdAcpiDefaultOemId),\r
-    sizeof (mBootGraphicsResourceTableTemplate.Header.OemId)\r
+    MIN (PcdGetSize (PcdAcpiDefaultOemId), sizeof (Header->OemId))\r
     );\r
-  OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
-  CopyMem (&mBootGraphicsResourceTableTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
-  mBootGraphicsResourceTableTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);\r
-  mBootGraphicsResourceTableTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);\r
-  mBootGraphicsResourceTableTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
+  WriteUnaligned64 (&Header->OemTableId, PcdGet64 (PcdAcpiDefaultOemTableId));\r
+  Header->OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);\r
+  Header->CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);\r
+  Header->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
 \r
   //\r
-  // Install Boot Logo protocol.\r
+  // Install Boot Logo and Boot Logo 2 Protocols.\r
   //\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &mBootLogoHandle,\r
                   &gEfiBootLogoProtocolGuid,\r
                   &mBootLogoProtocolTemplate,\r
+                  &gEdkiiBootLogo2ProtocolGuid,\r
+                  &mBootLogo2ProtocolTemplate,\r
                   NULL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r