2 handles console redirection from boot manager
4 Copyright (c) 2004 - 2015, 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 "BootMaintenanceManager.h"
18 Function compares a device path data structure to that of all the nodes of a
19 second device path instance.
21 @param Multi A pointer to a multi-instance device path data
23 @param Single A pointer to a single-instance device path data
26 @retval TRUE If the Single device path is contained within Multi device path.
27 @retval FALSE The Single device path is not match within Multi device path.
32 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
33 IN EFI_DEVICE_PATH_PROTOCOL
*Single
36 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
37 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
40 if (Multi
== NULL
|| Single
== NULL
) {
45 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
48 // Search for the match of 'Single' in 'Multi'
50 while (DevicePathInst
!= NULL
) {
52 // If the single device path is found in multiple device paths,
55 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
56 FreePool (DevicePathInst
);
60 FreePool (DevicePathInst
);
61 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
68 Check whether the device path node is ISA Serial Node.
70 @param Acpi Device path node to be checked
72 @retval TRUE It's ISA Serial Node.
73 @retval FALSE It's NOT ISA Serial Node.
78 IN ACPI_HID_DEVICE_PATH
*Acpi
82 (DevicePathType (Acpi
) == ACPI_DEVICE_PATH
) &&
83 (DevicePathSubType (Acpi
) == ACPI_DP
) &&
84 (ReadUnaligned32 (&Acpi
->HID
) == EISA_PNP_ID (0x0501))
89 Update Com Ports attributes from DevicePath
91 @param DevicePath DevicePath that contains Com ports
93 @retval EFI_SUCCESS The update is successful.
97 UpdateComAttributeFromVariable (
98 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
102 Update the multi-instance device path of Terminal Device based on
103 the global TerminalMenu. If ChangeTernimal is TRUE, the terminal
104 device path in the Terminal Device in TerminalMenu is also updated.
106 @param DevicePath The multi-instance device path.
107 @param ChangeTerminal TRUE, then device path in the Terminal Device
108 in TerminalMenu is also updated; FALSE, no update.
110 @return EFI_SUCCESS The function completes successfully.
114 ChangeTerminalDevicePath (
115 IN OUT EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
116 IN BOOLEAN ChangeTerminal
119 EFI_DEVICE_PATH_PROTOCOL
*Node
;
120 EFI_DEVICE_PATH_PROTOCOL
*Node1
;
121 ACPI_HID_DEVICE_PATH
*Acpi
;
122 UART_DEVICE_PATH
*Uart
;
123 UART_DEVICE_PATH
*Uart1
;
125 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
126 BM_MENU_ENTRY
*NewMenuEntry
;
129 Node
= NextDevicePathNode (Node
);
131 while (!IsDevicePathEnd (Node
)) {
132 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
133 if (IsIsaSerialNode (Acpi
)) {
134 CopyMem (&Com
, &Acpi
->UID
, sizeof (UINT32
));
137 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Com
);
139 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
140 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
141 Uart
= (UART_DEVICE_PATH
*) Node
;
144 &NewTerminalContext
->BaudRate
,
150 &NewTerminalContext
->DataBits
,
156 &NewTerminalContext
->Parity
,
162 &NewTerminalContext
->StopBits
,
166 // Change the device path in the ComPort
168 if (ChangeTerminal
) {
169 Node1
= NewTerminalContext
->DevicePath
;
170 Node1
= NextDevicePathNode (Node1
);
171 while (!IsDevicePathEnd (Node1
)) {
172 if ((DevicePathType (Node1
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node1
) == MSG_UART_DP
)) {
173 Uart1
= (UART_DEVICE_PATH
*) Node1
;
176 &NewTerminalContext
->BaudRate
,
182 &NewTerminalContext
->DataBits
,
188 &NewTerminalContext
->Parity
,
194 &NewTerminalContext
->StopBits
,
202 Node1
= NextDevicePathNode (Node1
);
211 Node
= NextDevicePathNode (Node
);
219 Update the device path that describing a terminal device
220 based on the new BaudRate, Data Bits, parity and Stop Bits
223 @param DevicePath terminal device's path
227 ChangeVariableDevicePath (
228 IN OUT EFI_DEVICE_PATH_PROTOCOL
*DevicePath
231 EFI_DEVICE_PATH_PROTOCOL
*Node
;
232 ACPI_HID_DEVICE_PATH
*Acpi
;
233 UART_DEVICE_PATH
*Uart
;
235 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
236 BM_MENU_ENTRY
*NewMenuEntry
;
239 Node
= NextDevicePathNode (Node
);
241 while (!IsDevicePathEnd (Node
)) {
242 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
243 if (IsIsaSerialNode (Acpi
)) {
244 CopyMem (&Com
, &Acpi
->UID
, sizeof (UINT32
));
247 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
248 NewMenuEntry
= BOpt_GetMenuEntry (
252 ASSERT (NewMenuEntry
!= NULL
);
253 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
254 Uart
= (UART_DEVICE_PATH
*) Node
;
257 &NewTerminalContext
->BaudRate
,
263 &NewTerminalContext
->DataBits
,
269 &NewTerminalContext
->Parity
,
275 &NewTerminalContext
->StopBits
,
280 Node
= NextDevicePathNode (Node
);
285 Retrieve ACPI UID of UART from device path
287 @param Handle The handle for the UART device.
288 @param AcpiUid The ACPI UID on output.
290 @retval TRUE Find valid UID from device path
291 @retval FALSE Can't find
296 IN EFI_HANDLE Handle
,
297 IN OUT UINT32
*AcpiUid
301 ACPI_HID_DEVICE_PATH
*Acpi
;
302 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
304 Status
= gBS
->HandleProtocol (
306 &gEfiDevicePathProtocolGuid
,
307 (VOID
**) &DevicePath
309 if (EFI_ERROR (Status
)) {
314 for (; !IsDevicePathEnd (DevicePath
); DevicePath
= NextDevicePathNode (DevicePath
)) {
315 if ((DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (DevicePath
) == MSG_UART_DP
)) {
319 // Acpi points to the node before the Uart node
321 Acpi
= (ACPI_HID_DEVICE_PATH
*) DevicePath
;
324 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
325 if (AcpiUid
!= NULL
) {
326 CopyMem (AcpiUid
, &Acpi
->UID
, sizeof (UINT32
));
335 Sort Uart handles array with Acpi->UID from low to high.
337 @param Handles EFI_SERIAL_IO_PROTOCOL handle buffer
338 @param NoHandles EFI_SERIAL_IO_PROTOCOL handle count
342 IN EFI_HANDLE
*Handles
,
352 EFI_HANDLE TempHandle
;
354 for (Index1
= 0; Index1
< NoHandles
-1; Index1
++) {
355 if (!RetrieveUartUid (Handles
[Index1
], &AcpiUid1
)) {
358 TempHandle
= Handles
[Index1
];
360 TempAcpiUid
= AcpiUid1
;
362 for (Index2
= Index1
+1; Index2
< NoHandles
; Index2
++) {
363 if (!RetrieveUartUid (Handles
[Index2
], &AcpiUid2
)) {
366 if (AcpiUid2
< TempAcpiUid
) {
367 TempAcpiUid
= AcpiUid2
;
368 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
,
458 (VOID
**) &DevicePath
462 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
463 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
467 // Acpi points to the node before Uart node
469 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
472 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
473 NewMenuEntry
= BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT
);
474 if (NewMenuEntry
== NULL
) {
476 return EFI_OUT_OF_RESOURCES
;
479 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
480 CopyMem (&NewMenuEntry
->OptionNumber
, &Acpi
->UID
, sizeof (UINT32
));
481 NewTerminalContext
->DevicePath
= DuplicateDevicePath (DevicePath
);
483 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
484 // coz' the misc data for each platform is not correct, actually it's the device path stored in
485 // datahub which is not completed, so a searching for end of device path will enter a
488 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (DevicePath
);
489 if (NULL
== NewMenuEntry
->DisplayString
) {
490 NewMenuEntry
->DisplayString
= UiDevicePathToStr (DevicePath
);
493 NewMenuEntry
->HelpString
= NULL
;
495 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
497 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
499 gBS
->HandleProtocol (
501 &gEfiSerialIoProtocolGuid
,
506 &NewTerminalContext
->BaudRate
,
507 &SerialIo
->Mode
->BaudRate
,
512 &NewTerminalContext
->DataBits
,
513 &SerialIo
->Mode
->DataBits
,
518 &NewTerminalContext
->Parity
,
519 &SerialIo
->Mode
->Parity
,
524 &NewTerminalContext
->StopBits
,
525 &SerialIo
->Mode
->StopBits
,
528 InsertTailList (&TerminalMenu
.Head
, &NewMenuEntry
->Link
);
529 TerminalMenu
.MenuNumber
++;
532 if (Handles
!= NULL
) {
537 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
539 GetEfiGlobalVariable2 (L
"ConOut", (VOID
**)&OutDevicePath
, NULL
);
540 GetEfiGlobalVariable2 (L
"ConIn", (VOID
**)&InpDevicePath
, NULL
);
541 GetEfiGlobalVariable2 (L
"ErrOut", (VOID
**)&ErrDevicePath
, NULL
);
542 if (OutDevicePath
!= NULL
) {
543 UpdateComAttributeFromVariable (OutDevicePath
);
546 if (InpDevicePath
!= NULL
) {
547 UpdateComAttributeFromVariable (InpDevicePath
);
550 if (ErrDevicePath
!= NULL
) {
551 UpdateComAttributeFromVariable (ErrDevicePath
);
554 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
555 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
556 if (NULL
== NewMenuEntry
) {
557 return EFI_NOT_FOUND
;
560 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
562 NewTerminalContext
->TerminalType
= 0;
563 NewTerminalContext
->IsConIn
= FALSE
;
564 NewTerminalContext
->IsConOut
= FALSE
;
565 NewTerminalContext
->IsStdErr
= FALSE
;
567 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
568 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
570 for (Index2
= 0; Index2
< (ARRAY_SIZE (TerminalTypeGuid
)); Index2
++) {
571 CopyMem (&Vendor
.Guid
, &TerminalTypeGuid
[Index2
], sizeof (EFI_GUID
));
572 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
573 NewDevicePath
= AppendDevicePathNode (
574 NewTerminalContext
->DevicePath
,
575 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
577 if (NewMenuEntry
->HelpString
!= NULL
) {
578 FreePool (NewMenuEntry
->HelpString
);
581 // NewMenuEntry->HelpString = UiDevicePathToStr (NewDevicePath);
582 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
584 NewMenuEntry
->HelpString
= NULL
;
586 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
588 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
590 if (MatchDevicePaths (OutDevicePath
, NewDevicePath
)) {
591 NewTerminalContext
->IsConOut
= TRUE
;
592 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
595 if (MatchDevicePaths (InpDevicePath
, NewDevicePath
)) {
596 NewTerminalContext
->IsConIn
= TRUE
;
597 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
600 if (MatchDevicePaths (ErrDevicePath
, NewDevicePath
)) {
601 NewTerminalContext
->IsStdErr
= TRUE
;
602 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
611 Update Com Ports attributes from DevicePath
613 @param DevicePath DevicePath that contains Com ports
615 @retval EFI_SUCCESS The update is successful.
616 @retval EFI_NOT_FOUND Can not find specific menu entry
619 UpdateComAttributeFromVariable (
620 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
623 EFI_DEVICE_PATH_PROTOCOL
*Node
;
624 EFI_DEVICE_PATH_PROTOCOL
*SerialNode
;
625 ACPI_HID_DEVICE_PATH
*Acpi
;
626 UART_DEVICE_PATH
*Uart
;
627 UART_DEVICE_PATH
*Uart1
;
628 UINTN TerminalNumber
;
629 BM_MENU_ENTRY
*NewMenuEntry
;
630 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
634 Node
= NextDevicePathNode (Node
);
636 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
637 while (!IsDevicePathEnd (Node
)) {
638 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
639 if (IsIsaSerialNode (Acpi
)) {
640 CopyMem (&TerminalNumber
, &Acpi
->UID
, sizeof (UINT32
));
643 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
644 Uart
= (UART_DEVICE_PATH
*) Node
;
645 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalNumber
);
646 if (NULL
== NewMenuEntry
) {
647 return EFI_NOT_FOUND
;
650 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
652 &NewTerminalContext
->BaudRate
,
658 &NewTerminalContext
->DataBits
,
664 &NewTerminalContext
->Parity
,
670 &NewTerminalContext
->StopBits
,
675 SerialNode
= NewTerminalContext
->DevicePath
;
676 SerialNode
= NextDevicePathNode (SerialNode
);
677 while (!IsDevicePathEnd (SerialNode
)) {
678 if ((DevicePathType (SerialNode
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (SerialNode
) == MSG_UART_DP
)) {
680 // Update following device paths according to
681 // previous acquired uart attributes
683 Uart1
= (UART_DEVICE_PATH
*) SerialNode
;
686 &NewTerminalContext
->BaudRate
,
692 &NewTerminalContext
->DataBits
,
697 &NewTerminalContext
->Parity
,
702 &NewTerminalContext
->StopBits
,
709 SerialNode
= NextDevicePathNode (SerialNode
);
716 Node
= NextDevicePathNode (Node
);
727 Build up Console Menu based on types passed in. The type can
728 be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
729 and BM_CONSOLE_ERR_CONTEXT_SELECT.
731 @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
732 and BM_CONSOLE_ERR_CONTEXT_SELECT.
734 @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
735 @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev",
736 "ConInDev" or "ConErrDev" doesn't exists.
737 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
738 @retval EFI_SUCCESS Function completes successfully.
743 IN UINTN ConsoleMenuType
746 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
747 EFI_DEVICE_PATH_PROTOCOL
*AllDevicePath
;
748 EFI_DEVICE_PATH_PROTOCOL
*MultiDevicePath
;
749 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
754 BM_MENU_ENTRY
*NewMenuEntry
;
755 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
756 TYPE_OF_TERMINAL Terminal
;
758 BM_MENU_OPTION
*ConsoleMenu
;
761 AllDevicePath
= NULL
;
763 switch (ConsoleMenuType
) {
764 case BM_CONSOLE_IN_CONTEXT_SELECT
:
765 ConsoleMenu
= &ConsoleInpMenu
;
766 GetEfiGlobalVariable2 (L
"ConIn", (VOID
**)&DevicePath
, NULL
);
767 GetEfiGlobalVariable2 (L
"ConInDev", (VOID
**)&AllDevicePath
, NULL
);
770 case BM_CONSOLE_OUT_CONTEXT_SELECT
:
771 ConsoleMenu
= &ConsoleOutMenu
;
772 GetEfiGlobalVariable2 (L
"ConOut", (VOID
**)&DevicePath
, NULL
);
773 GetEfiGlobalVariable2 (L
"ConOutDev", (VOID
**)&AllDevicePath
, NULL
);
776 case BM_CONSOLE_ERR_CONTEXT_SELECT
:
777 ConsoleMenu
= &ConsoleErrMenu
;
778 GetEfiGlobalVariable2 (L
"ErrOut", (VOID
**)&DevicePath
, NULL
);
779 GetEfiGlobalVariable2 (L
"ErrOutDev", (VOID
**)&AllDevicePath
, NULL
);
783 return EFI_UNSUPPORTED
;
786 if (NULL
== AllDevicePath
) {
787 return EFI_NOT_FOUND
;
790 InitializeListHead (&ConsoleMenu
->Head
);
792 AllCount
= EfiDevicePathInstanceCount (AllDevicePath
);
793 ConsoleMenu
->MenuNumber
= 0;
795 // Following is menu building up for Console Devices selected.
797 MultiDevicePath
= AllDevicePath
;
799 for (Index
= 0; Index
< AllCount
; Index
++) {
800 DevicePathInst
= GetNextDevicePathInstance (&MultiDevicePath
, &Size
);
802 NewMenuEntry
= BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT
);
803 if (NULL
== NewMenuEntry
) {
804 return EFI_OUT_OF_RESOURCES
;
807 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
808 NewMenuEntry
->OptionNumber
= Index2
;
810 NewConsoleContext
->DevicePath
= DuplicateDevicePath (DevicePathInst
);
811 ASSERT (NewConsoleContext
->DevicePath
!= NULL
);
812 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (NewConsoleContext
->DevicePath
);
813 if (NULL
== NewMenuEntry
->DisplayString
) {
814 NewMenuEntry
->DisplayString
= UiDevicePathToStr (NewConsoleContext
->DevicePath
);
817 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
819 if (NULL
== NewMenuEntry
->HelpString
) {
820 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
822 NewMenuEntry
->HelpStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->HelpString
, NULL
);
825 NewConsoleContext
->IsTerminal
= IsTerminalDevicePath (
826 NewConsoleContext
->DevicePath
,
831 NewConsoleContext
->IsActive
= MatchDevicePaths (
833 NewConsoleContext
->DevicePath
836 if (NewConsoleContext
->IsTerminal
) {
837 BOpt_DestroyMenuEntry (NewMenuEntry
);
840 ConsoleMenu
->MenuNumber
++;
841 InsertTailList (&ConsoleMenu
->Head
, &NewMenuEntry
->Link
);
849 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
851 @retval EFI_SUCCESS The function always complete successfully.
859 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT
);
860 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT
);
861 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT
);
866 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
868 @retval EFI_SUCCESS The function always complete successfully.
875 BOpt_FreeMenu (&ConsoleOutMenu
);
876 BOpt_FreeMenu (&ConsoleInpMenu
);
877 BOpt_FreeMenu (&ConsoleErrMenu
);
878 BOpt_FreeMenu (&TerminalMenu
);
883 Test whether DevicePath is a valid Terminal
886 @param DevicePath DevicePath to be checked
887 @param Termi If DevicePath is valid Terminal, terminal type is returned.
888 @param Com If DevicePath is valid Terminal, Com Port type is returned.
890 @retval TRUE If DevicePath point to a Terminal.
891 @retval FALSE If DevicePath does not point to a Terminal.
895 IsTerminalDevicePath (
896 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
897 OUT TYPE_OF_TERMINAL
*Termi
,
902 EFI_DEVICE_PATH_PROTOCOL
*Node
;
903 VENDOR_DEVICE_PATH
*Vendor
;
904 UART_DEVICE_PATH
*Uart
;
905 ACPI_HID_DEVICE_PATH
*Acpi
;
912 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
914 // Vendor points to the node before the End node
916 Vendor
= (VENDOR_DEVICE_PATH
*) Node
;
918 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
919 Uart
= (UART_DEVICE_PATH
*) Node
;
924 // Acpi points to the node before the UART node
926 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
930 if (Vendor
== NULL
||
931 DevicePathType (Vendor
) != MESSAGING_DEVICE_PATH
||
932 DevicePathSubType (Vendor
) != MSG_VENDOR_DP
||
938 // There are four kinds of Terminal types
939 // check to see whether this devicepath
940 // is one of that type
942 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[0])) {
943 *Termi
= TerminalTypePcAnsi
;
946 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[1])) {
947 *Termi
= TerminalTypeVt100
;
950 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[2])) {
951 *Termi
= TerminalTypeVt100Plus
;
954 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[3])) {
955 *Termi
= TerminalTypeVtUtf8
;
958 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[4])) {
959 *Termi
= TerminalTypeTtyTerm
;
973 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
974 CopyMem (Com
, &Acpi
->UID
, sizeof (UINT32
));
983 Get mode number according to column and row
985 @param CallbackData The BMM context data.
989 IN BMM_CALLBACK_DATA
*CallbackData
999 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
1001 ConOut
= gST
->ConOut
;
1002 MaxMode
= (UINTN
) (ConOut
->Mode
->MaxMode
);
1004 CurrentCol
= PcdGet32 (PcdSetupConOutColumn
);
1005 CurrentRow
= PcdGet32 (PcdSetupConOutRow
);
1006 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
1007 Status
= ConOut
->QueryMode (ConOut
, Mode
, &Col
, &Row
);
1008 if (!EFI_ERROR(Status
)) {
1009 if (CurrentCol
== Col
&& CurrentRow
== Row
) {
1010 CallbackData
->BmmFakeNvData
.ConsoleOutMode
= (UINT16
) Mode
;
1019 Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]
1020 in BMM_FAKE_NV_DATA structure.
1022 @param CallbackData The BMM context data.
1027 IN BMM_CALLBACK_DATA
*CallbackData
1031 BM_MENU_ENTRY
*NewMenuEntry
;
1033 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1035 ASSERT (CallbackData
!= NULL
);
1037 ConInCheck
= &CallbackData
->BmmFakeNvData
.ConsoleInCheck
[0];
1038 for (Index
= 0; ((Index
< ConsoleInpMenu
.MenuNumber
) && \
1039 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1040 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
1041 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1042 ConInCheck
[Index
] = NewConsoleContext
->IsActive
;
1048 Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]
1049 in BMM_FAKE_NV_DATA structure.
1051 @param CallbackData The BMM context data.
1055 GetConsoleOutCheck (
1056 IN BMM_CALLBACK_DATA
*CallbackData
1060 BM_MENU_ENTRY
*NewMenuEntry
;
1062 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1064 ASSERT (CallbackData
!= NULL
);
1065 ConOutCheck
= &CallbackData
->BmmFakeNvData
.ConsoleOutCheck
[0];
1066 for (Index
= 0; ((Index
< ConsoleOutMenu
.MenuNumber
) && \
1067 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1068 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleOutMenu
, Index
);
1069 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1070 ConOutCheck
[Index
] = NewConsoleContext
->IsActive
;
1076 Initialize standard error output device check box to ConsoleErrCheck[MAX_MENU_NUMBER]
1077 in BMM_FAKE_NV_DATA structure.
1079 @param CallbackData The BMM context data.
1083 GetConsoleErrCheck (
1084 IN BMM_CALLBACK_DATA
*CallbackData
1088 BM_MENU_ENTRY
*NewMenuEntry
;
1090 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1092 ASSERT (CallbackData
!= NULL
);
1093 ConErrCheck
= &CallbackData
->BmmFakeNvData
.ConsoleErrCheck
[0];
1094 for (Index
= 0; ((Index
< ConsoleErrMenu
.MenuNumber
) && \
1095 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1096 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
1097 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1098 ConErrCheck
[Index
] = NewConsoleContext
->IsActive
;
1104 Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)
1105 to BMM_FAKE_NV_DATA structure.
1107 @param CallbackData The BMM context data.
1111 GetTerminalAttribute (
1112 IN BMM_CALLBACK_DATA
*CallbackData
1115 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
1116 BM_MENU_ENTRY
*NewMenuEntry
;
1117 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1118 UINT16 TerminalIndex
;
1119 UINT8 AttributeIndex
;
1121 ASSERT (CallbackData
!= NULL
);
1123 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
1124 for (TerminalIndex
= 0; ((TerminalIndex
< TerminalMenu
.MenuNumber
) && \
1125 (TerminalIndex
< MAX_MENU_NUMBER
)); TerminalIndex
++) {
1126 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalIndex
);
1127 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
1128 for (AttributeIndex
= 0; AttributeIndex
< sizeof (BaudRateList
) / sizeof (BaudRateList
[0]); AttributeIndex
++) {
1129 if (NewTerminalContext
->BaudRate
== (UINT64
) (BaudRateList
[AttributeIndex
].Value
)) {
1130 NewTerminalContext
->BaudRateIndex
= AttributeIndex
;
1134 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (DataBitsList
); AttributeIndex
++) {
1135 if (NewTerminalContext
->DataBits
== (UINT64
) (DataBitsList
[AttributeIndex
].Value
)) {
1136 NewTerminalContext
->DataBitsIndex
= AttributeIndex
;
1141 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (ParityList
); AttributeIndex
++) {
1142 if (NewTerminalContext
->Parity
== (UINT64
) (ParityList
[AttributeIndex
].Value
)) {
1143 NewTerminalContext
->ParityIndex
= AttributeIndex
;
1148 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (StopBitsList
); AttributeIndex
++) {
1149 if (NewTerminalContext
->StopBits
== (UINT64
) (StopBitsList
[AttributeIndex
].Value
)) {
1150 NewTerminalContext
->StopBitsIndex
= AttributeIndex
;
1154 CurrentFakeNVMap
->COMBaudRate
[TerminalIndex
] = NewTerminalContext
->BaudRateIndex
;
1155 CurrentFakeNVMap
->COMDataRate
[TerminalIndex
] = NewTerminalContext
->DataBitsIndex
;
1156 CurrentFakeNVMap
->COMStopBits
[TerminalIndex
] = NewTerminalContext
->StopBitsIndex
;
1157 CurrentFakeNVMap
->COMParity
[TerminalIndex
] = NewTerminalContext
->ParityIndex
;
1158 CurrentFakeNVMap
->COMTerminalType
[TerminalIndex
] = NewTerminalContext
->TerminalType
;
1159 CurrentFakeNVMap
->COMFlowControl
[TerminalIndex
] = NewTerminalContext
->FlowControl
;