/** @file
  This module install ACPI Boot Graphics Resource Table (BGRT).

  Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
  Copyright (c) 2016, Microsoft Corporation<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/

#include <Uefi.h>

#include <IndustryStandard/Acpi.h>

#include <Protocol/AcpiTable.h>
#include <Protocol/GraphicsOutput.h>
#include <Protocol/BootLogo.h>
#include <Protocol/BootLogo2.h>

#include <Guid/EventGroup.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/SafeIntLib.h>
#include <Library/BmpSupportLib.h>

/**
  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;
}
