]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c
MdeModulePkg: Add Boot Logo 2 Protocol
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / BootGraphicsResourceTableDxe / BootGraphicsResourceTableDxe.c
CommitLineData
0284e90c
LG
1/** @file\r
2 This module install ACPI Boot Graphics Resource Table (BGRT).\r
3\r
53be7721 4 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
0284e90c
LG
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12**/\r
13\r
14#include <Uefi.h>\r
15\r
96f0d1ca 16#include <IndustryStandard/Acpi.h>\r
0284e90c
LG
17\r
18#include <Protocol/AcpiTable.h>\r
19#include <Protocol/GraphicsOutput.h>\r
20#include <Protocol/BootLogo.h>\r
21\r
22#include <Guid/EventGroup.h>\r
23\r
24#include <Library/BaseLib.h>\r
25#include <Library/BaseMemoryLib.h>\r
26#include <Library/MemoryAllocationLib.h>\r
27#include <Library/UefiBootServicesTableLib.h>\r
28#include <Library/DebugLib.h>\r
e84f07b5 29#include <Library/PcdLib.h>\r
53be7721
MK
30#include <Library/SafeIntLib.h>\r
31#include <Library/BmpSupportLib.h>\r
0284e90c 32\r
53be7721
MK
33/**\r
34 Update information of logo image drawn on screen.\r
35\r
36 @param This The pointer to the Boot Logo protocol instance.\r
37 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer\r
38 is set to NULL, it indicates that logo image is no\r
39 longer on the screen.\r
40 @param DestinationX X coordinate of destination for the BltBuffer.\r
41 @param DestinationY Y coordinate of destination for the BltBuffer.\r
42 @param Width Width of rectangle in BltBuffer in pixels.\r
43 @param Height Hight of rectangle in BltBuffer in pixels.\r
44\r
45 @retval EFI_SUCCESS The boot logo information was updated.\r
46 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
47 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to\r
48 insufficient memory resources.\r
49\r
50**/\r
51EFI_STATUS\r
52EFIAPI\r
53SetBootLogo (\r
54 IN EFI_BOOT_LOGO_PROTOCOL *This,\r
55 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
56 IN UINTN DestinationX,\r
57 IN UINTN DestinationY,\r
58 IN UINTN Width,\r
59 IN UINTN Height\r
60 );\r
61\r
62//\r
63// Boot Logo Protocol Handle\r
0284e90c 64//\r
53be7721
MK
65EFI_HANDLE mBootLogoHandle = NULL;\r
66\r
67//\r
68// Boot Logo Protocol Instance\r
0284e90c 69//\r
53be7721
MK
70EFI_BOOT_LOGO_PROTOCOL mBootLogoProtocolTemplate = {\r
71 SetBootLogo\r
72};\r
0284e90c 73\r
53be7721
MK
74EFI_EVENT mBootGraphicsReadyToBootEvent;\r
75UINTN mBootGraphicsResourceTableKey = 0;\r
0284e90c
LG
76BOOLEAN mIsLogoValid = FALSE;\r
77EFI_GRAPHICS_OUTPUT_BLT_PIXEL *mLogoBltBuffer = NULL;\r
53be7721
MK
78UINTN mLogoDestX = 0;\r
79UINTN mLogoDestY = 0;\r
80UINTN mLogoWidth = 0;\r
0284e90c 81UINTN mLogoHeight = 0;\r
53be7721
MK
82BOOLEAN mAcpiBgrtInstalled = FALSE;\r
83BOOLEAN mAcpiBgrtStatusChanged = FALSE;\r
84BOOLEAN mAcpiBgrtBufferChanged = FALSE;\r
0284e90c 85\r
53be7721
MK
86//\r
87// ACPI Boot Graphics Resource Table template\r
88//\r
0284e90c
LG
89EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate = {\r
90 {\r
91 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,\r
92 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),\r
93 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION, // Revision\r
94 0x00, // Checksum will be updated at runtime\r
95 //\r
e84f07b5 96 // It is expected that these values will be updated at EntryPoint.\r
0284e90c 97 //\r
e84f07b5
SZ
98 {0x00}, // OEM ID is a 6 bytes long field\r
99 0x00, // OEM Table ID(8 bytes long)\r
100 0x00, // OEM Revision\r
101 0x00, // Creator ID\r
102 0x00, // Creator Revision\r
0284e90c
LG
103 },\r
104 EFI_ACPI_5_0_BGRT_VERSION, // Version\r
105 EFI_ACPI_5_0_BGRT_STATUS_VALID, // Status\r
106 EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP, // Image Type\r
107 0, // Image Address\r
108 0, // Image Offset X\r
109 0 // Image Offset Y\r
110};\r
111\r
0284e90c
LG
112/**\r
113 Update information of logo image drawn on screen.\r
114\r
115 @param This The pointer to the Boot Logo protocol instance.\r
116 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer\r
117 is set to NULL, it indicates that logo image is no\r
118 longer on the screen.\r
119 @param DestinationX X coordinate of destination for the BltBuffer.\r
120 @param DestinationY Y coordinate of destination for the BltBuffer.\r
121 @param Width Width of rectangle in BltBuffer in pixels.\r
122 @param Height Hight of rectangle in BltBuffer in pixels.\r
123\r
124 @retval EFI_SUCCESS The boot logo information was updated.\r
125 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
126 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to\r
127 insufficient memory resources.\r
128\r
129**/\r
130EFI_STATUS\r
131EFIAPI\r
132SetBootLogo (\r
133 IN EFI_BOOT_LOGO_PROTOCOL *This,\r
134 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
135 IN UINTN DestinationX,\r
136 IN UINTN DestinationY,\r
137 IN UINTN Width,\r
138 IN UINTN Height\r
139 )\r
140{\r
53be7721
MK
141 EFI_STATUS Status;\r
142 UINTN BufferSize;\r
143 UINT32 Result32;\r
a46c3657 144\r
0284e90c
LG
145 if (BltBuffer == NULL) {\r
146 mIsLogoValid = FALSE;\r
cbafa15e 147 mAcpiBgrtStatusChanged = TRUE;\r
0284e90c
LG
148 return EFI_SUCCESS;\r
149 }\r
150\r
53be7721
MK
151 //\r
152 // Width and height are not allowed to be zero.\r
153 //\r
0284e90c
LG
154 if (Width == 0 || Height == 0) {\r
155 return EFI_INVALID_PARAMETER;\r
156 }\r
53be7721
MK
157\r
158 //\r
159 // Verify destination, width, and height do not overflow 32-bit values.\r
160 // The Boot Graphics Resource Table only has 32-bit fields for these values.\r
161 //\r
162 Status = SafeUintnToUint32 (DestinationX, &Result32);\r
163 if (EFI_ERROR (Status)) {\r
164 return EFI_INVALID_PARAMETER;\r
0284e90c 165 }\r
53be7721
MK
166 Status = SafeUintnToUint32 (DestinationY, &Result32);\r
167 if (EFI_ERROR (Status)) {\r
168 return EFI_INVALID_PARAMETER;\r
169 }\r
170 Status = SafeUintnToUint32 (Width, &Result32);\r
171 if (EFI_ERROR (Status)) {\r
172 return EFI_INVALID_PARAMETER;\r
173 }\r
174 Status = SafeUintnToUint32 (Height, &Result32);\r
175 if (EFI_ERROR (Status)) {\r
176 return EFI_INVALID_PARAMETER;\r
177 }\r
178\r
a46c3657 179 //\r
53be7721
MK
180 // Ensure the Height * Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) does\r
181 // not overflow UINTN\r
a46c3657 182 //\r
53be7721
MK
183 Status = SafeUintnMult (\r
184 Width,\r
185 Height,\r
186 &BufferSize\r
187 );\r
188 if (EFI_ERROR (Status)) {\r
189 return EFI_UNSUPPORTED;\r
190 }\r
191 Status = SafeUintnMult (\r
192 BufferSize,\r
193 sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),\r
194 &BufferSize\r
195 );\r
196 if (EFI_ERROR (Status)) {\r
a46c3657
ED
197 return EFI_UNSUPPORTED;\r
198 }\r
53be7721 199\r
a46c3657 200 //\r
53be7721 201 // Update state\r
a46c3657 202 //\r
53be7721
MK
203 mAcpiBgrtBufferChanged = TRUE;\r
204\r
205 //\r
206 // Free old logo buffer\r
207 //\r
208 if (mLogoBltBuffer != NULL) {\r
209 FreePool (mLogoBltBuffer);\r
210 mLogoBltBuffer = NULL;\r
a46c3657 211 }\r
0284e90c 212\r
53be7721
MK
213 //\r
214 // Allocate new logo buffer\r
215 //\r
216 mLogoBltBuffer = AllocateCopyPool (BufferSize, BltBuffer);\r
0284e90c
LG
217 if (mLogoBltBuffer == NULL) {\r
218 return EFI_OUT_OF_RESOURCES;\r
219 }\r
53be7721
MK
220\r
221 mLogoDestX = DestinationX;\r
222 mLogoDestY = DestinationY;\r
223 mLogoWidth = Width;\r
224 mLogoHeight = Height;\r
0284e90c
LG
225 mIsLogoValid = TRUE;\r
226\r
227 return EFI_SUCCESS;\r
228}\r
229\r
230/**\r
53be7721
MK
231 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
232 install the Boot Graphics Resource Table.\r
0284e90c 233\r
53be7721
MK
234 @param[in] Event The Event that is being processed.\r
235 @param[in] Context The Event Context.\r
0284e90c
LG
236\r
237**/\r
238VOID\r
53be7721
MK
239EFIAPI\r
240BgrtReadyToBootEventNotify (\r
241 IN EFI_EVENT Event,\r
242 IN VOID *Context\r
0284e90c
LG
243 )\r
244{\r
53be7721
MK
245 EFI_STATUS Status;\r
246 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;\r
247 VOID *ImageBuffer;\r
248 UINT32 BmpSize;\r
0284e90c 249\r
0284e90c
LG
250 //\r
251 // Get ACPI Table protocol.\r
252 //\r
53be7721
MK
253 Status = gBS->LocateProtocol (\r
254 &gEfiAcpiTableProtocolGuid,\r
255 NULL,\r
256 (VOID **) &AcpiTableProtocol\r
257 );\r
0284e90c 258 if (EFI_ERROR (Status)) {\r
53be7721 259 return;\r
0284e90c
LG
260 }\r
261\r
262 //\r
cbafa15e 263 // Check whether Boot Graphics Resource Table is already installed.\r
0284e90c 264 //\r
cbafa15e 265 if (mAcpiBgrtInstalled) {\r
266 if (!mAcpiBgrtStatusChanged && !mAcpiBgrtBufferChanged) {\r
267 //\r
268 // Nothing has changed\r
269 //\r
53be7721 270 return;\r
cbafa15e 271 } else {\r
272 //\r
53be7721 273 // If BGRT data change happens, then uninstall orignal AcpiTable first\r
cbafa15e 274 //\r
275 Status = AcpiTableProtocol->UninstallAcpiTable (\r
276 AcpiTableProtocol,\r
277 mBootGraphicsResourceTableKey\r
278 );\r
279 if (EFI_ERROR (Status)) {\r
53be7721
MK
280 return;\r
281 }\r
cbafa15e 282 }\r
283 } else {\r
284 //\r
53be7721 285 // Check whether Logo exists\r
cbafa15e 286 //\r
53be7721
MK
287 if (mLogoBltBuffer == NULL) {\r
288 return;\r
cbafa15e 289 }\r
0284e90c
LG
290 }\r
291\r
cbafa15e 292 if (mAcpiBgrtBufferChanged) {\r
293 //\r
53be7721 294 // Free the old BMP image buffer\r
cbafa15e 295 //\r
53be7721
MK
296 ImageBuffer = (UINT8 *)(UINTN)mBootGraphicsResourceTableTemplate.ImageAddress;\r
297 if (ImageBuffer != NULL) {\r
298 FreePool (ImageBuffer);\r
cbafa15e 299 }\r
0284e90c 300\r
cbafa15e 301 //\r
53be7721
MK
302 // Convert GOP Blt buffer to BMP image. Pass in ImageBuffer set to NULL\r
303 // so the BMP image is allocated by TranslateGopBltToBmp().\r
cbafa15e 304 //\r
53be7721
MK
305 ImageBuffer = NULL;\r
306 Status = TranslateGopBltToBmp (\r
307 mLogoBltBuffer,\r
308 (UINT32)mLogoHeight,\r
309 (UINT32)mLogoWidth,\r
310 &ImageBuffer,\r
311 &BmpSize\r
312 );\r
313 if (EFI_ERROR (Status)) {\r
314 return;\r
a46c3657 315 }\r
4c58575e
CZ
316\r
317 //\r
53be7721 318 // Free the logo buffer\r
cbafa15e 319 //\r
cbafa15e 320 FreePool (mLogoBltBuffer);\r
321 mLogoBltBuffer = NULL;\r
322\r
53be7721
MK
323 //\r
324 // Update BMP image fields of the Boot Graphics Resource Table\r
325 //\r
326 mBootGraphicsResourceTableTemplate.ImageAddress = (UINT64)(UINTN)ImageBuffer;\r
327 mBootGraphicsResourceTableTemplate.ImageOffsetX = (UINT32)mLogoDestX;\r
328 mBootGraphicsResourceTableTemplate.ImageOffsetY = (UINT32)mLogoDestY;\r
0284e90c 329 }\r
0284e90c 330\r
53be7721
MK
331 //\r
332 // Update Status field of Boot Graphics Resource Table\r
333 //\r
334 if (mIsLogoValid) {\r
335 mBootGraphicsResourceTableTemplate.Status = EFI_ACPI_5_0_BGRT_STATUS_VALID;\r
336 } else {\r
337 mBootGraphicsResourceTableTemplate.Status = EFI_ACPI_5_0_BGRT_STATUS_INVALID;\r
338 }\r
0284e90c
LG
339\r
340 //\r
53be7721 341 // Update Checksum of Boot Graphics Resource Table\r
0284e90c 342 //\r
53be7721
MK
343 mBootGraphicsResourceTableTemplate.Header.Checksum = 0;\r
344 mBootGraphicsResourceTableTemplate.Header.Checksum =\r
345 CalculateCheckSum8 (\r
346 (UINT8 *)&mBootGraphicsResourceTableTemplate,\r
347 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE)\r
348 );\r
0284e90c
LG
349\r
350 //\r
351 // Publish Boot Graphics Resource Table.\r
352 //\r
353 Status = AcpiTableProtocol->InstallAcpiTable (\r
354 AcpiTableProtocol,\r
355 &mBootGraphicsResourceTableTemplate,\r
356 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),\r
357 &mBootGraphicsResourceTableKey\r
358 );\r
359 if (EFI_ERROR (Status)) {\r
53be7721 360 return;\r
0284e90c
LG
361 }\r
362\r
53be7721 363 mAcpiBgrtInstalled = TRUE;\r
cbafa15e 364 mAcpiBgrtStatusChanged = FALSE;\r
365 mAcpiBgrtBufferChanged = FALSE;\r
0284e90c
LG
366}\r
367\r
368/**\r
369 The module Entry Point of the Boot Graphics Resource Table DXE driver.\r
370\r
371 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
372 @param[in] SystemTable A pointer to the EFI System Table.\r
373\r
374 @retval EFI_SUCCESS The entry point is executed successfully.\r
375 @retval Other Some error occurs when executing this entry point.\r
376\r
377**/\r
378EFI_STATUS\r
379EFIAPI\r
380BootGraphicsDxeEntryPoint (\r
53be7721
MK
381 IN EFI_HANDLE ImageHandle,\r
382 IN EFI_SYSTEM_TABLE *SystemTable\r
0284e90c
LG
383 )\r
384{\r
53be7721
MK
385 EFI_STATUS Status;\r
386 EFI_ACPI_DESCRIPTION_HEADER *Header;\r
e84f07b5 387\r
53be7721
MK
388 //\r
389 // Update Header fields of Boot Graphics Resource Table from PCDs\r
390 //\r
391 Header = &mBootGraphicsResourceTableTemplate.Header;\r
392 ZeroMem (Header->OemId, sizeof (Header->OemId));\r
e84f07b5 393 CopyMem (\r
53be7721 394 Header->OemId,\r
e84f07b5 395 PcdGetPtr (PcdAcpiDefaultOemId),\r
53be7721 396 MIN (PcdGetSize (PcdAcpiDefaultOemId), sizeof (Header->OemId))\r
e84f07b5 397 );\r
53be7721
MK
398 WriteUnaligned64 (&Header->OemTableId, PcdGet64 (PcdAcpiDefaultOemTableId));\r
399 Header->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
400 Header->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
401 Header->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
0284e90c
LG
402\r
403 //\r
404 // Install Boot Logo protocol.\r
405 //\r
406 Status = gBS->InstallMultipleProtocolInterfaces (\r
407 &mBootLogoHandle,\r
408 &gEfiBootLogoProtocolGuid,\r
409 &mBootLogoProtocolTemplate,\r
410 NULL\r
411 );\r
412 ASSERT_EFI_ERROR (Status);\r
413\r
414 //\r
415 // Register notify function to install BGRT on ReadyToBoot Event.\r
416 //\r
417 Status = gBS->CreateEventEx (\r
418 EVT_NOTIFY_SIGNAL,\r
419 TPL_CALLBACK,\r
420 BgrtReadyToBootEventNotify,\r
421 NULL,\r
422 &gEfiEventReadyToBootGuid,\r
423 &mBootGraphicsReadyToBootEvent\r
424 );\r
425 ASSERT_EFI_ERROR (Status);\r
426\r
427 return Status;\r
428}\r