--- /dev/null
+/** @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