]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c
Add Acpi50 FPDT and BGRT module into MdeModulePkg.
[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
4 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
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
74\r
75EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE mBootGraphicsResourceTableTemplate = {\r
76 {\r
77 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE,\r
78 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),\r
79 EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE_REVISION, // Revision\r
80 0x00, // Checksum will be updated at runtime\r
81 //\r
82 // It is expected that these values will be updated at runtime.\r
83 //\r
84 EFI_ACPI_OEM_ID, // OEMID is a 6 bytes long field\r
85 EFI_ACPI_OEM_TABLE_ID, // OEM table identification(8 bytes long)\r
86 EFI_ACPI_OEM_REVISION, // OEM revision number\r
87 EFI_ACPI_CREATOR_ID, // ASL compiler vendor ID\r
88 EFI_ACPI_CREATOR_REVISION, // ASL compiler revision number\r
89 },\r
90 EFI_ACPI_5_0_BGRT_VERSION, // Version\r
91 EFI_ACPI_5_0_BGRT_STATUS_VALID, // Status\r
92 EFI_ACPI_5_0_BGRT_IMAGE_TYPE_BMP, // Image Type\r
93 0, // Image Address\r
94 0, // Image Offset X\r
95 0 // Image Offset Y\r
96};\r
97\r
98/**\r
99 Update information of logo image drawn on screen.\r
100\r
101 @param This The pointer to the Boot Logo protocol instance.\r
102 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer\r
103 is set to NULL, it indicates that logo image is no\r
104 longer on the screen.\r
105 @param DestinationX X coordinate of destination for the BltBuffer.\r
106 @param DestinationY Y coordinate of destination for the BltBuffer.\r
107 @param Width Width of rectangle in BltBuffer in pixels.\r
108 @param Height Hight of rectangle in BltBuffer in pixels.\r
109\r
110 @retval EFI_SUCCESS The boot logo information was updated.\r
111 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
112 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to\r
113 insufficient memory resources.\r
114\r
115**/\r
116EFI_STATUS\r
117EFIAPI\r
118SetBootLogo (\r
119 IN EFI_BOOT_LOGO_PROTOCOL *This,\r
120 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
121 IN UINTN DestinationX,\r
122 IN UINTN DestinationY,\r
123 IN UINTN Width,\r
124 IN UINTN Height\r
125 );\r
126\r
127EFI_BOOT_LOGO_PROTOCOL mBootLogoProtocolTemplate = { SetBootLogo };\r
128\r
129/**\r
130 Update information of logo image drawn on screen.\r
131\r
132 @param This The pointer to the Boot Logo protocol instance.\r
133 @param BltBuffer The BLT buffer for logo drawn on screen. If BltBuffer\r
134 is set to NULL, it indicates that logo image is no\r
135 longer on the screen.\r
136 @param DestinationX X coordinate of destination for the BltBuffer.\r
137 @param DestinationY Y coordinate of destination for the BltBuffer.\r
138 @param Width Width of rectangle in BltBuffer in pixels.\r
139 @param Height Hight of rectangle in BltBuffer in pixels.\r
140\r
141 @retval EFI_SUCCESS The boot logo information was updated.\r
142 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
143 @retval EFI_OUT_OF_RESOURCES The logo information was not updated due to\r
144 insufficient memory resources.\r
145\r
146**/\r
147EFI_STATUS\r
148EFIAPI\r
149SetBootLogo (\r
150 IN EFI_BOOT_LOGO_PROTOCOL *This,\r
151 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
152 IN UINTN DestinationX,\r
153 IN UINTN DestinationY,\r
154 IN UINTN Width,\r
155 IN UINTN Height\r
156 )\r
157{\r
158 if (BltBuffer == NULL) {\r
159 mIsLogoValid = FALSE;\r
160 return EFI_SUCCESS;\r
161 }\r
162\r
163 if (Width == 0 || Height == 0) {\r
164 return EFI_INVALID_PARAMETER;\r
165 }\r
166\r
167 if (mLogoBltBuffer != NULL) {\r
168 FreePool (mLogoBltBuffer);\r
169 }\r
170\r
171 mLogoBltBuffer = AllocateCopyPool (\r
172 Width * Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),\r
173 BltBuffer\r
174 );\r
175 if (mLogoBltBuffer == NULL) {\r
176 return EFI_OUT_OF_RESOURCES;\r
177 }\r
178 mLogoDestX = DestinationX;\r
179 mLogoDestY = DestinationY;\r
180 mLogoWidth = Width;\r
181 mLogoHeight = Height;\r
182 mIsLogoValid = TRUE;\r
183\r
184 return EFI_SUCCESS;\r
185}\r
186\r
187/**\r
188 This function calculates and updates an UINT8 checksum.\r
189\r
190 @param[in] Buffer Pointer to buffer to checksum.\r
191 @param[in] Size Number of bytes to checksum.\r
192\r
193**/\r
194VOID\r
195BgrtAcpiTableChecksum (\r
196 IN UINT8 *Buffer,\r
197 IN UINTN Size\r
198 )\r
199{\r
200 UINTN ChecksumOffset;\r
201\r
202 ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);\r
203\r
204 //\r
205 // Set checksum to 0 first.\r
206 //\r
207 Buffer[ChecksumOffset] = 0;\r
208\r
209 //\r
210 // Update checksum value.\r
211 //\r
212 Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);\r
213}\r
214\r
215/**\r
216 Allocate EfiReservedMemoryType below 4G memory address.\r
217\r
218 This function allocates EfiReservedMemoryType below 4G memory address.\r
219\r
220 @param[in] Size Size of memory to allocate.\r
221\r
222 @return Allocated address for output.\r
223\r
224**/\r
225VOID *\r
226BgrtAllocateReservedMemoryBelow4G (\r
227 IN UINTN Size\r
228 )\r
229{\r
230 UINTN Pages;\r
231 EFI_PHYSICAL_ADDRESS Address;\r
232 EFI_STATUS Status;\r
233 VOID *Buffer;\r
234\r
235 Pages = EFI_SIZE_TO_PAGES (Size);\r
236 Address = 0xffffffff;\r
237\r
238 Status = gBS->AllocatePages (\r
239 AllocateMaxAddress,\r
240 EfiReservedMemoryType,\r
241 Pages,\r
242 &Address\r
243 );\r
244 ASSERT_EFI_ERROR (Status);\r
245\r
246 Buffer = (VOID *) (UINTN) Address;\r
247 ZeroMem (Buffer, Size);\r
248\r
249 return Buffer;\r
250}\r
251\r
252/**\r
253 Install Boot Graphics Resource Table to ACPI table.\r
254\r
255 @return Status code.\r
256\r
257**/\r
258EFI_STATUS\r
259InstallBootGraphicsResourceTable (\r
260 VOID\r
261 )\r
262{\r
263 EFI_STATUS Status;\r
264 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;\r
265 UINT8 *ImageBuffer;\r
266 UINTN PaddingSize;\r
267 UINTN BmpSize;\r
268 UINT8 *Image;\r
269 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPixel;\r
270 UINTN Col;\r
271 UINTN Row;\r
272\r
273 //\r
274 // Check whether Boot Graphics Resource Table is already installed.\r
275 //\r
276 if (mAcpiBgrtInstalled) {\r
277 return EFI_SUCCESS;\r
278 }\r
279\r
280 //\r
281 // Get ACPI Table protocol.\r
282 //\r
283 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);\r
284 if (EFI_ERROR (Status)) {\r
285 return Status;\r
286 }\r
287\r
288 //\r
289 // Check whether Logo exist.\r
290 //\r
291 if (mLogoBltBuffer == NULL) {\r
292 return EFI_NOT_FOUND;\r
293 }\r
294\r
295 //\r
296 // Allocate memory for BMP file.\r
297 //\r
298 PaddingSize = mLogoWidth & 0x3;\r
299 BmpSize = (mLogoWidth * 3 + PaddingSize) * mLogoHeight + sizeof (BMP_IMAGE_HEADER);\r
300 ImageBuffer = BgrtAllocateReservedMemoryBelow4G (BmpSize);\r
301 if (ImageBuffer == NULL) {\r
302 return EFI_OUT_OF_RESOURCES;\r
303 }\r
304\r
305 mBmpImageHeaderTemplate.Size = (UINT32) BmpSize;\r
306 mBmpImageHeaderTemplate.ImageSize = (UINT32) BmpSize - sizeof (BMP_IMAGE_HEADER);\r
307 mBmpImageHeaderTemplate.PixelWidth = (UINT32) mLogoWidth;\r
308 mBmpImageHeaderTemplate.PixelHeight = (UINT32) mLogoHeight;\r
309 CopyMem (ImageBuffer, &mBmpImageHeaderTemplate, sizeof (BMP_IMAGE_HEADER));\r
310\r
311 //\r
312 // Convert BLT buffer to BMP file.\r
313 //\r
314 Image = ImageBuffer + sizeof (BMP_IMAGE_HEADER);\r
315 for (Row = 0; Row < mLogoHeight; Row++) {\r
316 BltPixel = &mLogoBltBuffer[(mLogoHeight - Row - 1) * mLogoWidth];\r
317\r
318 for (Col = 0; Col < mLogoWidth; Col++) {\r
319 *Image++ = BltPixel->Blue;\r
320 *Image++ = BltPixel->Green;\r
321 *Image++ = BltPixel->Red;\r
322 BltPixel++;\r
323 }\r
324\r
325 //\r
326 // Padding for 4 byte alignment.\r
327 //\r
328 Image += PaddingSize;\r
329 }\r
330 FreePool (mLogoBltBuffer);\r
331 mLogoBltBuffer = NULL;\r
332\r
333 mBootGraphicsResourceTableTemplate.Status = (UINT8) (mIsLogoValid ? EFI_ACPI_5_0_BGRT_STATUS_VALID : EFI_ACPI_5_0_BGRT_STATUS_INVALID);\r
334 mBootGraphicsResourceTableTemplate.ImageAddress = (UINT64) (UINTN) ImageBuffer;\r
335 mBootGraphicsResourceTableTemplate.ImageOffsetX = (UINT32) mLogoDestX;\r
336 mBootGraphicsResourceTableTemplate.ImageOffsetY = (UINT32) mLogoDestY;\r
337\r
338 //\r
339 // Update Checksum.\r
340 //\r
341 BgrtAcpiTableChecksum ((UINT8 *) &mBootGraphicsResourceTableTemplate, sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE));\r
342\r
343 //\r
344 // Publish Boot Graphics Resource Table.\r
345 //\r
346 Status = AcpiTableProtocol->InstallAcpiTable (\r
347 AcpiTableProtocol,\r
348 &mBootGraphicsResourceTableTemplate,\r
349 sizeof (EFI_ACPI_5_0_BOOT_GRAPHICS_RESOURCE_TABLE),\r
350 &mBootGraphicsResourceTableKey\r
351 );\r
352 if (EFI_ERROR (Status)) {\r
353 return Status;\r
354 }\r
355\r
356 mAcpiBgrtInstalled = TRUE;\r
357 return Status;\r
358}\r
359\r
360/**\r
361 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
362 install the Boot Graphics Resource Table.\r
363\r
364 @param[in] Event The Event that is being processed.\r
365 @param[in] Context The Event Context.\r
366\r
367**/\r
368VOID\r
369EFIAPI\r
370BgrtReadyToBootEventNotify (\r
371 IN EFI_EVENT Event,\r
372 IN VOID *Context\r
373 )\r
374{\r
375 InstallBootGraphicsResourceTable ();\r
376}\r
377\r
378/**\r
379 The module Entry Point of the Boot Graphics Resource Table DXE driver.\r
380\r
381 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
382 @param[in] SystemTable A pointer to the EFI System Table.\r
383\r
384 @retval EFI_SUCCESS The entry point is executed successfully.\r
385 @retval Other Some error occurs when executing this entry point.\r
386\r
387**/\r
388EFI_STATUS\r
389EFIAPI\r
390BootGraphicsDxeEntryPoint (\r
391 IN EFI_HANDLE ImageHandle,\r
392 IN EFI_SYSTEM_TABLE *SystemTable\r
393 )\r
394{\r
395 EFI_STATUS Status;\r
396\r
397 //\r
398 // Install Boot Logo protocol.\r
399 //\r
400 Status = gBS->InstallMultipleProtocolInterfaces (\r
401 &mBootLogoHandle,\r
402 &gEfiBootLogoProtocolGuid,\r
403 &mBootLogoProtocolTemplate,\r
404 NULL\r
405 );\r
406 ASSERT_EFI_ERROR (Status);\r
407\r
408 //\r
409 // Register notify function to install BGRT on ReadyToBoot Event.\r
410 //\r
411 Status = gBS->CreateEventEx (\r
412 EVT_NOTIFY_SIGNAL,\r
413 TPL_CALLBACK,\r
414 BgrtReadyToBootEventNotify,\r
415 NULL,\r
416 &gEfiEventReadyToBootGuid,\r
417 &mBootGraphicsReadyToBootEvent\r
418 );\r
419 ASSERT_EFI_ERROR (Status);\r
420\r
421 return Status;\r
422}\r