VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c

Last change on this file was 99404, checked in by vboxsync, 14 months ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 19.6 KB
Line 
1/** @file
2 This module install ACPI Boot Graphics Resource Table (BGRT).
3
4 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2016, Microsoft Corporation<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7**/
8
9#include <Uefi.h>
10
11#include <IndustryStandard/Acpi.h>
12
13#include <Protocol/AcpiTable.h>
14#include <Protocol/GraphicsOutput.h>
15#include <Protocol/BootLogo.h>
16#include <Protocol/BootLogo2.h>
17
18#include <Guid/EventGroup.h>
19
20#include <Library/BaseLib.h>
21#include <Library/BaseMemoryLib.h>
22#include <Library/MemoryAllocationLib.h>
23#include <Library/UefiBootServicesTableLib.h>
24#include <Library/DebugLib.h>
25#include <Library/PcdLib.h>
26#include <Library/SafeIntLib.h>
27#include <Library/BmpSupportLib.h>
28
29/**
30 Update information of logo image drawn on screen.
31
32 @param[in] This The pointer to the Boot Logo protocol 2 instance.
33 @param[in] BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer
34 is set to NULL, it indicates that logo image is no
35 longer on the screen.
36 @param[in] DestinationX X coordinate of destination for the BltBuffer.
37 @param[in] DestinationY Y coordinate of destination for the BltBuffer.
38 @param[in] Width Width of rectangle in BltBuffer in pixels.
39 @param[in] Height Hight of rectangle in BltBuffer in pixels.
40
41 @retval EFI_SUCCESS The boot logo information was updated.
42 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
43 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to
44 insufficient memory resources.
45**/
46EFI_STATUS
47EFIAPI
48SetBootLogo (
49 IN EFI_BOOT_LOGO_PROTOCOL *This,
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
57/**
58 Update information of logo image drawn on screen.
59
60 @param[in] This The pointer to the Boot Logo protocol 2 instance.
61 @param[in] BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer
62 is set to NULL, it indicates that logo image is no
63 longer on the screen.
64 @param[in] DestinationX X coordinate of destination for the BltBuffer.
65 @param[in] DestinationY Y coordinate of destination for the BltBuffer.
66 @param[in] Width Width of rectangle in BltBuffer in pixels.
67 @param[in] Height Hight of rectangle in BltBuffer in pixels.
68
69 @retval EFI_SUCCESS The boot logo information was updated.
70 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
71 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to
72 insufficient memory resources.
73**/
74EFI_STATUS
75EFIAPI
76SetBootLogo2 (
77 IN EDKII_BOOT_LOGO2_PROTOCOL *This,
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
85/**
86 Get the location of the boot logo on the screen.
87
88 @param[in] This The pointer to the Boot Logo Protocol 2 instance
89 @param[out] BltBuffer Returns pointer to the GOP BLT buffer that was
90 previously registered with SetBootLogo2(). The
91 buffer returned must not be modified or freed.
92 @param[out] DestinationX Returns the X start position of the GOP BLT buffer
93 that was previously registered with SetBootLogo2().
94 @param[out] DestinationY Returns the Y start position of the GOP BLT buffer
95 that was previously registered with SetBootLogo2().
96 @param[out] Width Returns the width of the GOP BLT buffer
97 that was previously registered with SetBootLogo2().
98 @param[out] Height Returns the height of the GOP BLT buffer
99 that was previously registered with SetBootLogo2().
100
101 @retval EFI_SUCCESS The location of the boot logo was returned.
102 @retval EFI_NOT_READY The boot logo has not been set.
103 @retval EFI_INVALID_PARAMETER BltBuffer is NULL.
104 @retval EFI_INVALID_PARAMETER DestinationX is NULL.
105 @retval EFI_INVALID_PARAMETER DestinationY is NULL.
106 @retval EFI_INVALID_PARAMETER Width is NULL.
107 @retval EFI_INVALID_PARAMETER Height is NULL.
108**/
109EFI_STATUS
110EFIAPI
111GetBootLogo2 (
112 IN EDKII_BOOT_LOGO2_PROTOCOL *This,
113 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltBuffer,
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 = {
129 SetBootLogo
130};
131
132///
133/// Boot Logo 2 Protocol instance
134///
135EDKII_BOOT_LOGO2_PROTOCOL mBootLogo2ProtocolTemplate = {
136 SetBootLogo2,
137 GetBootLogo2
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 {
157 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,
158 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),
159 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION, // Revision
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
172 EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP, // Image Type
173 0, // Image Address
174 0, // Image Offset X
175 0 // Image Offset Y
176};
177
178/**
179 Update information of logo image drawn on screen.
180
181 @param This The pointer to the Boot Logo protocol instance.
182 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer
183 is set to NULL, it indicates that logo image is no
184 longer on the screen.
185 @param DestinationX X coordinate of destination for the BltBuffer.
186 @param DestinationY Y coordinate of destination for the BltBuffer.
187 @param Width Width of rectangle in BltBuffer in pixels.
188 @param Height Hight of rectangle in BltBuffer in pixels.
189
190 @retval EFI_SUCCESS The boot logo information was updated.
191 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
192 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to
193 insufficient memory resources.
194
195**/
196EFI_STATUS
197EFIAPI
198SetBootLogo (
199 IN EFI_BOOT_LOGO_PROTOCOL *This,
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 (
211 &mBootLogo2ProtocolTemplate,
212 BltBuffer,
213 DestinationX,
214 DestinationY,
215 Width,
216 Height
217 );
218}
219
220/**
221 Update information of logo image drawn on screen.
222
223 @param[in] This The pointer to the Boot Logo protocol 2 instance.
224 @param[in] BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer
225 is set to NULL, it indicates that logo image is no
226 longer on the screen.
227 @param[in] DestinationX X coordinate of destination for the BltBuffer.
228 @param[in] DestinationY Y coordinate of destination for the BltBuffer.
229 @param[in] Width Width of rectangle in BltBuffer in pixels.
230 @param[in] Height Hight of rectangle in BltBuffer in pixels.
231
232 @retval EFI_SUCCESS The boot logo information was updated.
233 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
234 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to
235 insufficient memory resources.
236**/
237EFI_STATUS
238EFIAPI
239SetBootLogo2 (
240 IN EDKII_BOOT_LOGO2_PROTOCOL *This,
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,
304 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),
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
341/**
342 Get the location of the boot logo on the screen.
343
344 @param[in] This The pointer to the Boot Logo Protocol 2 instance
345 @param[out] BltBuffer Returns pointer to the GOP BLT buffer that was
346 previously registered with SetBootLogo2(). The
347 buffer returned must not be modified or freed.
348 @param[out] DestinationX Returns the X start position of the GOP BLT buffer
349 that was previously registered with SetBootLogo2().
350 @param[out] DestinationY Returns the Y start position of the GOP BLT buffer
351 that was previously registered with SetBootLogo2().
352 @param[out] Width Returns the width of the GOP BLT buffer
353 that was previously registered with SetBootLogo2().
354 @param[out] Height Returns the height of the GOP BLT buffer
355 that was previously registered with SetBootLogo2().
356
357 @retval EFI_SUCCESS The location of the boot logo was returned.
358 @retval EFI_NOT_READY The boot logo has not been set.
359 @retval EFI_INVALID_PARAMETER BltBuffer is NULL.
360 @retval EFI_INVALID_PARAMETER DestinationX is NULL.
361 @retval EFI_INVALID_PARAMETER DestinationY is NULL.
362 @retval EFI_INVALID_PARAMETER Width is NULL.
363 @retval EFI_INVALID_PARAMETER Height is NULL.
364**/
365EFI_STATUS
366EFIAPI
367GetBootLogo2 (
368 IN EDKII_BOOT_LOGO2_PROTOCOL *This,
369 OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL **BltBuffer,
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
407/**
408 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to
409 install the Boot Graphics Resource Table.
410
411 @param[in] Event The Event that is being processed.
412 @param[in] Context The Event Context.
413
414**/
415VOID
416EFIAPI
417BgrtReadyToBootEventNotify (
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 =
522 CalculateCheckSum8 (
523 (UINT8 *)&mBootGraphicsResourceTableTemplate,
524 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE)
525 );
526
527 //
528 // Publish Boot Graphics Resource Table.
529 //
530 Status = AcpiTableProtocol->InstallAcpiTable (
531 AcpiTableProtocol,
532 &mBootGraphicsResourceTableTemplate,
533 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),
534 &mBootGraphicsResourceTableKey
535 );
536 if (EFI_ERROR (Status)) {
537 return;
538 }
539
540 mAcpiBgrtInstalled = TRUE;
541 mAcpiBgrtStatusChanged = FALSE;
542 mAcpiBgrtBufferChanged = FALSE;
543}
544
545/**
546 The module Entry Point of the Boot Graphics Resource Table DXE driver.
547
548 @param[in] ImageHandle The firmware allocated handle for the EFI image.
549 @param[in] SystemTable A pointer to the EFI System Table.
550
551 @retval EFI_SUCCESS The entry point is executed successfully.
552 @retval Other Some error occurs when executing this entry point.
553
554**/
555EFI_STATUS
556EFIAPI
557BootGraphicsDxeEntryPoint (
558 IN EFI_HANDLE ImageHandle,
559 IN EFI_SYSTEM_TABLE *SystemTable
560 )
561{
562 EFI_STATUS Status;
563 EFI_ACPI_DESCRIPTION_HEADER *Header;
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,
588 &mBootLogo2ProtocolTemplate,
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,
599 BgrtReadyToBootEventNotify,
600 NULL,
601 &gEfiEventReadyToBootGuid,
602 &mBootGraphicsReadyToBootEvent
603 );
604 ASSERT_EFI_ERROR (Status);
605
606 return Status;
607}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use