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