]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c
Add Acpi50 FPDT and BGRT module into MdeModulePkg.
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / BootGraphicsResourceTableDxe / BootGraphicsResourceTableDxe.c
diff --git a/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c b/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c
new file mode 100644 (file)
index 0000000..cde4f06
--- /dev/null
@@ -0,0 +1,422 @@
+/** @file\r
+  This module install ACPI Boot Graphics Resource Table (BGRT).\r
+\r
+  Copyright (c) 2011, 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
+**/\r
+\r
+#include <Uefi.h>\r
+\r
+#include <IndustryStandard/Acpi50.h>\r
+#include <IndustryStandard/Bmp.h>\r
+\r
+#include <Protocol/AcpiTable.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+#include <Protocol/BootLogo.h>\r
+\r
+#include <Guid/EventGroup.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+//\r
+// ACPI table information used to initialize tables.\r
+//\r
+#define EFI_ACPI_OEM_ID           "INTEL"\r
+#define EFI_ACPI_OEM_TABLE_ID     0x2020204F4E414954ULL // "TIANO   "\r
+#define EFI_ACPI_OEM_REVISION     0x00000001\r
+#define EFI_ACPI_CREATOR_ID       0x5446534D            // TBD "MSFT"\r
+#define EFI_ACPI_CREATOR_REVISION 0x01000013            // TBD\r
+\r
+//\r
+// Module globals.\r
+//\r
+EFI_EVENT  mBootGraphicsReadyToBootEvent;\r
+UINTN      mBootGraphicsResourceTableKey = 0;\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
+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
+\r
+BOOLEAN  mAcpiBgrtInstalled = FALSE;\r
+\r
+EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate = {\r
+  {\r
+    EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,\r
+    sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),\r
+    EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION,     // Revision\r
+    0x00,  // Checksum will be updated at runtime\r
+    //\r
+    // It is expected that these values will be updated at runtime.\r
+    //\r
+    EFI_ACPI_OEM_ID,            // OEMID is a 6 bytes long field\r
+    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)\r
+    EFI_ACPI_OEM_REVISION,      // OEM revision number\r
+    EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID\r
+    EFI_ACPI_CREATOR_REVISION,  // ASL compiler revision number\r
+  },\r
+  EFI_ACPI_5_0_BGRT_VERSION,         // Version\r
+  EFI_ACPI_5_0_BGRT_STATUS_VALID,    // Status\r
+  EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP,  // Image Type\r
+  0,                                 // Image Address\r
+  0,                                 // Image Offset X\r
+  0                                  // Image Offset Y\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
+**/\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
+EFI_BOOT_LOGO_PROTOCOL  mBootLogoProtocolTemplate = { SetBootLogo };\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
+**/\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
+  if (BltBuffer == NULL) {\r
+    mIsLogoValid = FALSE;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (mLogoBltBuffer != NULL) {\r
+    FreePool (mLogoBltBuffer);\r
+  }\r
+\r
+  mLogoBltBuffer = AllocateCopyPool (\r
+                     Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),\r
+                     BltBuffer\r
+                     );\r
+  if (mLogoBltBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\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
+**/\r
+VOID\r
+BgrtAcpiTableChecksum (\r
+  IN UINT8      *Buffer,\r
+  IN UINTN      Size\r
+  )\r
+{\r
+  UINTN ChecksumOffset;\r
+\r
+  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);\r
+\r
+  //\r
+  // Set checksum to 0 first.\r
+  //\r
+  Buffer[ChecksumOffset] = 0;\r
+\r
+  //\r
+  // Update checksum value.\r
+  //\r
+  Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);\r
+}\r
+\r
+/**\r
+  Allocate EfiReservedMemoryType below 4G memory address.\r
+\r
+  This function allocates EfiReservedMemoryType below 4G memory address.\r
+\r
+  @param[in]  Size   Size of memory to allocate.\r
+\r
+  @return Allocated address for output.\r
+\r
+**/\r
+VOID *\r
+BgrtAllocateReservedMemoryBelow4G (\r
+  IN UINTN       Size\r
+  )\r
+{\r
+  UINTN                 Pages;\r
+  EFI_PHYSICAL_ADDRESS  Address;\r
+  EFI_STATUS            Status;\r
+  VOID                  *Buffer;\r
+\r
+  Pages   = EFI_SIZE_TO_PAGES (Size);\r
+  Address = 0xffffffff;\r
+\r
+  Status = gBS->AllocatePages (\r
+                  AllocateMaxAddress,\r
+                  EfiReservedMemoryType,\r
+                  Pages,\r
+                  &Address\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Buffer = (VOID *) (UINTN) Address;\r
+  ZeroMem (Buffer, Size);\r
+\r
+  return Buffer;\r
+}\r
+\r
+/**\r
+  Install Boot Graphics Resource Table to ACPI table.\r
+\r
+  @return Status code.\r
+\r
+**/\r
+EFI_STATUS\r
+InstallBootGraphicsResourceTable (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTableProtocol;\r
+  UINT8                         *ImageBuffer;\r
+  UINTN                         PaddingSize;\r
+  UINTN                         BmpSize;\r
+  UINT8                         *Image;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPixel;\r
+  UINTN                         Col;\r
+  UINTN                         Row;\r
+\r
+  //\r
+  // Check whether Boot Graphics Resource Table is already installed.\r
+  //\r
+  if (mAcpiBgrtInstalled) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Get ACPI Table protocol.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Check whether Logo exist.\r
+  //\r
+  if (mLogoBltBuffer == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Allocate memory for BMP file.\r
+  //\r
+  PaddingSize = mLogoWidth & 0x3;\r
+  BmpSize = (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER);\r
+  ImageBuffer = BgrtAllocateReservedMemoryBelow4G (BmpSize);\r
+  if (ImageBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\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
+  //\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.Status = (UINT8) (mIsLogoValid ? EFI_ACPI_5_0_BGRT_STATUS_VALID : EFI_ACPI_5_0_BGRT_STATUS_INVALID);\r
+  mBootGraphicsResourceTableTemplate.ImageAddress = (UINT64) (UINTN) ImageBuffer;\r
+  mBootGraphicsResourceTableTemplate.ImageOffsetX = (UINT32) mLogoDestX;\r
+  mBootGraphicsResourceTableTemplate.ImageOffsetY = (UINT32) mLogoDestY;\r
+\r
+  //\r
+  // Update Checksum.\r
+  //\r
+  BgrtAcpiTableChecksum ((UINT8 *) &mBootGraphicsResourceTableTemplate, sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE));\r
+\r
+  //\r
+  // Publish Boot Graphics Resource Table.\r
+  //\r
+  Status = AcpiTableProtocol->InstallAcpiTable (\r
+                                AcpiTableProtocol,\r
+                                &mBootGraphicsResourceTableTemplate,\r
+                                sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),\r
+                                &mBootGraphicsResourceTableKey\r
+                                );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  mAcpiBgrtInstalled = TRUE;\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
+  The module Entry Point of the Boot Graphics Resource Table DXE driver.\r
+\r
+  @param[in]  ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param[in]  SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS    The entry point is executed successfully.\r
+  @retval Other          Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootGraphicsDxeEntryPoint (\r
+  IN EFI_HANDLE          ImageHandle,\r
+  IN EFI_SYSTEM_TABLE    *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Install Boot Logo protocol.\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &mBootLogoHandle,\r
+                  &gEfiBootLogoProtocolGuid,\r
+                  &mBootLogoProtocolTemplate,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Register notify function to install BGRT on ReadyToBoot Event.\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  BgrtReadyToBootEventNotify,\r
+                  NULL,\r
+                  &gEfiEventReadyToBootGuid,\r
+                  &mBootGraphicsReadyToBootEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r