2 handles console redirection from boot manager
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 UART_FLOW_CONTROL_DEVICE_PATH mFlowControlDevicePath
=
14 MESSAGING_DEVICE_PATH
,
17 (UINT8
)(sizeof(UART_FLOW_CONTROL_DEVICE_PATH
)),
18 (UINT8
)((sizeof(UART_FLOW_CONTROL_DEVICE_PATH
)) >> 8)
21 DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL
,
22 UART_FLOW_CONTROL_HARDWARE
26 Check the device path node whether it's the Flow Control node or not.
28 @param[in] FlowControl The device path node to be checked.
30 @retval TRUE It's the Flow Control node.
31 @retval FALSE It's not.
35 IsUartFlowControlNode (
36 IN UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
40 (DevicePathType (FlowControl
) == MESSAGING_DEVICE_PATH
) &&
41 (DevicePathSubType (FlowControl
) == MSG_VENDOR_DP
) &&
42 (CompareGuid (&FlowControl
->Guid
, &gEfiUartDevicePathGuid
))
47 Check whether the device path node is ISA Serial Node.
49 @param Acpi Device path node to be checked
51 @retval TRUE It's ISA Serial Node.
52 @retval FALSE It's NOT ISA Serial Node.
57 IN ACPI_HID_DEVICE_PATH
*Acpi
61 (DevicePathType (Acpi
) == ACPI_DEVICE_PATH
) &&
62 (DevicePathSubType (Acpi
) == ACPI_DP
) &&
63 (ReadUnaligned32 (&Acpi
->HID
) == EISA_PNP_ID (0x0501))
68 Update Com Ports attributes from DevicePath
70 @param DevicePath DevicePath that contains Com ports
72 @retval EFI_SUCCESS The update is successful.
76 UpdateComAttributeFromVariable (
77 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
81 Update the multi-instance device path of Terminal Device based on
82 the global TerminalMenu. If ChangeTernimal is TRUE, the terminal
83 device path in the Terminal Device in TerminalMenu is also updated.
85 @param DevicePath The multi-instance device path.
86 @param ChangeTerminal TRUE, then device path in the Terminal Device
87 in TerminalMenu is also updated; FALSE, no update.
89 @return EFI_SUCCESS The function completes successfully.
93 ChangeTerminalDevicePath (
94 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevicePath
,
95 IN BOOLEAN ChangeTerminal
98 EFI_DEVICE_PATH_PROTOCOL
*Node
;
99 EFI_DEVICE_PATH_PROTOCOL
*Node1
;
100 ACPI_HID_DEVICE_PATH
*Acpi
;
101 UART_DEVICE_PATH
*Uart
;
102 UART_DEVICE_PATH
*Uart1
;
104 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
105 BM_MENU_ENTRY
*NewMenuEntry
;
106 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControlNode
;
109 Node
= NextDevicePathNode (Node
);
111 while (!IsDevicePathEnd (Node
)) {
112 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
113 if (IsIsaSerialNode (Acpi
)) {
114 CopyMem (&Com
, &Acpi
->UID
, sizeof (UINT32
));
117 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Com
);
119 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
120 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
121 Uart
= (UART_DEVICE_PATH
*) Node
;
124 &NewTerminalContext
->BaudRate
,
130 &NewTerminalContext
->DataBits
,
136 &NewTerminalContext
->Parity
,
142 &NewTerminalContext
->StopBits
,
146 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (Node
);
147 if (IsUartFlowControlNode (FlowControlNode
)) {
148 FlowControlNode
->FlowControlMap
= NewTerminalContext
->FlowControl
;
151 // Append the Flow control device node when user enable flow control.
153 if (NewTerminalContext
->FlowControl
!= 0) {
154 mFlowControlDevicePath
.FlowControlMap
= NewTerminalContext
->FlowControl
;
155 *DevicePath
= AppendDevicePathNode (
157 (EFI_DEVICE_PATH_PROTOCOL
*) (&mFlowControlDevicePath
)
163 // Change the device path in the ComPort
165 if (ChangeTerminal
) {
166 Node1
= NewTerminalContext
->DevicePath
;
167 Node1
= NextDevicePathNode (Node1
);
168 while (!IsDevicePathEnd (Node1
)) {
169 if ((DevicePathType (Node1
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node1
) == MSG_UART_DP
)) {
170 Uart1
= (UART_DEVICE_PATH
*) Node1
;
173 &NewTerminalContext
->BaudRate
,
179 &NewTerminalContext
->DataBits
,
185 &NewTerminalContext
->Parity
,
191 &NewTerminalContext
->StopBits
,
199 Node1
= NextDevicePathNode (Node1
);
208 Node
= NextDevicePathNode (Node
);
218 Retrieve ACPI UID of UART from device path
220 @param Handle The handle for the UART device.
221 @param AcpiUid The ACPI UID on output.
223 @retval TRUE Find valid UID from device path
224 @retval FALSE Can't find
229 IN EFI_HANDLE Handle
,
230 IN OUT UINT32
*AcpiUid
234 ACPI_HID_DEVICE_PATH
*Acpi
;
235 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
237 Status
= gBS
->HandleProtocol (
239 &gEfiDevicePathProtocolGuid
,
240 (VOID
**) &DevicePath
242 if (EFI_ERROR (Status
)) {
247 for (; !IsDevicePathEnd (DevicePath
); DevicePath
= NextDevicePathNode (DevicePath
)) {
248 if ((DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (DevicePath
) == MSG_UART_DP
)) {
252 // Acpi points to the node before the Uart node
254 Acpi
= (ACPI_HID_DEVICE_PATH
*) DevicePath
;
257 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
258 if (AcpiUid
!= NULL
) {
259 CopyMem (AcpiUid
, &Acpi
->UID
, sizeof (UINT32
));
268 Sort Uart handles array with Acpi->UID from low to high.
270 @param Handles EFI_SERIAL_IO_PROTOCOL handle buffer
271 @param NoHandles EFI_SERIAL_IO_PROTOCOL handle count
275 IN EFI_HANDLE
*Handles
,
285 EFI_HANDLE TempHandle
;
287 for (Index1
= 0; Index1
< NoHandles
-1; Index1
++) {
288 if (!RetrieveUartUid (Handles
[Index1
], &AcpiUid1
)) {
291 TempHandle
= Handles
[Index1
];
293 TempAcpiUid
= AcpiUid1
;
295 for (Index2
= Index1
+1; Index2
< NoHandles
; Index2
++) {
296 if (!RetrieveUartUid (Handles
[Index2
], &AcpiUid2
)) {
299 if (AcpiUid2
< TempAcpiUid
) {
300 TempAcpiUid
= AcpiUid2
;
301 TempHandle
= Handles
[Index2
];
305 Handles
[Position
] = Handles
[Index1
];
306 Handles
[Index1
] = TempHandle
;
311 Test whether DevicePath is a valid Terminal
314 @param DevicePath DevicePath to be checked
315 @param Termi If DevicePath is valid Terminal, terminal type is returned.
316 @param Com If DevicePath is valid Terminal, Com Port type is returned.
318 @retval TRUE If DevicePath point to a Terminal.
319 @retval FALSE If DevicePath does not point to a Terminal.
323 IsTerminalDevicePath (
324 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
325 OUT TYPE_OF_TERMINAL
*Termi
,
330 Build a list containing all serial devices.
333 @retval EFI_SUCCESS The function complete successfully.
334 @retval EFI_UNSUPPORTED No serial ports present.
347 ACPI_HID_DEVICE_PATH
*Acpi
;
348 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
349 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
350 EFI_DEVICE_PATH_PROTOCOL
*Node
;
351 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
352 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
353 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
354 BM_MENU_ENTRY
*NewMenuEntry
;
355 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
356 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
357 VENDOR_DEVICE_PATH Vendor
;
360 // Get all handles that have SerialIo protocol installed
362 InitializeListHead (&TerminalMenu
.Head
);
363 TerminalMenu
.MenuNumber
= 0;
364 Status
= gBS
->LocateHandleBuffer (
366 &gEfiSerialIoProtocolGuid
,
371 if (EFI_ERROR (Status
)) {
373 // No serial ports present
375 return EFI_UNSUPPORTED
;
379 // Sort Uart handles array with Acpi->UID from low to high
380 // then Terminal menu can be built from low Acpi->UID to high Acpi->UID
382 SortedUartHandle (Handles
, NoHandles
);
384 for (Index
= 0; Index
< NoHandles
; Index
++) {
386 // Check to see whether the handle has DevicePath Protocol installed
388 gBS
->HandleProtocol (
390 &gEfiDevicePathProtocolGuid
,
391 (VOID
**) &DevicePath
395 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
396 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
400 // Acpi points to the node before Uart node
402 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
405 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
406 NewMenuEntry
= BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT
);
407 if (NewMenuEntry
== NULL
) {
409 return EFI_OUT_OF_RESOURCES
;
412 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
413 CopyMem (&NewMenuEntry
->OptionNumber
, &Acpi
->UID
, sizeof (UINT32
));
414 NewTerminalContext
->DevicePath
= DuplicateDevicePath (DevicePath
);
416 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
417 // coz' the misc data for each platform is not correct, actually it's the device path stored in
418 // datahub which is not completed, so a searching for end of device path will enter a
421 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (DevicePath
);
422 if (NULL
== NewMenuEntry
->DisplayString
) {
423 NewMenuEntry
->DisplayString
= DevicePathToStr (DevicePath
);
426 NewMenuEntry
->HelpString
= NULL
;
428 gBS
->HandleProtocol (
430 &gEfiSerialIoProtocolGuid
,
435 &NewTerminalContext
->BaudRate
,
436 &SerialIo
->Mode
->BaudRate
,
441 &NewTerminalContext
->DataBits
,
442 &SerialIo
->Mode
->DataBits
,
447 &NewTerminalContext
->Parity
,
448 &SerialIo
->Mode
->Parity
,
453 &NewTerminalContext
->StopBits
,
454 &SerialIo
->Mode
->StopBits
,
458 NewTerminalContext
->FlowControl
= 0;
459 SerialIo
->GetControl(SerialIo
, &FlowControl
);
460 if ((FlowControl
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) != 0) {
461 NewTerminalContext
->FlowControl
= UART_FLOW_CONTROL_HARDWARE
;
464 InsertTailList (&TerminalMenu
.Head
, &NewMenuEntry
->Link
);
465 TerminalMenu
.MenuNumber
++;
468 if (Handles
!= NULL
) {
473 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
475 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
476 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
477 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
478 if (OutDevicePath
!= NULL
) {
479 UpdateComAttributeFromVariable (OutDevicePath
);
482 if (InpDevicePath
!= NULL
) {
483 UpdateComAttributeFromVariable (InpDevicePath
);
486 if (ErrDevicePath
!= NULL
) {
487 UpdateComAttributeFromVariable (ErrDevicePath
);
490 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
491 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
492 if (NULL
== NewMenuEntry
) {
493 return EFI_NOT_FOUND
;
496 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
498 NewTerminalContext
->TerminalType
= 0;
499 NewTerminalContext
->IsConIn
= FALSE
;
500 NewTerminalContext
->IsConOut
= FALSE
;
501 NewTerminalContext
->IsStdErr
= FALSE
;
503 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
504 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
506 for (Index2
= 0; Index2
< 4; Index2
++) {
507 CopyMem (&Vendor
.Guid
, &TerminalTypeGuid
[Index2
], sizeof (EFI_GUID
));
508 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
509 NewDevicePath
= AppendDevicePathNode (
510 NewTerminalContext
->DevicePath
,
511 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
513 if (NewMenuEntry
->HelpString
!= NULL
) {
514 FreePool (NewMenuEntry
->HelpString
);
517 // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);
518 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
520 NewMenuEntry
->HelpString
= NULL
;
522 if (BdsLibMatchDevicePaths (OutDevicePath
, NewDevicePath
)) {
523 NewTerminalContext
->IsConOut
= TRUE
;
524 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
527 if (BdsLibMatchDevicePaths (InpDevicePath
, NewDevicePath
)) {
528 NewTerminalContext
->IsConIn
= TRUE
;
529 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
532 if (BdsLibMatchDevicePaths (ErrDevicePath
, NewDevicePath
)) {
533 NewTerminalContext
->IsStdErr
= TRUE
;
534 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
543 Update Com Ports attributes from DevicePath
545 @param DevicePath DevicePath that contains Com ports
547 @retval EFI_SUCCESS The update is successful.
548 @retval EFI_NOT_FOUND Can not find specific menu entry
551 UpdateComAttributeFromVariable (
552 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
555 EFI_DEVICE_PATH_PROTOCOL
*Node
;
556 EFI_DEVICE_PATH_PROTOCOL
*SerialNode
;
557 ACPI_HID_DEVICE_PATH
*Acpi
;
558 UART_DEVICE_PATH
*Uart
;
559 UART_DEVICE_PATH
*Uart1
;
560 UINTN TerminalNumber
;
561 BM_MENU_ENTRY
*NewMenuEntry
;
562 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
564 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControlNode
;
565 BOOLEAN HasFlowControlNode
;
567 HasFlowControlNode
= FALSE
;
569 Node
= NextDevicePathNode (Node
);
571 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
572 while (!IsDevicePathEnd (Node
)) {
573 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
574 if (IsIsaSerialNode (Acpi
)) {
575 CopyMem (&TerminalNumber
, &Acpi
->UID
, sizeof (UINT32
));
578 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
579 Uart
= (UART_DEVICE_PATH
*) Node
;
580 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalNumber
);
581 if (NULL
== NewMenuEntry
) {
582 return EFI_NOT_FOUND
;
585 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
587 &NewTerminalContext
->BaudRate
,
593 &NewTerminalContext
->DataBits
,
599 &NewTerminalContext
->Parity
,
605 &NewTerminalContext
->StopBits
,
610 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (Node
);
611 if (IsUartFlowControlNode (FlowControlNode
)) {
612 HasFlowControlNode
= TRUE
;
613 NewTerminalContext
->FlowControl
= (UINT8
) ReadUnaligned32 (&FlowControlNode
->FlowControlMap
);
614 } else if (NewTerminalContext
->FlowControl
!= 0) {
616 // No Flow Control device path node, assumption no Flow control
618 NewTerminalContext
->FlowControl
= 0;
621 SerialNode
= NewTerminalContext
->DevicePath
;
622 SerialNode
= NextDevicePathNode (SerialNode
);
623 while (!IsDevicePathEnd (SerialNode
)) {
624 if ((DevicePathType (SerialNode
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (SerialNode
) == MSG_UART_DP
)) {
626 // Update following device paths according to
627 // previous acquired uart attributes
629 Uart1
= (UART_DEVICE_PATH
*) SerialNode
;
632 &NewTerminalContext
->BaudRate
,
638 &NewTerminalContext
->DataBits
,
643 &NewTerminalContext
->Parity
,
648 &NewTerminalContext
->StopBits
,
652 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (SerialNode
);
653 if (IsUartFlowControlNode (FlowControlNode
)) {
654 FlowControlNode
->FlowControlMap
= NewTerminalContext
->FlowControl
;
656 if (HasFlowControlNode
) {
657 mFlowControlDevicePath
.FlowControlMap
= NewTerminalContext
->FlowControl
;
658 NewTerminalContext
->DevicePath
= AppendDevicePathNode (
659 NewTerminalContext
->DevicePath
,
660 (EFI_DEVICE_PATH_PROTOCOL
*) (&mFlowControlDevicePath
)
667 SerialNode
= NextDevicePathNode (SerialNode
);
674 Node
= NextDevicePathNode (Node
);
685 Build up Console Menu based on types passed in. The type can
686 be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
687 and BM_CONSOLE_ERR_CONTEXT_SELECT.
689 @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
690 and BM_CONSOLE_ERR_CONTEXT_SELECT.
692 @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
693 @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev",
694 "ConInDev" or "ConErrDev" doesn't exists.
695 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
696 @retval EFI_SUCCESS Function completes successfully.
701 IN UINTN ConsoleMenuType
704 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
705 EFI_DEVICE_PATH_PROTOCOL
*AllDevicePath
;
706 EFI_DEVICE_PATH_PROTOCOL
*MultiDevicePath
;
707 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
712 BM_MENU_ENTRY
*NewMenuEntry
;
713 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
714 TYPE_OF_TERMINAL Terminal
;
716 BM_MENU_OPTION
*ConsoleMenu
;
719 AllDevicePath
= NULL
;
721 switch (ConsoleMenuType
) {
722 case BM_CONSOLE_IN_CONTEXT_SELECT
:
723 ConsoleMenu
= &ConsoleInpMenu
;
724 DevicePath
= EfiLibGetVariable (
726 &gEfiGlobalVariableGuid
729 AllDevicePath
= EfiLibGetVariable (
731 &gEfiGlobalVariableGuid
735 case BM_CONSOLE_OUT_CONTEXT_SELECT
:
736 ConsoleMenu
= &ConsoleOutMenu
;
737 DevicePath
= EfiLibGetVariable (
739 &gEfiGlobalVariableGuid
742 AllDevicePath
= EfiLibGetVariable (
744 &gEfiGlobalVariableGuid
748 case BM_CONSOLE_ERR_CONTEXT_SELECT
:
749 ConsoleMenu
= &ConsoleErrMenu
;
750 DevicePath
= EfiLibGetVariable (
752 &gEfiGlobalVariableGuid
755 AllDevicePath
= EfiLibGetVariable (
757 &gEfiGlobalVariableGuid
762 return EFI_UNSUPPORTED
;
765 if (NULL
== AllDevicePath
) {
766 return EFI_NOT_FOUND
;
769 InitializeListHead (&ConsoleMenu
->Head
);
771 AllCount
= EfiDevicePathInstanceCount (AllDevicePath
);
772 ConsoleMenu
->MenuNumber
= 0;
774 // Following is menu building up for Console Devices selected.
776 MultiDevicePath
= AllDevicePath
;
778 for (Index
= 0; Index
< AllCount
; Index
++) {
779 DevicePathInst
= GetNextDevicePathInstance (&MultiDevicePath
, &Size
);
781 NewMenuEntry
= BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT
);
782 if (NULL
== NewMenuEntry
) {
783 return EFI_OUT_OF_RESOURCES
;
786 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
787 NewMenuEntry
->OptionNumber
= Index2
;
789 NewConsoleContext
->DevicePath
= DuplicateDevicePath (DevicePathInst
);
790 ASSERT (NewConsoleContext
->DevicePath
!= NULL
);
791 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (NewConsoleContext
->DevicePath
);
792 if (NULL
== NewMenuEntry
->DisplayString
) {
793 NewMenuEntry
->DisplayString
= DevicePathToStr (NewConsoleContext
->DevicePath
);
796 NewConsoleContext
->IsTerminal
= IsTerminalDevicePath (
797 NewConsoleContext
->DevicePath
,
802 NewConsoleContext
->IsActive
= BdsLibMatchDevicePaths (
804 NewConsoleContext
->DevicePath
807 if (NewConsoleContext
->IsTerminal
) {
808 BOpt_DestroyMenuEntry (NewMenuEntry
);
811 ConsoleMenu
->MenuNumber
++;
812 InsertTailList (&ConsoleMenu
->Head
, &NewMenuEntry
->Link
);
820 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
822 @retval EFI_SUCCESS The function always complete successfully.
830 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT
);
831 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT
);
832 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT
);
837 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
839 @retval EFI_SUCCESS The function always complete successfully.
846 BOpt_FreeMenu (&ConsoleOutMenu
);
847 BOpt_FreeMenu (&ConsoleInpMenu
);
848 BOpt_FreeMenu (&ConsoleErrMenu
);
849 BOpt_FreeMenu (&TerminalMenu
);
854 Test whether DevicePath is a valid Terminal
857 @param DevicePath DevicePath to be checked
858 @param Termi If DevicePath is valid Terminal, terminal type is returned.
859 @param Com If DevicePath is valid Terminal, Com Port type is returned.
861 @retval TRUE If DevicePath point to a Terminal.
862 @retval FALSE If DevicePath does not point to a Terminal.
866 IsTerminalDevicePath (
867 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
868 OUT TYPE_OF_TERMINAL
*Termi
,
873 EFI_DEVICE_PATH_PROTOCOL
*Node
;
874 VENDOR_DEVICE_PATH
*Vendor
;
875 UART_DEVICE_PATH
*Uart
;
876 ACPI_HID_DEVICE_PATH
*Acpi
;
883 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
885 // Vendor points to the node before the End node
887 Vendor
= (VENDOR_DEVICE_PATH
*) Node
;
889 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
890 Uart
= (UART_DEVICE_PATH
*) Node
;
895 // Acpi points to the node before the UART node
897 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
901 if (Vendor
== NULL
||
902 DevicePathType (Vendor
) != MESSAGING_DEVICE_PATH
||
903 DevicePathSubType (Vendor
) != MSG_VENDOR_DP
||
909 // There are four kinds of Terminal types
910 // check to see whether this devicepath
911 // is one of that type
913 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[0])) {
914 *Termi
= TerminalTypePcAnsi
;
917 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[1])) {
918 *Termi
= TerminalTypeVt100
;
921 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[2])) {
922 *Termi
= TerminalTypeVt100Plus
;
925 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[3])) {
926 *Termi
= TerminalTypeVtUtf8
;
939 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
940 CopyMem (Com
, &Acpi
->UID
, sizeof (UINT32
));
949 Get mode number according to column and row
951 @param CallbackData The BMM context data.
955 IN BMM_CALLBACK_DATA
*CallbackData
965 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
967 ConOut
= gST
->ConOut
;
968 MaxMode
= (UINTN
) (ConOut
->Mode
->MaxMode
);
970 CurrentCol
= PcdGet32 (PcdSetupConOutColumn
);
971 CurrentRow
= PcdGet32 (PcdSetupConOutRow
);
972 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
973 Status
= ConOut
->QueryMode (ConOut
, Mode
, &Col
, &Row
);
974 if (!EFI_ERROR(Status
)) {
975 if (CurrentCol
== Col
&& CurrentRow
== Row
) {
976 CallbackData
->BmmFakeNvData
.ConsoleOutMode
= (UINT16
) Mode
;
985 Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]
986 in BMM_FAKE_NV_DATA structure.
988 @param CallbackData The BMM context data.
993 IN BMM_CALLBACK_DATA
*CallbackData
997 BM_MENU_ENTRY
*NewMenuEntry
;
999 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1001 ASSERT (CallbackData
!= NULL
);
1003 ConInCheck
= &CallbackData
->BmmFakeNvData
.ConsoleInCheck
[0];
1004 for (Index
= 0; ((Index
< ConsoleInpMenu
.MenuNumber
) && \
1005 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1006 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
1007 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1008 ConInCheck
[Index
] = NewConsoleContext
->IsActive
;
1014 Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]
1015 in BMM_FAKE_NV_DATA structure.
1017 @param CallbackData The BMM context data.
1021 GetConsoleOutCheck (
1022 IN BMM_CALLBACK_DATA
*CallbackData
1026 BM_MENU_ENTRY
*NewMenuEntry
;
1028 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1030 ASSERT (CallbackData
!= NULL
);
1031 ConOutCheck
= &CallbackData
->BmmFakeNvData
.ConsoleOutCheck
[0];
1032 for (Index
= 0; ((Index
< ConsoleOutMenu
.MenuNumber
) && \
1033 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1034 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
1035 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1036 ConOutCheck
[Index
] = NewConsoleContext
->IsActive
;
1042 Initialize standard error output device check box to ConsoleErrCheck[MAX_MENU_NUMBER]
1043 in BMM_FAKE_NV_DATA structure.
1045 @param CallbackData The BMM context data.
1049 GetConsoleErrCheck (
1050 IN BMM_CALLBACK_DATA
*CallbackData
1054 BM_MENU_ENTRY
*NewMenuEntry
;
1056 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1058 ASSERT (CallbackData
!= NULL
);
1059 ConErrCheck
= &CallbackData
->BmmFakeNvData
.ConsoleErrCheck
[0];
1060 for (Index
= 0; ((Index
< ConsoleErrMenu
.MenuNumber
) && \
1061 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1062 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
1063 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1064 ConErrCheck
[Index
] = NewConsoleContext
->IsActive
;
1070 Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)
1071 to BMM_FAKE_NV_DATA structure.
1073 @param CallbackData The BMM context data.
1077 GetTerminalAttribute (
1078 IN BMM_CALLBACK_DATA
*CallbackData
1081 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
1082 BM_MENU_ENTRY
*NewMenuEntry
;
1083 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1084 UINT16 TerminalIndex
;
1085 UINT8 AttributeIndex
;
1087 ASSERT (CallbackData
!= NULL
);
1089 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
1090 for (TerminalIndex
= 0; ((TerminalIndex
< TerminalMenu
.MenuNumber
) && \
1091 (TerminalIndex
< MAX_MENU_NUMBER
)); TerminalIndex
++) {
1092 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalIndex
);
1093 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
1094 for (AttributeIndex
= 0; AttributeIndex
< sizeof (BaudRateList
) / sizeof (BaudRateList
[0]); AttributeIndex
++) {
1095 if (NewTerminalContext
->BaudRate
== (UINT64
) (BaudRateList
[AttributeIndex
].Value
)) {
1096 NewTerminalContext
->BaudRateIndex
= AttributeIndex
;
1100 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (DataBitsList
); AttributeIndex
++) {
1101 if (NewTerminalContext
->DataBits
== (UINT64
) (DataBitsList
[AttributeIndex
].Value
)) {
1102 NewTerminalContext
->DataBitsIndex
= AttributeIndex
;
1107 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (ParityList
); AttributeIndex
++) {
1108 if (NewTerminalContext
->Parity
== (UINT64
) (ParityList
[AttributeIndex
].Value
)) {
1109 NewTerminalContext
->ParityIndex
= AttributeIndex
;
1114 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (StopBitsList
); AttributeIndex
++) {
1115 if (NewTerminalContext
->StopBits
== (UINT64
) (StopBitsList
[AttributeIndex
].Value
)) {
1116 NewTerminalContext
->StopBitsIndex
= AttributeIndex
;
1120 CurrentFakeNVMap
->COMBaudRate
[TerminalIndex
] = NewTerminalContext
->BaudRateIndex
;
1121 CurrentFakeNVMap
->COMDataRate
[TerminalIndex
] = NewTerminalContext
->DataBitsIndex
;
1122 CurrentFakeNVMap
->COMStopBits
[TerminalIndex
] = NewTerminalContext
->StopBitsIndex
;
1123 CurrentFakeNVMap
->COMParity
[TerminalIndex
] = NewTerminalContext
->ParityIndex
;
1124 CurrentFakeNVMap
->COMTerminalType
[TerminalIndex
] = NewTerminalContext
->TerminalType
;
1125 CurrentFakeNVMap
->COMFlowControl
[TerminalIndex
] = NewTerminalContext
->FlowControl
;