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