2 handles console redirection from boot manager
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BootMaint.h"
17 UART_FLOW_CONTROL_DEVICE_PATH mFlowControlDevicePath
=
20 MESSAGING_DEVICE_PATH
,
23 (UINT8
)(sizeof(UART_FLOW_CONTROL_DEVICE_PATH
)),
24 (UINT8
)((sizeof(UART_FLOW_CONTROL_DEVICE_PATH
)) >> 8)
27 DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL
,
28 UART_FLOW_CONTROL_HARDWARE
32 Check the device path node whether it's the Flow Control node or not.
34 @param[in] FlowControl The device path node to be checked.
36 @retval TRUE It's the Flow Control node.
37 @retval FALSE It's not.
41 IsUartFlowControlNode (
42 IN UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
46 (DevicePathType (FlowControl
) == MESSAGING_DEVICE_PATH
) &&
47 (DevicePathSubType (FlowControl
) == MSG_VENDOR_DP
) &&
48 (CompareGuid (&FlowControl
->Guid
, &gEfiUartDevicePathGuid
))
53 Check whether the device path node is ISA Serial Node.
55 @param Acpi Device path node to be checked
57 @retval TRUE It's ISA Serial Node.
58 @retval FALSE It's NOT ISA Serial Node.
63 IN ACPI_HID_DEVICE_PATH
*Acpi
67 (DevicePathType (Acpi
) == ACPI_DEVICE_PATH
) &&
68 (DevicePathSubType (Acpi
) == ACPI_DP
) &&
69 (ReadUnaligned32 (&Acpi
->HID
) == EISA_PNP_ID (0x0501))
74 Update Com Ports attributes from DevicePath
76 @param DevicePath DevicePath that contains Com ports
78 @retval EFI_SUCCESS The update is successful.
82 UpdateComAttributeFromVariable (
83 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
87 Update the multi-instance device path of Terminal Device based on
88 the global TerminalMenu. If ChangeTernimal is TRUE, the terminal
89 device path in the Terminal Device in TerminalMenu is also updated.
91 @param DevicePath The multi-instance device path.
92 @param ChangeTerminal TRUE, then device path in the Terminal Device
93 in TerminalMenu is also updated; FALSE, no update.
95 @return EFI_SUCCESS The function completes successfully.
99 ChangeTerminalDevicePath (
100 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
,
101 IN BOOLEAN ChangeTerminal
104 EFI_DEVICE_PATH_PROTOCOL
*Node
;
105 EFI_DEVICE_PATH_PROTOCOL
*Node1
;
106 ACPI_HID_DEVICE_PATH
*Acpi
;
107 UART_DEVICE_PATH
*Uart
;
108 UART_DEVICE_PATH
*Uart1
;
110 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
111 BM_MENU_ENTRY
*NewMenuEntry
;
112 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControlNode
;
115 Node
= NextDevicePathNode (Node
);
117 while (!IsDevicePathEnd (Node
)) {
118 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
119 if (IsIsaSerialNode (Acpi
)) {
120 CopyMem (&Com
, &Acpi
->UID
, sizeof (UINT32
));
123 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Com
);
125 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
126 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
127 Uart
= (UART_DEVICE_PATH
*) Node
;
130 &NewTerminalContext
->BaudRate
,
136 &NewTerminalContext
->DataBits
,
142 &NewTerminalContext
->Parity
,
148 &NewTerminalContext
->StopBits
,
152 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (Node
);
153 if (IsUartFlowControlNode (FlowControlNode
)) {
154 FlowControlNode
->FlowControlMap
= NewTerminalContext
->FlowControl
;
157 // Append the Flow control device node when user enable flow control.
159 if (NewTerminalContext
->FlowControl
!= 0) {
160 mFlowControlDevicePath
.FlowControlMap
= NewTerminalContext
->FlowControl
;
161 *DevicePath
= AppendDevicePathNode (
163 (EFI_DEVICE_PATH_PROTOCOL
*) (&mFlowControlDevicePath
)
169 // Change the device path in the ComPort
171 if (ChangeTerminal
) {
172 Node1
= NewTerminalContext
->DevicePath
;
173 Node1
= NextDevicePathNode (Node1
);
174 while (!IsDevicePathEnd (Node1
)) {
175 if ((DevicePathType (Node1
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node1
) == MSG_UART_DP
)) {
176 Uart1
= (UART_DEVICE_PATH
*) Node1
;
179 &NewTerminalContext
->BaudRate
,
185 &NewTerminalContext
->DataBits
,
191 &NewTerminalContext
->Parity
,
197 &NewTerminalContext
->StopBits
,
205 Node1
= NextDevicePathNode (Node1
);
214 Node
= NextDevicePathNode (Node
);
224 Retrieve ACPI UID of UART from device path
226 @param Handle The handle for the UART device.
227 @param AcpiUid The ACPI UID on output.
229 @retval TRUE Find valid UID from device path
230 @retval FALSE Can't find
235 IN EFI_HANDLE Handle
,
236 IN OUT UINT32
*AcpiUid
240 ACPI_HID_DEVICE_PATH
*Acpi
;
241 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
243 Status
= gBS
->HandleProtocol (
245 &gEfiDevicePathProtocolGuid
,
246 (VOID
**) &DevicePath
248 if (EFI_ERROR (Status
)) {
253 for (; !IsDevicePathEnd (DevicePath
); DevicePath
= NextDevicePathNode (DevicePath
)) {
254 if ((DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (DevicePath
) == MSG_UART_DP
)) {
258 // Acpi points to the node before the Uart node
260 Acpi
= (ACPI_HID_DEVICE_PATH
*) DevicePath
;
263 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
264 if (AcpiUid
!= NULL
) {
265 CopyMem (AcpiUid
, &Acpi
->UID
, sizeof (UINT32
));
274 Sort Uart handles array with Acpi->UID from low to high.
276 @param Handles EFI_SERIAL_IO_PROTOCOL handle buffer
277 @param NoHandles EFI_SERIAL_IO_PROTOCOL handle count
281 IN EFI_HANDLE
*Handles
,
291 EFI_HANDLE TempHandle
;
293 for (Index1
= 0; Index1
< NoHandles
-1; Index1
++) {
294 if (!RetrieveUartUid (Handles
[Index1
], &AcpiUid1
)) {
297 TempHandle
= Handles
[Index1
];
299 TempAcpiUid
= AcpiUid1
;
301 for (Index2
= Index1
+1; Index2
< NoHandles
; Index2
++) {
302 if (!RetrieveUartUid (Handles
[Index2
], &AcpiUid2
)) {
305 if (AcpiUid2
< TempAcpiUid
) {
306 TempAcpiUid
= AcpiUid2
;
307 TempHandle
= Handles
[Index2
];
311 Handles
[Position
] = Handles
[Index1
];
312 Handles
[Index1
] = TempHandle
;
317 Test whether DevicePath is a valid Terminal
320 @param DevicePath DevicePath to be checked
321 @param Termi If DevicePath is valid Terminal, terminal type is returned.
322 @param Com If DevicePath is valid Terminal, Com Port type is returned.
324 @retval TRUE If DevicePath point to a Terminal.
325 @retval FALSE If DevicePath does not point to a Terminal.
329 IsTerminalDevicePath (
330 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
331 OUT TYPE_OF_TERMINAL
*Termi
,
336 Build a list containing all serial devices.
339 @retval EFI_SUCCESS The function complete successfully.
340 @retval EFI_UNSUPPORTED No serial ports present.
353 ACPI_HID_DEVICE_PATH
*Acpi
;
354 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
355 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
356 EFI_DEVICE_PATH_PROTOCOL
*Node
;
357 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
358 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
359 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
360 BM_MENU_ENTRY
*NewMenuEntry
;
361 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
362 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
363 VENDOR_DEVICE_PATH Vendor
;
366 // Get all handles that have SerialIo protocol installed
368 InitializeListHead (&TerminalMenu
.Head
);
369 TerminalMenu
.MenuNumber
= 0;
370 Status
= gBS
->LocateHandleBuffer (
372 &gEfiSerialIoProtocolGuid
,
377 if (EFI_ERROR (Status
)) {
379 // No serial ports present
381 return EFI_UNSUPPORTED
;
385 // Sort Uart handles array with Acpi->UID from low to high
386 // then Terminal menu can be built from low Acpi->UID to high Acpi->UID
388 SortedUartHandle (Handles
, NoHandles
);
390 for (Index
= 0; Index
< NoHandles
; Index
++) {
392 // Check to see whether the handle has DevicePath Protocol installed
394 gBS
->HandleProtocol (
396 &gEfiDevicePathProtocolGuid
,
397 (VOID
**) &DevicePath
401 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
402 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
406 // Acpi points to the node before Uart node
408 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
411 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
412 NewMenuEntry
= BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT
);
413 if (NewMenuEntry
== NULL
) {
415 return EFI_OUT_OF_RESOURCES
;
418 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
419 CopyMem (&NewMenuEntry
->OptionNumber
, &Acpi
->UID
, sizeof (UINT32
));
420 NewTerminalContext
->DevicePath
= DuplicateDevicePath (DevicePath
);
422 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
423 // coz' the misc data for each platform is not correct, actually it's the device path stored in
424 // datahub which is not completed, so a searching for end of device path will enter a
427 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (DevicePath
);
428 if (NULL
== NewMenuEntry
->DisplayString
) {
429 NewMenuEntry
->DisplayString
= DevicePathToStr (DevicePath
);
432 NewMenuEntry
->HelpString
= NULL
;
434 gBS
->HandleProtocol (
436 &gEfiSerialIoProtocolGuid
,
441 &NewTerminalContext
->BaudRate
,
442 &SerialIo
->Mode
->BaudRate
,
447 &NewTerminalContext
->DataBits
,
448 &SerialIo
->Mode
->DataBits
,
453 &NewTerminalContext
->Parity
,
454 &SerialIo
->Mode
->Parity
,
459 &NewTerminalContext
->StopBits
,
460 &SerialIo
->Mode
->StopBits
,
464 NewTerminalContext
->FlowControl
= 0;
465 SerialIo
->GetControl(SerialIo
, &FlowControl
);
466 if ((FlowControl
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) != 0) {
467 NewTerminalContext
->FlowControl
= UART_FLOW_CONTROL_HARDWARE
;
470 InsertTailList (&TerminalMenu
.Head
, &NewMenuEntry
->Link
);
471 TerminalMenu
.MenuNumber
++;
474 if (Handles
!= NULL
) {
479 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
481 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
482 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
483 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
484 if (OutDevicePath
!= NULL
) {
485 UpdateComAttributeFromVariable (OutDevicePath
);
488 if (InpDevicePath
!= NULL
) {
489 UpdateComAttributeFromVariable (InpDevicePath
);
492 if (ErrDevicePath
!= NULL
) {
493 UpdateComAttributeFromVariable (ErrDevicePath
);
496 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
497 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
498 if (NULL
== NewMenuEntry
) {
499 return EFI_NOT_FOUND
;
502 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
504 NewTerminalContext
->TerminalType
= 0;
505 NewTerminalContext
->IsConIn
= FALSE
;
506 NewTerminalContext
->IsConOut
= FALSE
;
507 NewTerminalContext
->IsStdErr
= FALSE
;
509 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
510 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
512 for (Index2
= 0; Index2
< 4; Index2
++) {
513 CopyMem (&Vendor
.Guid
, &TerminalTypeGuid
[Index2
], sizeof (EFI_GUID
));
514 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
515 NewDevicePath
= AppendDevicePathNode (
516 NewTerminalContext
->DevicePath
,
517 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
519 if (NewMenuEntry
->HelpString
!= NULL
) {
520 FreePool (NewMenuEntry
->HelpString
);
523 // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);
524 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
526 NewMenuEntry
->HelpString
= NULL
;
528 if (BdsLibMatchDevicePaths (OutDevicePath
, NewDevicePath
)) {
529 NewTerminalContext
->IsConOut
= TRUE
;
530 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
533 if (BdsLibMatchDevicePaths (InpDevicePath
, NewDevicePath
)) {
534 NewTerminalContext
->IsConIn
= TRUE
;
535 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
538 if (BdsLibMatchDevicePaths (ErrDevicePath
, NewDevicePath
)) {
539 NewTerminalContext
->IsStdErr
= TRUE
;
540 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
549 Update Com Ports attributes from DevicePath
551 @param DevicePath DevicePath that contains Com ports
553 @retval EFI_SUCCESS The update is successful.
554 @retval EFI_NOT_FOUND Can not find specific menu entry
557 UpdateComAttributeFromVariable (
558 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
561 EFI_DEVICE_PATH_PROTOCOL
*Node
;
562 EFI_DEVICE_PATH_PROTOCOL
*SerialNode
;
563 ACPI_HID_DEVICE_PATH
*Acpi
;
564 UART_DEVICE_PATH
*Uart
;
565 UART_DEVICE_PATH
*Uart1
;
566 UINTN TerminalNumber
;
567 BM_MENU_ENTRY
*NewMenuEntry
;
568 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
570 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControlNode
;
571 BOOLEAN HasFlowControlNode
;
573 HasFlowControlNode
= FALSE
;
575 Node
= NextDevicePathNode (Node
);
577 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
578 while (!IsDevicePathEnd (Node
)) {
579 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
580 if (IsIsaSerialNode (Acpi
)) {
581 CopyMem (&TerminalNumber
, &Acpi
->UID
, sizeof (UINT32
));
584 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
585 Uart
= (UART_DEVICE_PATH
*) Node
;
586 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalNumber
);
587 if (NULL
== NewMenuEntry
) {
588 return EFI_NOT_FOUND
;
591 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
593 &NewTerminalContext
->BaudRate
,
599 &NewTerminalContext
->DataBits
,
605 &NewTerminalContext
->Parity
,
611 &NewTerminalContext
->StopBits
,
616 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (Node
);
617 if (IsUartFlowControlNode (FlowControlNode
)) {
618 HasFlowControlNode
= TRUE
;
619 NewTerminalContext
->FlowControl
= (UINT8
) ReadUnaligned32 (&FlowControlNode
->FlowControlMap
);
620 } else if (NewTerminalContext
->FlowControl
!= 0) {
622 // No Flow Control device path node, assumption no Flow control
624 NewTerminalContext
->FlowControl
= 0;
627 SerialNode
= NewTerminalContext
->DevicePath
;
628 SerialNode
= NextDevicePathNode (SerialNode
);
629 while (!IsDevicePathEnd (SerialNode
)) {
630 if ((DevicePathType (SerialNode
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (SerialNode
) == MSG_UART_DP
)) {
632 // Update following device paths according to
633 // previous acquired uart attributes
635 Uart1
= (UART_DEVICE_PATH
*) SerialNode
;
638 &NewTerminalContext
->BaudRate
,
644 &NewTerminalContext
->DataBits
,
649 &NewTerminalContext
->Parity
,
654 &NewTerminalContext
->StopBits
,
658 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (SerialNode
);
659 if (IsUartFlowControlNode (FlowControlNode
)) {
660 FlowControlNode
->FlowControlMap
= NewTerminalContext
->FlowControl
;
662 if (HasFlowControlNode
) {
663 mFlowControlDevicePath
.FlowControlMap
= NewTerminalContext
->FlowControl
;
664 NewTerminalContext
->DevicePath
= AppendDevicePathNode (
665 NewTerminalContext
->DevicePath
,
666 (EFI_DEVICE_PATH_PROTOCOL
*) (&mFlowControlDevicePath
)
673 SerialNode
= NextDevicePathNode (SerialNode
);
680 Node
= NextDevicePathNode (Node
);
691 Build up Console Menu based on types passed in. The type can
692 be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
693 and BM_CONSOLE_ERR_CONTEXT_SELECT.
695 @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
696 and BM_CONSOLE_ERR_CONTEXT_SELECT.
698 @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
699 @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev",
700 "ConInDev" or "ConErrDev" doesn't exists.
701 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
702 @retval EFI_SUCCESS Function completes successfully.
707 IN UINTN ConsoleMenuType
710 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
711 EFI_DEVICE_PATH_PROTOCOL
*AllDevicePath
;
712 EFI_DEVICE_PATH_PROTOCOL
*MultiDevicePath
;
713 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
718 BM_MENU_ENTRY
*NewMenuEntry
;
719 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
720 TYPE_OF_TERMINAL Terminal
;
722 BM_MENU_OPTION
*ConsoleMenu
;
725 AllDevicePath
= NULL
;
727 switch (ConsoleMenuType
) {
728 case BM_CONSOLE_IN_CONTEXT_SELECT
:
729 ConsoleMenu
= &ConsoleInpMenu
;
730 DevicePath
= EfiLibGetVariable (
732 &gEfiGlobalVariableGuid
735 AllDevicePath
= EfiLibGetVariable (
737 &gEfiGlobalVariableGuid
741 case BM_CONSOLE_OUT_CONTEXT_SELECT
:
742 ConsoleMenu
= &ConsoleOutMenu
;
743 DevicePath
= EfiLibGetVariable (
745 &gEfiGlobalVariableGuid
748 AllDevicePath
= EfiLibGetVariable (
750 &gEfiGlobalVariableGuid
754 case BM_CONSOLE_ERR_CONTEXT_SELECT
:
755 ConsoleMenu
= &ConsoleErrMenu
;
756 DevicePath
= EfiLibGetVariable (
758 &gEfiGlobalVariableGuid
761 AllDevicePath
= EfiLibGetVariable (
763 &gEfiGlobalVariableGuid
768 return EFI_UNSUPPORTED
;
771 if (NULL
== AllDevicePath
) {
772 return EFI_NOT_FOUND
;
775 InitializeListHead (&ConsoleMenu
->Head
);
777 AllCount
= EfiDevicePathInstanceCount (AllDevicePath
);
778 ConsoleMenu
->MenuNumber
= 0;
780 // Following is menu building up for Console Devices selected.
782 MultiDevicePath
= AllDevicePath
;
784 for (Index
= 0; Index
< AllCount
; Index
++) {
785 DevicePathInst
= GetNextDevicePathInstance (&MultiDevicePath
, &Size
);
787 NewMenuEntry
= BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT
);
788 if (NULL
== NewMenuEntry
) {
789 return EFI_OUT_OF_RESOURCES
;
792 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
793 NewMenuEntry
->OptionNumber
= Index2
;
795 NewConsoleContext
->DevicePath
= DuplicateDevicePath (DevicePathInst
);
796 ASSERT (NewConsoleContext
->DevicePath
!= NULL
);
797 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (NewConsoleContext
->DevicePath
);
798 if (NULL
== NewMenuEntry
->DisplayString
) {
799 NewMenuEntry
->DisplayString
= DevicePathToStr (NewConsoleContext
->DevicePath
);
802 NewConsoleContext
->IsTerminal
= IsTerminalDevicePath (
803 NewConsoleContext
->DevicePath
,
808 NewConsoleContext
->IsActive
= BdsLibMatchDevicePaths (
810 NewConsoleContext
->DevicePath
813 if (NewConsoleContext
->IsTerminal
) {
814 BOpt_DestroyMenuEntry (NewMenuEntry
);
817 ConsoleMenu
->MenuNumber
++;
818 InsertTailList (&ConsoleMenu
->Head
, &NewMenuEntry
->Link
);
826 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
828 @retval EFI_SUCCESS The function always complete successfully.
836 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT
);
837 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT
);
838 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT
);
843 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
845 @retval EFI_SUCCESS The function always complete successfully.
852 BOpt_FreeMenu (&ConsoleOutMenu
);
853 BOpt_FreeMenu (&ConsoleInpMenu
);
854 BOpt_FreeMenu (&ConsoleErrMenu
);
855 BOpt_FreeMenu (&TerminalMenu
);
860 Test whether DevicePath is a valid Terminal
863 @param DevicePath DevicePath to be checked
864 @param Termi If DevicePath is valid Terminal, terminal type is returned.
865 @param Com If DevicePath is valid Terminal, Com Port type is returned.
867 @retval TRUE If DevicePath point to a Terminal.
868 @retval FALSE If DevicePath does not point to a Terminal.
872 IsTerminalDevicePath (
873 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
874 OUT TYPE_OF_TERMINAL
*Termi
,
879 EFI_DEVICE_PATH_PROTOCOL
*Node
;
880 VENDOR_DEVICE_PATH
*Vendor
;
881 UART_DEVICE_PATH
*Uart
;
882 ACPI_HID_DEVICE_PATH
*Acpi
;
889 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
891 // Vendor points to the node before the End node
893 Vendor
= (VENDOR_DEVICE_PATH
*) Node
;
895 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
896 Uart
= (UART_DEVICE_PATH
*) Node
;
901 // Acpi points to the node before the UART node
903 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
907 if (Vendor
== NULL
||
908 DevicePathType (Vendor
) != MESSAGING_DEVICE_PATH
||
909 DevicePathSubType (Vendor
) != MSG_VENDOR_DP
||
915 // There are four kinds of Terminal types
916 // check to see whether this devicepath
917 // is one of that type
919 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[0])) {
920 *Termi
= TerminalTypePcAnsi
;
923 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[1])) {
924 *Termi
= TerminalTypeVt100
;
927 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[2])) {
928 *Termi
= TerminalTypeVt100Plus
;
931 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[3])) {
932 *Termi
= TerminalTypeVtUtf8
;
945 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
946 CopyMem (Com
, &Acpi
->UID
, sizeof (UINT32
));
955 Get mode number according to column and row
957 @param CallbackData The BMM context data.
961 IN BMM_CALLBACK_DATA
*CallbackData
971 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
973 ConOut
= gST
->ConOut
;
974 MaxMode
= (UINTN
) (ConOut
->Mode
->MaxMode
);
976 CurrentCol
= PcdGet32 (PcdSetupConOutColumn
);
977 CurrentRow
= PcdGet32 (PcdSetupConOutRow
);
978 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
979 Status
= ConOut
->QueryMode (ConOut
, Mode
, &Col
, &Row
);
980 if (!EFI_ERROR(Status
)) {
981 if (CurrentCol
== Col
&& CurrentRow
== Row
) {
982 CallbackData
->BmmFakeNvData
.ConsoleOutMode
= (UINT16
) Mode
;
991 Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]
992 in BMM_FAKE_NV_DATA structure.
994 @param CallbackData The BMM context data.
999 IN BMM_CALLBACK_DATA
*CallbackData
1003 BM_MENU_ENTRY
*NewMenuEntry
;
1005 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1007 ASSERT (CallbackData
!= NULL
);
1009 ConInCheck
= &CallbackData
->BmmFakeNvData
.ConsoleInCheck
[0];
1010 for (Index
= 0; ((Index
< ConsoleInpMenu
.MenuNumber
) && \
1011 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1012 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
1013 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1014 ConInCheck
[Index
] = NewConsoleContext
->IsActive
;
1020 Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]
1021 in BMM_FAKE_NV_DATA structure.
1023 @param CallbackData The BMM context data.
1027 GetConsoleOutCheck (
1028 IN BMM_CALLBACK_DATA
*CallbackData
1032 BM_MENU_ENTRY
*NewMenuEntry
;
1034 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1036 ASSERT (CallbackData
!= NULL
);
1037 ConOutCheck
= &CallbackData
->BmmFakeNvData
.ConsoleOutCheck
[0];
1038 for (Index
= 0; ((Index
< ConsoleOutMenu
.MenuNumber
) && \
1039 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1040 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
1041 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1042 ConOutCheck
[Index
] = NewConsoleContext
->IsActive
;
1048 Initialize standard error output device check box to ConsoleErrCheck[MAX_MENU_NUMBER]
1049 in BMM_FAKE_NV_DATA structure.
1051 @param CallbackData The BMM context data.
1055 GetConsoleErrCheck (
1056 IN BMM_CALLBACK_DATA
*CallbackData
1060 BM_MENU_ENTRY
*NewMenuEntry
;
1062 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1064 ASSERT (CallbackData
!= NULL
);
1065 ConErrCheck
= &CallbackData
->BmmFakeNvData
.ConsoleErrCheck
[0];
1066 for (Index
= 0; ((Index
< ConsoleErrMenu
.MenuNumber
) && \
1067 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1068 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
1069 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1070 ConErrCheck
[Index
] = NewConsoleContext
->IsActive
;
1076 Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)
1077 to BMM_FAKE_NV_DATA structure.
1079 @param CallbackData The BMM context data.
1083 GetTerminalAttribute (
1084 IN BMM_CALLBACK_DATA
*CallbackData
1087 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
1088 BM_MENU_ENTRY
*NewMenuEntry
;
1089 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1090 UINT16 TerminalIndex
;
1091 UINT8 AttributeIndex
;
1093 ASSERT (CallbackData
!= NULL
);
1095 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
1096 for (TerminalIndex
= 0; ((TerminalIndex
< TerminalMenu
.MenuNumber
) && \
1097 (TerminalIndex
< MAX_MENU_NUMBER
)); TerminalIndex
++) {
1098 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalIndex
);
1099 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
1100 for (AttributeIndex
= 0; AttributeIndex
< sizeof (BaudRateList
) / sizeof (BaudRateList
[0]); AttributeIndex
++) {
1101 if (NewTerminalContext
->BaudRate
== (UINT64
) (BaudRateList
[AttributeIndex
].Value
)) {
1102 NewTerminalContext
->BaudRateIndex
= AttributeIndex
;
1106 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (DataBitsList
); AttributeIndex
++) {
1107 if (NewTerminalContext
->DataBits
== (UINT64
) (DataBitsList
[AttributeIndex
].Value
)) {
1108 NewTerminalContext
->DataBitsIndex
= AttributeIndex
;
1113 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (ParityList
); AttributeIndex
++) {
1114 if (NewTerminalContext
->Parity
== (UINT64
) (ParityList
[AttributeIndex
].Value
)) {
1115 NewTerminalContext
->ParityIndex
= AttributeIndex
;
1120 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (StopBitsList
); AttributeIndex
++) {
1121 if (NewTerminalContext
->StopBits
== (UINT64
) (StopBitsList
[AttributeIndex
].Value
)) {
1122 NewTerminalContext
->StopBitsIndex
= AttributeIndex
;
1126 CurrentFakeNVMap
->COMBaudRate
[TerminalIndex
] = NewTerminalContext
->BaudRateIndex
;
1127 CurrentFakeNVMap
->COMDataRate
[TerminalIndex
] = NewTerminalContext
->DataBitsIndex
;
1128 CurrentFakeNVMap
->COMStopBits
[TerminalIndex
] = NewTerminalContext
->StopBitsIndex
;
1129 CurrentFakeNVMap
->COMParity
[TerminalIndex
] = NewTerminalContext
->ParityIndex
;
1130 CurrentFakeNVMap
->COMTerminalType
[TerminalIndex
] = NewTerminalContext
->TerminalType
;
1131 CurrentFakeNVMap
->COMFlowControl
[TerminalIndex
] = NewTerminalContext
->FlowControl
;