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