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>
32 // ACPI table information used to initialize tables.
34 #define EFI_ACPI_OEM_ID "INTEL"
35 #define EFI_ACPI_OEM_TABLE_ID 0x2020204F4E414954ULL // "TIANO "
36 #define EFI_ACPI_OEM_REVISION 0x00000001
37 #define EFI_ACPI_CREATOR_ID 0x5446534D // TBD "MSFT"
38 #define EFI_ACPI_CREATOR_REVISION 0x01000013 // TBD
43 EFI_EVENT mBootGraphicsReadyToBootEvent
;
44 UINTN mBootGraphicsResourceTableKey
= 0;
46 EFI_HANDLE mBootLogoHandle
= NULL
;
47 BOOLEAN mIsLogoValid
= FALSE
;
48 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*mLogoBltBuffer
= NULL
;
52 UINTN mLogoHeight
= 0;
54 BMP_IMAGE_HEADER mBmpImageHeaderTemplate
= {
57 0, // Size will be updated at runtime
59 sizeof (BMP_IMAGE_HEADER
), // ImageOffset
60 sizeof (BMP_IMAGE_HEADER
) - OFFSET_OF (BMP_IMAGE_HEADER
, HeaderSize
), // HeaderSize
61 0, // PixelWidth will be updated at runtime
62 0, // PixelHeight will be updated at runtime
66 0, // ImageSize will be updated at runtime
73 BOOLEAN mAcpiBgrtInstalled
= FALSE
;
74 BOOLEAN mAcpiBgrtStatusChanged
= FALSE
;
75 BOOLEAN mAcpiBgrtBufferChanged
= FALSE
;
77 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate
= {
79 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE
,
80 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE
),
81 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION
, // Revision
82 0x00, // Checksum will be updated at runtime
84 // It is expected that these values will be updated at runtime.
86 EFI_ACPI_OEM_ID
, // OEMID is a 6 bytes long field
87 EFI_ACPI_OEM_TABLE_ID
, // OEM table identification(8 bytes long)
88 EFI_ACPI_OEM_REVISION
, // OEM revision number
89 EFI_ACPI_CREATOR_ID
, // ASL compiler vendor ID
90 EFI_ACPI_CREATOR_REVISION
, // ASL compiler revision number
92 EFI_ACPI_5_0_BGRT_VERSION
, // Version
93 EFI_ACPI_5_0_BGRT_STATUS_VALID
, // Status
94 EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP
, // Image Type
101 Update information of logo image drawn on screen.
103 @param This The pointer to the Boot Logo protocol instance.
104 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer
105 is set to NULL, it indicates that logo image is no
106 longer on the screen.
107 @param DestinationX X coordinate of destination for the BltBuffer.
108 @param DestinationY Y coordinate of destination for the BltBuffer.
109 @param Width Width of rectangle in BltBuffer in pixels.
110 @param Height Hight of rectangle in BltBuffer in pixels.
112 @retval EFI_SUCCESS The boot logo information was updated.
113 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
114 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to
115 insufficient memory resources.
121 IN EFI_BOOT_LOGO_PROTOCOL
*This
,
122 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
123 IN UINTN DestinationX
,
124 IN UINTN DestinationY
,
129 EFI_BOOT_LOGO_PROTOCOL mBootLogoProtocolTemplate
= { SetBootLogo
};
132 Update information of logo image drawn on screen.
134 @param This The pointer to the Boot Logo protocol instance.
135 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer
136 is set to NULL, it indicates that logo image is no
137 longer on the screen.
138 @param DestinationX X coordinate of destination for the BltBuffer.
139 @param DestinationY Y coordinate of destination for the BltBuffer.
140 @param Width Width of rectangle in BltBuffer in pixels.
141 @param Height Hight of rectangle in BltBuffer in pixels.
143 @retval EFI_SUCCESS The boot logo information was updated.
144 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
145 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to
146 insufficient memory resources.
152 IN EFI_BOOT_LOGO_PROTOCOL
*This
,
153 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
154 IN UINTN DestinationX
,
155 IN UINTN DestinationY
,
162 if (BltBuffer
== NULL
) {
163 mIsLogoValid
= FALSE
;
164 mAcpiBgrtStatusChanged
= TRUE
;
168 if (Width
== 0 || Height
== 0) {
169 return EFI_INVALID_PARAMETER
;
172 mAcpiBgrtBufferChanged
= TRUE
;
173 if (mLogoBltBuffer
!= NULL
) {
174 FreePool (mLogoBltBuffer
);
175 mLogoBltBuffer
= NULL
;
179 // Ensure the Height * Width doesn't overflow
181 if (Height
> DivU64x64Remainder ((UINTN
) ~0, Width
, NULL
)) {
182 return EFI_UNSUPPORTED
;
184 BufferSize
= MultU64x64 (Width
, Height
);
187 // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
189 if (BufferSize
> DivU64x32 ((UINTN
) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
))) {
190 return EFI_UNSUPPORTED
;
193 mLogoBltBuffer
= AllocateCopyPool (
194 (UINTN
)BufferSize
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
),
197 if (mLogoBltBuffer
== NULL
) {
198 return EFI_OUT_OF_RESOURCES
;
200 mLogoDestX
= DestinationX
;
201 mLogoDestY
= DestinationY
;
203 mLogoHeight
= Height
;
210 This function calculates and updates an UINT8 checksum.
212 @param[in] Buffer Pointer to buffer to checksum.
213 @param[in] Size Number of bytes to checksum.
217 BgrtAcpiTableChecksum (
222 UINTN ChecksumOffset
;
224 ChecksumOffset
= OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
, Checksum
);
227 // Set checksum to 0 first.
229 Buffer
[ChecksumOffset
] = 0;
232 // Update checksum value.
234 Buffer
[ChecksumOffset
] = CalculateCheckSum8 (Buffer
, Size
);
238 Allocate EfiBootServicesData below 4G memory address.
240 This function allocates EfiBootServicesData below 4G memory address.
242 @param[in] Size Size of memory to allocate.
244 @return Allocated address for output.
248 BgrtAllocateBsDataMemoryBelow4G (
253 EFI_PHYSICAL_ADDRESS Address
;
257 Pages
= EFI_SIZE_TO_PAGES (Size
);
258 Address
= 0xffffffff;
260 Status
= gBS
->AllocatePages (
266 ASSERT_EFI_ERROR (Status
);
268 Buffer
= (VOID
*) (UINTN
) Address
;
269 ZeroMem (Buffer
, Size
);
275 Install Boot Graphics Resource Table to ACPI table.
281 InstallBootGraphicsResourceTable (
286 EFI_ACPI_TABLE_PROTOCOL
*AcpiTableProtocol
;
292 EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltPixel
;
297 // Get ACPI Table protocol.
299 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**) &AcpiTableProtocol
);
300 if (EFI_ERROR (Status
)) {
305 // Check whether Boot Graphics Resource Table is already installed.
307 if (mAcpiBgrtInstalled
) {
308 if (!mAcpiBgrtStatusChanged
&& !mAcpiBgrtBufferChanged
) {
310 // Nothing has changed
315 // If BGRT data change happens. Uninstall Orignal AcpiTable first
317 Status
= AcpiTableProtocol
->UninstallAcpiTable (
319 mBootGraphicsResourceTableKey
321 if (EFI_ERROR (Status
)) {
327 // Check whether Logo exist.
329 if ( mLogoBltBuffer
== NULL
) {
330 return EFI_NOT_FOUND
;
334 if (mAcpiBgrtBufferChanged
) {
336 // reserve original BGRT buffer size
338 OrigBmpSize
= mBmpImageHeaderTemplate
.ImageSize
+ sizeof (BMP_IMAGE_HEADER
);
340 // Free orignal BMP memory
342 if (mBootGraphicsResourceTableTemplate
.ImageAddress
) {
343 gBS
->FreePages(mBootGraphicsResourceTableTemplate
.ImageAddress
, EFI_SIZE_TO_PAGES(OrigBmpSize
));
347 // Allocate memory for BMP file.
349 PaddingSize
= mLogoWidth
& 0x3;
352 // First check mLogoWidth * 3 + PaddingSize doesn't overflow
354 if (mLogoWidth
> (((UINT32
) ~0) - PaddingSize
) / 3 ) {
355 return EFI_UNSUPPORTED
;
359 // Second check (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER) doesn't overflow
361 if (mLogoHeight
> (((UINT32
) ~0) - sizeof (BMP_IMAGE_HEADER
)) / (mLogoWidth
* 3 + PaddingSize
)) {
362 return EFI_UNSUPPORTED
;
366 // The image should be stored in EfiBootServicesData, allowing the system to reclaim the memory
368 BmpSize
= (mLogoWidth
* 3 + PaddingSize
) * mLogoHeight
+ sizeof (BMP_IMAGE_HEADER
);
369 ImageBuffer
= BgrtAllocateBsDataMemoryBelow4G (BmpSize
);
370 if (ImageBuffer
== NULL
) {
371 return EFI_OUT_OF_RESOURCES
;
374 mBmpImageHeaderTemplate
.Size
= (UINT32
) BmpSize
;
375 mBmpImageHeaderTemplate
.ImageSize
= (UINT32
) BmpSize
- sizeof (BMP_IMAGE_HEADER
);
376 mBmpImageHeaderTemplate
.PixelWidth
= (UINT32
) mLogoWidth
;
377 mBmpImageHeaderTemplate
.PixelHeight
= (UINT32
) mLogoHeight
;
378 CopyMem (ImageBuffer
, &mBmpImageHeaderTemplate
, sizeof (BMP_IMAGE_HEADER
));
381 // Convert BLT buffer to BMP file.
383 Image
= ImageBuffer
+ sizeof (BMP_IMAGE_HEADER
);
384 for (Row
= 0; Row
< mLogoHeight
; Row
++) {
385 BltPixel
= &mLogoBltBuffer
[(mLogoHeight
- Row
- 1) * mLogoWidth
];
387 for (Col
= 0; Col
< mLogoWidth
; Col
++) {
388 *Image
++ = BltPixel
->Blue
;
389 *Image
++ = BltPixel
->Green
;
390 *Image
++ = BltPixel
->Red
;
395 // Padding for 4 byte alignment.
397 Image
+= PaddingSize
;
399 FreePool (mLogoBltBuffer
);
400 mLogoBltBuffer
= NULL
;
402 mBootGraphicsResourceTableTemplate
.ImageAddress
= (UINT64
) (UINTN
) ImageBuffer
;
403 mBootGraphicsResourceTableTemplate
.ImageOffsetX
= (UINT32
) mLogoDestX
;
404 mBootGraphicsResourceTableTemplate
.ImageOffsetY
= (UINT32
) mLogoDestY
;
407 mBootGraphicsResourceTableTemplate
.Status
= (UINT8
) (mIsLogoValid
? EFI_ACPI_5_0_BGRT_STATUS_VALID
: EFI_ACPI_5_0_BGRT_STATUS_INVALID
);
412 BgrtAcpiTableChecksum ((UINT8
*) &mBootGraphicsResourceTableTemplate
, sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE
));
415 // Publish Boot Graphics Resource Table.
417 Status
= AcpiTableProtocol
->InstallAcpiTable (
419 &mBootGraphicsResourceTableTemplate
,
420 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE
),
421 &mBootGraphicsResourceTableKey
423 if (EFI_ERROR (Status
)) {
427 mAcpiBgrtInstalled
= TRUE
;
428 mAcpiBgrtStatusChanged
= FALSE
;
429 mAcpiBgrtBufferChanged
= FALSE
;
435 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to
436 install the Boot Graphics Resource Table.
438 @param[in] Event The Event that is being processed.
439 @param[in] Context The Event Context.
444 BgrtReadyToBootEventNotify (
449 InstallBootGraphicsResourceTable ();
453 The module Entry Point of the Boot Graphics Resource Table DXE driver.
455 @param[in] ImageHandle The firmware allocated handle for the EFI image.
456 @param[in] SystemTable A pointer to the EFI System Table.
458 @retval EFI_SUCCESS The entry point is executed successfully.
459 @retval Other Some error occurs when executing this entry point.
464 BootGraphicsDxeEntryPoint (
465 IN EFI_HANDLE ImageHandle
,
466 IN EFI_SYSTEM_TABLE
*SystemTable
472 // Install Boot Logo protocol.
474 Status
= gBS
->InstallMultipleProtocolInterfaces (
476 &gEfiBootLogoProtocolGuid
,
477 &mBootLogoProtocolTemplate
,
480 ASSERT_EFI_ERROR (Status
);
483 // Register notify function to install BGRT on ReadyToBoot Event.
485 Status
= gBS
->CreateEventEx (
488 BgrtReadyToBootEventNotify
,
490 &gEfiEventReadyToBootGuid
,
491 &mBootGraphicsReadyToBootEvent
493 ASSERT_EFI_ERROR (Status
);