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
,
196 Node1
= NextDevicePathNode (Node1
);
205 Node
= NextDevicePathNode (Node
);
213 Update the device path that describing a terminal device
214 based on the new BaudRate, Data Bits, parity and Stop Bits
217 @param DevicePath terminal device's path
221 ChangeVariableDevicePath (
222 IN OUT EFI_DEVICE_PATH_PROTOCOL
*DevicePath
225 EFI_DEVICE_PATH_PROTOCOL
*Node
;
226 ACPI_HID_DEVICE_PATH
*Acpi
;
227 UART_DEVICE_PATH
*Uart
;
229 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
230 BM_MENU_ENTRY
*NewMenuEntry
;
233 Node
= NextDevicePathNode (Node
);
235 while (!IsDevicePathEnd (Node
)) {
236 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
237 if (IsIsaSerialNode (Acpi
)) {
238 CopyMem (&Com
, &Acpi
->UID
, sizeof (UINT32
));
241 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
242 NewMenuEntry
= BOpt_GetMenuEntry (
246 ASSERT (NewMenuEntry
!= NULL
);
247 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
248 Uart
= (UART_DEVICE_PATH
*) Node
;
251 &NewTerminalContext
->BaudRate
,
257 &NewTerminalContext
->DataBits
,
263 &NewTerminalContext
->Parity
,
269 &NewTerminalContext
->StopBits
,
274 Node
= NextDevicePathNode (Node
);
279 Retrieve ACPI UID of UART from device path
281 @param Handle The handle for the UART device.
282 @param AcpiUid The ACPI UID on output.
284 @retval TRUE Find valid UID from device path
285 @retval FALSE Can't find
290 IN EFI_HANDLE Handle
,
291 IN OUT UINT32
*AcpiUid
295 ACPI_HID_DEVICE_PATH
*Acpi
;
296 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
298 Status
= gBS
->HandleProtocol (
300 &gEfiDevicePathProtocolGuid
,
301 (VOID
**) &DevicePath
303 if (EFI_ERROR (Status
)) {
308 for (; !IsDevicePathEnd (DevicePath
); DevicePath
= NextDevicePathNode (DevicePath
)) {
309 if ((DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (DevicePath
) == MSG_UART_DP
)) {
313 // Acpi points to the node before the Uart node
315 Acpi
= (ACPI_HID_DEVICE_PATH
*) DevicePath
;
318 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
319 if (AcpiUid
!= NULL
) {
320 CopyMem (AcpiUid
, &Acpi
->UID
, sizeof (UINT32
));
329 Sort Uart handles array with Acpi->UID from low to high.
331 @param Handles EFI_SERIAL_IO_PROTOCOL handle buffer
332 @param NoHandles EFI_SERIAL_IO_PROTOCOL handle count
336 IN EFI_HANDLE
*Handles
,
346 EFI_HANDLE TempHandle
;
348 for (Index1
= 0; Index1
< NoHandles
-1; Index1
++) {
349 if (!RetrieveUartUid (Handles
[Index1
], &AcpiUid1
)) {
352 TempHandle
= Handles
[Index1
];
354 TempAcpiUid
= AcpiUid1
;
356 for (Index2
= Index1
+1; Index2
< NoHandles
; Index2
++) {
357 if (!RetrieveUartUid (Handles
[Index2
], &AcpiUid2
)) {
360 if (AcpiUid2
< TempAcpiUid
) {
361 TempAcpiUid
= AcpiUid2
;
362 TempHandle
= Handles
[Index2
];
366 Handles
[Position
] = Handles
[Index1
];
367 Handles
[Index1
] = TempHandle
;
372 Test whether DevicePath is a valid Terminal
375 @param DevicePath DevicePath to be checked
376 @param Termi If DevicePath is valid Terminal, terminal type is returned.
377 @param Com If DevicePath is valid Terminal, Com Port type is returned.
379 @retval TRUE If DevicePath point to a Terminal.
380 @retval FALSE If DevicePath does not point to a Terminal.
384 IsTerminalDevicePath (
385 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
386 OUT TYPE_OF_TERMINAL
*Termi
,
391 Build a list containing all serial devices.
394 @retval EFI_SUCCESS The function complete successfully.
395 @retval EFI_UNSUPPORTED No serial ports present.
408 ACPI_HID_DEVICE_PATH
*Acpi
;
409 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
410 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
411 EFI_DEVICE_PATH_PROTOCOL
*Node
;
412 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
413 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
414 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
415 BM_MENU_ENTRY
*NewMenuEntry
;
416 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
417 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
418 VENDOR_DEVICE_PATH Vendor
;
421 // Get all handles that have SerialIo protocol installed
423 InitializeListHead (&TerminalMenu
.Head
);
424 TerminalMenu
.MenuNumber
= 0;
425 Status
= gBS
->LocateHandleBuffer (
427 &gEfiSerialIoProtocolGuid
,
432 if (EFI_ERROR (Status
)) {
434 // No serial ports present
436 return EFI_UNSUPPORTED
;
440 // Sort Uart handles array with Acpi->UID from low to high
441 // then Terminal menu can be built from low Acpi->UID to high Acpi->UID
443 SortedUartHandle (Handles
, NoHandles
);
445 for (Index
= 0; Index
< NoHandles
; Index
++) {
447 // Check to see whether the handle has DevicePath Protocol installed
449 gBS
->HandleProtocol (
451 &gEfiDevicePathProtocolGuid
,
452 (VOID
**) &DevicePath
456 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
457 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
461 // Acpi points to the node before Uart node
463 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
466 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
467 NewMenuEntry
= BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT
);
468 if (NewMenuEntry
== NULL
) {
470 return EFI_OUT_OF_RESOURCES
;
473 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
474 CopyMem (&NewMenuEntry
->OptionNumber
, &Acpi
->UID
, sizeof (UINT32
));
475 NewTerminalContext
->DevicePath
= DuplicateDevicePath (DevicePath
);
477 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
478 // coz' the misc data for each platform is not correct, actually it's the device path stored in
479 // datahub which is not completed, so a searching for end of device path will enter a
482 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (DevicePath
);
483 if (NULL
== NewMenuEntry
->DisplayString
) {
484 NewMenuEntry
->DisplayString
= UiDevicePathToStr (DevicePath
);
487 NewMenuEntry
->HelpString
= NULL
;
489 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
491 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
493 gBS
->HandleProtocol (
495 &gEfiSerialIoProtocolGuid
,
500 &NewTerminalContext
->BaudRate
,
501 &SerialIo
->Mode
->BaudRate
,
506 &NewTerminalContext
->DataBits
,
507 &SerialIo
->Mode
->DataBits
,
512 &NewTerminalContext
->Parity
,
513 &SerialIo
->Mode
->Parity
,
518 &NewTerminalContext
->StopBits
,
519 &SerialIo
->Mode
->StopBits
,
522 InsertTailList (&TerminalMenu
.Head
, &NewMenuEntry
->Link
);
523 TerminalMenu
.MenuNumber
++;
526 if (Handles
!= NULL
) {
531 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
533 GetEfiGlobalVariable2 (L
"ConOut", (VOID
**)&OutDevicePath
, NULL
);
534 GetEfiGlobalVariable2 (L
"ConIn", (VOID
**)&InpDevicePath
, NULL
);
535 GetEfiGlobalVariable2 (L
"ErrOut", (VOID
**)&ErrDevicePath
, NULL
);
536 if (OutDevicePath
!= NULL
) {
537 UpdateComAttributeFromVariable (OutDevicePath
);
540 if (InpDevicePath
!= NULL
) {
541 UpdateComAttributeFromVariable (InpDevicePath
);
544 if (ErrDevicePath
!= NULL
) {
545 UpdateComAttributeFromVariable (ErrDevicePath
);
548 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
549 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
550 if (NULL
== NewMenuEntry
) {
551 return EFI_NOT_FOUND
;
554 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
556 NewTerminalContext
->TerminalType
= 0;
557 NewTerminalContext
->IsConIn
= FALSE
;
558 NewTerminalContext
->IsConOut
= FALSE
;
559 NewTerminalContext
->IsStdErr
= FALSE
;
561 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
562 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
564 for (Index2
= 0; Index2
< (ARRAY_SIZE (TerminalTypeGuid
)); Index2
++) {
565 CopyMem (&Vendor
.Guid
, &TerminalTypeGuid
[Index2
], sizeof (EFI_GUID
));
566 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
567 NewDevicePath
= AppendDevicePathNode (
568 NewTerminalContext
->DevicePath
,
569 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
571 if (NewMenuEntry
->HelpString
!= NULL
) {
572 FreePool (NewMenuEntry
->HelpString
);
575 // NewMenuEntry->HelpString = UiDevicePathToStr (NewDevicePath);
576 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
578 NewMenuEntry
->HelpString
= NULL
;
580 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
582 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
584 if (MatchDevicePaths (OutDevicePath
, NewDevicePath
)) {
585 NewTerminalContext
->IsConOut
= TRUE
;
586 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
589 if (MatchDevicePaths (InpDevicePath
, NewDevicePath
)) {
590 NewTerminalContext
->IsConIn
= TRUE
;
591 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
594 if (MatchDevicePaths (ErrDevicePath
, NewDevicePath
)) {
595 NewTerminalContext
->IsStdErr
= TRUE
;
596 NewTerminalContext
->TerminalType
= (UINT8
) Index2
;
605 Update Com Ports attributes from DevicePath
607 @param DevicePath DevicePath that contains Com ports
609 @retval EFI_SUCCESS The update is successful.
610 @retval EFI_NOT_FOUND Can not find specific menu entry
613 UpdateComAttributeFromVariable (
614 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
617 EFI_DEVICE_PATH_PROTOCOL
*Node
;
618 EFI_DEVICE_PATH_PROTOCOL
*SerialNode
;
619 ACPI_HID_DEVICE_PATH
*Acpi
;
620 UART_DEVICE_PATH
*Uart
;
621 UART_DEVICE_PATH
*Uart1
;
622 UINTN TerminalNumber
;
623 BM_MENU_ENTRY
*NewMenuEntry
;
624 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
628 Node
= NextDevicePathNode (Node
);
630 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
631 while (!IsDevicePathEnd (Node
)) {
632 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
633 if (IsIsaSerialNode (Acpi
)) {
634 CopyMem (&TerminalNumber
, &Acpi
->UID
, sizeof (UINT32
));
637 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
638 Uart
= (UART_DEVICE_PATH
*) Node
;
639 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalNumber
);
640 if (NULL
== NewMenuEntry
) {
641 return EFI_NOT_FOUND
;
644 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
646 &NewTerminalContext
->BaudRate
,
652 &NewTerminalContext
->DataBits
,
658 &NewTerminalContext
->Parity
,
664 &NewTerminalContext
->StopBits
,
669 SerialNode
= NewTerminalContext
->DevicePath
;
670 SerialNode
= NextDevicePathNode (SerialNode
);
671 while (!IsDevicePathEnd (SerialNode
)) {
672 if ((DevicePathType (SerialNode
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (SerialNode
) == MSG_UART_DP
)) {
674 // Update following device paths according to
675 // previous acquired uart attributes
677 Uart1
= (UART_DEVICE_PATH
*) SerialNode
;
680 &NewTerminalContext
->BaudRate
,
686 &NewTerminalContext
->DataBits
,
691 &NewTerminalContext
->Parity
,
696 &NewTerminalContext
->StopBits
,
703 SerialNode
= NextDevicePathNode (SerialNode
);
710 Node
= NextDevicePathNode (Node
);
721 Build up Console Menu based on types passed in. The type can
722 be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
723 and BM_CONSOLE_ERR_CONTEXT_SELECT.
725 @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
726 and BM_CONSOLE_ERR_CONTEXT_SELECT.
728 @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
729 @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev",
730 "ConInDev" or "ConErrDev" doesn't exists.
731 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
732 @retval EFI_SUCCESS Function completes successfully.
737 IN UINTN ConsoleMenuType
740 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
741 EFI_DEVICE_PATH_PROTOCOL
*AllDevicePath
;
742 EFI_DEVICE_PATH_PROTOCOL
*MultiDevicePath
;
743 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
748 BM_MENU_ENTRY
*NewMenuEntry
;
749 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
750 TYPE_OF_TERMINAL Terminal
;
752 BM_MENU_OPTION
*ConsoleMenu
;
755 AllDevicePath
= NULL
;
757 switch (ConsoleMenuType
) {
758 case BM_CONSOLE_IN_CONTEXT_SELECT
:
759 ConsoleMenu
= &ConsoleInpMenu
;
760 GetEfiGlobalVariable2 (L
"ConIn", (VOID
**)&DevicePath
, NULL
);
761 GetEfiGlobalVariable2 (L
"ConInDev", (VOID
**)&AllDevicePath
, NULL
);
764 case BM_CONSOLE_OUT_CONTEXT_SELECT
:
765 ConsoleMenu
= &ConsoleOutMenu
;
766 GetEfiGlobalVariable2 (L
"ConOut", (VOID
**)&DevicePath
, NULL
);
767 GetEfiGlobalVariable2 (L
"ConOutDev", (VOID
**)&AllDevicePath
, NULL
);
770 case BM_CONSOLE_ERR_CONTEXT_SELECT
:
771 ConsoleMenu
= &ConsoleErrMenu
;
772 GetEfiGlobalVariable2 (L
"ErrOut", (VOID
**)&DevicePath
, NULL
);
773 GetEfiGlobalVariable2 (L
"ErrOutDev", (VOID
**)&AllDevicePath
, NULL
);
777 return EFI_UNSUPPORTED
;
780 if (NULL
== AllDevicePath
) {
781 return EFI_NOT_FOUND
;
784 InitializeListHead (&ConsoleMenu
->Head
);
786 AllCount
= EfiDevicePathInstanceCount (AllDevicePath
);
787 ConsoleMenu
->MenuNumber
= 0;
789 // Following is menu building up for Console Devices selected.
791 MultiDevicePath
= AllDevicePath
;
793 for (Index
= 0; Index
< AllCount
; Index
++) {
794 DevicePathInst
= GetNextDevicePathInstance (&MultiDevicePath
, &Size
);
796 NewMenuEntry
= BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT
);
797 if (NULL
== NewMenuEntry
) {
798 return EFI_OUT_OF_RESOURCES
;
801 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
802 NewMenuEntry
->OptionNumber
= Index2
;
804 NewConsoleContext
->DevicePath
= DuplicateDevicePath (DevicePathInst
);
805 ASSERT (NewConsoleContext
->DevicePath
!= NULL
);
806 NewMenuEntry
->DisplayString
= EfiLibStrFromDatahub (NewConsoleContext
->DevicePath
);
807 if (NULL
== NewMenuEntry
->DisplayString
) {
808 NewMenuEntry
->DisplayString
= UiDevicePathToStr (NewConsoleContext
->DevicePath
);
811 NewMenuEntry
->DisplayStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->DisplayString
, NULL
);
813 if (NULL
== NewMenuEntry
->HelpString
) {
814 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
816 NewMenuEntry
->HelpStringToken
= HiiSetString (mBmmCallbackInfo
->BmmHiiHandle
, 0, NewMenuEntry
->HelpString
, NULL
);
819 NewConsoleContext
->IsTerminal
= IsTerminalDevicePath (
820 NewConsoleContext
->DevicePath
,
825 NewConsoleContext
->IsActive
= MatchDevicePaths (
827 NewConsoleContext
->DevicePath
830 if (NewConsoleContext
->IsTerminal
) {
831 BOpt_DestroyMenuEntry (NewMenuEntry
);
834 ConsoleMenu
->MenuNumber
++;
835 InsertTailList (&ConsoleMenu
->Head
, &NewMenuEntry
->Link
);
843 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
845 @retval EFI_SUCCESS The function always complete successfully.
853 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT
);
854 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT
);
855 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT
);
860 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
862 @retval EFI_SUCCESS The function always complete successfully.
869 BOpt_FreeMenu (&ConsoleOutMenu
);
870 BOpt_FreeMenu (&ConsoleInpMenu
);
871 BOpt_FreeMenu (&ConsoleErrMenu
);
872 BOpt_FreeMenu (&TerminalMenu
);
877 Test whether DevicePath is a valid Terminal
880 @param DevicePath DevicePath to be checked
881 @param Termi If DevicePath is valid Terminal, terminal type is returned.
882 @param Com If DevicePath is valid Terminal, Com Port type is returned.
884 @retval TRUE If DevicePath point to a Terminal.
885 @retval FALSE If DevicePath does not point to a Terminal.
889 IsTerminalDevicePath (
890 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
891 OUT TYPE_OF_TERMINAL
*Termi
,
896 EFI_DEVICE_PATH_PROTOCOL
*Node
;
897 VENDOR_DEVICE_PATH
*Vendor
;
898 UART_DEVICE_PATH
*Uart
;
899 ACPI_HID_DEVICE_PATH
*Acpi
;
906 for (Node
= DevicePath
; !IsDevicePathEnd (Node
); Node
= NextDevicePathNode (Node
)) {
908 // Vendor points to the node before the End node
910 Vendor
= (VENDOR_DEVICE_PATH
*) Node
;
912 if ((DevicePathType (Node
) == MESSAGING_DEVICE_PATH
) && (DevicePathSubType (Node
) == MSG_UART_DP
)) {
913 Uart
= (UART_DEVICE_PATH
*) Node
;
918 // Acpi points to the node before the UART node
920 Acpi
= (ACPI_HID_DEVICE_PATH
*) Node
;
924 if (Vendor
== NULL
||
925 DevicePathType (Vendor
) != MESSAGING_DEVICE_PATH
||
926 DevicePathSubType (Vendor
) != MSG_VENDOR_DP
||
932 // There are four kinds of Terminal types
933 // check to see whether this devicepath
934 // is one of that type
936 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[0])) {
937 *Termi
= TerminalTypePcAnsi
;
940 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[1])) {
941 *Termi
= TerminalTypeVt100
;
944 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[2])) {
945 *Termi
= TerminalTypeVt100Plus
;
948 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[3])) {
949 *Termi
= TerminalTypeVtUtf8
;
952 if (CompareGuid (&Vendor
->Guid
, &TerminalTypeGuid
[4])) {
953 *Termi
= TerminalTypeTtyTerm
;
967 if ((Acpi
!= NULL
) && IsIsaSerialNode (Acpi
)) {
968 CopyMem (Com
, &Acpi
->UID
, sizeof (UINT32
));
977 Get mode number according to column and row
979 @param CallbackData The BMM context data.
983 IN BMM_CALLBACK_DATA
*CallbackData
993 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
995 ConOut
= gST
->ConOut
;
996 MaxMode
= (UINTN
) (ConOut
->Mode
->MaxMode
);
998 CurrentCol
= PcdGet32 (PcdSetupConOutColumn
);
999 CurrentRow
= PcdGet32 (PcdSetupConOutRow
);
1000 for (Mode
= 0; Mode
< MaxMode
; Mode
++) {
1001 Status
= ConOut
->QueryMode (ConOut
, Mode
, &Col
, &Row
);
1002 if (!EFI_ERROR(Status
)) {
1003 if (CurrentCol
== Col
&& CurrentRow
== Row
) {
1004 CallbackData
->BmmFakeNvData
.ConsoleOutMode
= (UINT16
) Mode
;
1013 Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]
1014 in BMM_FAKE_NV_DATA structure.
1016 @param CallbackData The BMM context data.
1021 IN BMM_CALLBACK_DATA
*CallbackData
1025 BM_MENU_ENTRY
*NewMenuEntry
;
1027 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1028 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1030 ASSERT (CallbackData
!= NULL
);
1032 ConInCheck
= &CallbackData
->BmmFakeNvData
.ConsoleInCheck
[0];
1033 for (Index
= 0; ((Index
< ConsoleInpMenu
.MenuNumber
) && \
1034 (Index
< MAX_MENU_NUMBER
)) ; Index
++) {
1035 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleInpMenu
, Index
);
1036 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1037 ConInCheck
[Index
] = NewConsoleContext
->IsActive
;
1040 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
1041 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
1042 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
1043 ASSERT (Index
+ ConsoleInpMenu
.MenuNumber
< MAX_MENU_NUMBER
);
1044 ConInCheck
[Index
+ ConsoleInpMenu
.MenuNumber
] = NewTerminalContext
->IsConIn
;
1050 Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]
1051 in BMM_FAKE_NV_DATA structure.
1053 @param CallbackData The BMM context data.
1057 GetConsoleOutCheck (
1058 IN BMM_CALLBACK_DATA
*CallbackData
1062 BM_MENU_ENTRY
*NewMenuEntry
;
1064 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
1065 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1067 ASSERT (CallbackData
!= NULL
);
1068 ConOutCheck
= &CallbackData
->BmmFakeNvData
.ConsoleOutCheck
[0];
1069 for (Index
= 0; ((Index
< ConsoleOutMenu
.MenuNumber
) && \
1070 (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
++) {
1107 NewMenuEntry
= BOpt_GetMenuEntry (&ConsoleErrMenu
, Index
);
1108 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1109 ConErrCheck
[Index
] = NewConsoleContext
->IsActive
;
1112 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
1113 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
1114 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
1115 ASSERT (Index
+ ConsoleErrMenu
.MenuNumber
< MAX_MENU_NUMBER
);
1116 ConErrCheck
[Index
+ ConsoleErrMenu
.MenuNumber
] = NewTerminalContext
->IsStdErr
;
1122 Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)
1123 to BMM_FAKE_NV_DATA structure.
1125 @param CallbackData The BMM context data.
1129 GetTerminalAttribute (
1130 IN BMM_CALLBACK_DATA
*CallbackData
1133 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
1134 BM_MENU_ENTRY
*NewMenuEntry
;
1135 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
1136 UINT16 TerminalIndex
;
1137 UINT8 AttributeIndex
;
1139 ASSERT (CallbackData
!= NULL
);
1141 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
1142 for (TerminalIndex
= 0; ((TerminalIndex
< TerminalMenu
.MenuNumber
) && \
1143 (TerminalIndex
< MAX_MENU_NUMBER
)); TerminalIndex
++) {
1144 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, TerminalIndex
);
1145 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
1146 for (AttributeIndex
= 0; AttributeIndex
< sizeof (BaudRateList
) / sizeof (BaudRateList
[0]); AttributeIndex
++) {
1147 if (NewTerminalContext
->BaudRate
== (UINT64
) (BaudRateList
[AttributeIndex
].Value
)) {
1148 NewTerminalContext
->BaudRateIndex
= AttributeIndex
;
1152 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (DataBitsList
); AttributeIndex
++) {
1153 if (NewTerminalContext
->DataBits
== (UINT64
) (DataBitsList
[AttributeIndex
].Value
)) {
1154 NewTerminalContext
->DataBitsIndex
= AttributeIndex
;
1159 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (ParityList
); AttributeIndex
++) {
1160 if (NewTerminalContext
->Parity
== (UINT64
) (ParityList
[AttributeIndex
].Value
)) {
1161 NewTerminalContext
->ParityIndex
= AttributeIndex
;
1166 for (AttributeIndex
= 0; AttributeIndex
< ARRAY_SIZE (StopBitsList
); AttributeIndex
++) {
1167 if (NewTerminalContext
->StopBits
== (UINT64
) (StopBitsList
[AttributeIndex
].Value
)) {
1168 NewTerminalContext
->StopBitsIndex
= AttributeIndex
;
1172 CurrentFakeNVMap
->COMBaudRate
[TerminalIndex
] = NewTerminalContext
->BaudRateIndex
;
1173 CurrentFakeNVMap
->COMDataRate
[TerminalIndex
] = NewTerminalContext
->DataBitsIndex
;
1174 CurrentFakeNVMap
->COMStopBits
[TerminalIndex
] = NewTerminalContext
->StopBitsIndex
;
1175 CurrentFakeNVMap
->COMParity
[TerminalIndex
] = NewTerminalContext
->ParityIndex
;
1176 CurrentFakeNVMap
->COMTerminalType
[TerminalIndex
] = NewTerminalContext
->TerminalType
;
1177 CurrentFakeNVMap
->COMFlowControl
[TerminalIndex
] = NewTerminalContext
->FlowControl
;