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