]> git.proxmox.com Git - mirror_edk2.git/blame - EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/ConsoleOption.c
Fix the issues,
[mirror_edk2.git] / EdkUnixPkg / Dxe / PlatformBds / Generic / BootMaint / ConsoleOption.c
CommitLineData
c9093a06 1/*++\r
2Copyright (c) 2006, Intel Corporation \r
3All rights reserved. This program and the accompanying materials \r
4are licensed and made available under the terms and conditions of the BSD License \r
5which accompanies this distribution. The full text of the license may be found at \r
6http://opensource.org/licenses/bsd-license.php \r
7 \r
8THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
9WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
10\r
11Module Name:\r
12\r
13 ConsoleOption.c\r
14 \r
15Abstract:\r
16\r
17 handles console redirection from boot manager\r
18\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
24#include "BootMaint.h"\r
25\r
26EFI_DEVICE_PATH_PROTOCOL *\r
27DevicePathInstanceDup (\r
28 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
29 );\r
30\r
31EFI_STATUS\r
32UpdateComAttributeFromVariable (\r
33 EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
34 );\r
35\r
36EFI_STATUS\r
37ChangeTerminalDevicePath (\r
38 EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
39 BOOLEAN ChangeTerminal\r
40 )\r
41{\r
42 EFI_DEVICE_PATH_PROTOCOL *Node;\r
43 EFI_DEVICE_PATH_PROTOCOL *Node1;\r
44 ACPI_HID_DEVICE_PATH *Acpi;\r
45 UART_DEVICE_PATH *Uart;\r
46 UART_DEVICE_PATH *Uart1;\r
47 UINTN Com;\r
48 UINT32 Match;\r
49 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
50 BM_MENU_ENTRY *NewMenuEntry;\r
51\r
52 Match = EISA_PNP_ID (0x0501);\r
53 Node = DevicePath;\r
54 Node = NextDevicePathNode (Node);\r
55 Com = 0;\r
56 while (!IsDevicePathEnd (Node)) {\r
57 if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {\r
58 Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
59 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
60 CopyMem (&Com, &Acpi->UID, sizeof (UINT32));\r
61 }\r
62 }\r
63\r
64 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);\r
65 if (NULL == NewMenuEntry) {\r
66 return EFI_NOT_FOUND;\r
67 }\r
68\r
69 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
70 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
71 Uart = (UART_DEVICE_PATH *) Node;\r
72 CopyMem (\r
73 &Uart->BaudRate,\r
74 &NewTerminalContext->BaudRate,\r
75 sizeof (UINT64)\r
76 );\r
77\r
78 CopyMem (\r
79 &Uart->DataBits,\r
80 &NewTerminalContext->DataBits,\r
81 sizeof (UINT8)\r
82 );\r
83\r
84 CopyMem (\r
85 &Uart->Parity,\r
86 &NewTerminalContext->Parity,\r
87 sizeof (UINT8)\r
88 );\r
89\r
90 CopyMem (\r
91 &Uart->StopBits,\r
92 &NewTerminalContext->StopBits,\r
93 sizeof (UINT8)\r
94 );\r
95 //\r
96 // Change the device path in the ComPort\r
97 //\r
98 if (ChangeTerminal) {\r
99 Node1 = NewTerminalContext->DevicePath;\r
100 Node1 = NextDevicePathNode (Node1);\r
101 while (!IsDevicePathEnd (Node1)) {\r
102 if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) {\r
103 Uart1 = (UART_DEVICE_PATH *) Node1;\r
104 CopyMem (\r
105 &Uart1->BaudRate,\r
106 &NewTerminalContext->BaudRate,\r
107 sizeof (UINT64)\r
108 );\r
109\r
110 CopyMem (\r
111 &Uart1->DataBits,\r
112 &NewTerminalContext->DataBits,\r
113 sizeof (UINT8)\r
114 );\r
115\r
116 CopyMem (\r
117 &Uart1->Parity,\r
118 &NewTerminalContext->Parity,\r
119 sizeof (UINT8)\r
120 );\r
121\r
122 CopyMem (\r
123 &Uart1->StopBits,\r
124 &NewTerminalContext->StopBits,\r
125 sizeof (UINT8)\r
126 );\r
127 break;\r
128 }\r
129 //\r
130 // end if\r
131 //\r
132 Node1 = NextDevicePathNode (Node1);\r
133 }\r
134 //\r
135 // end while\r
136 //\r
137 break;\r
138 }\r
139 }\r
140\r
141 Node = NextDevicePathNode (Node);\r
142 }\r
143\r
144 return EFI_SUCCESS;\r
145\r
146}\r
147\r
148VOID\r
149ChangeVariableDevicePath (\r
150 EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
151 )\r
152{\r
153 EFI_DEVICE_PATH_PROTOCOL *Node;\r
154 ACPI_HID_DEVICE_PATH *Acpi;\r
155 UART_DEVICE_PATH *Uart;\r
156 UINTN Com;\r
157 UINT32 Match;\r
158 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
159 BM_MENU_ENTRY *NewMenuEntry;\r
160\r
161 Match = EISA_PNP_ID (0x0501);\r
162 Node = DevicePath;\r
163 Node = NextDevicePathNode (Node);\r
164 Com = 0;\r
165 while (!IsDevicePathEnd (Node)) {\r
166 if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {\r
167 Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
168 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
169 CopyMem (&Com, &Acpi->UID, sizeof (UINT32));\r
170 }\r
171 }\r
172\r
173 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
174 NewMenuEntry = BOpt_GetMenuEntry (\r
175 &TerminalMenu,\r
176 Com\r
177 );\r
2bbf72b0 178 ASSERT (NewMenuEntry != NULL);\r
c9093a06 179 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
180 Uart = (UART_DEVICE_PATH *) Node;\r
181 CopyMem (\r
182 &Uart->BaudRate,\r
183 &NewTerminalContext->BaudRate,\r
184 sizeof (UINT64)\r
185 );\r
186\r
187 CopyMem (\r
188 &Uart->DataBits,\r
189 &NewTerminalContext->DataBits,\r
190 sizeof (UINT8)\r
191 );\r
192\r
193 CopyMem (\r
194 &Uart->Parity,\r
195 &NewTerminalContext->Parity,\r
196 sizeof (UINT8)\r
197 );\r
198\r
199 CopyMem (\r
200 &Uart->StopBits,\r
201 &NewTerminalContext->StopBits,\r
202 sizeof (UINT8)\r
203 );\r
204 }\r
205\r
206 Node = NextDevicePathNode (Node);\r
207 }\r
208\r
209 return ;\r
210}\r
211\r
212BOOLEAN\r
213IsTerminalDevicePath (\r
214 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
215 OUT TYPE_OF_TERMINAL *Termi,\r
216 OUT UINTN *Com\r
217 );\r
218\r
219EFI_STATUS\r
220LocateSerialIo (\r
221 VOID\r
222 )\r
223/*++\r
224\r
225Routine Description:\r
226 Build a list containing all serial devices \r
227 \r
228Arguments:\r
229 \r
230Returns:\r
231 \r
232--*/\r
233{\r
234 UINT8 *Ptr;\r
235 UINTN Index;\r
236 UINTN Index2;\r
237 UINTN NoHandles;\r
238 EFI_HANDLE *Handles;\r
239 EFI_STATUS Status;\r
240 ACPI_HID_DEVICE_PATH *Acpi;\r
241 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
242 UINT32 Match;\r
243 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
244 EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;\r
245 EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;\r
246 EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;\r
247 BM_MENU_ENTRY *NewMenuEntry;\r
248 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
249 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
250 VENDOR_DEVICE_PATH Vendor;\r
251 //\r
252 // Get all handles that have SerialIo protocol installed\r
253 //\r
254 InitializeListHead (&TerminalMenu.Head);\r
255 TerminalMenu.MenuNumber = 0;\r
256 Status = gBS->LocateHandleBuffer (\r
257 ByProtocol,\r
258 &gEfiSerialIoProtocolGuid,\r
259 NULL,\r
260 &NoHandles,\r
261 &Handles\r
262 );\r
263 if (EFI_ERROR (Status)) {\r
264 //\r
265 // No serial ports present\r
266 //\r
267 return EFI_UNSUPPORTED;\r
268 }\r
269\r
270 for (Index = 0; Index < NoHandles; Index++) {\r
271 //\r
272 // Check to see whether the handle has DevicePath Protocol installed\r
273 //\r
274 gBS->HandleProtocol (\r
275 Handles[Index],\r
276 &gEfiDevicePathProtocolGuid,\r
997e26f6 277 (VOID**) &DevicePath\r
c9093a06 278 );\r
279 Ptr = (UINT8 *) DevicePath;\r
280 while (*Ptr != END_DEVICE_PATH_TYPE) {\r
281 Ptr++;\r
282 }\r
283\r
284 Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);\r
285 Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;\r
286 Match = EISA_PNP_ID (0x0501);\r
287\r
288 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
289 NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);\r
290 if (!NewMenuEntry) {\r
291 return EFI_OUT_OF_RESOURCES;\r
292 }\r
293\r
294 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
295 CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));\r
296 NewTerminalContext->DevicePath = DevicePathInstanceDup (DevicePath);\r
297 //\r
298 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!\r
299 // coz' the misc data for each platform is not correct, actually it's the device path stored in\r
300 // datahub which is not completed, so a searching for end of device path will enter a\r
301 // dead-loop.\r
302 //\r
303 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);\r
304 if (NULL == NewMenuEntry->DisplayString) {\r
305 NewMenuEntry->DisplayString = DevicePathToStr (DevicePath);\r
306 }\r
307\r
308 NewMenuEntry->HelpString = NULL;\r
309\r
310 gBS->HandleProtocol (\r
311 Handles[Index],\r
312 &gEfiSerialIoProtocolGuid,\r
997e26f6 313 (VOID**) &SerialIo\r
c9093a06 314 );\r
315\r
316 CopyMem (\r
317 &NewTerminalContext->BaudRate,\r
318 &SerialIo->Mode->BaudRate,\r
319 sizeof (UINT64)\r
320 );\r
321\r
322 CopyMem (\r
323 &NewTerminalContext->DataBits,\r
324 &SerialIo->Mode->DataBits,\r
325 sizeof (UINT8)\r
326 );\r
327\r
328 CopyMem (\r
329 &NewTerminalContext->Parity,\r
330 &SerialIo->Mode->Parity,\r
331 sizeof (UINT8)\r
332 );\r
333\r
334 CopyMem (\r
335 &NewTerminalContext->StopBits,\r
336 &SerialIo->Mode->StopBits,\r
337 sizeof (UINT8)\r
338 );\r
339 InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);\r
340 TerminalMenu.MenuNumber++;\r
341 }\r
342 }\r
343 //\r
344 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var\r
345 //\r
346 OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);\r
347 InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);\r
348 ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);\r
349 if (OutDevicePath) {\r
350 UpdateComAttributeFromVariable (OutDevicePath);\r
351 }\r
352\r
353 if (InpDevicePath) {\r
354 UpdateComAttributeFromVariable (InpDevicePath);\r
355 }\r
356\r
357 if (ErrDevicePath) {\r
358 UpdateComAttributeFromVariable (ErrDevicePath);\r
359 }\r
360\r
361 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
362 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
363 if (NULL == NewMenuEntry) {\r
364 return EFI_NOT_FOUND;\r
365 }\r
366\r
367 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
368\r
369 NewTerminalContext->TerminalType = 0;\r
370 NewTerminalContext->IsConIn = FALSE;\r
371 NewTerminalContext->IsConOut = FALSE;\r
372 NewTerminalContext->IsStdErr = FALSE;\r
373\r
374 Vendor.Header.Type = MESSAGING_DEVICE_PATH;\r
375 Vendor.Header.SubType = MSG_VENDOR_DP;\r
376\r
377 for (Index2 = 0; Index2 < 4; Index2++) {\r
378 CopyMem (&Vendor.Guid, &Guid[Index2], sizeof (EFI_GUID));\r
379 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));\r
380 NewDevicePath = AppendDevicePathNode (\r
381 NewTerminalContext->DevicePath,\r
382 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor\r
383 );\r
384 SafeFreePool (NewMenuEntry->HelpString);\r
385 //\r
386 // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);\r
387 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;\r
388 //\r
389 NewMenuEntry->HelpString = NULL;\r
390\r
391 if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) {\r
392 NewTerminalContext->IsConOut = TRUE;\r
393 NewTerminalContext->TerminalType = (UINT8) Index2;\r
394 }\r
395\r
396 if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) {\r
397 NewTerminalContext->IsConIn = TRUE;\r
398 NewTerminalContext->TerminalType = (UINT8) Index2;\r
399 }\r
400\r
401 if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) {\r
402 NewTerminalContext->IsStdErr = TRUE;\r
403 NewTerminalContext->TerminalType = (UINT8) Index2;\r
404 }\r
405 }\r
406 }\r
407\r
408 return EFI_SUCCESS;\r
409}\r
410\r
411EFI_STATUS\r
412UpdateComAttributeFromVariable (\r
413 EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
414 )\r
415/*++\r
416\r
417Routine Description:\r
418 Update Com Ports attributes from DevicePath\r
419 \r
420Arguments:\r
421 DevicePath - DevicePath that contains Com ports\r
422 \r
423Returns:\r
424 \r
425--*/\r
426{\r
427 EFI_DEVICE_PATH_PROTOCOL *Node;\r
428 EFI_DEVICE_PATH_PROTOCOL *SerialNode;\r
429 ACPI_HID_DEVICE_PATH *Acpi;\r
430 UART_DEVICE_PATH *Uart;\r
431 UART_DEVICE_PATH *Uart1;\r
432 UINT32 Match;\r
433 UINTN TerminalNumber;\r
434 BM_MENU_ENTRY *NewMenuEntry;\r
435 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
436 UINTN Index;\r
437\r
438 Match = EISA_PNP_ID (0x0501);\r
439 Node = DevicePath;\r
440 Node = NextDevicePathNode (Node);\r
441 TerminalNumber = 0;\r
442 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
443 while (!IsDevicePathEnd (Node)) {\r
444 if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {\r
445 Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
446 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
447 CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));\r
448 }\r
449 }\r
450\r
451 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
452 Uart = (UART_DEVICE_PATH *) Node;\r
453 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);\r
454 if (NULL == NewMenuEntry) {\r
455 return EFI_NOT_FOUND;\r
456 }\r
457\r
458 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
459 CopyMem (\r
460 &NewTerminalContext->BaudRate,\r
461 &Uart->BaudRate,\r
462 sizeof (UINT64)\r
463 );\r
464\r
465 CopyMem (\r
466 &NewTerminalContext->DataBits,\r
467 &Uart->DataBits,\r
468 sizeof (UINT8)\r
469 );\r
470\r
471 CopyMem (\r
472 &NewTerminalContext->Parity,\r
473 &Uart->Parity,\r
474 sizeof (UINT8)\r
475 );\r
476\r
477 CopyMem (\r
478 &NewTerminalContext->StopBits,\r
479 &Uart->StopBits,\r
480 sizeof (UINT8)\r
481 );\r
482\r
483 SerialNode = NewTerminalContext->DevicePath;\r
484 SerialNode = NextDevicePathNode (SerialNode);\r
485 while (!IsDevicePathEnd (SerialNode)) {\r
486 if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {\r
487 //\r
488 // Update following device paths according to\r
489 // previous acquired uart attributes\r
490 //\r
491 Uart1 = (UART_DEVICE_PATH *) SerialNode;\r
492 CopyMem (\r
493 &Uart1->BaudRate,\r
494 &NewTerminalContext->BaudRate,\r
495 sizeof (UINT64)\r
496 );\r
497\r
498 CopyMem (\r
499 &Uart1->DataBits,\r
500 &NewTerminalContext->DataBits,\r
501 sizeof (UINT8)\r
502 );\r
503 CopyMem (\r
504 &Uart1->Parity,\r
505 &NewTerminalContext->Parity,\r
506 sizeof (UINT8)\r
507 );\r
508 CopyMem (\r
509 &Uart1->StopBits,\r
510 &NewTerminalContext->StopBits,\r
511 sizeof (UINT8)\r
512 );\r
513\r
514 break;\r
515 }\r
516\r
517 SerialNode = NextDevicePathNode (SerialNode);\r
518 }\r
519 //\r
520 // end while\r
521 //\r
522 }\r
523\r
524 Node = NextDevicePathNode (Node);\r
525 }\r
526 //\r
527 // end while\r
528 //\r
529 }\r
530\r
531 return EFI_SUCCESS;\r
532}\r
533\r
534EFI_DEVICE_PATH_PROTOCOL *\r
535DevicePathInstanceDup (\r
536 IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
537 )\r
538/*++\r
539\r
540Routine Description:\r
541 Function creates a device path data structure that identically matches the \r
542 device path passed in.\r
543\r
544Arguments:\r
545 DevPath - A pointer to a device path data structure.\r
546\r
547Returns:\r
548\r
549 The new copy of DevPath is created to identically match the input. \r
550 Otherwise, NULL is returned.\r
551\r
552--*/\r
553{\r
554 EFI_DEVICE_PATH_PROTOCOL *NewDevPath;\r
555 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
556 EFI_DEVICE_PATH_PROTOCOL *Temp;\r
557 UINT8 *Ptr;\r
558 UINTN Size;\r
559\r
560 //\r
561 // get the size of an instance from the input\r
562 //\r
563 Temp = DevPath;\r
564 DevicePathInst = GetNextDevicePathInstance (&Temp, &Size);\r
565\r
566 //\r
567 // Make a copy and set proper end type\r
568 //\r
569 NewDevPath = NULL;\r
570 if (Size) {\r
571 NewDevPath = AllocateZeroPool (Size);\r
572 ASSERT (NewDevPath != NULL);\r
573 }\r
574\r
575 if (NewDevPath) {\r
576 CopyMem (NewDevPath, DevicePathInst, Size);\r
577 Ptr = (UINT8 *) NewDevPath;\r
578 Ptr += Size - sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
579 Temp = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
580 SetDevicePathEndNode (Temp);\r
581 }\r
582\r
583 return NewDevPath;\r
584}\r
585\r
586EFI_STATUS\r
587GetConsoleMenu (\r
588 IN UINTN ConsoleMenuType\r
589 )\r
590{\r
591 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
592 EFI_DEVICE_PATH_PROTOCOL *AllDevicePath;\r
593 EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath;\r
594 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
595 UINTN Size;\r
596 UINTN AllCount;\r
597 UINTN Index;\r
598 UINTN Index2;\r
599 BM_MENU_ENTRY *NewMenuEntry;\r
600 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
601 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
602 TYPE_OF_TERMINAL Terminal;\r
603 BM_MENU_ENTRY *NewTerminalMenuEntry;\r
604 UINTN Com;\r
605 BM_MENU_OPTION *ConsoleMenu;\r
606\r
607 DevicePath = NULL;\r
608 AllDevicePath = NULL;\r
609 AllCount = 0;\r
610 switch (ConsoleMenuType) {\r
611 case BM_CONSOLE_IN_CONTEXT_SELECT:\r
612 ConsoleMenu = &ConsoleInpMenu;\r
613 DevicePath = EfiLibGetVariable (\r
614 L"ConIn",\r
615 &gEfiGlobalVariableGuid\r
616 );\r
617\r
618 AllDevicePath = EfiLibGetVariable (\r
619 L"ConInDev",\r
620 &gEfiGlobalVariableGuid\r
621 );\r
622 break;\r
623\r
624 case BM_CONSOLE_OUT_CONTEXT_SELECT:\r
625 ConsoleMenu = &ConsoleOutMenu;\r
626 DevicePath = EfiLibGetVariable (\r
627 L"ConOut",\r
628 &gEfiGlobalVariableGuid\r
629 );\r
630\r
631 AllDevicePath = EfiLibGetVariable (\r
632 L"ConOutDev",\r
633 &gEfiGlobalVariableGuid\r
634 );\r
635 break;\r
636\r
637 case BM_CONSOLE_ERR_CONTEXT_SELECT:\r
638 ConsoleMenu = &ConsoleErrMenu;\r
639 DevicePath = EfiLibGetVariable (\r
640 L"ErrOut",\r
641 &gEfiGlobalVariableGuid\r
642 );\r
643\r
644 AllDevicePath = EfiLibGetVariable (\r
645 L"ErrOutDev",\r
646 &gEfiGlobalVariableGuid\r
647 );\r
648 break;\r
649\r
650 default:\r
651 return EFI_UNSUPPORTED;\r
652 }\r
653\r
654 if (NULL == AllDevicePath) {\r
655 return EFI_NOT_FOUND;\r
656 }\r
657\r
658 InitializeListHead (&ConsoleMenu->Head);\r
659\r
660 AllCount = EfiDevicePathInstanceCount (AllDevicePath);\r
661 ConsoleMenu->MenuNumber = 0;\r
662 //\r
663 // Following is menu building up for Console Out Devices\r
664 //\r
665 MultiDevicePath = AllDevicePath;\r
666 Index2 = 0;\r
667 for (Index = 0; Index < AllCount; Index++) {\r
668 DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size);\r
669\r
670 NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);\r
671 if (NULL == NewMenuEntry) {\r
672 return EFI_OUT_OF_RESOURCES;\r
673 }\r
674\r
675 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
676 NewMenuEntry->OptionNumber = Index2;\r
677\r
678 NewConsoleContext->DevicePath = DevicePathInstanceDup (DevicePathInst);\r
679 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);\r
680 if (NULL == NewMenuEntry->DisplayString) {\r
681 NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath);\r
682 }\r
683\r
684 NewConsoleContext->IsTerminal = IsTerminalDevicePath (\r
685 NewConsoleContext->DevicePath,\r
686 &Terminal,\r
687 &Com\r
688 );\r
689\r
690 NewConsoleContext->IsActive = BdsLibMatchDevicePaths (\r
691 DevicePath,\r
692 NewConsoleContext->DevicePath\r
693 );\r
694 NewTerminalMenuEntry = NULL;\r
695 NewTerminalContext = NULL;\r
696\r
697 if (NewConsoleContext->IsTerminal) {\r
698 BOpt_DestroyMenuEntry (NewMenuEntry);\r
699 } else {\r
700 Index2++;\r
701 ConsoleMenu->MenuNumber++;\r
702 InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);\r
703 }\r
704 }\r
705\r
706 return EFI_SUCCESS;\r
707}\r
708\r
709EFI_STATUS\r
710GetAllConsoles (\r
711 VOID\r
712 )\r
713/*++\r
714\r
715Routine Description:\r
716 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu\r
717\r
718Arguments:\r
719 \r
720Returns:\r
721 EFI_SUCCESS \r
722 Others\r
723 \r
724--*/\r
725{\r
726 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);\r
727 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);\r
728 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);\r
729 return EFI_SUCCESS;\r
730}\r
731\r
732EFI_STATUS\r
733FreeAllConsoles (\r
734 VOID\r
735 )\r
736/*++\r
737\r
738Routine Description:\r
739 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu\r
740\r
741Arguments:\r
742 \r
743Returns:\r
744 EFI_SUCCESS \r
745 Others\r
746 \r
747--*/\r
748{\r
749 BOpt_FreeMenu (&ConsoleOutMenu);\r
750 BOpt_FreeMenu (&ConsoleInpMenu);\r
751 BOpt_FreeMenu (&ConsoleErrMenu);\r
752 BOpt_FreeMenu (&TerminalMenu);\r
753 return EFI_SUCCESS;\r
754}\r
755\r
756BOOLEAN\r
757IsTerminalDevicePath (\r
758 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
759 OUT TYPE_OF_TERMINAL *Termi,\r
760 OUT UINTN *Com\r
761 )\r
762/*++\r
763\r
764Routine Description:\r
765 Test whether DevicePath is a valid Terminal\r
766\r
767Arguments:\r
768 DevicePath - DevicePath to be checked\r
769 Termi - If is terminal, give its type\r
770 Com - If is Com Port, give its type\r
771 \r
772Returns:\r
773 TRUE - If DevicePath point to a Terminal\r
774 FALSE\r
775 \r
776--*/\r
777{\r
778 UINT8 *Ptr;\r
779 BOOLEAN IsTerminal;\r
780 VENDOR_DEVICE_PATH *Vendor;\r
781 ACPI_HID_DEVICE_PATH *Acpi;\r
782 UINT32 Match;\r
783 EFI_GUID TempGuid;\r
784\r
785 IsTerminal = FALSE;\r
786\r
787 //\r
788 // Parse the Device Path, should be change later!!!\r
789 //\r
790 Ptr = (UINT8 *) DevicePath;\r
791 while (*Ptr != END_DEVICE_PATH_TYPE) {\r
792 Ptr++;\r
793 }\r
794\r
795 Ptr = Ptr - sizeof (VENDOR_DEVICE_PATH);\r
796 Vendor = (VENDOR_DEVICE_PATH *) Ptr;\r
797\r
798 //\r
799 // There are four kinds of Terminal types\r
800 // check to see whether this devicepath\r
801 // is one of that type\r
802 //\r
803 CopyMem (&TempGuid, &Vendor->Guid, sizeof (EFI_GUID));\r
804\r
805 if (CompareGuid (&TempGuid, &Guid[0])) {\r
806 *Termi = PC_ANSI;\r
807 IsTerminal = TRUE;\r
808 } else {\r
809 if (CompareGuid (&TempGuid, &Guid[1])) {\r
810 *Termi = VT_100;\r
811 IsTerminal = TRUE;\r
812 } else {\r
813 if (CompareGuid (&TempGuid, &Guid[2])) {\r
814 *Termi = VT_100_PLUS;\r
815 IsTerminal = TRUE;\r
816 } else {\r
817 if (CompareGuid (&TempGuid, &Guid[3])) {\r
818 *Termi = VT_UTF8;\r
819 IsTerminal = TRUE;\r
820 } else {\r
821 IsTerminal = FALSE;\r
822 }\r
823 }\r
824 }\r
825 }\r
826\r
827 if (!IsTerminal) {\r
828 return FALSE;\r
829 }\r
830\r
831 Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);\r
832 Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;\r
833 Match = EISA_PNP_ID (0x0501);\r
834 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {\r
835 CopyMem (Com, &Acpi->UID, sizeof (UINT32));\r
836 } else {\r
837 return FALSE;\r
838 }\r
839\r
840 return TRUE;\r
841}\r