]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmConsole.c
CommitLineData
067ed98a
RN
1/** @file\r
2 Library functions which contain all the code to connect console device.\r
3\r
d1102dba 4Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
fad21b7c 5(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
067ed98a
RN
7\r
8**/\r
9\r
10#include "InternalBm.h"\r
11\r
1436aea4 12CHAR16 *mConVarName[] = {\r
067ed98a
RN
13 L"ConIn",\r
14 L"ConOut",\r
15 L"ErrOut",\r
16 L"ConInDev",\r
17 L"ConOutDev",\r
18 L"ErrOutDev"\r
19};\r
20\r
21/**\r
22 Search out the video controller.\r
23\r
24 @return PCI device path of the video controller.\r
25**/\r
26EFI_HANDLE\r
27BmGetVideoController (\r
28 VOID\r
29 )\r
30{\r
1436aea4
MK
31 EFI_STATUS Status;\r
32 UINTN RootBridgeHandleCount;\r
33 EFI_HANDLE *RootBridgeHandleBuffer;\r
34 UINTN HandleCount;\r
35 EFI_HANDLE *HandleBuffer;\r
36 UINTN RootBridgeIndex;\r
37 UINTN Index;\r
38 EFI_HANDLE VideoController;\r
39 EFI_PCI_IO_PROTOCOL *PciIo;\r
40 PCI_TYPE00 Pci;\r
067ed98a
RN
41\r
42 //\r
43 // Make all the PCI_IO protocols show up\r
44 //\r
45 Status = gBS->LocateHandleBuffer (\r
46 ByProtocol,\r
47 &gEfiPciRootBridgeIoProtocolGuid,\r
48 NULL,\r
49 &RootBridgeHandleCount,\r
50 &RootBridgeHandleBuffer\r
51 );\r
52 if (EFI_ERROR (Status) || (RootBridgeHandleCount == 0)) {\r
53 return NULL;\r
54 }\r
55\r
56 VideoController = NULL;\r
57 for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {\r
58 gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, FALSE);\r
59\r
60 //\r
61 // Start to check all the pci io to find the first video controller\r
62 //\r
63 Status = gBS->LocateHandleBuffer (\r
64 ByProtocol,\r
65 &gEfiPciIoProtocolGuid,\r
66 NULL,\r
67 &HandleCount,\r
68 &HandleBuffer\r
69 );\r
70 if (EFI_ERROR (Status)) {\r
71 continue;\r
72 }\r
73\r
74 for (Index = 0; Index < HandleCount; Index++) {\r
1436aea4 75 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID **)&PciIo);\r
067ed98a
RN
76 if (!EFI_ERROR (Status)) {\r
77 //\r
78 // Check for all video controller\r
79 //\r
80 Status = PciIo->Pci.Read (\r
1436aea4
MK
81 PciIo,\r
82 EfiPciIoWidthUint32,\r
83 0,\r
84 sizeof (Pci) / sizeof (UINT32),\r
85 &Pci\r
86 );\r
067ed98a
RN
87 if (!EFI_ERROR (Status) && IS_PCI_VGA (&Pci)) {\r
88 // TODO: use IS_PCI_DISPLAY??\r
89 VideoController = HandleBuffer[Index];\r
90 break;\r
91 }\r
92 }\r
93 }\r
1436aea4 94\r
067ed98a
RN
95 FreePool (HandleBuffer);\r
96\r
97 if (VideoController != NULL) {\r
98 break;\r
99 }\r
100 }\r
1436aea4 101\r
067ed98a 102 FreePool (RootBridgeHandleBuffer);\r
d1102dba 103\r
067ed98a
RN
104 return VideoController;\r
105}\r
106\r
107/**\r
d1102dba 108 Query all the children of VideoController and return the device paths of all the\r
067ed98a
RN
109 children that support GraphicsOutput protocol.\r
110\r
111 @param VideoController PCI handle of video controller.\r
112\r
113 @return Device paths of all the children that support GraphicsOutput protocol.\r
114**/\r
115EFI_DEVICE_PATH_PROTOCOL *\r
116EFIAPI\r
117EfiBootManagerGetGopDevicePath (\r
1436aea4 118 IN EFI_HANDLE VideoController\r
067ed98a
RN
119 )\r
120{\r
121 UINTN Index;\r
122 EFI_STATUS Status;\r
123 EFI_GUID **ProtocolBuffer;\r
124 UINTN ProtocolBufferCount;\r
125 UINTN ProtocolIndex;\r
126 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
127 UINTN EntryCount;\r
128 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
129 EFI_DEVICE_PATH_PROTOCOL *Next;\r
130 EFI_DEVICE_PATH_PROTOCOL *Previous;\r
131 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
132 EFI_DEVICE_PATH_PROTOCOL *GopPool;\r
133 EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath;\r
134\r
067ed98a
RN
135 Status = gBS->ProtocolsPerHandle (\r
136 VideoController,\r
137 &ProtocolBuffer,\r
138 &ProtocolBufferCount\r
139 );\r
140 if (EFI_ERROR (Status)) {\r
141 return NULL;\r
142 }\r
143\r
144 GopPool = NULL;\r
145\r
146 for (ProtocolIndex = 0; ProtocolIndex < ProtocolBufferCount; ProtocolIndex++) {\r
147 Status = gBS->OpenProtocolInformation (\r
148 VideoController,\r
149 ProtocolBuffer[ProtocolIndex],\r
150 &OpenInfoBuffer,\r
151 &EntryCount\r
152 );\r
153 if (EFI_ERROR (Status)) {\r
154 continue;\r
155 }\r
156\r
157 for (Index = 0; Index < EntryCount; Index++) {\r
158 //\r
159 // Query all the children\r
160 //\r
161 if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
162 Status = gBS->OpenProtocol (\r
163 OpenInfoBuffer[Index].ControllerHandle,\r
164 &gEfiDevicePathProtocolGuid,\r
1436aea4 165 (VOID **)&DevicePath,\r
067ed98a
RN
166 NULL,\r
167 NULL,\r
168 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
169 );\r
170 if (EFI_ERROR (Status)) {\r
171 continue;\r
172 }\r
173\r
174 Previous = NULL;\r
175 for (Next = DevicePath; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {\r
176 Previous = Next;\r
177 }\r
1436aea4 178\r
067ed98a
RN
179 ASSERT (Previous != NULL);\r
180\r
1436aea4 181 if ((DevicePathType (Previous) == ACPI_DEVICE_PATH) && (DevicePathSubType (Previous) == ACPI_ADR_DP)) {\r
067ed98a
RN
182 Status = gBS->OpenProtocol (\r
183 OpenInfoBuffer[Index].ControllerHandle,\r
184 &gEfiGraphicsOutputProtocolGuid,\r
185 NULL,\r
186 NULL,\r
187 NULL,\r
188 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
189 );\r
190 if (!EFI_ERROR (Status)) {\r
191 //\r
192 // Append the device path to GOP pool when there is GOP protocol installed.\r
193 //\r
194 TempDevicePath = GopPool;\r
1436aea4 195 GopPool = AppendDevicePathInstance (GopPool, DevicePath);\r
067ed98a
RN
196 gBS->FreePool (TempDevicePath);\r
197 }\r
198 }\r
199\r
1436aea4 200 if ((DevicePathType (Previous) == HARDWARE_DEVICE_PATH) && (DevicePathSubType (Previous) == HW_CONTROLLER_DP)) {\r
067ed98a
RN
201 //\r
202 // Recursively look for GOP child in this frame buffer handle\r
203 //\r
87000d77 204 DEBUG ((DEBUG_INFO, "[Bds] Looking for GOP child deeper ... \n"));\r
1436aea4 205 TempDevicePath = GopPool;\r
067ed98a 206 ReturnDevicePath = EfiBootManagerGetGopDevicePath (OpenInfoBuffer[Index].ControllerHandle);\r
1436aea4 207 GopPool = AppendDevicePathInstance (GopPool, ReturnDevicePath);\r
067ed98a
RN
208 gBS->FreePool (ReturnDevicePath);\r
209 gBS->FreePool (TempDevicePath);\r
210 }\r
211 }\r
212 }\r
213\r
214 FreePool (OpenInfoBuffer);\r
215 }\r
216\r
217 FreePool (ProtocolBuffer);\r
218\r
219 return GopPool;\r
220}\r
221\r
222/**\r
223 Connect the platform active active video controller.\r
224\r
225 @param VideoController PCI handle of video controller.\r
226\r
227 @retval EFI_NOT_FOUND There is no active video controller.\r
228 @retval EFI_SUCCESS The video controller is connected.\r
229**/\r
230EFI_STATUS\r
231EFIAPI\r
232EfiBootManagerConnectVideoController (\r
1436aea4 233 EFI_HANDLE VideoController OPTIONAL\r
067ed98a
RN
234 )\r
235{\r
1436aea4 236 EFI_DEVICE_PATH_PROTOCOL *Gop;\r
d1102dba 237\r
067ed98a
RN
238 if (VideoController == NULL) {\r
239 //\r
240 // Get the platform vga device\r
241 //\r
242 VideoController = BmGetVideoController ();\r
243 }\r
d1102dba 244\r
067ed98a
RN
245 if (VideoController == NULL) {\r
246 return EFI_NOT_FOUND;\r
247 }\r
248\r
249 //\r
3b28e744 250 // Try to connect the PCI device path, so that GOP driver could start on this\r
067ed98a 251 // device and create child handles with GraphicsOutput Protocol installed\r
d1102dba 252 // on them, then we get device paths of these child handles and select\r
067ed98a
RN
253 // them as possible console device.\r
254 //\r
255 gBS->ConnectController (VideoController, NULL, NULL, FALSE);\r
256\r
257 Gop = EfiBootManagerGetGopDevicePath (VideoController);\r
258 if (Gop == NULL) {\r
259 return EFI_NOT_FOUND;\r
260 }\r
261\r
262 EfiBootManagerUpdateConsoleVariable (ConOut, Gop, NULL);\r
263 FreePool (Gop);\r
264\r
265 //\r
266 // Necessary for ConPlatform and ConSplitter driver to start up again after ConOut is updated.\r
267 //\r
268 return gBS->ConnectController (VideoController, NULL, NULL, TRUE);\r
269}\r
270\r
271/**\r
272 Fill console handle in System Table if there are no valid console handle in.\r
273\r
274 Firstly, check the validation of console handle in System Table. If it is invalid,\r
d1102dba 275 update it by the first console device handle from EFI console variable.\r
067ed98a
RN
276\r
277 @param VarName The name of the EFI console variable.\r
278 @param ConsoleGuid Specified Console protocol GUID.\r
d1102dba 279 @param ConsoleHandle On IN, console handle in System Table to be checked.\r
067ed98a 280 On OUT, new console handle in system table.\r
d1102dba 281 @param ProtocolInterface On IN, console protocol on console handle in System Table to be checked.\r
067ed98a
RN
282 On OUT, new console protocol on new console handle in system table.\r
283\r
284 @retval TRUE System Table has been updated.\r
285 @retval FALSE System Table hasn't been updated.\r
286\r
287**/\r
d1102dba 288BOOLEAN\r
067ed98a 289BmUpdateSystemTableConsole (\r
1436aea4
MK
290 IN CHAR16 *VarName,\r
291 IN EFI_GUID *ConsoleGuid,\r
292 IN OUT EFI_HANDLE *ConsoleHandle,\r
293 IN OUT VOID **ProtocolInterface\r
067ed98a
RN
294 )\r
295{\r
1436aea4
MK
296 EFI_STATUS Status;\r
297 UINTN DevicePathSize;\r
298 EFI_DEVICE_PATH_PROTOCOL *FullDevicePath;\r
299 EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
300 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
301 EFI_DEVICE_PATH_PROTOCOL *FullInstance;\r
302 VOID *Interface;\r
303 EFI_HANDLE NewHandle;\r
304 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
067ed98a
RN
305\r
306 ASSERT (VarName != NULL);\r
307 ASSERT (ConsoleHandle != NULL);\r
308 ASSERT (ConsoleGuid != NULL);\r
309 ASSERT (ProtocolInterface != NULL);\r
310\r
311 if (*ConsoleHandle != NULL) {\r
312 Status = gBS->HandleProtocol (\r
1436aea4
MK
313 *ConsoleHandle,\r
314 ConsoleGuid,\r
315 &Interface\r
316 );\r
317 if ((Status == EFI_SUCCESS) && (Interface == *ProtocolInterface)) {\r
067ed98a
RN
318 //\r
319 // If ConsoleHandle is valid and console protocol on this handle also\r
320 // also matched, just return.\r
321 //\r
322 return FALSE;\r
323 }\r
324 }\r
d1102dba 325\r
067ed98a
RN
326 //\r
327 // Get all possible consoles device path from EFI variable\r
328 //\r
1436aea4 329 GetEfiGlobalVariable2 (VarName, (VOID **)&VarConsole, NULL);\r
067ed98a
RN
330 if (VarConsole == NULL) {\r
331 //\r
332 // If there is no any console device, just return.\r
333 //\r
334 return FALSE;\r
335 }\r
336\r
337 FullDevicePath = VarConsole;\r
338\r
339 do {\r
340 //\r
341 // Check every instance of the console variable\r
342 //\r
1436aea4 343 Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
067ed98a 344 if (Instance == NULL) {\r
87000d77 345 DEBUG ((DEBUG_ERROR, "[Bds] No valid console instance is found for %s!\n", VarName));\r
067ed98a
RN
346 // We should not ASSERT when all the console devices are removed.\r
347 // ASSERT_EFI_ERROR (EFI_NOT_FOUND);\r
348 FreePool (FullDevicePath);\r
349 return FALSE;\r
350 }\r
d1102dba 351\r
067ed98a
RN
352 //\r
353 // Find console device handle by device path instance\r
354 //\r
fad21b7c 355 FullInstance = Instance;\r
1436aea4
MK
356 Status = gBS->LocateDevicePath (\r
357 ConsoleGuid,\r
358 &Instance,\r
359 &NewHandle\r
360 );\r
fad21b7c 361 FreePool (FullInstance);\r
067ed98a
RN
362 if (!EFI_ERROR (Status)) {\r
363 //\r
364 // Get the console protocol on this console device handle\r
365 //\r
366 Status = gBS->HandleProtocol (\r
367 NewHandle,\r
368 ConsoleGuid,\r
369 &Interface\r
370 );\r
371 if (!EFI_ERROR (Status)) {\r
372 //\r
373 // Update new console handle in System Table.\r
374 //\r
375 *ConsoleHandle = NewHandle;\r
376 *ProtocolInterface = Interface;\r
377 if (CompareGuid (ConsoleGuid, &gEfiSimpleTextOutProtocolGuid)) {\r
378 //\r
379 // If it is console out device, set console mode 80x25 if current mode is invalid.\r
380 //\r
1436aea4 381 TextOut = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Interface;\r
067ed98a
RN
382 if (TextOut->Mode->Mode == -1) {\r
383 TextOut->SetMode (TextOut, 0);\r
384 }\r
385 }\r
1436aea4 386\r
fad21b7c 387 FreePool (FullDevicePath);\r
067ed98a
RN
388 return TRUE;\r
389 }\r
390 }\r
067ed98a
RN
391 } while (Instance != NULL);\r
392\r
393 //\r
394 // No any available console devcie found.\r
395 //\r
fad21b7c 396 FreePool (FullDevicePath);\r
067ed98a
RN
397 return FALSE;\r
398}\r
399\r
400/**\r
401 This function updates the console variable based on ConVarName. It can\r
402 add or remove one specific console device path from the variable\r
403\r
404 @param ConsoleType ConIn, ConOut, ErrOut, ConInDev, ConOutDev or ErrOutDev.\r
405 @param CustomizedConDevicePath The console device path to be added to\r
406 the console variable. Cannot be multi-instance.\r
407 @param ExclusiveDevicePath The console device path to be removed\r
408 from the console variable. Cannot be multi-instance.\r
409\r
410 @retval EFI_UNSUPPORTED The added device path is the same as a removed one.\r
411 @retval EFI_SUCCESS Successfully added or removed the device path from the\r
412 console variable.\r
413 @retval others Return status of RT->SetVariable().\r
414\r
415**/\r
416EFI_STATUS\r
417EFIAPI\r
418EfiBootManagerUpdateConsoleVariable (\r
419 IN CONSOLE_TYPE ConsoleType,\r
420 IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,\r
421 IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath\r
422 )\r
423{\r
424 EFI_STATUS Status;\r
425 EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
426 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
427 EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
428\r
f0209935 429 if (ConsoleType >= ARRAY_SIZE (mConVarName)) {\r
067ed98a
RN
430 return EFI_INVALID_PARAMETER;\r
431 }\r
432\r
433 //\r
434 // Notes: check the device path point, here should check\r
435 // with compare memory\r
436 //\r
437 if (CustomizedConDevicePath == ExclusiveDevicePath) {\r
438 return EFI_UNSUPPORTED;\r
439 }\r
1436aea4 440\r
067ed98a
RN
441 //\r
442 // Delete the ExclusiveDevicePath from current default console\r
443 //\r
1436aea4 444 GetEfiGlobalVariable2 (mConVarName[ConsoleType], (VOID **)&VarConsole, NULL);\r
067ed98a
RN
445 //\r
446 // Initialize NewDevicePath\r
447 //\r
448 NewDevicePath = VarConsole;\r
449\r
450 //\r
451 // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.\r
452 // In the end, NewDevicePath is the final device path.\r
453 //\r
1436aea4
MK
454 if ((ExclusiveDevicePath != NULL) && (VarConsole != NULL)) {\r
455 NewDevicePath = BmDelPartMatchInstance (VarConsole, ExclusiveDevicePath);\r
067ed98a 456 }\r
1436aea4 457\r
067ed98a
RN
458 //\r
459 // Try to append customized device path to NewDevicePath.\r
460 //\r
461 if (CustomizedConDevicePath != NULL) {\r
462 if (!BmMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {\r
463 //\r
464 // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.\r
465 //\r
466 NewDevicePath = BmDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);\r
467 //\r
468 // In the first check, the default console variable will be _ModuleEntryPoint,\r
469 // just append current customized device path\r
470 //\r
471 TempNewDevicePath = NewDevicePath;\r
1436aea4 472 NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);\r
067ed98a 473 if (TempNewDevicePath != NULL) {\r
1436aea4 474 FreePool (TempNewDevicePath);\r
067ed98a
RN
475 }\r
476 }\r
477 }\r
478\r
479 //\r
480 // Finally, Update the variable of the default console by NewDevicePath\r
481 //\r
482 Status = gRT->SetVariable (\r
483 mConVarName[ConsoleType],\r
484 &gEfiGlobalVariableGuid,\r
485 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS\r
1436aea4 486 | ((ConsoleType < ConInDev) ? EFI_VARIABLE_NON_VOLATILE : 0),\r
067ed98a
RN
487 GetDevicePathSize (NewDevicePath),\r
488 NewDevicePath\r
489 );\r
490\r
491 if (VarConsole == NewDevicePath) {\r
492 if (VarConsole != NULL) {\r
1436aea4 493 FreePool (VarConsole);\r
067ed98a
RN
494 }\r
495 } else {\r
496 if (VarConsole != NULL) {\r
1436aea4 497 FreePool (VarConsole);\r
067ed98a 498 }\r
1436aea4 499\r
067ed98a 500 if (NewDevicePath != NULL) {\r
1436aea4 501 FreePool (NewDevicePath);\r
067ed98a
RN
502 }\r
503 }\r
504\r
505 return Status;\r
506}\r
507\r
067ed98a
RN
508/**\r
509 Connect the console device base on the variable ConsoleType.\r
510\r
511 @param ConsoleType ConIn, ConOut or ErrOut.\r
512\r
513 @retval EFI_NOT_FOUND There is not any console devices connected\r
514 success\r
515 @retval EFI_SUCCESS Success connect any one instance of the console\r
516 device path base on the variable ConVarName.\r
517\r
518**/\r
519EFI_STATUS\r
520EFIAPI\r
521EfiBootManagerConnectConsoleVariable (\r
1436aea4 522 IN CONSOLE_TYPE ConsoleType\r
067ed98a
RN
523 )\r
524{\r
525 EFI_STATUS Status;\r
526 EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;\r
527 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
528 EFI_DEVICE_PATH_PROTOCOL *Next;\r
529 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;\r
530 UINTN Size;\r
531 BOOLEAN DeviceExist;\r
532 EFI_HANDLE Handle;\r
533\r
534 if ((ConsoleType != ConIn) && (ConsoleType != ConOut) && (ConsoleType != ErrOut)) {\r
535 return EFI_INVALID_PARAMETER;\r
536 }\r
537\r
538 Status = EFI_SUCCESS;\r
539 DeviceExist = FALSE;\r
540 Handle = NULL;\r
541\r
542 //\r
543 // Check if the console variable exist\r
544 //\r
1436aea4 545 GetEfiGlobalVariable2 (mConVarName[ConsoleType], (VOID **)&StartDevicePath, NULL);\r
067ed98a
RN
546 if (StartDevicePath == NULL) {\r
547 return EFI_UNSUPPORTED;\r
548 }\r
549\r
550 CopyOfDevicePath = StartDevicePath;\r
551 do {\r
552 //\r
553 // Check every instance of the console variable\r
554 //\r
1436aea4 555 Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);\r
067ed98a
RN
556 if (Instance == NULL) {\r
557 FreePool (StartDevicePath);\r
558 return EFI_UNSUPPORTED;\r
559 }\r
d1102dba 560\r
1436aea4 561 Next = Instance;\r
067ed98a
RN
562 while (!IsDevicePathEndType (Next)) {\r
563 Next = NextDevicePathNode (Next);\r
564 }\r
565\r
566 SetDevicePathEndNode (Next);\r
567 //\r
568 // Connect the USB console\r
d1102dba 569 // USB console device path is a short-form device path that\r
067ed98a
RN
570 // starts with the first element being a USB WWID\r
571 // or a USB Class device path\r
572 //\r
573 if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
574 ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP) || (DevicePathSubType (Instance) == MSG_USB_WWID_DP))\r
1436aea4
MK
575 )\r
576 {\r
067ed98a
RN
577 Status = BmConnectUsbShortFormDevicePath (Instance);\r
578 if (!EFI_ERROR (Status)) {\r
579 DeviceExist = TRUE;\r
580 }\r
581 } else {\r
582 for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {\r
1436aea4 583 if ((DevicePathType (Next) == ACPI_DEVICE_PATH) && (DevicePathSubType (Next) == ACPI_ADR_DP)) {\r
067ed98a 584 break;\r
1436aea4
MK
585 } else if ((DevicePathType (Next) == HARDWARE_DEVICE_PATH) &&\r
586 (DevicePathSubType (Next) == HW_CONTROLLER_DP) &&\r
587 (DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH) &&\r
588 (DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP)\r
589 )\r
590 {\r
067ed98a
RN
591 break;\r
592 }\r
593 }\r
1436aea4 594\r
067ed98a
RN
595 if (!IsDevicePathEnd (Next)) {\r
596 //\r
597 // For GOP device path, start the video driver with NULL remaining device path\r
598 //\r
599 SetDevicePathEndNode (Next);\r
600 Status = EfiBootManagerConnectDevicePath (Instance, &Handle);\r
601 if (!EFI_ERROR (Status)) {\r
602 gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
603 }\r
604 } else {\r
605 Status = EfiBootManagerConnectDevicePath (Instance, NULL);\r
606 }\r
1436aea4 607\r
067ed98a
RN
608 if (EFI_ERROR (Status)) {\r
609 //\r
610 // Delete the instance from the console varialbe\r
611 //\r
612 EfiBootManagerUpdateConsoleVariable (ConsoleType, NULL, Instance);\r
613 } else {\r
614 DeviceExist = TRUE;\r
615 }\r
616 }\r
1436aea4
MK
617\r
618 FreePool (Instance);\r
067ed98a
RN
619 } while (CopyOfDevicePath != NULL);\r
620\r
621 FreePool (StartDevicePath);\r
622\r
623 if (!DeviceExist) {\r
624 return EFI_NOT_FOUND;\r
625 }\r
626\r
627 return EFI_SUCCESS;\r
628}\r
629\r
067ed98a
RN
630/**\r
631 This function will search every input/output device in current system,\r
632 and make every input/output device as potential console device.\r
633**/\r
634VOID\r
635EFIAPI\r
636EfiBootManagerConnectAllConsoles (\r
637 VOID\r
638 )\r
639{\r
640 UINTN Index;\r
641 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;\r
642 UINTN HandleCount;\r
643 EFI_HANDLE *HandleBuffer;\r
644\r
645 Index = 0;\r
646 HandleCount = 0;\r
647 HandleBuffer = NULL;\r
648 ConDevicePath = NULL;\r
649\r
650 //\r
651 // Update all the console variables\r
652 //\r
653 gBS->LocateHandleBuffer (\r
1436aea4
MK
654 ByProtocol,\r
655 &gEfiSimpleTextInProtocolGuid,\r
656 NULL,\r
657 &HandleCount,\r
658 &HandleBuffer\r
659 );\r
067ed98a
RN
660\r
661 for (Index = 0; Index < HandleCount; Index++) {\r
662 gBS->HandleProtocol (\r
1436aea4
MK
663 HandleBuffer[Index],\r
664 &gEfiDevicePathProtocolGuid,\r
665 (VOID **)&ConDevicePath\r
666 );\r
067ed98a
RN
667 EfiBootManagerUpdateConsoleVariable (ConIn, ConDevicePath, NULL);\r
668 }\r
669\r
670 if (HandleBuffer != NULL) {\r
1436aea4 671 FreePool (HandleBuffer);\r
067ed98a
RN
672 HandleBuffer = NULL;\r
673 }\r
674\r
675 gBS->LocateHandleBuffer (\r
1436aea4
MK
676 ByProtocol,\r
677 &gEfiSimpleTextOutProtocolGuid,\r
678 NULL,\r
679 &HandleCount,\r
680 &HandleBuffer\r
681 );\r
067ed98a
RN
682 for (Index = 0; Index < HandleCount; Index++) {\r
683 gBS->HandleProtocol (\r
1436aea4
MK
684 HandleBuffer[Index],\r
685 &gEfiDevicePathProtocolGuid,\r
686 (VOID **)&ConDevicePath\r
687 );\r
067ed98a
RN
688 EfiBootManagerUpdateConsoleVariable (ConOut, ConDevicePath, NULL);\r
689 EfiBootManagerUpdateConsoleVariable (ErrOut, ConDevicePath, NULL);\r
690 }\r
691\r
692 if (HandleBuffer != NULL) {\r
1436aea4 693 FreePool (HandleBuffer);\r
067ed98a
RN
694 }\r
695\r
696 //\r
697 // Connect all console variables\r
698 //\r
699 EfiBootManagerConnectAllDefaultConsoles ();\r
700}\r
701\r
067ed98a
RN
702/**\r
703 This function will connect all the console devices base on the console\r
704 device variable ConIn, ConOut and ErrOut.\r
705\r
706 @retval EFI_DEVICE_ERROR All the consoles were not connected due to an error.\r
707 @retval EFI_SUCCESS Success connect any one instance of the console\r
708 device path base on the variable ConVarName.\r
709**/\r
710EFI_STATUS\r
711EFIAPI\r
712EfiBootManagerConnectAllDefaultConsoles (\r
713 VOID\r
714 )\r
715{\r
1436aea4
MK
716 EFI_STATUS Status;\r
717 BOOLEAN OneConnected;\r
718 BOOLEAN SystemTableUpdated;\r
067ed98a
RN
719\r
720 OneConnected = FALSE;\r
721\r
722 Status = EfiBootManagerConnectConsoleVariable (ConOut);\r
723 if (!EFI_ERROR (Status)) {\r
724 OneConnected = TRUE;\r
725 }\r
067ed98a 726\r
1436aea4 727 PERF_EVENT ("ConOutReady");\r
d1102dba 728\r
067ed98a
RN
729 Status = EfiBootManagerConnectConsoleVariable (ConIn);\r
730 if (!EFI_ERROR (Status)) {\r
731 OneConnected = TRUE;\r
732 }\r
1436aea4 733\r
67e9ab84 734 PERF_EVENT ("ConInReady");\r
067ed98a
RN
735\r
736 Status = EfiBootManagerConnectConsoleVariable (ErrOut);\r
737 if (!EFI_ERROR (Status)) {\r
738 OneConnected = TRUE;\r
739 }\r
1436aea4 740\r
67e9ab84 741 PERF_EVENT ("ErrOutReady");\r
067ed98a
RN
742\r
743 SystemTableUpdated = FALSE;\r
744 //\r
745 // Fill console handles in System Table if no console device assignd.\r
746 //\r
1436aea4 747 if (BmUpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn)) {\r
067ed98a
RN
748 SystemTableUpdated = TRUE;\r
749 }\r
1436aea4
MK
750\r
751 if (BmUpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut)) {\r
067ed98a
RN
752 SystemTableUpdated = TRUE;\r
753 }\r
1436aea4
MK
754\r
755 if (BmUpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr)) {\r
067ed98a
RN
756 SystemTableUpdated = TRUE;\r
757 }\r
758\r
759 if (SystemTableUpdated) {\r
760 //\r
761 // Update the CRC32 in the EFI System Table header\r
762 //\r
763 gST->Hdr.CRC32 = 0;\r
764 gBS->CalculateCrc32 (\r
1436aea4
MK
765 (UINT8 *)&gST->Hdr,\r
766 gST->Hdr.HeaderSize,\r
767 &gST->Hdr.CRC32\r
768 );\r
067ed98a
RN
769 }\r
770\r
771 return OneConnected ? EFI_SUCCESS : EFI_DEVICE_ERROR;\r
772}\r