TianoCore EDK2 master
Loading...
Searching...
No Matches
BootGraphicsResourceTableDxe.c
Go to the documentation of this file.
1
9#include <Uefi.h>
10
12
13#include <Protocol/AcpiTable.h>
15#include <Protocol/BootLogo.h>
16#include <Protocol/BootLogo2.h>
17
18#include <Guid/EventGroup.h>
19
20#include <Library/BaseLib.h>
24#include <Library/DebugLib.h>
25#include <Library/PcdLib.h>
26#include <Library/SafeIntLib.h>
28
47EFIAPI
50 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
51 IN UINTN DestinationX,
52 IN UINTN DestinationY,
53 IN UINTN Width,
54 IN UINTN Height
55 );
56
75EFIAPI
78 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
79 IN UINTN DestinationX,
80 IN UINTN DestinationY,
81 IN UINTN Width,
82 IN UINTN Height
83 );
84
110EFIAPI
114 OUT UINTN *DestinationX,
115 OUT UINTN *DestinationY,
116 OUT UINTN *Width,
117 OUT UINTN *Height
118 );
119
120//
121// Boot Logo Protocol Handle
122//
123EFI_HANDLE mBootLogoHandle = NULL;
124
125//
126// Boot Logo Protocol Instance
127//
128EFI_BOOT_LOGO_PROTOCOL mBootLogoProtocolTemplate = {
130};
131
138};
139
140EFI_EVENT mBootGraphicsReadyToBootEvent;
141UINTN mBootGraphicsResourceTableKey = 0;
142BOOLEAN mIsLogoValid = FALSE;
143EFI_GRAPHICS_OUTPUT_BLT_PIXEL *mLogoBltBuffer = NULL;
144UINTN mLogoDestX = 0;
145UINTN mLogoDestY = 0;
146UINTN mLogoWidth = 0;
147UINTN mLogoHeight = 0;
148BOOLEAN mAcpiBgrtInstalled = FALSE;
149BOOLEAN mAcpiBgrtStatusChanged = FALSE;
150BOOLEAN mAcpiBgrtBufferChanged = FALSE;
151
152//
153// ACPI Boot Graphics Resource Table template
154//
155EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate = {
156 {
160 0x00, // Checksum will be updated at runtime
161 //
162 // It is expected that these values will be updated at EntryPoint.
163 //
164 { 0x00 }, // OEM ID is a 6 bytes long field
165 0x00, // OEM Table ID(8 bytes long)
166 0x00, // OEM Revision
167 0x00, // Creator ID
168 0x00, // Creator Revision
169 },
170 EFI_ACPI_5_0_BGRT_VERSION, // Version
171 EFI_ACPI_5_0_BGRT_STATUS_VALID, // Status
173 0, // Image Address
174 0, // Image Offset X
175 0 // Image Offset Y
176};
177
197EFIAPI
200 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
201 IN UINTN DestinationX,
202 IN UINTN DestinationY,
203 IN UINTN Width,
204 IN UINTN Height
205 )
206{
207 //
208 // Call same service in Boot Logo 2 Protocol
209 //
210 return SetBootLogo2 (
212 BltBuffer,
213 DestinationX,
214 DestinationY,
215 Width,
216 Height
217 );
218}
219
238EFIAPI
241 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
242 IN UINTN DestinationX,
243 IN UINTN DestinationY,
244 IN UINTN Width,
245 IN UINTN Height
246 )
247{
248 EFI_STATUS Status;
249 UINTN BufferSize;
250 UINT32 Result32;
251
252 if (BltBuffer == NULL) {
253 mIsLogoValid = FALSE;
254 mAcpiBgrtStatusChanged = TRUE;
255 return EFI_SUCCESS;
256 }
257
258 //
259 // Width and height are not allowed to be zero.
260 //
261 if ((Width == 0) || (Height == 0)) {
262 return EFI_INVALID_PARAMETER;
263 }
264
265 //
266 // Verify destination, width, and height do not overflow 32-bit values.
267 // The Boot Graphics Resource Table only has 32-bit fields for these values.
268 //
269 Status = SafeUintnToUint32 (DestinationX, &Result32);
270 if (EFI_ERROR (Status)) {
271 return EFI_INVALID_PARAMETER;
272 }
273
274 Status = SafeUintnToUint32 (DestinationY, &Result32);
275 if (EFI_ERROR (Status)) {
276 return EFI_INVALID_PARAMETER;
277 }
278
279 Status = SafeUintnToUint32 (Width, &Result32);
280 if (EFI_ERROR (Status)) {
281 return EFI_INVALID_PARAMETER;
282 }
283
284 Status = SafeUintnToUint32 (Height, &Result32);
285 if (EFI_ERROR (Status)) {
286 return EFI_INVALID_PARAMETER;
287 }
288
289 //
290 // Ensure the Height * Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) does
291 // not overflow UINTN
292 //
293 Status = SafeUintnMult (
294 Width,
295 Height,
296 &BufferSize
297 );
298 if (EFI_ERROR (Status)) {
299 return EFI_UNSUPPORTED;
300 }
301
302 Status = SafeUintnMult (
303 BufferSize,
305 &BufferSize
306 );
307 if (EFI_ERROR (Status)) {
308 return EFI_UNSUPPORTED;
309 }
310
311 //
312 // Update state
313 //
314 mAcpiBgrtBufferChanged = TRUE;
315
316 //
317 // Free old logo buffer
318 //
319 if (mLogoBltBuffer != NULL) {
320 FreePool (mLogoBltBuffer);
321 mLogoBltBuffer = NULL;
322 }
323
324 //
325 // Allocate new logo buffer
326 //
327 mLogoBltBuffer = AllocateCopyPool (BufferSize, BltBuffer);
328 if (mLogoBltBuffer == NULL) {
329 return EFI_OUT_OF_RESOURCES;
330 }
331
332 mLogoDestX = DestinationX;
333 mLogoDestY = DestinationY;
334 mLogoWidth = Width;
335 mLogoHeight = Height;
336 mIsLogoValid = TRUE;
337
338 return EFI_SUCCESS;
339}
340
366EFIAPI
370 OUT UINTN *DestinationX,
371 OUT UINTN *DestinationY,
372 OUT UINTN *Width,
373 OUT UINTN *Height
374 )
375{
376 //
377 // If the boot logo has not been set with SetBootLogo() or SetBootLogo() was
378 // called with a NULL BltBuffer then the boot logo is not valid and
379 // EFI_NOT_READY is returned.
380 //
381 if (mLogoBltBuffer == NULL) {
382 DEBUG ((DEBUG_ERROR, "Request to get boot logo location before boot logo has been set.\n"));
383 return EFI_NOT_READY;
384 }
385
386 //
387 // Make sure none of the boot logo location parameters are NULL.
388 //
389 if ((BltBuffer == NULL) || (DestinationX == NULL) || (DestinationY == NULL) ||
390 (Width == NULL) || (Height == NULL))
391 {
392 return EFI_INVALID_PARAMETER;
393 }
394
395 //
396 // Boot logo is valid. Return values from module globals.
397 //
398 *BltBuffer = mLogoBltBuffer;
399 *DestinationX = mLogoDestX;
400 *DestinationY = mLogoDestY;
401 *Width = mLogoWidth;
402 *Height = mLogoHeight;
403
404 return EFI_SUCCESS;
405}
406
415VOID
416EFIAPI
418 IN EFI_EVENT Event,
419 IN VOID *Context
420 )
421{
422 EFI_STATUS Status;
423 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
424 VOID *ImageBuffer;
425 UINT32 BmpSize;
426
427 //
428 // Get ACPI Table protocol.
429 //
430 Status = gBS->LocateProtocol (
431 &gEfiAcpiTableProtocolGuid,
432 NULL,
433 (VOID **)&AcpiTableProtocol
434 );
435 if (EFI_ERROR (Status)) {
436 return;
437 }
438
439 //
440 // Check whether Boot Graphics Resource Table is already installed.
441 //
442 if (mAcpiBgrtInstalled) {
443 if (!mAcpiBgrtStatusChanged && !mAcpiBgrtBufferChanged) {
444 //
445 // Nothing has changed
446 //
447 return;
448 } else {
449 //
450 // If BGRT data change happens, then uninstall orignal AcpiTable first
451 //
452 Status = AcpiTableProtocol->UninstallAcpiTable (
453 AcpiTableProtocol,
454 mBootGraphicsResourceTableKey
455 );
456 if (EFI_ERROR (Status)) {
457 return;
458 }
459 }
460 } else {
461 //
462 // Check whether Logo exists
463 //
464 if (mLogoBltBuffer == NULL) {
465 return;
466 }
467 }
468
469 if (mAcpiBgrtBufferChanged) {
470 //
471 // Free the old BMP image buffer
472 //
473 ImageBuffer = (UINT8 *)(UINTN)mBootGraphicsResourceTableTemplate.ImageAddress;
474 if (ImageBuffer != NULL) {
475 FreePool (ImageBuffer);
476 }
477
478 //
479 // Convert GOP Blt buffer to BMP image. Pass in ImageBuffer set to NULL
480 // so the BMP image is allocated by TranslateGopBltToBmp().
481 //
482 ImageBuffer = NULL;
483 Status = TranslateGopBltToBmp (
484 mLogoBltBuffer,
485 (UINT32)mLogoHeight,
486 (UINT32)mLogoWidth,
487 &ImageBuffer,
488 &BmpSize
489 );
490 if (EFI_ERROR (Status)) {
491 return;
492 }
493
494 //
495 // Free the logo buffer
496 //
497 FreePool (mLogoBltBuffer);
498 mLogoBltBuffer = NULL;
499
500 //
501 // Update BMP image fields of the Boot Graphics Resource Table
502 //
503 mBootGraphicsResourceTableTemplate.ImageAddress = (UINT64)(UINTN)ImageBuffer;
504 mBootGraphicsResourceTableTemplate.ImageOffsetX = (UINT32)mLogoDestX;
505 mBootGraphicsResourceTableTemplate.ImageOffsetY = (UINT32)mLogoDestY;
506 }
507
508 //
509 // Update Status field of Boot Graphics Resource Table
510 //
511 if (mIsLogoValid) {
512 mBootGraphicsResourceTableTemplate.Status = EFI_ACPI_5_0_BGRT_STATUS_VALID;
513 } else {
514 mBootGraphicsResourceTableTemplate.Status = EFI_ACPI_5_0_BGRT_STATUS_INVALID;
515 }
516
517 //
518 // Update Checksum of Boot Graphics Resource Table
519 //
520 mBootGraphicsResourceTableTemplate.Header.Checksum = 0;
521 mBootGraphicsResourceTableTemplate.Header.Checksum =
523 (UINT8 *)&mBootGraphicsResourceTableTemplate,
525 );
526
527 //
528 // Publish Boot Graphics Resource Table.
529 //
530 Status = AcpiTableProtocol->InstallAcpiTable (
531 AcpiTableProtocol,
532 &mBootGraphicsResourceTableTemplate,
534 &mBootGraphicsResourceTableKey
535 );
536 if (EFI_ERROR (Status)) {
537 return;
538 }
539
540 mAcpiBgrtInstalled = TRUE;
541 mAcpiBgrtStatusChanged = FALSE;
542 mAcpiBgrtBufferChanged = FALSE;
543}
544
556EFIAPI
558 IN EFI_HANDLE ImageHandle,
559 IN EFI_SYSTEM_TABLE *SystemTable
560 )
561{
562 EFI_STATUS Status;
564
565 //
566 // Update Header fields of Boot Graphics Resource Table from PCDs
567 //
568 Header = &mBootGraphicsResourceTableTemplate.Header;
569 ZeroMem (Header->OemId, sizeof (Header->OemId));
570 CopyMem (
571 Header->OemId,
572 PcdGetPtr (PcdAcpiDefaultOemId),
573 MIN (PcdGetSize (PcdAcpiDefaultOemId), sizeof (Header->OemId))
574 );
575 WriteUnaligned64 (&Header->OemTableId, PcdGet64 (PcdAcpiDefaultOemTableId));
576 Header->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
577 Header->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
578 Header->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
579
580 //
581 // Install Boot Logo and Boot Logo 2 Protocols.
582 //
583 Status = gBS->InstallMultipleProtocolInterfaces (
584 &mBootLogoHandle,
585 &gEfiBootLogoProtocolGuid,
586 &mBootLogoProtocolTemplate,
587 &gEdkiiBootLogo2ProtocolGuid,
589 NULL
590 );
591 ASSERT_EFI_ERROR (Status);
592
593 //
594 // Register notify function to install BGRT on ReadyToBoot Event.
595 //
596 Status = gBS->CreateEventEx (
597 EVT_NOTIFY_SIGNAL,
598 TPL_CALLBACK,
600 NULL,
601 &gEfiEventReadyToBootGuid,
602 &mBootGraphicsReadyToBootEvent
603 );
604 ASSERT_EFI_ERROR (Status);
605
606 return Status;
607}
UINT64 UINTN
#define EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP
Definition: Acpi50.h:1112
#define EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE
Definition: Acpi50.h:1900
#define EFI_ACPI_5_0_BGRT_VERSION
Definition: Acpi50.h:1099
#define EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION
Definition: Acpi50.h:1094
UINT8 EFIAPI CalculateCheckSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
Definition: CheckSum.c:71
UINT64 EFIAPI WriteUnaligned64(OUT UINT64 *Buffer, IN UINT64 Value)
Definition: Unaligned.c:236
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
RETURN_STATUS EFIAPI TranslateGopBltToBmp(IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *GopBlt, IN UINT32 PixelHeight, IN UINT32 PixelWidth, IN OUT VOID **BmpImage, IN OUT UINT32 *BmpImageSize)
EFI_STATUS EFIAPI BootGraphicsDxeEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
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 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)
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)
EDKII_BOOT_LOGO2_PROTOCOL mBootLogo2ProtocolTemplate
VOID EFIAPI BgrtReadyToBootEventNotify(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGetSize(TokenName)
Definition: PcdLib.h:440
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
RETURN_STATUS EFIAPI SafeUintnMult(IN UINTN Multiplicand, IN UINTN Multiplier, OUT UINTN *Result)
Definition: SafeIntLib32.c:430
RETURN_STATUS EFIAPI SafeUintnToUint32(IN UINTN Operand, OUT UINT32 *Result)
Definition: SafeIntLib32.c:177
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS