]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
Add back the BdsDeleteBootOption to pass build.
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / GenericBdsLib / BdsConsole.c
CommitLineData
5c08e117 1/** @file\r
2 BDS Lib functions which contain all the code to connect console device\r
3\r
9572320f 4Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
180a5a35 5This program and the accompanying materials\r
5c08e117 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "InternalBdsLib.h"\r
0682583a 16#include "Bmp.h"\r
5c08e117 17\r
18/**\r
19 Check if we need to save the EFI variable with "ConVarName" as name\r
20 as NV type\r
775a9b19 21 If ConVarName is NULL, then ASSERT().\r
22 \r
5c08e117 23 @param ConVarName The name of the EFI variable.\r
24\r
25 @retval TRUE Set the EFI variable as NV type.\r
26 @retval FALSE EFI variable as NV type can be set NonNV.\r
27**/\r
28BOOLEAN\r
29IsNvNeed (\r
30 IN CHAR16 *ConVarName\r
31 )\r
32{\r
33 CHAR16 *Ptr;\r
34\r
775a9b19 35 ASSERT (ConVarName != NULL);\r
36 \r
5c08e117 37 Ptr = ConVarName;\r
38\r
39 //\r
40 // If the variable includes "Dev" at last, we consider\r
41 // it does not support NV attribute.\r
42 //\r
43 while (*Ptr != L'\0') {\r
44 Ptr++;\r
45 }\r
46\r
9260b915 47 if (((INTN)((UINTN)Ptr - (UINTN)ConVarName) / sizeof (CHAR16)) <= 3) {\r
f0a3b1a2 48 return TRUE;\r
49 }\r
50 \r
5c08e117 51 if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {\r
52 return FALSE;\r
53 } else {\r
54 return TRUE;\r
55 }\r
56}\r
57\r
dad60833 58/**\r
59 Fill console handle in System Table if there are no valid console handle in.\r
60\r
61 Firstly, check the validation of console handle in System Table. If it is invalid,\r
62 update it by the first console device handle from EFI console variable. \r
63\r
64 @param VarName The name of the EFI console variable.\r
65 @param ConsoleGuid Specified Console protocol GUID.\r
66 @param ConsoleHandle On IN, console handle in System Table to be checked. \r
67 On OUT, new console hanlde in system table.\r
68 @param ProtocolInterface On IN, console protocol on console handle in System Table to be checked. \r
69 On OUT, new console protocol on new console hanlde in system table.\r
406ddad3 70\r
71 @retval TRUE System Table has been updated.\r
72 @retval FALSE System Table hasn't been updated.\r
73\r
dad60833 74**/\r
406ddad3 75BOOLEAN \r
dad60833 76UpdateSystemTableConsole (\r
77 IN CHAR16 *VarName,\r
78 IN EFI_GUID *ConsoleGuid,\r
79 IN OUT EFI_HANDLE *ConsoleHandle,\r
80 IN OUT VOID **ProtocolInterface\r
81 )\r
82{\r
83 EFI_STATUS Status;\r
84 UINTN DevicePathSize;\r
85 EFI_DEVICE_PATH_PROTOCOL *FullDevicePath;\r
86 EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
87 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
88 VOID *Interface;\r
89 EFI_HANDLE NewHandle;\r
90\r
91 ASSERT (VarName != NULL);\r
92 ASSERT (ConsoleHandle != NULL);\r
93 ASSERT (ConsoleGuid != NULL);\r
94 ASSERT (ProtocolInterface != NULL);\r
95\r
96 if (*ConsoleHandle != NULL) {\r
97 Status = gBS->HandleProtocol (\r
98 *ConsoleHandle,\r
99 ConsoleGuid,\r
100 &Interface\r
101 );\r
102 if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) {\r
103 //\r
104 // If ConsoleHandle is valid and console protocol on this handle also\r
105 // also matched, just return.\r
106 //\r
406ddad3 107 return FALSE;\r
dad60833 108 }\r
109 }\r
110 \r
111 //\r
112 // Get all possible consoles device path from EFI variable\r
113 //\r
114 VarConsole = BdsLibGetVariableAndSize (\r
115 VarName,\r
116 &gEfiGlobalVariableGuid,\r
117 &DevicePathSize\r
118 );\r
119 if (VarConsole == NULL) {\r
120 //\r
121 // If there is no any console device, just return.\r
122 //\r
406ddad3 123 return FALSE;\r
dad60833 124 }\r
125\r
126 FullDevicePath = VarConsole;\r
127\r
128 do {\r
129 //\r
130 // Check every instance of the console variable\r
131 //\r
132 Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
133 if (Instance == NULL) {\r
134 FreePool (FullDevicePath);\r
135 ASSERT (FALSE);\r
136 }\r
137 \r
138 //\r
139 // Find console device handle by device path instance\r
140 //\r
141 Status = gBS->LocateDevicePath (\r
142 ConsoleGuid,\r
143 &Instance,\r
144 &NewHandle\r
145 );\r
146 if (!EFI_ERROR (Status)) {\r
147 //\r
148 // Get the console protocol on this console device handle\r
149 //\r
150 Status = gBS->HandleProtocol (\r
151 NewHandle,\r
152 ConsoleGuid,\r
153 &Interface\r
154 );\r
155 if (!EFI_ERROR (Status)) {\r
156 //\r
157 // Update new console handle in System Table.\r
158 //\r
159 *ConsoleHandle = NewHandle;\r
160 *ProtocolInterface = Interface;\r
406ddad3 161 return TRUE;\r
dad60833 162 }\r
163 }\r
164\r
165 } while (Instance != NULL);\r
166\r
167 //\r
168 // No any available console devcie found.\r
169 //\r
406ddad3 170 return FALSE;\r
dad60833 171}\r
172\r
5c08e117 173/**\r
174 This function update console variable based on ConVarName, it can\r
175 add or remove one specific console device path from the variable\r
176\r
177 @param ConVarName Console related variable name, ConIn, ConOut,\r
178 ErrOut.\r
179 @param CustomizedConDevicePath The console device path which will be added to\r
180 the console variable ConVarName, this parameter\r
181 can not be multi-instance.\r
182 @param ExclusiveDevicePath The console device path which will be removed\r
183 from the console variable ConVarName, this\r
184 parameter can not be multi-instance.\r
185\r
186 @retval EFI_UNSUPPORTED The added device path is same to the removed one.\r
187 @retval EFI_SUCCESS Success add or remove the device path from the\r
188 console variable.\r
189\r
190**/\r
191EFI_STATUS\r
192EFIAPI\r
193BdsLibUpdateConsoleVariable (\r
194 IN CHAR16 *ConVarName,\r
195 IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,\r
196 IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath\r
197 )\r
198{\r
199 EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
200 UINTN DevicePathSize;\r
201 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
202 EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
203 UINT32 Attributes;\r
204\r
205 VarConsole = NULL;\r
206 DevicePathSize = 0;\r
207\r
208 //\r
209 // Notes: check the device path point, here should check\r
210 // with compare memory\r
211 //\r
212 if (CustomizedConDevicePath == ExclusiveDevicePath) {\r
213 return EFI_UNSUPPORTED;\r
214 }\r
215 //\r
216 // Delete the ExclusiveDevicePath from current default console\r
217 //\r
218 VarConsole = BdsLibGetVariableAndSize (\r
219 ConVarName,\r
220 &gEfiGlobalVariableGuid,\r
221 &DevicePathSize\r
222 );\r
223\r
224 //\r
225 // Initialize NewDevicePath\r
226 //\r
227 NewDevicePath = VarConsole;\r
228\r
229 //\r
230 // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.\r
231 // In the end, NewDevicePath is the final device path.\r
232 //\r
233 if (ExclusiveDevicePath != NULL && VarConsole != NULL) {\r
234 NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);\r
235 }\r
236 //\r
237 // Try to append customized device path to NewDevicePath.\r
238 //\r
239 if (CustomizedConDevicePath != NULL) {\r
240 if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {\r
241 //\r
242 // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.\r
243 //\r
244 NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);\r
245 //\r
246 // In the first check, the default console variable will be _ModuleEntryPoint,\r
247 // just append current customized device path\r
248 //\r
249 TempNewDevicePath = NewDevicePath;\r
250 NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);\r
251 if (TempNewDevicePath != NULL) {\r
252 FreePool(TempNewDevicePath);\r
253 }\r
254 }\r
255 }\r
256\r
257 //\r
258 // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.\r
259 //\r
260 if (IsNvNeed(ConVarName)) {\r
261 //\r
262 // ConVarName has NV attribute.\r
263 //\r
264 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
265 } else {\r
266 //\r
267 // ConVarName does not have NV attribute.\r
268 //\r
269 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
270 }\r
271\r
272 //\r
273 // Finally, Update the variable of the default console by NewDevicePath\r
274 //\r
275 gRT->SetVariable (\r
276 ConVarName,\r
277 &gEfiGlobalVariableGuid,\r
278 Attributes,\r
279 GetDevicePathSize (NewDevicePath),\r
280 NewDevicePath\r
281 );\r
282\r
283 if (VarConsole == NewDevicePath) {\r
284 if (VarConsole != NULL) {\r
285 FreePool(VarConsole);\r
286 }\r
287 } else {\r
288 if (VarConsole != NULL) {\r
289 FreePool(VarConsole);\r
290 }\r
291 if (NewDevicePath != NULL) {\r
292 FreePool(NewDevicePath);\r
293 }\r
294 }\r
295\r
296 return EFI_SUCCESS;\r
297\r
298}\r
299\r
300\r
301/**\r
302 Connect the console device base on the variable ConVarName, if\r
303 device path of the ConVarName is multi-instance device path, if\r
304 anyone of the instances is connected success, then this function\r
305 will return success.\r
306\r
307 @param ConVarName Console related variable name, ConIn, ConOut,\r
308 ErrOut.\r
309\r
310 @retval EFI_NOT_FOUND There is not any console devices connected\r
311 success\r
312 @retval EFI_SUCCESS Success connect any one instance of the console\r
313 device path base on the variable ConVarName.\r
314\r
315**/\r
316EFI_STATUS\r
317EFIAPI\r
318BdsLibConnectConsoleVariable (\r
319 IN CHAR16 *ConVarName\r
320 )\r
321{\r
322 EFI_STATUS Status;\r
323 EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;\r
324 UINTN VariableSize;\r
325 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
326 EFI_DEVICE_PATH_PROTOCOL *Next;\r
327 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;\r
328 UINTN Size;\r
329 BOOLEAN DeviceExist;\r
330\r
331 Status = EFI_SUCCESS;\r
332 DeviceExist = FALSE;\r
333\r
334 //\r
335 // Check if the console variable exist\r
336 //\r
337 StartDevicePath = BdsLibGetVariableAndSize (\r
338 ConVarName,\r
339 &gEfiGlobalVariableGuid,\r
340 &VariableSize\r
341 );\r
342 if (StartDevicePath == NULL) {\r
343 return EFI_UNSUPPORTED;\r
344 }\r
345\r
346 CopyOfDevicePath = StartDevicePath;\r
347 do {\r
348 //\r
349 // Check every instance of the console variable\r
350 //\r
351 Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);\r
352 if (Instance == NULL) {\r
353 FreePool (StartDevicePath);\r
354 return EFI_UNSUPPORTED;\r
355 }\r
356 \r
357 Next = Instance;\r
358 while (!IsDevicePathEndType (Next)) {\r
359 Next = NextDevicePathNode (Next);\r
360 }\r
361\r
362 SetDevicePathEndNode (Next);\r
363 //\r
9572320f
RN
364 // Connect the USB console\r
365 // USB console device path is a short-form device path that \r
366 // starts with the first element being a USB WWID\r
367 // or a USB Class device path\r
5c08e117 368 //\r
a29a93b4 369 if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
370 ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)\r
371 || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)\r
372 )) {\r
9572320f 373 Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance);\r
a29a93b4 374 if (!EFI_ERROR (Status)) {\r
375 DeviceExist = TRUE;\r
376 }\r
5c08e117 377 } else {\r
a29a93b4 378 //\r
379 // Connect the instance device path\r
380 //\r
381 Status = BdsLibConnectDevicePath (Instance);\r
382 if (EFI_ERROR (Status)) {\r
383 //\r
384 // Delete the instance from the console varialbe\r
385 //\r
386 BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);\r
387 } else {\r
388 DeviceExist = TRUE;\r
389 }\r
5c08e117 390 }\r
391 FreePool(Instance);\r
392 } while (CopyOfDevicePath != NULL);\r
393\r
394 FreePool (StartDevicePath);\r
395\r
396 if (!DeviceExist) {\r
397 return EFI_NOT_FOUND;\r
398 }\r
399\r
400 return EFI_SUCCESS;\r
401}\r
402\r
403\r
404/**\r
405 This function will search every simpletext device in current system,\r
406 and make every simpletext device as pertantial console device.\r
407\r
408**/\r
409VOID\r
410EFIAPI\r
411BdsLibConnectAllConsoles (\r
412 VOID\r
413 )\r
414{\r
415 UINTN Index;\r
416 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;\r
417 UINTN HandleCount;\r
418 EFI_HANDLE *HandleBuffer;\r
419\r
420 Index = 0;\r
421 HandleCount = 0;\r
422 HandleBuffer = NULL;\r
423 ConDevicePath = NULL;\r
424\r
425 //\r
426 // Update all the console variables\r
427 //\r
428 gBS->LocateHandleBuffer (\r
429 ByProtocol,\r
430 &gEfiSimpleTextInProtocolGuid,\r
431 NULL,\r
432 &HandleCount,\r
433 &HandleBuffer\r
434 );\r
435\r
436 for (Index = 0; Index < HandleCount; Index++) {\r
437 gBS->HandleProtocol (\r
438 HandleBuffer[Index],\r
439 &gEfiDevicePathProtocolGuid,\r
440 (VOID **) &ConDevicePath\r
441 );\r
442 BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);\r
443 }\r
444\r
445 if (HandleBuffer != NULL) {\r
446 FreePool(HandleBuffer);\r
447 HandleBuffer = NULL;\r
448 }\r
449\r
450 gBS->LocateHandleBuffer (\r
451 ByProtocol,\r
452 &gEfiSimpleTextOutProtocolGuid,\r
453 NULL,\r
454 &HandleCount,\r
455 &HandleBuffer\r
456 );\r
457 for (Index = 0; Index < HandleCount; Index++) {\r
458 gBS->HandleProtocol (\r
459 HandleBuffer[Index],\r
460 &gEfiDevicePathProtocolGuid,\r
461 (VOID **) &ConDevicePath\r
462 );\r
463 BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);\r
464 BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);\r
465 }\r
466\r
467 if (HandleBuffer != NULL) {\r
468 FreePool(HandleBuffer);\r
469 }\r
470\r
471 //\r
472 // Connect all console variables\r
473 //\r
474 BdsLibConnectAllDefaultConsoles ();\r
475\r
476}\r
477\r
478/**\r
479 This function will connect console device base on the console\r
480 device variable ConIn, ConOut and ErrOut.\r
481\r
482 @retval EFI_SUCCESS At least one of the ConIn and ConOut device have\r
483 been connected success.\r
484 @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable ().\r
485\r
486**/\r
487EFI_STATUS\r
488EFIAPI\r
489BdsLibConnectAllDefaultConsoles (\r
490 VOID\r
491 )\r
492{\r
493 EFI_STATUS Status;\r
406ddad3 494 BOOLEAN SystemTableUpdated;\r
5c08e117 495\r
496 //\r
497 // Connect all default console variables\r
498 //\r
499\r
500 //\r
501 // It seems impossible not to have any ConOut device on platform,\r
502 // so we check the status here.\r
503 //\r
504 Status = BdsLibConnectConsoleVariable (L"ConOut");\r
505 if (EFI_ERROR (Status)) {\r
506 return Status;\r
507 }\r
508\r
509 //\r
510 // Insert the performance probe for Console Out\r
511 //\r
512 PERF_START (NULL, "ConOut", "BDS", 1);\r
513 PERF_END (NULL, "ConOut", "BDS", 0);\r
514\r
515 //\r
516 // Because possibly the platform is legacy free, in such case,\r
517 // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,\r
518 // so we need not check the status.\r
519 //\r
520 BdsLibConnectConsoleVariable (L"ConIn");\r
521\r
522 //\r
523 // The _ModuleEntryPoint err out var is legal.\r
524 //\r
525 BdsLibConnectConsoleVariable (L"ErrOut");\r
526\r
406ddad3 527 SystemTableUpdated = FALSE;\r
dad60833 528 //\r
529 // Fill console handles in System Table if no console device assignd.\r
530 //\r
406ddad3 531 if (UpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) {\r
532 SystemTableUpdated = TRUE;\r
533 }\r
534 if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) {\r
535 SystemTableUpdated = TRUE;\r
536 }\r
537 if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) {\r
538 SystemTableUpdated = TRUE;\r
539 }\r
540\r
541 if (SystemTableUpdated) {\r
542 //\r
543 // Update the CRC32 in the EFI System Table header\r
544 //\r
545 gST->Hdr.CRC32 = 0;\r
546 gBS->CalculateCrc32 (\r
547 (UINT8 *) &gST->Hdr,\r
548 gST->Hdr.HeaderSize,\r
549 &gST->Hdr.CRC32\r
550 );\r
551 }\r
dad60833 552\r
5c08e117 553 return EFI_SUCCESS;\r
554\r
555}\r
556\r
557/**\r
558 Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer\r
559 is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
560 buffer is passed in it will be used if it is big enough.\r
561\r
562 @param BmpImage Pointer to BMP file\r
563 @param BmpImageSize Number of bytes in BmpImage\r
564 @param GopBlt Buffer containing GOP version of BmpImage.\r
565 @param GopBltSize Size of GopBlt in bytes.\r
566 @param PixelHeight Height of GopBlt/BmpImage in pixels\r
567 @param PixelWidth Width of GopBlt/BmpImage in pixels\r
568\r
569 @retval EFI_SUCCESS GopBlt and GopBltSize are returned.\r
570 @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image\r
571 @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough.\r
572 GopBltSize will contain the required size.\r
573 @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate.\r
574\r
575**/\r
576EFI_STATUS\r
577ConvertBmpToGopBlt (\r
578 IN VOID *BmpImage,\r
579 IN UINTN BmpImageSize,\r
580 IN OUT VOID **GopBlt,\r
581 IN OUT UINTN *GopBltSize,\r
582 OUT UINTN *PixelHeight,\r
583 OUT UINTN *PixelWidth\r
584 )\r
585{\r
586 UINT8 *Image;\r
587 UINT8 *ImageHeader;\r
588 BMP_IMAGE_HEADER *BmpHeader;\r
589 BMP_COLOR_MAP *BmpColorMap;\r
590 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
591 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
88f2bdb5 592 UINT64 BltBufferSize;\r
5c08e117 593 UINTN Index;\r
594 UINTN Height;\r
595 UINTN Width;\r
596 UINTN ImageIndex;\r
597 BOOLEAN IsAllocated;\r
598\r
599 BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
600\r
601 if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
602 return EFI_UNSUPPORTED;\r
603 }\r
604\r
605 //\r
606 // Doesn't support compress.\r
607 //\r
608 if (BmpHeader->CompressionType != 0) {\r
609 return EFI_UNSUPPORTED;\r
610 }\r
611\r
612 //\r
613 // Calculate Color Map offset in the image.\r
614 //\r
615 Image = BmpImage;\r
616 BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
617\r
618 //\r
619 // Calculate graphics image data address in the image\r
620 //\r
621 Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
622 ImageHeader = Image;\r
623\r
624 //\r
625 // Calculate the BltBuffer needed size.\r
626 //\r
d2eec319 627 BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);\r
628 //\r
629 // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow\r
630 //\r
631 if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {\r
632 return EFI_UNSUPPORTED;\r
633 }\r
634 BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
635\r
5c08e117 636 IsAllocated = FALSE;\r
637 if (*GopBlt == NULL) {\r
638 //\r
639 // GopBlt is not allocated by caller.\r
640 //\r
88f2bdb5 641 *GopBltSize = (UINTN) BltBufferSize;\r
5c08e117 642 *GopBlt = AllocatePool (*GopBltSize);\r
643 IsAllocated = TRUE;\r
644 if (*GopBlt == NULL) {\r
645 return EFI_OUT_OF_RESOURCES;\r
646 }\r
647 } else {\r
648 //\r
649 // GopBlt has been allocated by caller.\r
650 //\r
2bf3421a 651 if (*GopBltSize < (UINTN) BltBufferSize) {\r
88f2bdb5 652 *GopBltSize = (UINTN) BltBufferSize;\r
5c08e117 653 return EFI_BUFFER_TOO_SMALL;\r
654 }\r
655 }\r
656\r
657 *PixelWidth = BmpHeader->PixelWidth;\r
658 *PixelHeight = BmpHeader->PixelHeight;\r
659\r
660 //\r
661 // Convert image from BMP to Blt buffer format\r
662 //\r
663 BltBuffer = *GopBlt;\r
664 for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
665 Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
666 for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
667 switch (BmpHeader->BitPerPixel) {\r
668 case 1:\r
669 //\r
670 // Convert 1-bit (2 colors) BMP to 24-bit color\r
671 //\r
672 for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
673 Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
674 Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
675 Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
676 Blt++;\r
677 Width++;\r
678 }\r
679\r
680 Blt--;\r
681 Width--;\r
682 break;\r
683\r
684 case 4:\r
685 //\r
686 // Convert 4-bit (16 colors) BMP Palette to 24-bit color\r
687 //\r
688 Index = (*Image) >> 4;\r
689 Blt->Red = BmpColorMap[Index].Red;\r
690 Blt->Green = BmpColorMap[Index].Green;\r
691 Blt->Blue = BmpColorMap[Index].Blue;\r
692 if (Width < (BmpHeader->PixelWidth - 1)) {\r
693 Blt++;\r
694 Width++;\r
695 Index = (*Image) & 0x0f;\r
696 Blt->Red = BmpColorMap[Index].Red;\r
697 Blt->Green = BmpColorMap[Index].Green;\r
698 Blt->Blue = BmpColorMap[Index].Blue;\r
699 }\r
700 break;\r
701\r
702 case 8:\r
703 //\r
704 // Convert 8-bit (256 colors) BMP Palette to 24-bit color\r
705 //\r
706 Blt->Red = BmpColorMap[*Image].Red;\r
707 Blt->Green = BmpColorMap[*Image].Green;\r
708 Blt->Blue = BmpColorMap[*Image].Blue;\r
709 break;\r
710\r
711 case 24:\r
712 //\r
713 // It is 24-bit BMP.\r
714 //\r
715 Blt->Blue = *Image++;\r
716 Blt->Green = *Image++;\r
717 Blt->Red = *Image;\r
718 break;\r
719\r
720 default:\r
721 //\r
722 // Other bit format BMP is not supported.\r
723 //\r
724 if (IsAllocated) {\r
725 FreePool (*GopBlt);\r
726 *GopBlt = NULL;\r
727 }\r
728 return EFI_UNSUPPORTED;\r
729 break;\r
730 };\r
731\r
732 }\r
733\r
734 ImageIndex = (UINTN) (Image - ImageHeader);\r
735 if ((ImageIndex % 4) != 0) {\r
736 //\r
737 // Bmp Image starts each row on a 32-bit boundary!\r
738 //\r
739 Image = Image + (4 - (ImageIndex % 4));\r
740 }\r
741 }\r
742\r
743 return EFI_SUCCESS;\r
744}\r
745\r
5c08e117 746/**\r
24cdd14e
LG
747 Use SystemTable Conout to stop video based Simple Text Out consoles from going\r
748 to the video device. Put up LogoFile on every video device that is a console.\r
5c08e117 749\r
750 @param[in] LogoFile File name of logo to display on the center of the screen.\r
751\r
752 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.\r
753 @retval EFI_UNSUPPORTED Logo not found\r
754\r
755**/\r
756EFI_STATUS\r
757EFIAPI\r
758EnableQuietBoot (\r
759 IN EFI_GUID *LogoFile\r
760 )\r
761{\r
762 EFI_STATUS Status;\r
5c08e117 763 EFI_OEM_BADGING_PROTOCOL *Badging;\r
764 UINT32 SizeOfX;\r
765 UINT32 SizeOfY;\r
766 INTN DestX;\r
767 INTN DestY;\r
768 UINT8 *ImageData;\r
769 UINTN ImageSize;\r
770 UINTN BltSize;\r
771 UINT32 Instance;\r
772 EFI_BADGING_FORMAT Format;\r
773 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
774 UINTN CoordinateX;\r
775 UINTN CoordinateY;\r
776 UINTN Height;\r
777 UINTN Width;\r
778 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
779 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
780 UINT32 ColorDepth;\r
781 UINT32 RefreshRate;\r
782 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
783\r
5c08e117 784 UgaDraw = NULL;\r
785 //\r
786 // Try to open GOP first\r
787 //\r
788 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
789 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
790 GraphicsOutput = NULL;\r
791 //\r
792 // Open GOP failed, try to open UGA\r
793 //\r
794 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
795 }\r
796 if (EFI_ERROR (Status)) {\r
797 return EFI_UNSUPPORTED;\r
798 }\r
799\r
5c08e117 800 //\r
5d7c1609 801 // Erase Cursor from screen\r
5c08e117 802 //\r
5d7c1609 803 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
804\r
805 Badging = NULL;\r
806 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
5c08e117 807\r
808 if (GraphicsOutput != NULL) {\r
809 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
810 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
811\r
812 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
813 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
814 if (EFI_ERROR (Status)) {\r
815 return EFI_UNSUPPORTED;\r
816 }\r
817 } else {\r
818 return EFI_UNSUPPORTED;\r
819 }\r
820\r
821 Instance = 0;\r
822 while (1) {\r
823 ImageData = NULL;\r
824 ImageSize = 0;\r
825\r
826 if (Badging != NULL) {\r
827 //\r
828 // Get image from OEMBadging protocol.\r
829 //\r
830 Status = Badging->GetImage (\r
831 Badging,\r
832 &Instance,\r
833 &Format,\r
834 &ImageData,\r
835 &ImageSize,\r
836 &Attribute,\r
837 &CoordinateX,\r
838 &CoordinateY\r
839 );\r
840 if (EFI_ERROR (Status)) {\r
841 return Status;\r
842 }\r
843\r
844 //\r
845 // Currently only support BMP format.\r
846 //\r
847 if (Format != EfiBadgingFormatBMP) {\r
848 if (ImageData != NULL) {\r
849 FreePool (ImageData);\r
850 }\r
851 continue;\r
852 }\r
853 } else {\r
854 //\r
855 // Get the specified image from FV.\r
856 //\r
857 Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);\r
858 if (EFI_ERROR (Status)) {\r
859 return EFI_UNSUPPORTED;\r
860 }\r
861\r
862 CoordinateX = 0;\r
863 CoordinateY = 0;\r
864 Attribute = EfiBadgingDisplayAttributeCenter;\r
865 }\r
866\r
867 Blt = NULL;\r
868 Status = ConvertBmpToGopBlt (\r
869 ImageData,\r
870 ImageSize,\r
871 (VOID **) &Blt,\r
872 &BltSize,\r
873 &Height,\r
874 &Width\r
875 );\r
876 if (EFI_ERROR (Status)) {\r
877 FreePool (ImageData);\r
878\r
879 if (Badging == NULL) {\r
880 return Status;\r
881 } else {\r
882 continue;\r
883 }\r
884 }\r
885\r
886 //\r
887 // Calculate the display position according to Attribute.\r
888 //\r
889 switch (Attribute) {\r
890 case EfiBadgingDisplayAttributeLeftTop:\r
891 DestX = CoordinateX;\r
892 DestY = CoordinateY;\r
893 break;\r
894\r
895 case EfiBadgingDisplayAttributeCenterTop:\r
896 DestX = (SizeOfX - Width) / 2;\r
897 DestY = CoordinateY;\r
898 break;\r
899\r
900 case EfiBadgingDisplayAttributeRightTop:\r
901 DestX = (SizeOfX - Width - CoordinateX);\r
902 DestY = CoordinateY;;\r
903 break;\r
904\r
905 case EfiBadgingDisplayAttributeCenterRight:\r
906 DestX = (SizeOfX - Width - CoordinateX);\r
907 DestY = (SizeOfY - Height) / 2;\r
908 break;\r
909\r
910 case EfiBadgingDisplayAttributeRightBottom:\r
911 DestX = (SizeOfX - Width - CoordinateX);\r
912 DestY = (SizeOfY - Height - CoordinateY);\r
913 break;\r
914\r
915 case EfiBadgingDisplayAttributeCenterBottom:\r
916 DestX = (SizeOfX - Width) / 2;\r
917 DestY = (SizeOfY - Height - CoordinateY);\r
918 break;\r
919\r
920 case EfiBadgingDisplayAttributeLeftBottom:\r
921 DestX = CoordinateX;\r
922 DestY = (SizeOfY - Height - CoordinateY);\r
923 break;\r
924\r
925 case EfiBadgingDisplayAttributeCenterLeft:\r
926 DestX = CoordinateX;\r
927 DestY = (SizeOfY - Height) / 2;\r
928 break;\r
929\r
930 case EfiBadgingDisplayAttributeCenter:\r
931 DestX = (SizeOfX - Width) / 2;\r
932 DestY = (SizeOfY - Height) / 2;\r
933 break;\r
934\r
935 default:\r
936 DestX = CoordinateX;\r
937 DestY = CoordinateY;\r
938 break;\r
939 }\r
940\r
941 if ((DestX >= 0) && (DestY >= 0)) {\r
942 if (GraphicsOutput != NULL) {\r
943 Status = GraphicsOutput->Blt (\r
944 GraphicsOutput,\r
945 Blt,\r
946 EfiBltBufferToVideo,\r
947 0,\r
948 0,\r
949 (UINTN) DestX,\r
950 (UINTN) DestY,\r
951 Width,\r
952 Height,\r
953 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
954 );\r
955 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
956 Status = UgaDraw->Blt (\r
957 UgaDraw,\r
958 (EFI_UGA_PIXEL *) Blt,\r
959 EfiUgaBltBufferToVideo,\r
960 0,\r
961 0,\r
962 (UINTN) DestX,\r
963 (UINTN) DestY,\r
964 Width,\r
965 Height,\r
966 Width * sizeof (EFI_UGA_PIXEL)\r
967 );\r
968 } else {\r
969 Status = EFI_UNSUPPORTED;\r
970 }\r
971 }\r
972\r
973 FreePool (ImageData);\r
974\r
975 if (Blt != NULL) {\r
976 FreePool (Blt);\r
977 }\r
978\r
979 if (Badging == NULL) {\r
980 break;\r
981 }\r
982 }\r
983\r
984 return Status;\r
985}\r
986\r
987/**\r
24cdd14e
LG
988 Use SystemTable Conout to turn on video based Simple Text Out consoles. The \r
989 Simple Text Out screens will now be synced up with all non video output devices\r
5c08e117 990\r
991 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.\r
992\r
993**/\r
994EFI_STATUS\r
995EFIAPI\r
996DisableQuietBoot (\r
997 VOID\r
998 )\r
999{\r
5c08e117 1000\r
1001 //\r
5d7c1609 1002 // Enable Cursor on Screen\r
5c08e117 1003 //\r
5d7c1609 1004 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
1005 return EFI_SUCCESS;\r
5c08e117 1006}\r
1007\r