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