]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
Correct minor error.
[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
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
5c08e117 731 return EFI_UNSUPPORTED;\r
5c08e117 732}\r
733\r
734\r
735/**\r
736 Use Console Control to turn off UGA based Simple Text Out consoles from going\r
737 to the UGA device. Put up LogoFile on every UGA device that is a console\r
738\r
739 @param[in] LogoFile File name of logo to display on the center of the screen.\r
740\r
741 @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed.\r
742 @retval EFI_UNSUPPORTED Logo not found\r
743\r
744**/\r
745EFI_STATUS\r
746EFIAPI\r
747EnableQuietBoot (\r
748 IN EFI_GUID *LogoFile\r
749 )\r
750{\r
751 EFI_STATUS Status;\r
5c08e117 752 EFI_OEM_BADGING_PROTOCOL *Badging;\r
753 UINT32 SizeOfX;\r
754 UINT32 SizeOfY;\r
755 INTN DestX;\r
756 INTN DestY;\r
757 UINT8 *ImageData;\r
758 UINTN ImageSize;\r
759 UINTN BltSize;\r
760 UINT32 Instance;\r
761 EFI_BADGING_FORMAT Format;\r
762 EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
763 UINTN CoordinateX;\r
764 UINTN CoordinateY;\r
765 UINTN Height;\r
766 UINTN Width;\r
767 EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
768 EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
769 UINT32 ColorDepth;\r
770 UINT32 RefreshRate;\r
771 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
772\r
5c08e117 773 UgaDraw = NULL;\r
774 //\r
775 // Try to open GOP first\r
776 //\r
777 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);\r
778 if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
779 GraphicsOutput = NULL;\r
780 //\r
781 // Open GOP failed, try to open UGA\r
782 //\r
783 Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);\r
784 }\r
785 if (EFI_ERROR (Status)) {\r
786 return EFI_UNSUPPORTED;\r
787 }\r
788\r
5c08e117 789 //\r
5d7c1609 790 // Erase Cursor from screen\r
5c08e117 791 //\r
5d7c1609 792 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
793\r
794 Badging = NULL;\r
795 Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);\r
5c08e117 796\r
797 if (GraphicsOutput != NULL) {\r
798 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
799 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
800\r
801 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
802 Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
803 if (EFI_ERROR (Status)) {\r
804 return EFI_UNSUPPORTED;\r
805 }\r
806 } else {\r
807 return EFI_UNSUPPORTED;\r
808 }\r
809\r
810 Instance = 0;\r
811 while (1) {\r
812 ImageData = NULL;\r
813 ImageSize = 0;\r
814\r
815 if (Badging != NULL) {\r
816 //\r
817 // Get image from OEMBadging protocol.\r
818 //\r
819 Status = Badging->GetImage (\r
820 Badging,\r
821 &Instance,\r
822 &Format,\r
823 &ImageData,\r
824 &ImageSize,\r
825 &Attribute,\r
826 &CoordinateX,\r
827 &CoordinateY\r
828 );\r
829 if (EFI_ERROR (Status)) {\r
830 return Status;\r
831 }\r
832\r
833 //\r
834 // Currently only support BMP format.\r
835 //\r
836 if (Format != EfiBadgingFormatBMP) {\r
837 if (ImageData != NULL) {\r
838 FreePool (ImageData);\r
839 }\r
840 continue;\r
841 }\r
842 } else {\r
843 //\r
844 // Get the specified image from FV.\r
845 //\r
846 Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);\r
847 if (EFI_ERROR (Status)) {\r
848 return EFI_UNSUPPORTED;\r
849 }\r
850\r
851 CoordinateX = 0;\r
852 CoordinateY = 0;\r
853 Attribute = EfiBadgingDisplayAttributeCenter;\r
854 }\r
855\r
856 Blt = NULL;\r
857 Status = ConvertBmpToGopBlt (\r
858 ImageData,\r
859 ImageSize,\r
860 (VOID **) &Blt,\r
861 &BltSize,\r
862 &Height,\r
863 &Width\r
864 );\r
865 if (EFI_ERROR (Status)) {\r
866 FreePool (ImageData);\r
867\r
868 if (Badging == NULL) {\r
869 return Status;\r
870 } else {\r
871 continue;\r
872 }\r
873 }\r
874\r
875 //\r
876 // Calculate the display position according to Attribute.\r
877 //\r
878 switch (Attribute) {\r
879 case EfiBadgingDisplayAttributeLeftTop:\r
880 DestX = CoordinateX;\r
881 DestY = CoordinateY;\r
882 break;\r
883\r
884 case EfiBadgingDisplayAttributeCenterTop:\r
885 DestX = (SizeOfX - Width) / 2;\r
886 DestY = CoordinateY;\r
887 break;\r
888\r
889 case EfiBadgingDisplayAttributeRightTop:\r
890 DestX = (SizeOfX - Width - CoordinateX);\r
891 DestY = CoordinateY;;\r
892 break;\r
893\r
894 case EfiBadgingDisplayAttributeCenterRight:\r
895 DestX = (SizeOfX - Width - CoordinateX);\r
896 DestY = (SizeOfY - Height) / 2;\r
897 break;\r
898\r
899 case EfiBadgingDisplayAttributeRightBottom:\r
900 DestX = (SizeOfX - Width - CoordinateX);\r
901 DestY = (SizeOfY - Height - CoordinateY);\r
902 break;\r
903\r
904 case EfiBadgingDisplayAttributeCenterBottom:\r
905 DestX = (SizeOfX - Width) / 2;\r
906 DestY = (SizeOfY - Height - CoordinateY);\r
907 break;\r
908\r
909 case EfiBadgingDisplayAttributeLeftBottom:\r
910 DestX = CoordinateX;\r
911 DestY = (SizeOfY - Height - CoordinateY);\r
912 break;\r
913\r
914 case EfiBadgingDisplayAttributeCenterLeft:\r
915 DestX = CoordinateX;\r
916 DestY = (SizeOfY - Height) / 2;\r
917 break;\r
918\r
919 case EfiBadgingDisplayAttributeCenter:\r
920 DestX = (SizeOfX - Width) / 2;\r
921 DestY = (SizeOfY - Height) / 2;\r
922 break;\r
923\r
924 default:\r
925 DestX = CoordinateX;\r
926 DestY = CoordinateY;\r
927 break;\r
928 }\r
929\r
930 if ((DestX >= 0) && (DestY >= 0)) {\r
931 if (GraphicsOutput != NULL) {\r
932 Status = GraphicsOutput->Blt (\r
933 GraphicsOutput,\r
934 Blt,\r
935 EfiBltBufferToVideo,\r
936 0,\r
937 0,\r
938 (UINTN) DestX,\r
939 (UINTN) DestY,\r
940 Width,\r
941 Height,\r
942 Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
943 );\r
944 } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
945 Status = UgaDraw->Blt (\r
946 UgaDraw,\r
947 (EFI_UGA_PIXEL *) Blt,\r
948 EfiUgaBltBufferToVideo,\r
949 0,\r
950 0,\r
951 (UINTN) DestX,\r
952 (UINTN) DestY,\r
953 Width,\r
954 Height,\r
955 Width * sizeof (EFI_UGA_PIXEL)\r
956 );\r
957 } else {\r
958 Status = EFI_UNSUPPORTED;\r
959 }\r
960 }\r
961\r
962 FreePool (ImageData);\r
963\r
964 if (Blt != NULL) {\r
965 FreePool (Blt);\r
966 }\r
967\r
968 if (Badging == NULL) {\r
969 break;\r
970 }\r
971 }\r
972\r
973 return Status;\r
974}\r
975\r
976/**\r
977 Use Console Control to turn on UGA based Simple Text Out consoles. The UGA\r
978 Simple Text Out screens will now be synced up with all non UGA output devices\r
979\r
980 @retval EFI_SUCCESS UGA devices are back in text mode and synced up.\r
981\r
982**/\r
983EFI_STATUS\r
984EFIAPI\r
985DisableQuietBoot (\r
986 VOID\r
987 )\r
988{\r
5c08e117 989\r
990 //\r
5d7c1609 991 // Enable Cursor on Screen\r
5c08e117 992 //\r
5d7c1609 993 gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
994 return EFI_SUCCESS;\r
5c08e117 995}\r
996\r