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