]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c
Enable Help string scroll when the help info can't show all at current page.
[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
cbafa15e 4 Copyright (c) 2011 - 2012, 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
16#include <IndustryStandard/Acpi50.h>\r
17#include <IndustryStandard/Bmp.h>\r
18\r
19#include <Protocol/AcpiTable.h>\r
20#include <Protocol/GraphicsOutput.h>\r
21#include <Protocol/BootLogo.h>\r
22\r
23#include <Guid/EventGroup.h>\r
24\r
25#include <Library/BaseLib.h>\r
26#include <Library/BaseMemoryLib.h>\r
27#include <Library/MemoryAllocationLib.h>\r
28#include <Library/UefiBootServicesTableLib.h>\r
29#include <Library/DebugLib.h>\r
30\r
31//\r
32// ACPI table information used to initialize tables.\r
33//\r
34#define EFI_ACPI_OEM_ID "INTEL"\r
35#define EFI_ACPI_OEM_TABLE_ID 0x2020204F4E414954ULL // "TIANO "\r
36#define EFI_ACPI_OEM_REVISION 0x00000001\r
37#define EFI_ACPI_CREATOR_ID 0x5446534D // TBD "MSFT"\r
38#define EFI_ACPI_CREATOR_REVISION 0x01000013 // TBD\r
39\r
40//\r
41// Module globals.\r
42//\r
43EFI_EVENT mBootGraphicsReadyToBootEvent;\r
44UINTN mBootGraphicsResourceTableKey = 0;\r
45\r
46EFI_HANDLE mBootLogoHandle = NULL;\r
47BOOLEAN mIsLogoValid = FALSE;\r
48EFI_GRAPHICS_OUTPUT_BLT_PIXEL *mLogoBltBuffer = NULL;\r
49UINTN mLogoDestX = 0;\r
50UINTN mLogoDestY = 0;\r
51UINTN mLogoWidth = 0;\r
52UINTN mLogoHeight = 0;\r
53\r
54BMP_IMAGE_HEADER mBmpImageHeaderTemplate = {\r
55 'B', // CharB\r
56 'M', // CharM\r
57 0, // Size will be updated at runtime\r
58 {0, 0}, // Reserved\r
59 sizeof (BMP_IMAGE_HEADER), // ImageOffset\r
60 sizeof (BMP_IMAGE_HEADER) - OFFSET_OF (BMP_IMAGE_HEADER, HeaderSize), // HeaderSize\r
61 0, // PixelWidth will be updated at runtime\r
62 0, // PixelHeight will be updated at runtime\r
63 1, // Planes\r
64 24, // BitPerPixel\r
65 0, // CompressionType\r
66 0, // ImageSize will be updated at runtime\r
67 0, // XPixelsPerMeter\r
68 0, // YPixelsPerMeter\r
69 0, // NumberOfColors\r
70 0 // ImportantColors\r
71};\r
72\r
73BOOLEAN mAcpiBgrtInstalled = FALSE;\r
cbafa15e 74BOOLEAN mAcpiBgrtStatusChanged = FALSE;\r
75BOOLEAN mAcpiBgrtBufferChanged = FALSE;\r
0284e90c
LG
76\r
77EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate = {\r
78 {\r
79 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,\r
80 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),\r
81 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION, // Revision\r
82 0x00, // Checksum will be updated at runtime\r
83 //\r
84 // It is expected that these values will be updated at runtime.\r
85 //\r
86 EFI_ACPI_OEM_ID, // OEMID is a 6 bytes long field\r
87 EFI_ACPI_OEM_TABLE_ID, // OEM table identification(8 bytes long)\r
88 EFI_ACPI_OEM_REVISION, // OEM revision number\r
89 EFI_ACPI_CREATOR_ID, // ASL compiler vendor ID\r
90 EFI_ACPI_CREATOR_REVISION, // ASL compiler revision number\r
91 },\r
92 EFI_ACPI_5_0_BGRT_VERSION, // Version\r
93 EFI_ACPI_5_0_BGRT_STATUS_VALID, // Status\r
94 EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP, // Image Type\r
95 0, // Image Address\r
96 0, // Image Offset X\r
97 0 // Image Offset Y\r
98};\r
99\r
100/**\r
101 Update information of logo image drawn on screen.\r
102\r
103 @param This The pointer to the Boot Logo protocol instance.\r
104 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer\r
105 is set to NULL, it indicates that logo image is no\r
106 longer on the screen.\r
107 @param DestinationX X coordinate of destination for the BltBuffer.\r
108 @param DestinationY Y coordinate of destination for the BltBuffer.\r
109 @param Width Width of rectangle in BltBuffer in pixels.\r
110 @param Height Hight of rectangle in BltBuffer in pixels.\r
111\r
112 @retval EFI_SUCCESS The boot logo information was updated.\r
113 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
114 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to\r
115 insufficient memory resources.\r
116\r
117**/\r
118EFI_STATUS\r
119EFIAPI\r
120SetBootLogo (\r
121 IN EFI_BOOT_LOGO_PROTOCOL *This,\r
122 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
123 IN UINTN DestinationX,\r
124 IN UINTN DestinationY,\r
125 IN UINTN Width,\r
126 IN UINTN Height\r
127 );\r
128\r
129EFI_BOOT_LOGO_PROTOCOL mBootLogoProtocolTemplate = { SetBootLogo };\r
130\r
131/**\r
132 Update information of logo image drawn on screen.\r
133\r
134 @param This The pointer to the Boot Logo protocol instance.\r
135 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer\r
136 is set to NULL, it indicates that logo image is no\r
137 longer on the screen.\r
138 @param DestinationX X coordinate of destination for the BltBuffer.\r
139 @param DestinationY Y coordinate of destination for the BltBuffer.\r
140 @param Width Width of rectangle in BltBuffer in pixels.\r
141 @param Height Hight of rectangle in BltBuffer in pixels.\r
142\r
143 @retval EFI_SUCCESS The boot logo information was updated.\r
144 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
145 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to\r
146 insufficient memory resources.\r
147\r
148**/\r
149EFI_STATUS\r
150EFIAPI\r
151SetBootLogo (\r
152 IN EFI_BOOT_LOGO_PROTOCOL *This,\r
153 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
154 IN UINTN DestinationX,\r
155 IN UINTN DestinationY,\r
156 IN UINTN Width,\r
157 IN UINTN Height\r
158 )\r
159{\r
160 if (BltBuffer == NULL) {\r
161 mIsLogoValid = FALSE;\r
cbafa15e 162 mAcpiBgrtStatusChanged = TRUE;\r
0284e90c
LG
163 return EFI_SUCCESS;\r
164 }\r
165\r
166 if (Width == 0 || Height == 0) {\r
167 return EFI_INVALID_PARAMETER;\r
168 }\r
cbafa15e 169 \r
170 mAcpiBgrtBufferChanged = TRUE;\r
0284e90c
LG
171 if (mLogoBltBuffer != NULL) {\r
172 FreePool (mLogoBltBuffer);\r
cbafa15e 173 mLogoBltBuffer = NULL;\r
0284e90c
LG
174 }\r
175\r
176 mLogoBltBuffer = AllocateCopyPool (\r
177 Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),\r
178 BltBuffer\r
179 );\r
180 if (mLogoBltBuffer == NULL) {\r
181 return EFI_OUT_OF_RESOURCES;\r
182 }\r
183 mLogoDestX = DestinationX;\r
184 mLogoDestY = DestinationY;\r
185 mLogoWidth = Width;\r
186 mLogoHeight = Height;\r
187 mIsLogoValid = TRUE;\r
188\r
189 return EFI_SUCCESS;\r
190}\r
191\r
192/**\r
193 This function calculates and updates an UINT8 checksum.\r
194\r
195 @param[in] Buffer Pointer to buffer to checksum.\r
196 @param[in] Size Number of bytes to checksum.\r
197\r
198**/\r
199VOID\r
200BgrtAcpiTableChecksum (\r
201 IN UINT8 *Buffer,\r
202 IN UINTN Size\r
203 )\r
204{\r
205 UINTN ChecksumOffset;\r
206\r
207 ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);\r
208\r
209 //\r
210 // Set checksum to 0 first.\r
211 //\r
212 Buffer[ChecksumOffset] = 0;\r
213\r
214 //\r
215 // Update checksum value.\r
216 //\r
217 Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);\r
218}\r
219\r
220/**\r
221 Allocate EfiReservedMemoryType below 4G memory address.\r
222\r
223 This function allocates EfiReservedMemoryType below 4G memory address.\r
224\r
225 @param[in] Size Size of memory to allocate.\r
226\r
227 @return Allocated address for output.\r
228\r
229**/\r
230VOID *\r
231BgrtAllocateReservedMemoryBelow4G (\r
232 IN UINTN Size\r
233 )\r
234{\r
235 UINTN Pages;\r
236 EFI_PHYSICAL_ADDRESS Address;\r
237 EFI_STATUS Status;\r
238 VOID *Buffer;\r
239\r
240 Pages = EFI_SIZE_TO_PAGES (Size);\r
241 Address = 0xffffffff;\r
242\r
243 Status = gBS->AllocatePages (\r
244 AllocateMaxAddress,\r
245 EfiReservedMemoryType,\r
246 Pages,\r
247 &Address\r
248 );\r
249 ASSERT_EFI_ERROR (Status);\r
250\r
251 Buffer = (VOID *) (UINTN) Address;\r
252 ZeroMem (Buffer, Size);\r
253\r
254 return Buffer;\r
255}\r
256\r
257/**\r
258 Install Boot Graphics Resource Table to ACPI table.\r
259\r
260 @return Status code.\r
261\r
262**/\r
263EFI_STATUS\r
264InstallBootGraphicsResourceTable (\r
265 VOID\r
266 )\r
267{\r
268 EFI_STATUS Status;\r
269 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;\r
270 UINT8 *ImageBuffer;\r
271 UINTN PaddingSize;\r
272 UINTN BmpSize;\r
cbafa15e 273 UINTN OrigBmpSize;\r
0284e90c
LG
274 UINT8 *Image;\r
275 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPixel;\r
276 UINTN Col;\r
277 UINTN Row;\r
278\r
0284e90c
LG
279 //\r
280 // Get ACPI Table protocol.\r
281 //\r
282 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);\r
283 if (EFI_ERROR (Status)) {\r
284 return Status;\r
285 }\r
286\r
287 //\r
cbafa15e 288 // Check whether Boot Graphics Resource Table is already installed.\r
0284e90c 289 //\r
cbafa15e 290 if (mAcpiBgrtInstalled) {\r
291 if (!mAcpiBgrtStatusChanged && !mAcpiBgrtBufferChanged) {\r
292 //\r
293 // Nothing has changed\r
294 //\r
295 return EFI_SUCCESS;\r
296 } else {\r
297 //\r
298 // If BGRT data change happens. Uninstall Orignal AcpiTable first\r
299 //\r
300 Status = AcpiTableProtocol->UninstallAcpiTable (\r
301 AcpiTableProtocol,\r
302 mBootGraphicsResourceTableKey\r
303 );\r
304 if (EFI_ERROR (Status)) {\r
305 return Status;\r
306 } \r
307 }\r
308 } else {\r
309 //\r
310 // Check whether Logo exist.\r
311 //\r
312 if ( mLogoBltBuffer == NULL) {\r
313 return EFI_NOT_FOUND;\r
314 }\r
0284e90c
LG
315 }\r
316\r
cbafa15e 317 if (mAcpiBgrtBufferChanged) {\r
318 //\r
319 // reserve original BGRT buffer size\r
320 //\r
321 OrigBmpSize = mBmpImageHeaderTemplate.ImageSize + sizeof (BMP_IMAGE_HEADER);\r
322 //\r
323 // Free orignal BMP memory \r
324 // \r
325 if (mBootGraphicsResourceTableTemplate.ImageAddress) {\r
326 gBS->FreePages(mBootGraphicsResourceTableTemplate.ImageAddress, EFI_SIZE_TO_PAGES(OrigBmpSize));\r
327 }\r
0284e90c 328\r
cbafa15e 329 //\r
330 // Allocate memory for BMP file.\r
331 //\r
332 PaddingSize = mLogoWidth & 0x3;\r
333 BmpSize = (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER);\r
334 ImageBuffer = BgrtAllocateReservedMemoryBelow4G (BmpSize);\r
335 if (ImageBuffer == NULL) {\r
336 return EFI_OUT_OF_RESOURCES;\r
337 }\r
0284e90c 338\r
cbafa15e 339 mBmpImageHeaderTemplate.Size = (UINT32) BmpSize;\r
340 mBmpImageHeaderTemplate.ImageSize = (UINT32) BmpSize - sizeof (BMP_IMAGE_HEADER);\r
341 mBmpImageHeaderTemplate.PixelWidth = (UINT32) mLogoWidth;\r
342 mBmpImageHeaderTemplate.PixelHeight = (UINT32) mLogoHeight;\r
343 CopyMem (ImageBuffer, &mBmpImageHeaderTemplate, sizeof (BMP_IMAGE_HEADER));\r
344 \r
345 //\r
346 // Convert BLT buffer to BMP file.\r
347 //\r
348 Image = ImageBuffer + sizeof (BMP_IMAGE_HEADER);\r
349 for (Row = 0; Row < mLogoHeight; Row++) {\r
0284e90c
LG
350 BltPixel = &mLogoBltBuffer[(mLogoHeight - Row - 1) * mLogoWidth];\r
351\r
352 for (Col = 0; Col < mLogoWidth; Col++) {\r
353 *Image++ = BltPixel->Blue;\r
354 *Image++ = BltPixel->Green;\r
355 *Image++ = BltPixel->Red;\r
356 BltPixel++;\r
357 }\r
358\r
cbafa15e 359 //\r
360 // Padding for 4 byte alignment.\r
361 //\r
362 Image += PaddingSize;\r
363 }\r
364 FreePool (mLogoBltBuffer);\r
365 mLogoBltBuffer = NULL;\r
366\r
367 mBootGraphicsResourceTableTemplate.ImageAddress = (UINT64) (UINTN) ImageBuffer;\r
368 mBootGraphicsResourceTableTemplate.ImageOffsetX = (UINT32) mLogoDestX;\r
369 mBootGraphicsResourceTableTemplate.ImageOffsetY = (UINT32) mLogoDestY;\r
0284e90c 370 }\r
0284e90c
LG
371\r
372 mBootGraphicsResourceTableTemplate.Status = (UINT8) (mIsLogoValid ? EFI_ACPI_5_0_BGRT_STATUS_VALID : EFI_ACPI_5_0_BGRT_STATUS_INVALID);\r
0284e90c
LG
373\r
374 //\r
375 // Update Checksum.\r
376 //\r
377 BgrtAcpiTableChecksum ((UINT8 *) &mBootGraphicsResourceTableTemplate, sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE));\r
378\r
379 //\r
380 // Publish Boot Graphics Resource Table.\r
381 //\r
382 Status = AcpiTableProtocol->InstallAcpiTable (\r
383 AcpiTableProtocol,\r
384 &mBootGraphicsResourceTableTemplate,\r
385 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),\r
386 &mBootGraphicsResourceTableKey\r
387 );\r
388 if (EFI_ERROR (Status)) {\r
389 return Status;\r
390 }\r
391\r
392 mAcpiBgrtInstalled = TRUE;\r
cbafa15e 393 mAcpiBgrtStatusChanged = FALSE;\r
394 mAcpiBgrtBufferChanged = FALSE;\r
395 \r
0284e90c
LG
396 return Status;\r
397}\r
398\r
399/**\r
400 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
401 install the Boot Graphics Resource Table.\r
402\r
403 @param[in] Event The Event that is being processed.\r
404 @param[in] Context The Event Context.\r
405\r
406**/\r
407VOID\r
408EFIAPI\r
409BgrtReadyToBootEventNotify (\r
410 IN EFI_EVENT Event,\r
411 IN VOID *Context\r
412 )\r
413{\r
414 InstallBootGraphicsResourceTable ();\r
415}\r
416\r
417/**\r
418 The module Entry Point of the Boot Graphics Resource Table DXE driver.\r
419\r
420 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
421 @param[in] SystemTable A pointer to the EFI System Table.\r
422\r
423 @retval EFI_SUCCESS The entry point is executed successfully.\r
424 @retval Other Some error occurs when executing this entry point.\r
425\r
426**/\r
427EFI_STATUS\r
428EFIAPI\r
429BootGraphicsDxeEntryPoint (\r
430 IN EFI_HANDLE ImageHandle,\r
431 IN EFI_SYSTEM_TABLE *SystemTable\r
432 )\r
433{\r
434 EFI_STATUS Status;\r
435\r
436 //\r
437 // Install Boot Logo protocol.\r
438 //\r
439 Status = gBS->InstallMultipleProtocolInterfaces (\r
440 &mBootLogoHandle,\r
441 &gEfiBootLogoProtocolGuid,\r
442 &mBootLogoProtocolTemplate,\r
443 NULL\r
444 );\r
445 ASSERT_EFI_ERROR (Status);\r
446\r
447 //\r
448 // Register notify function to install BGRT on ReadyToBoot Event.\r
449 //\r
450 Status = gBS->CreateEventEx (\r
451 EVT_NOTIFY_SIGNAL,\r
452 TPL_CALLBACK,\r
453 BgrtReadyToBootEventNotify,\r
454 NULL,\r
455 &gEfiEventReadyToBootGuid,\r
456 &mBootGraphicsReadyToBootEvent\r
457 );\r
458 ASSERT_EFI_ERROR (Status);\r
459\r
460 return Status;\r
461}\r