2 This module install ACPI Boot Graphics Resource Table (BGRT).
4 Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <IndustryStandard/Acpi.h>
17 #include <IndustryStandard/Bmp.h>
19 #include <Protocol/AcpiTable.h>
20 #include <Protocol/GraphicsOutput.h>
21 #include <Protocol/BootLogo.h>
23 #include <Guid/EventGroup.h>
25 #include <Library/BaseLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 #include <Library/UefiBootServicesTableLib.h>
29 #include <Library/DebugLib.h>
30 #include <Library/PcdLib.h>
35 EFI_EVENT mBootGraphicsReadyToBootEvent
;
36 UINTN mBootGraphicsResourceTableKey
= 0;
38 EFI_HANDLE mBootLogoHandle
= NULL
;
39 BOOLEAN mIsLogoValid
= FALSE
;
40 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*mLogoBltBuffer
= NULL
;
44 UINTN mLogoHeight
= 0;
46 BMP_IMAGE_HEADER mBmpImageHeaderTemplate
= {
49 0, // Size will be updated at runtime
51 sizeof (BMP_IMAGE_HEADER
), // ImageOffset
52 sizeof (BMP_IMAGE_HEADER
) - OFFSET_OF (BMP_IMAGE_HEADER
, HeaderSize
), // HeaderSize
53 0, // PixelWidth will be updated at runtime
54 0, // PixelHeight will be updated at runtime
58 0, // ImageSize will be updated at runtime
65 BOOLEAN mAcpiBgrtInstalled
= FALSE
;
66 BOOLEAN mAcpiBgrtStatusChanged
= FALSE
;
67 BOOLEAN mAcpiBgrtBufferChanged
= FALSE
;
69 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate
= {
71 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE
,
72 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE
),
73 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION
, // Revision
74 0x00, // Checksum will be updated at runtime
76 // It is expected that these values will be updated at EntryPoint.
78 {0x00}, // OEM ID is a 6 bytes long field
79 0x00, // OEM Table ID(8 bytes long)
82 0x00, // Creator Revision
84 EFI_ACPI_5_0_BGRT_VERSION
, // Version
85 EFI_ACPI_5_0_BGRT_STATUS_VALID
, // Status
86 EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP
, // Image Type
93 Update information of logo image drawn on screen.
95 @param This The pointer to the Boot Logo protocol instance.
96 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer
97 is set to NULL, it indicates that logo image is no
99 @param DestinationX X coordinate of destination for the BltBuffer.
100 @param DestinationY Y coordinate of destination for the BltBuffer.
101 @param Width Width of rectangle in BltBuffer in pixels.
102 @param Height Hight of rectangle in BltBuffer in pixels.
104 @retval EFI_SUCCESS The boot logo information was updated.
105 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
106 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to
107 insufficient memory resources.
113 IN EFI_BOOT_LOGO_PROTOCOL
*This
,
114 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
115 IN UINTN DestinationX
,
116 IN UINTN DestinationY
,
121 EFI_BOOT_LOGO_PROTOCOL mBootLogoProtocolTemplate
= { SetBootLogo
};
124 Update information of logo image drawn on screen.
126 @param This The pointer to the Boot Logo protocol instance.
127 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer
128 is set to NULL, it indicates that logo image is no
129 longer on the screen.
130 @param DestinationX X coordinate of destination for the BltBuffer.
131 @param DestinationY Y coordinate of destination for the BltBuffer.
132 @param Width Width of rectangle in BltBuffer in pixels.
133 @param Height Hight of rectangle in BltBuffer in pixels.
135 @retval EFI_SUCCESS The boot logo information was updated.
136 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
137 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to
138 insufficient memory resources.
144 IN EFI_BOOT_LOGO_PROTOCOL
*This
,
145 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
146 IN UINTN DestinationX
,
147 IN UINTN DestinationY
,
154 if (BltBuffer
== NULL
) {
155 mIsLogoValid
= FALSE
;
156 mAcpiBgrtStatusChanged
= TRUE
;
160 if (Width
== 0 || Height
== 0) {
161 return EFI_INVALID_PARAMETER
;
164 mAcpiBgrtBufferChanged
= TRUE
;
165 if (mLogoBltBuffer
!= NULL
) {
166 FreePool (mLogoBltBuffer
);
167 mLogoBltBuffer
= NULL
;
171 // Ensure the Height * Width doesn't overflow
173 if (Height
> DivU64x64Remainder ((UINTN
) ~0, Width
, NULL
)) {
174 return EFI_UNSUPPORTED
;
176 BufferSize
= MultU64x64 (Width
, Height
);
179 // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
181 if (BufferSize
> DivU64x32 ((UINTN
) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
182 return EFI_UNSUPPORTED
;
185 mLogoBltBuffer
= AllocateCopyPool (
186 (UINTN
)BufferSize
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
),
189 if (mLogoBltBuffer
== NULL
) {
190 return EFI_OUT_OF_RESOURCES
;
192 mLogoDestX
= DestinationX
;
193 mLogoDestY
= DestinationY
;
195 mLogoHeight
= Height
;
202 This function calculates and updates an UINT8 checksum.
204 @param[in] Buffer Pointer to buffer to checksum.
205 @param[in] Size Number of bytes to checksum.
209 BgrtAcpiTableChecksum (
214 UINTN ChecksumOffset
;
216 ChecksumOffset
= OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
, Checksum
);
219 // Set checksum to 0 first.
221 Buffer
[ChecksumOffset
] = 0;
224 // Update checksum value.
226 Buffer
[ChecksumOffset
] = CalculateCheckSum8 (Buffer
, Size
);
230 Allocate EfiBootServicesData below 4G memory address.
232 This function allocates EfiBootServicesData below 4G memory address.
234 @param[in] Size Size of memory to allocate.
236 @return Allocated address for output.
240 BgrtAllocateBsDataMemoryBelow4G (
245 EFI_PHYSICAL_ADDRESS Address
;
249 Pages
= EFI_SIZE_TO_PAGES (Size
);
250 Address
= 0xffffffff;
252 Status
= gBS
->AllocatePages (
258 ASSERT_EFI_ERROR (Status
);
260 Buffer
= (VOID
*) (UINTN
) Address
;
261 ZeroMem (Buffer
, Size
);
267 Install Boot Graphics Resource Table to ACPI table.
273 InstallBootGraphicsResourceTable (
278 EFI_ACPI_TABLE_PROTOCOL
*AcpiTableProtocol
;
284 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltPixel
;
289 // Get ACPI Table protocol.
291 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**) &AcpiTableProtocol
);
292 if (EFI_ERROR (Status
)) {
297 // Check whether Boot Graphics Resource Table is already installed.
299 if (mAcpiBgrtInstalled
) {
300 if (!mAcpiBgrtStatusChanged
&& !mAcpiBgrtBufferChanged
) {
302 // Nothing has changed
307 // If BGRT data change happens. Uninstall Orignal AcpiTable first
309 Status
= AcpiTableProtocol
->UninstallAcpiTable (
311 mBootGraphicsResourceTableKey
313 if (EFI_ERROR (Status
)) {
319 // Check whether Logo exist.
321 if ( mLogoBltBuffer
== NULL
) {
322 return EFI_NOT_FOUND
;
326 if (mAcpiBgrtBufferChanged
) {
328 // reserve original BGRT buffer size
330 OrigBmpSize
= mBmpImageHeaderTemplate
.ImageSize
+ sizeof (BMP_IMAGE_HEADER
);
332 // Free orignal BMP memory
334 if (mBootGraphicsResourceTableTemplate
.ImageAddress
) {
335 gBS
->FreePages(mBootGraphicsResourceTableTemplate
.ImageAddress
, EFI_SIZE_TO_PAGES(OrigBmpSize
));
339 // Allocate memory for BMP file.
341 PaddingSize
= mLogoWidth
& 0x3;
344 // First check mLogoWidth * 3 + PaddingSize doesn't overflow
346 if (mLogoWidth
> (((UINT32
) ~0) - PaddingSize
) / 3 ) {
347 return EFI_UNSUPPORTED
;
351 // Second check (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER) doesn't overflow
353 if (mLogoHeight
> (((UINT32
) ~0) - sizeof (BMP_IMAGE_HEADER
)) / (mLogoWidth
* 3 + PaddingSize
)) {
354 return EFI_UNSUPPORTED
;
358 // The image should be stored in EfiBootServicesData, allowing the system to reclaim the memory
360 BmpSize
= (mLogoWidth
* 3 + PaddingSize
) * mLogoHeight
+ sizeof (BMP_IMAGE_HEADER
);
361 ImageBuffer
= BgrtAllocateBsDataMemoryBelow4G (BmpSize
);
362 if (ImageBuffer
== NULL
) {
363 return EFI_OUT_OF_RESOURCES
;
366 mBmpImageHeaderTemplate
.Size
= (UINT32
) BmpSize
;
367 mBmpImageHeaderTemplate
.ImageSize
= (UINT32
) BmpSize
- sizeof (BMP_IMAGE_HEADER
);
368 mBmpImageHeaderTemplate
.PixelWidth
= (UINT32
) mLogoWidth
;
369 mBmpImageHeaderTemplate
.PixelHeight
= (UINT32
) mLogoHeight
;
370 CopyMem (ImageBuffer
, &mBmpImageHeaderTemplate
, sizeof (BMP_IMAGE_HEADER
));
373 // Convert BLT buffer to BMP file.
375 Image
= ImageBuffer
+ sizeof (BMP_IMAGE_HEADER
);
376 for (Row
= 0; Row
< mLogoHeight
; Row
++) {
377 BltPixel
= &mLogoBltBuffer
[(mLogoHeight
- Row
- 1) * mLogoWidth
];
379 for (Col
= 0; Col
< mLogoWidth
; Col
++) {
380 *Image
++ = BltPixel
->Blue
;
381 *Image
++ = BltPixel
->Green
;
382 *Image
++ = BltPixel
->Red
;
387 // Padding for 4 byte alignment.
389 Image
+= PaddingSize
;
391 FreePool (mLogoBltBuffer
);
392 mLogoBltBuffer
= NULL
;
394 mBootGraphicsResourceTableTemplate
.ImageAddress
= (UINT64
) (UINTN
) ImageBuffer
;
395 mBootGraphicsResourceTableTemplate
.ImageOffsetX
= (UINT32
) mLogoDestX
;
396 mBootGraphicsResourceTableTemplate
.ImageOffsetY
= (UINT32
) mLogoDestY
;
399 mBootGraphicsResourceTableTemplate
.Status
= (UINT8
) (mIsLogoValid
? EFI_ACPI_5_0_BGRT_STATUS_VALID
: EFI_ACPI_5_0_BGRT_STATUS_INVALID
);
404 BgrtAcpiTableChecksum ((UINT8
*) &mBootGraphicsResourceTableTemplate
, sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE
));
407 // Publish Boot Graphics Resource Table.
409 Status
= AcpiTableProtocol
->InstallAcpiTable (
411 &mBootGraphicsResourceTableTemplate
,
412 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE
),
413 &mBootGraphicsResourceTableKey
415 if (EFI_ERROR (Status
)) {
419 mAcpiBgrtInstalled
= TRUE
;
420 mAcpiBgrtStatusChanged
= FALSE
;
421 mAcpiBgrtBufferChanged
= FALSE
;
427 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to
428 install the Boot Graphics Resource Table.
430 @param[in] Event The Event that is being processed.
431 @param[in] Context The Event Context.
436 BgrtReadyToBootEventNotify (
441 InstallBootGraphicsResourceTable ();
445 The module Entry Point of the Boot Graphics Resource Table DXE driver.
447 @param[in] ImageHandle The firmware allocated handle for the EFI image.
448 @param[in] SystemTable A pointer to the EFI System Table.
450 @retval EFI_SUCCESS The entry point is executed successfully.
451 @retval Other Some error occurs when executing this entry point.
456 BootGraphicsDxeEntryPoint (
457 IN EFI_HANDLE ImageHandle
,
458 IN EFI_SYSTEM_TABLE
*SystemTable
465 mBootGraphicsResourceTableTemplate
.Header
.OemId
,
466 PcdGetPtr (PcdAcpiDefaultOemId
),
467 sizeof (mBootGraphicsResourceTableTemplate
.Header
.OemId
)
469 OemTableId
= PcdGet64 (PcdAcpiDefaultOemTableId
);
470 CopyMem (&mBootGraphicsResourceTableTemplate
.Header
.OemTableId
, &OemTableId
, sizeof (UINT64
));
471 mBootGraphicsResourceTableTemplate
.Header
.OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
472 mBootGraphicsResourceTableTemplate
.Header
.CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
473 mBootGraphicsResourceTableTemplate
.Header
.CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
476 // Install Boot Logo protocol.
478 Status
= gBS
->InstallMultipleProtocolInterfaces (
480 &gEfiBootLogoProtocolGuid
,
481 &mBootLogoProtocolTemplate
,
484 ASSERT_EFI_ERROR (Status
);
487 // Register notify function to install BGRT on ReadyToBoot Event.
489 Status
= gBS
->CreateEventEx (
492 BgrtReadyToBootEventNotify
,
494 &gEfiEventReadyToBootGuid
,
495 &mBootGraphicsReadyToBootEvent
497 ASSERT_EFI_ERROR (Status
);