From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../BootGraphicsResourceTableDxe.c | 602 +++++++++++++++++++++ 1 file changed, 602 insertions(+) create mode 100644 roms/edk2/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c (limited to 'roms/edk2/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c') diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c b/roms/edk2/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c new file mode 100644 index 000000000..d16872e14 --- /dev/null +++ b/roms/edk2/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c @@ -0,0 +1,602 @@ +/** @file + This module install ACPI Boot Graphics Resource Table (BGRT). + + Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2016, Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Update information of logo image drawn on screen. + + @param[in] This The pointer to the Boot Logo protocol 2 instance. + @param[in] BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer + is set to NULL, it indicates that logo image is no + longer on the screen. + @param[in] DestinationX X coordinate of destination for the BltBuffer. + @param[in] DestinationY Y coordinate of destination for the BltBuffer. + @param[in] Width Width of rectangle in BltBuffer in pixels. + @param[in] Height Hight of rectangle in BltBuffer in pixels. + + @retval EFI_SUCCESS The boot logo information was updated. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to + insufficient memory resources. +**/ +EFI_STATUS +EFIAPI +SetBootLogo ( + IN EFI_BOOT_LOGO_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height + ); + +/** + Update information of logo image drawn on screen. + + @param[in] This The pointer to the Boot Logo protocol 2 instance. + @param[in] BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer + is set to NULL, it indicates that logo image is no + longer on the screen. + @param[in] DestinationX X coordinate of destination for the BltBuffer. + @param[in] DestinationY Y coordinate of destination for the BltBuffer. + @param[in] Width Width of rectangle in BltBuffer in pixels. + @param[in] Height Hight of rectangle in BltBuffer in pixels. + + @retval EFI_SUCCESS The boot logo information was updated. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to + insufficient memory resources. +**/ +EFI_STATUS +EFIAPI +SetBootLogo2 ( + IN EDKII_BOOT_LOGO2_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height + ); + +/** + Get the location of the boot logo on the screen. + + @param[in] This The pointer to the Boot Logo Protocol 2 instance + @param[out] BltBuffer Returns pointer to the GOP BLT buffer that was + previously registered with SetBootLogo2(). The + buffer returned must not be modified or freed. + @param[out] DestinationX Returns the X start position of the GOP BLT buffer + that was previously registered with SetBootLogo2(). + @param[out] DestinationY Returns the Y start position of the GOP BLT buffer + that was previously registered with SetBootLogo2(). + @param[out] Width Returns the width of the GOP BLT buffer + that was previously registered with SetBootLogo2(). + @param[out] Height Returns the height of the GOP BLT buffer + that was previously registered with SetBootLogo2(). + + @retval EFI_SUCCESS The location of the boot logo was returned. + @retval EFI_NOT_READY The boot logo has not been set. + @retval EFI_INVALID_PARAMETER BltBuffer is NULL. + @retval EFI_INVALID_PARAMETER DestinationX is NULL. + @retval EFI_INVALID_PARAMETER DestinationY is NULL. + @retval EFI_INVALID_PARAMETER Width is NULL. + @retval EFI_INVALID_PARAMETER Height is NULL. +**/ +EFI_STATUS +EFIAPI +GetBootLogo2 ( + IN EDKII_BOOT_LOGO2_PROTOCOL *This, + OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltBuffer, + OUT UINTN *DestinationX, + OUT UINTN *DestinationY, + OUT UINTN *Width, + OUT UINTN *Height + ); + +// +// Boot Logo Protocol Handle +// +EFI_HANDLE mBootLogoHandle = NULL; + +// +// Boot Logo Protocol Instance +// +EFI_BOOT_LOGO_PROTOCOL mBootLogoProtocolTemplate = { + SetBootLogo +}; + +/// +/// Boot Logo 2 Protocol instance +/// +EDKII_BOOT_LOGO2_PROTOCOL mBootLogo2ProtocolTemplate = { + SetBootLogo2, + GetBootLogo2 +}; + +EFI_EVENT mBootGraphicsReadyToBootEvent; +UINTN mBootGraphicsResourceTableKey = 0; +BOOLEAN mIsLogoValid = FALSE; +EFI_GRAPHICS_OUTPUT_BLT_PIXEL *mLogoBltBuffer = NULL; +UINTN mLogoDestX = 0; +UINTN mLogoDestY = 0; +UINTN mLogoWidth = 0; +UINTN mLogoHeight = 0; +BOOLEAN mAcpiBgrtInstalled = FALSE; +BOOLEAN mAcpiBgrtStatusChanged = FALSE; +BOOLEAN mAcpiBgrtBufferChanged = FALSE; + +// +// ACPI Boot Graphics Resource Table template +// +EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate = { + { + EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE, + sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE), + EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION, // Revision + 0x00, // Checksum will be updated at runtime + // + // It is expected that these values will be updated at EntryPoint. + // + {0x00}, // OEM ID is a 6 bytes long field + 0x00, // OEM Table ID(8 bytes long) + 0x00, // OEM Revision + 0x00, // Creator ID + 0x00, // Creator Revision + }, + EFI_ACPI_5_0_BGRT_VERSION, // Version + EFI_ACPI_5_0_BGRT_STATUS_VALID, // Status + EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP, // Image Type + 0, // Image Address + 0, // Image Offset X + 0 // Image Offset Y +}; + +/** + Update information of logo image drawn on screen. + + @param This The pointer to the Boot Logo protocol instance. + @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer + is set to NULL, it indicates that logo image is no + longer on the screen. + @param DestinationX X coordinate of destination for the BltBuffer. + @param DestinationY Y coordinate of destination for the BltBuffer. + @param Width Width of rectangle in BltBuffer in pixels. + @param Height Hight of rectangle in BltBuffer in pixels. + + @retval EFI_SUCCESS The boot logo information was updated. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to + insufficient memory resources. + +**/ +EFI_STATUS +EFIAPI +SetBootLogo ( + IN EFI_BOOT_LOGO_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height + ) +{ + // + // Call same service in Boot Logo 2 Protocol + // + return SetBootLogo2 ( + &mBootLogo2ProtocolTemplate, + BltBuffer, + DestinationX, + DestinationY, + Width, + Height + ); +} + +/** + Update information of logo image drawn on screen. + + @param[in] This The pointer to the Boot Logo protocol 2 instance. + @param[in] BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer + is set to NULL, it indicates that logo image is no + longer on the screen. + @param[in] DestinationX X coordinate of destination for the BltBuffer. + @param[in] DestinationY Y coordinate of destination for the BltBuffer. + @param[in] Width Width of rectangle in BltBuffer in pixels. + @param[in] Height Hight of rectangle in BltBuffer in pixels. + + @retval EFI_SUCCESS The boot logo information was updated. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to + insufficient memory resources. +**/ +EFI_STATUS +EFIAPI +SetBootLogo2 ( + IN EDKII_BOOT_LOGO2_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + UINT32 Result32; + + if (BltBuffer == NULL) { + mIsLogoValid = FALSE; + mAcpiBgrtStatusChanged = TRUE; + return EFI_SUCCESS; + } + + // + // Width and height are not allowed to be zero. + // + if (Width == 0 || Height == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Verify destination, width, and height do not overflow 32-bit values. + // The Boot Graphics Resource Table only has 32-bit fields for these values. + // + Status = SafeUintnToUint32 (DestinationX, &Result32); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + Status = SafeUintnToUint32 (DestinationY, &Result32); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + Status = SafeUintnToUint32 (Width, &Result32); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + Status = SafeUintnToUint32 (Height, &Result32); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + + // + // Ensure the Height * Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) does + // not overflow UINTN + // + Status = SafeUintnMult ( + Width, + Height, + &BufferSize + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + Status = SafeUintnMult ( + BufferSize, + sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), + &BufferSize + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Update state + // + mAcpiBgrtBufferChanged = TRUE; + + // + // Free old logo buffer + // + if (mLogoBltBuffer != NULL) { + FreePool (mLogoBltBuffer); + mLogoBltBuffer = NULL; + } + + // + // Allocate new logo buffer + // + mLogoBltBuffer = AllocateCopyPool (BufferSize, BltBuffer); + if (mLogoBltBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mLogoDestX = DestinationX; + mLogoDestY = DestinationY; + mLogoWidth = Width; + mLogoHeight = Height; + mIsLogoValid = TRUE; + + return EFI_SUCCESS; +} + +/** + Get the location of the boot logo on the screen. + + @param[in] This The pointer to the Boot Logo Protocol 2 instance + @param[out] BltBuffer Returns pointer to the GOP BLT buffer that was + previously registered with SetBootLogo2(). The + buffer returned must not be modified or freed. + @param[out] DestinationX Returns the X start position of the GOP BLT buffer + that was previously registered with SetBootLogo2(). + @param[out] DestinationY Returns the Y start position of the GOP BLT buffer + that was previously registered with SetBootLogo2(). + @param[out] Width Returns the width of the GOP BLT buffer + that was previously registered with SetBootLogo2(). + @param[out] Height Returns the height of the GOP BLT buffer + that was previously registered with SetBootLogo2(). + + @retval EFI_SUCCESS The location of the boot logo was returned. + @retval EFI_NOT_READY The boot logo has not been set. + @retval EFI_INVALID_PARAMETER BltBuffer is NULL. + @retval EFI_INVALID_PARAMETER DestinationX is NULL. + @retval EFI_INVALID_PARAMETER DestinationY is NULL. + @retval EFI_INVALID_PARAMETER Width is NULL. + @retval EFI_INVALID_PARAMETER Height is NULL. +**/ +EFI_STATUS +EFIAPI +GetBootLogo2 ( + IN EDKII_BOOT_LOGO2_PROTOCOL *This, + OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltBuffer, + OUT UINTN *DestinationX, + OUT UINTN *DestinationY, + OUT UINTN *Width, + OUT UINTN *Height + ) +{ + // + // If the boot logo has not been set with SetBootLogo() or SetBootLogo() was + // called with a NULL BltBuffer then the boot logo is not valid and + // EFI_NOT_READY is returned. + // + if (mLogoBltBuffer == NULL) { + DEBUG ((DEBUG_ERROR, "Request to get boot logo location before boot logo has been set.\n")); + return EFI_NOT_READY; + } + + // + // Make sure none of the boot logo location parameters are NULL. + // + if (BltBuffer == NULL || DestinationX == NULL || DestinationY == NULL || + Width == NULL || Height == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Boot logo is valid. Return values from module globals. + // + *BltBuffer = mLogoBltBuffer; + *DestinationX = mLogoDestX; + *DestinationY = mLogoDestY; + *Width = mLogoWidth; + *Height = mLogoHeight; + + return EFI_SUCCESS; +} + +/** + Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to + install the Boot Graphics Resource Table. + + @param[in] Event The Event that is being processed. + @param[in] Context The Event Context. + +**/ +VOID +EFIAPI +BgrtReadyToBootEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; + VOID *ImageBuffer; + UINT32 BmpSize; + + // + // Get ACPI Table protocol. + // + Status = gBS->LocateProtocol ( + &gEfiAcpiTableProtocolGuid, + NULL, + (VOID **) &AcpiTableProtocol + ); + if (EFI_ERROR (Status)) { + return; + } + + // + // Check whether Boot Graphics Resource Table is already installed. + // + if (mAcpiBgrtInstalled) { + if (!mAcpiBgrtStatusChanged && !mAcpiBgrtBufferChanged) { + // + // Nothing has changed + // + return; + } else { + // + // If BGRT data change happens, then uninstall orignal AcpiTable first + // + Status = AcpiTableProtocol->UninstallAcpiTable ( + AcpiTableProtocol, + mBootGraphicsResourceTableKey + ); + if (EFI_ERROR (Status)) { + return; + } + } + } else { + // + // Check whether Logo exists + // + if (mLogoBltBuffer == NULL) { + return; + } + } + + if (mAcpiBgrtBufferChanged) { + // + // Free the old BMP image buffer + // + ImageBuffer = (UINT8 *)(UINTN)mBootGraphicsResourceTableTemplate.ImageAddress; + if (ImageBuffer != NULL) { + FreePool (ImageBuffer); + } + + // + // Convert GOP Blt buffer to BMP image. Pass in ImageBuffer set to NULL + // so the BMP image is allocated by TranslateGopBltToBmp(). + // + ImageBuffer = NULL; + Status = TranslateGopBltToBmp ( + mLogoBltBuffer, + (UINT32)mLogoHeight, + (UINT32)mLogoWidth, + &ImageBuffer, + &BmpSize + ); + if (EFI_ERROR (Status)) { + return; + } + + // + // Free the logo buffer + // + FreePool (mLogoBltBuffer); + mLogoBltBuffer = NULL; + + // + // Update BMP image fields of the Boot Graphics Resource Table + // + mBootGraphicsResourceTableTemplate.ImageAddress = (UINT64)(UINTN)ImageBuffer; + mBootGraphicsResourceTableTemplate.ImageOffsetX = (UINT32)mLogoDestX; + mBootGraphicsResourceTableTemplate.ImageOffsetY = (UINT32)mLogoDestY; + } + + // + // Update Status field of Boot Graphics Resource Table + // + if (mIsLogoValid) { + mBootGraphicsResourceTableTemplate.Status = EFI_ACPI_5_0_BGRT_STATUS_VALID; + } else { + mBootGraphicsResourceTableTemplate.Status = EFI_ACPI_5_0_BGRT_STATUS_INVALID; + } + + // + // Update Checksum of Boot Graphics Resource Table + // + mBootGraphicsResourceTableTemplate.Header.Checksum = 0; + mBootGraphicsResourceTableTemplate.Header.Checksum = + CalculateCheckSum8 ( + (UINT8 *)&mBootGraphicsResourceTableTemplate, + sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE) + ); + + // + // Publish Boot Graphics Resource Table. + // + Status = AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + &mBootGraphicsResourceTableTemplate, + sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE), + &mBootGraphicsResourceTableKey + ); + if (EFI_ERROR (Status)) { + return; + } + + mAcpiBgrtInstalled = TRUE; + mAcpiBgrtStatusChanged = FALSE; + mAcpiBgrtBufferChanged = FALSE; +} + +/** + The module Entry Point of the Boot Graphics Resource Table DXE driver. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +BootGraphicsDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *Header; + + // + // Update Header fields of Boot Graphics Resource Table from PCDs + // + Header = &mBootGraphicsResourceTableTemplate.Header; + ZeroMem (Header->OemId, sizeof (Header->OemId)); + CopyMem ( + Header->OemId, + PcdGetPtr (PcdAcpiDefaultOemId), + MIN (PcdGetSize (PcdAcpiDefaultOemId), sizeof (Header->OemId)) + ); + WriteUnaligned64 (&Header->OemTableId, PcdGet64 (PcdAcpiDefaultOemTableId)); + Header->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); + Header->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); + Header->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); + + // + // Install Boot Logo and Boot Logo 2 Protocols. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mBootLogoHandle, + &gEfiBootLogoProtocolGuid, + &mBootLogoProtocolTemplate, + &gEdkiiBootLogo2ProtocolGuid, + &mBootLogo2ProtocolTemplate, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Register notify function to install BGRT on ReadyToBoot Event. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + BgrtReadyToBootEventNotify, + NULL, + &gEfiEventReadyToBootGuid, + &mBootGraphicsReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} -- cgit