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
9 #include "BootMaintenanceManager.h"
12 Function compares a device path data structure to that of all the nodes of a
13 second device path instance.
15 @param Multi A pointer to a multi-instance device path data
17 @param Single A pointer to a single-instance device path data
20 @retval TRUE If the Single device path is contained within Multi device path.
21 @retval FALSE The Single device path is not match within Multi device path.
26 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
27 IN EFI_DEVICE_PATH_PROTOCOL
*Single
30 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
31 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
34 if ((Multi
== NULL
) || (Single
== NULL
)) {
39 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
42 // Search for the match of 'Single' in 'Multi'
44 while (DevicePathInst
!= NULL
) {
46 // If the single device path is found in multiple device paths,
49 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
50 FreePool (DevicePathInst
);
54 FreePool (DevicePathInst
);
55 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
62 Check whether the device path node is ISA Serial Node.
64 @param Acpi Device path node to be checked
66 @retval TRUE It's ISA Serial Node.
67 @retval FALSE It's NOT ISA Serial Node.
72 IN ACPI_HID_DEVICE_PATH
*Acpi
76 (DevicePathType (Acpi
) == ACPI_DEVICE_PATH
) &&
77 (DevicePathSubType (Acpi
) == ACPI_DP
) &&
78 (ReadUnaligned32 (&Acpi
->HID
) == EISA_PNP_ID (0x0501))
83 Update Com Ports attributes from DevicePath
85 @param DevicePath DevicePath that contains Com ports
87 @retval EFI_SUCCESS The update is successful.
91 UpdateComAttributeFromVariable (
92 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
96 Update the multi-instance device path of Terminal Device based on
97 the global TerminalMenu. If ChangeTernimal is TRUE, the terminal
98 device path in the Terminal Device in TerminalMenu is also updated.
100 @param DevicePath The multi-instance device path.
101 @param ChangeTerminal TRUE, then device path in the Terminal Device
102 in TerminalMenu is also updated; FALSE, no update.
104 @return EFI_SUCCESS The function completes successfully.
108 ChangeTerminalDevicePath (
109 IN OUT EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
110 IN BOOLEAN ChangeTerminal
113 EFI_DEVICE_PATH_PROTOCOL
*Node
;
114 EFI_DEVICE_PATH_PROTOCOL
*Node1
;
115 ACPI_HID_DEVICE_PATH
*Acpi
;
116 UART_DEVICE_PATH
*Uart
;
117 UART_DEVICE_PATH
*Uart1
;
119 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
120 BM_MENU_ENTRY
*NewMenuEntry
;
123 Node
= NextDevicePathNode (Node
);
125 while (!IsDevicePathEnd (Node
)) {
126 Acpi
= (ACPI_HID_DEVICE_PATH
*)Node
;
127 if (IsIsaSerialNode (Acpi
)) {
128 CopyMem (&Com
, &Acpi
->UID
, sizeof (UINT32
));
131 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Com
);
133 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
134 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
135 Uart
= (UART_DEVICE_PATH
*)Node
;
138 &NewTerminalContext
->BaudRate
,
144 &NewTerminalContext
->DataBits
,
150 &NewTerminalContext
->Parity
,
156 &NewTerminalContext
->StopBits
,
160 // Change the device path in the ComPort
162 if (ChangeTerminal
) {
163 Node1
= NewTerminalContext
->DevicePath
;
164 Node1
= NextDevicePathNode (Node1
);
165 while (!IsDevicePathEnd (Node1
)) {
166 if ((DevicePathType (Node1
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node1
) == MSG_UART_DP
)) {
167 Uart1
= (UART_DEVICE_PATH
*)Node1
;
170 &NewTerminalContext
->BaudRate
,
176 &NewTerminalContext
->DataBits
,
182 &NewTerminalContext
->Parity
,
188 &NewTerminalContext
->StopBits
,
197 Node1
= NextDevicePathNode (Node1
);
207 Node
= NextDevicePathNode (Node
);
214 Update the device path that describing a terminal device
215 based on the new BaudRate, Data Bits, parity and Stop Bits
218 @param DevicePath terminal device's path
222 ChangeVariableDevicePath (
223 IN OUT EFI_DEVICE_PATH_PROTOCOL
*DevicePath
226 EFI_DEVICE_PATH_PROTOCOL
*Node
;
227 ACPI_HID_DEVICE_PATH
*Acpi
;
228 UART_DEVICE_PATH
*Uart
;
230 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
231 BM_MENU_ENTRY
*NewMenuEntry
;
234 Node
= NextDevicePathNode (Node
);
236 while (!IsDevicePathEnd (Node
)) {
237 Acpi
= (ACPI_HID_DEVICE_PATH
*)Node
;
238 if (IsIsaSerialNode (Acpi
)) {
239 CopyMem (&Com
, &Acpi
->UID
, sizeof (UINT32
));
242 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
243 NewMenuEntry
= BOpt_GetMenuEntry (
247 ASSERT (NewMenuEntry
!= NULL
);
248 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
249 Uart
= (UART_DEVICE_PATH
*)Node
;
252 &NewTerminalContext
->BaudRate
,
258 &NewTerminalContext
->DataBits
,
264 &NewTerminalContext
->Parity
,
270 &NewTerminalContext
->StopBits
,
275 Node
= NextDevicePathNode (Node
);
280 Retrieve ACPI UID of UART from device path
282 @param Handle The handle for the UART device.
283 @param AcpiUid The ACPI UID on output.
285 @retval TRUE Find valid UID from device path
286 @retval FALSE Can't find
291 IN EFI_HANDLE Handle
,
292 IN OUT UINT32
*AcpiUid
296 ACPI_HID_DEVICE_PATH
*Acpi
;
297 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
299 Status
= gBS
->HandleProtocol (
301 &gEfiDevicePathProtocolGuid
,
304 if (EFI_ERROR (Status
)) {
309 for ( ; !IsDevicePathEnd (DevicePath
); DevicePath
= NextDevicePathNode (DevicePath
)) {
310 if ((DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (DevicePath
) == MSG_UART_DP
)) {
315 // Acpi points to the node before the Uart node
317 Acpi
= (ACPI_HID_DEVICE_PATH
*)DevicePath
;
320 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
321 if (AcpiUid
!= NULL
) {
322 CopyMem (AcpiUid
, &Acpi
->UID
, sizeof (UINT32
));
332 Sort Uart handles array with Acpi->UID from low to high.
334 @param Handles EFI_SERIAL_IO_PROTOCOL handle buffer
335 @param NoHandles EFI_SERIAL_IO_PROTOCOL handle count
339 IN EFI_HANDLE
*Handles
,
349 EFI_HANDLE TempHandle
;
351 for (Index1
= 0; Index1
< NoHandles
-1; Index1
++) {
352 if (!RetrieveUartUid (Handles
[Index1
], &AcpiUid1
)) {
356 TempHandle
= Handles
[Index1
];
358 TempAcpiUid
= AcpiUid1
;
360 for (Index2
= Index1
+1; Index2
< NoHandles
; Index2
++) {
361 if (!RetrieveUartUid (Handles
[Index2
], &AcpiUid2
)) {
365 if (AcpiUid2
< TempAcpiUid
) {
366 TempAcpiUid
= AcpiUid2
;
367 TempHandle
= Handles
[Index2
];
372 Handles
[Position
] = Handles
[Index1
];
373 Handles
[Index1
] = TempHandle
;
378 Test whether DevicePath is a valid Terminal
381 @param DevicePath DevicePath to be checked
382 @param Termi If DevicePath is valid Terminal, terminal type is returned.
383 @param Com If DevicePath is valid Terminal, Com Port type is returned.
385 @retval TRUE If DevicePath point to a Terminal.
386 @retval FALSE If DevicePath does not point to a Terminal.
390 IsTerminalDevicePath (
391 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
392 OUT TYPE_OF_TERMINAL
*Termi
,
397 Build a list containing all serial devices.
400 @retval EFI_SUCCESS The function complete successfully.
401 @retval EFI_UNSUPPORTED No serial ports present.
414 ACPI_HID_DEVICE_PATH
*Acpi
;
415 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
416 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
417 EFI_DEVICE_PATH_PROTOCOL
*Node
;
418 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
419 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
420 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
421 BM_MENU_ENTRY
*NewMenuEntry
;
422 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
423 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
424 VENDOR_DEVICE_PATH Vendor
;
427 // Get all handles that have SerialIo protocol installed
429 InitializeListHead (&TerminalMenu
.Head
);
430 TerminalMenu
.MenuNumber
= 0;
431 Status
= gBS
->LocateHandleBuffer (
433 &gEfiSerialIoProtocolGuid
,
438 if (EFI_ERROR (Status
)) {
440 // No serial ports present
442 return EFI_UNSUPPORTED
;
446 // Sort Uart handles array with Acpi->UID from low to high
447 // then Terminal menu can be built from low Acpi->UID to high Acpi->UID
449 SortedUartHandle (Handles
, NoHandles
);
451 for (Index
= 0; Index
< NoHandles
; Index
++) {
453 // Check to see whether the handle has DevicePath Protocol installed
455 gBS
->HandleProtocol (
457 &gEfiDevicePathProtocolGuid
,
462 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
463 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
468 // Acpi points to the node before Uart node
470 Acpi
= (ACPI_HID_DEVICE_PATH
*)Node
;
473 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
474 NewMenuEntry
= BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT
);
475 if (NewMenuEntry
== NULL
) {
477 return EFI_OUT_OF_RESOURCES
;
480 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
481 CopyMem (&NewMenuEntry
->OptionNumber
, &Acpi
->UID
, sizeof (UINT32
));
482 NewTerminalContext
->DevicePath
= DuplicateDevicePath (DevicePath
);
484 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
485 // coz' the misc data for each platform is not correct, actually it's the device path stored in
486 // datahub which is not completed, so a searching for end of device path will enter a
489 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (DevicePath
);
490 if (NULL
== NewMenuEntry
->DisplayString
) {
491 NewMenuEntry
->DisplayString
= UiDevicePathToStr (DevicePath
);
494 NewMenuEntry
->HelpString
= NULL
;
496 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
498 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
500 gBS
->HandleProtocol (
502 &gEfiSerialIoProtocolGuid
,
507 &NewTerminalContext
->BaudRate
,
508 &SerialIo
->Mode
->BaudRate
,
513 &NewTerminalContext
->DataBits
,
514 &SerialIo
->Mode
->DataBits
,
519 &NewTerminalContext
->Parity
,
520 &SerialIo
->Mode
->Parity
,
525 &NewTerminalContext
->StopBits
,
526 &SerialIo
->Mode
->StopBits
,
529 InsertTailList (&TerminalMenu
.Head
, &NewMenuEntry
->Link
);
530 TerminalMenu
.MenuNumber
++;
534 if (Handles
!= NULL
) {
539 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
541 GetEfiGlobalVariable2 (L
"ConOut", (VOID
**)&OutDevicePath
, NULL
);
542 GetEfiGlobalVariable2 (L
"ConIn", (VOID
**)&InpDevicePath
, NULL
);
543 GetEfiGlobalVariable2 (L
"ErrOut", (VOID
**)&ErrDevicePath
, NULL
);
544 if (OutDevicePath
!= NULL
) {
545 UpdateComAttributeFromVariable (OutDevicePath
);
548 if (InpDevicePath
!= NULL
) {
549 UpdateComAttributeFromVariable (InpDevicePath
);
552 if (ErrDevicePath
!= NULL
) {
553 UpdateComAttributeFromVariable (ErrDevicePath
);
556 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
557 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
558 if (NULL
== NewMenuEntry
) {
559 return EFI_NOT_FOUND
;
562 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
564 NewTerminalContext
->TerminalType
= 0;
565 NewTerminalContext
->IsConIn
= FALSE
;
566 NewTerminalContext
->IsConOut
= FALSE
;
567 NewTerminalContext
->IsStdErr
= FALSE
;
569 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
570 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
572 for (Index2
= 0; Index2
< (ARRAY_SIZE (TerminalTypeGuid
)); Index2
++) {
573 CopyMem (&Vendor
.Guid
, &TerminalTypeGuid
[Index2
], sizeof (EFI_GUID
));
574 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
575 NewDevicePath
= AppendDevicePathNode (
576 NewTerminalContext
->DevicePath
,
577 (EFI_DEVICE_PATH_PROTOCOL
*)&Vendor
579 if (NewMenuEntry
->HelpString
!= NULL
) {
580 FreePool (NewMenuEntry
->HelpString
);
584 // NewMenuEntry->HelpString = UiDevicePathToStr (NewDevicePath);
585 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
587 NewMenuEntry
->HelpString
= NULL
;
589 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
591 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
593 if (MatchDevicePaths (OutDevicePath
, NewDevicePath
)) {
594 NewTerminalContext
->IsConOut
= TRUE
;
595 NewTerminalContext
->TerminalType
= (UINT8
)Index2
;
598 if (MatchDevicePaths (InpDevicePath
, NewDevicePath
)) {
599 NewTerminalContext
->IsConIn
= TRUE
;
600 NewTerminalContext
->TerminalType
= (UINT8
)Index2
;
603 if (MatchDevicePaths (ErrDevicePath
, NewDevicePath
)) {
604 NewTerminalContext
->IsStdErr
= TRUE
;
605 NewTerminalContext
->TerminalType
= (UINT8
)Index2
;
614 Update Com Ports attributes from DevicePath
616 @param DevicePath DevicePath that contains Com ports
618 @retval EFI_SUCCESS The update is successful.
619 @retval EFI_NOT_FOUND Can not find specific menu entry
622 UpdateComAttributeFromVariable (
623 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
626 EFI_DEVICE_PATH_PROTOCOL
*Node
;
627 EFI_DEVICE_PATH_PROTOCOL
*SerialNode
;
628 ACPI_HID_DEVICE_PATH
*Acpi
;
629 UART_DEVICE_PATH
*Uart
;
630 UART_DEVICE_PATH
*Uart1
;
631 UINTN TerminalNumber
;
632 BM_MENU_ENTRY
*NewMenuEntry
;
633 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
637 Node
= NextDevicePathNode (Node
);
639 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
640 while (!IsDevicePathEnd (Node
)) {
641 Acpi
= (ACPI_HID_DEVICE_PATH
*)Node
;
642 if (IsIsaSerialNode (Acpi
)) {
643 CopyMem (&TerminalNumber
, &Acpi
->UID
, sizeof (UINT32
));
646 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
647 Uart
= (UART_DEVICE_PATH
*)Node
;
648 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalNumber
);
649 if (NULL
== NewMenuEntry
) {
650 return EFI_NOT_FOUND
;
653 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
655 &NewTerminalContext
->BaudRate
,
661 &NewTerminalContext
->DataBits
,
667 &NewTerminalContext
->Parity
,
673 &NewTerminalContext
->StopBits
,
678 SerialNode
= NewTerminalContext
->DevicePath
;
679 SerialNode
= NextDevicePathNode (SerialNode
);
680 while (!IsDevicePathEnd (SerialNode
)) {
681 if ((DevicePathType (SerialNode
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (SerialNode
) == MSG_UART_DP
)) {
683 // Update following device paths according to
684 // previous acquired uart attributes
686 Uart1
= (UART_DEVICE_PATH
*)SerialNode
;
689 &NewTerminalContext
->BaudRate
,
695 &NewTerminalContext
->DataBits
,
700 &NewTerminalContext
->Parity
,
705 &NewTerminalContext
->StopBits
,
712 SerialNode
= NextDevicePathNode (SerialNode
);
720 Node
= NextDevicePathNode (Node
);
732 Build up Console Menu based on types passed in. The type can
733 be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
734 and BM_CONSOLE_ERR_CONTEXT_SELECT.
736 @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
737 and BM_CONSOLE_ERR_CONTEXT_SELECT.
739 @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
740 @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev",
741 "ConInDev" or "ConErrDev" doesn't exists.
742 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
743 @retval EFI_SUCCESS Function completes successfully.
748 IN UINTN ConsoleMenuType
751 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
752 EFI_DEVICE_PATH_PROTOCOL
*AllDevicePath
;
753 EFI_DEVICE_PATH_PROTOCOL
*MultiDevicePath
;
754 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
759 BM_MENU_ENTRY
*NewMenuEntry
;
760 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
761 TYPE_OF_TERMINAL Terminal
;
763 BM_MENU_OPTION
*ConsoleMenu
;
766 AllDevicePath
= NULL
;
768 switch (ConsoleMenuType
) {
769 case BM_CONSOLE_IN_CONTEXT_SELECT
:
770 ConsoleMenu
= &ConsoleInpMenu
;
771 GetEfiGlobalVariable2 (L
"ConIn", (VOID
**)&DevicePath
, NULL
);
772 GetEfiGlobalVariable2 (L
"ConInDev", (VOID
**)&AllDevicePath
, NULL
);
775 case BM_CONSOLE_OUT_CONTEXT_SELECT
:
776 ConsoleMenu
= &ConsoleOutMenu
;
777 GetEfiGlobalVariable2 (L
"ConOut", (VOID
**)&DevicePath
, NULL
);
778 GetEfiGlobalVariable2 (L
"ConOutDev", (VOID
**)&AllDevicePath
, NULL
);
781 case BM_CONSOLE_ERR_CONTEXT_SELECT
:
782 ConsoleMenu
= &ConsoleErrMenu
;
783 GetEfiGlobalVariable2 (L
"ErrOut", (VOID
**)&DevicePath
, NULL
);
784 GetEfiGlobalVariable2 (L
"ErrOutDev", (VOID
**)&AllDevicePath
, NULL
);
788 return EFI_UNSUPPORTED
;
791 if (NULL
== AllDevicePath
) {
792 return EFI_NOT_FOUND
;
795 InitializeListHead (&ConsoleMenu
->Head
);
797 AllCount
= EfiDevicePathInstanceCount (AllDevicePath
);
798 ConsoleMenu
->MenuNumber
= 0;
800 // Following is menu building up for Console Devices selected.
802 MultiDevicePath
= AllDevicePath
;
804 for (Index
= 0; Index
< AllCount
; Index
++) {
805 DevicePathInst
= GetNextDevicePathInstance (&MultiDevicePath
, &Size
);
807 NewMenuEntry
= BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT
);
808 if (NULL
== NewMenuEntry
) {
809 return EFI_OUT_OF_RESOURCES
;
812 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
813 NewMenuEntry
->OptionNumber
= Index2
;
815 NewConsoleContext
->DevicePath
= DuplicateDevicePath (DevicePathInst
);
816 ASSERT (NewConsoleContext
->DevicePath
!= NULL
);
817 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (NewConsoleContext
->DevicePath
);
818 if (NULL
== NewMenuEntry
->DisplayString
) {
819 NewMenuEntry
->DisplayString
= UiDevicePathToStr (NewConsoleContext
->DevicePath
);
822 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
824 if (NULL
== NewMenuEntry
->HelpString
) {
825 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
827 NewMenuEntry
->HelpStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->HelpString
, NULL
);
830 NewConsoleContext
->IsTerminal
= IsTerminalDevicePath (
831 NewConsoleContext
->DevicePath
,
836 NewConsoleContext
->IsActive
= MatchDevicePaths (
838 NewConsoleContext
->DevicePath
841 if (NewConsoleContext
->IsTerminal
) {
842 BOpt_DestroyMenuEntry (NewMenuEntry
);
845 ConsoleMenu
->MenuNumber
++;
846 InsertTailList (&ConsoleMenu
->Head
, &NewMenuEntry
->Link
);
854 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
856 @retval EFI_SUCCESS The function always complete successfully.
864 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT
);
865 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT
);
866 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT
);
871 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
873 @retval EFI_SUCCESS The function always complete successfully.
880 BOpt_FreeMenu (&ConsoleOutMenu
);
881 BOpt_FreeMenu (&ConsoleInpMenu
);
882 BOpt_FreeMenu (&ConsoleErrMenu
);
883 BOpt_FreeMenu (&TerminalMenu
);
888 Test whether DevicePath is a valid Terminal
891 @param DevicePath DevicePath to be checked
892 @param Termi If DevicePath is valid Terminal, terminal type is returned.
893 @param Com If DevicePath is valid Terminal, Com Port type is returned.
895 @retval TRUE If DevicePath point to a Terminal.
896 @retval FALSE If DevicePath does not point to a Terminal.
900 IsTerminalDevicePath (
901 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
902 OUT TYPE_OF_TERMINAL
*Termi
,
907 EFI_DEVICE_PATH_PROTOCOL
*Node
;
908 VENDOR_DEVICE_PATH
*Vendor
;
909 UART_DEVICE_PATH
*Uart
;
910 ACPI_HID_DEVICE_PATH
*Acpi
;
918 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
920 // Vendor points to the node before the End node
922 Vendor
= (VENDOR_DEVICE_PATH
*)Node
;
924 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
925 Uart
= (UART_DEVICE_PATH
*)Node
;
930 // Acpi points to the node before the UART node
932 Acpi
= (ACPI_HID_DEVICE_PATH
*)Node
;
936 if ((Vendor
== NULL
) ||
937 (DevicePathType (Vendor
) != MESSAGING_DEVICE_PATH
) ||
938 (DevicePathSubType (Vendor
) != MSG_VENDOR_DP
) ||
945 // There are 9 kinds of Terminal types
946 // check to see whether this devicepath
947 // is one of that type
949 for (Index
= 0; Index
< ARRAY_SIZE (TerminalTypeGuid
); Index
++) {
950 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[Index
])) {
957 if (Index
== ARRAY_SIZE (TerminalTypeGuid
)) {
965 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
966 CopyMem (Com
, &Acpi
->UID
, sizeof (UINT32
));
975 Get mode number according to column and row
977 @param CallbackData The BMM context data.
981 IN BMM_CALLBACK_DATA
*CallbackData
991 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
993 ConOut
= gST
->ConOut
;
994 MaxMode
= (UINTN
)(ConOut
->Mode
->MaxMode
);
996 CurrentCol
= PcdGet32 (PcdSetupConOutColumn
);
997 CurrentRow
= PcdGet32 (PcdSetupConOutRow
);
998 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
999 Status
= ConOut
->QueryMode (ConOut
, Mode
, &Col
, &Row
);
1000 if (!EFI_ERROR (Status
)) {
1001 if ((CurrentCol
== Col
) && (CurrentRow
== Row
)) {
1002 CallbackData
->BmmFakeNvData
.ConsoleOutMode
= (UINT16
)Mode
;
1011 Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]
1012 in BMM_FAKE_NV_DATA structure.
1014 @param CallbackData The BMM context data.
1019 IN BMM_CALLBACK_DATA
*CallbackData
1023 BM_MENU_ENTRY
*NewMenuEntry
;
1025 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1026 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1028 ASSERT (CallbackData
!= NULL
);
1030 ConInCheck
= &CallbackData
->BmmFakeNvData
.ConsoleInCheck
[0];
1031 for (Index
= 0; ((Index
< ConsoleInpMenu
.MenuNumber
) && \
1032 (Index
< MAX_MENU_NUMBER
)); Index
++)
1034 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
1035 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
1036 ConInCheck
[Index
] = NewConsoleContext
->IsActive
;
1039 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
1040 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
1041 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
1042 ASSERT (Index
+ ConsoleInpMenu
.MenuNumber
< MAX_MENU_NUMBER
);
1043 ConInCheck
[Index
+ ConsoleInpMenu
.MenuNumber
] = NewTerminalContext
->IsConIn
;
1049 Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]
1050 in BMM_FAKE_NV_DATA structure.
1052 @param CallbackData The BMM context data.
1056 GetConsoleOutCheck (
1057 IN BMM_CALLBACK_DATA
*CallbackData
1061 BM_MENU_ENTRY
*NewMenuEntry
;
1063 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1064 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1066 ASSERT (CallbackData
!= NULL
);
1067 ConOutCheck
= &CallbackData
->BmmFakeNvData
.ConsoleOutCheck
[0];
1068 for (Index
= 0; ((Index
< ConsoleOutMenu
.MenuNumber
) && \
1069 (Index
< MAX_MENU_NUMBER
)); Index
++)
1071 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
1072 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
1073 ConOutCheck
[Index
] = NewConsoleContext
->IsActive
;
1076 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
1077 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
1078 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
1079 ASSERT (Index
+ ConsoleOutMenu
.MenuNumber
< MAX_MENU_NUMBER
);
1080 ConOutCheck
[Index
+ ConsoleOutMenu
.MenuNumber
] = NewTerminalContext
->IsConOut
;
1086 Initialize standard error output device check box to ConsoleErrCheck[MAX_MENU_NUMBER]
1087 in BMM_FAKE_NV_DATA structure.
1089 @param CallbackData The BMM context data.
1093 GetConsoleErrCheck (
1094 IN BMM_CALLBACK_DATA
*CallbackData
1098 BM_MENU_ENTRY
*NewMenuEntry
;
1100 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1101 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1103 ASSERT (CallbackData
!= NULL
);
1104 ConErrCheck
= &CallbackData
->BmmFakeNvData
.ConsoleErrCheck
[0];
1105 for (Index
= 0; ((Index
< ConsoleErrMenu
.MenuNumber
) && \
1106 (Index
< MAX_MENU_NUMBER
)); Index
++)
1108 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
1109 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*)NewMenuEntry
->VariableContext
;
1110 ConErrCheck
[Index
] = NewConsoleContext
->IsActive
;
1113 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
1114 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
1115 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
1116 ASSERT (Index
+ ConsoleErrMenu
.MenuNumber
< MAX_MENU_NUMBER
);
1117 ConErrCheck
[Index
+ ConsoleErrMenu
.MenuNumber
] = NewTerminalContext
->IsStdErr
;
1123 Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)
1124 to BMM_FAKE_NV_DATA structure.
1126 @param CallbackData The BMM context data.
1130 GetTerminalAttribute (
1131 IN BMM_CALLBACK_DATA
*CallbackData
1134 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
1135 BM_MENU_ENTRY
*NewMenuEntry
;
1136 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1137 UINT16 TerminalIndex
;
1138 UINT8 AttributeIndex
;
1140 ASSERT (CallbackData
!= NULL
);
1142 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
1143 for (TerminalIndex
= 0; ((TerminalIndex
< TerminalMenu
.MenuNumber
) && \
1144 (TerminalIndex
< MAX_MENU_NUMBER
)); TerminalIndex
++)
1146 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalIndex
);
1147 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*)NewMenuEntry
->VariableContext
;
1148 for (AttributeIndex
= 0; AttributeIndex
< sizeof (BaudRateList
) / sizeof (BaudRateList
[0]); AttributeIndex
++) {
1149 if (NewTerminalContext
->BaudRate
== (UINT64
)(BaudRateList
[AttributeIndex
].Value
)) {
1150 NewTerminalContext
->BaudRateIndex
= AttributeIndex
;
1155 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (DataBitsList
); AttributeIndex
++) {
1156 if (NewTerminalContext
->DataBits
== (UINT64
)(DataBitsList
[AttributeIndex
].Value
)) {
1157 NewTerminalContext
->DataBitsIndex
= AttributeIndex
;
1162 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (ParityList
); AttributeIndex
++) {
1163 if (NewTerminalContext
->Parity
== (UINT64
)(ParityList
[AttributeIndex
].Value
)) {
1164 NewTerminalContext
->ParityIndex
= AttributeIndex
;
1169 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (StopBitsList
); AttributeIndex
++) {
1170 if (NewTerminalContext
->StopBits
== (UINT64
)(StopBitsList
[AttributeIndex
].Value
)) {
1171 NewTerminalContext
->StopBitsIndex
= AttributeIndex
;
1176 CurrentFakeNVMap
->COMBaudRate
[TerminalIndex
] = NewTerminalContext
->BaudRateIndex
;
1177 CurrentFakeNVMap
->COMDataRate
[TerminalIndex
] = NewTerminalContext
->DataBitsIndex
;
1178 CurrentFakeNVMap
->COMStopBits
[TerminalIndex
] = NewTerminalContext
->StopBitsIndex
;
1179 CurrentFakeNVMap
->COMParity
[TerminalIndex
] = NewTerminalContext
->ParityIndex
;
1180 CurrentFakeNVMap
->COMTerminalType
[TerminalIndex
] = NewTerminalContext
->TerminalType
;
1181 CurrentFakeNVMap
->COMFlowControl
[TerminalIndex
] = NewTerminalContext
->FlowControl
;