/** Update the device path that describing a terminal device based on the new BaudRate, Data Bits, parity and Stop Bits set. @param DevicePath terminal device's path **/ VOID ChangeVariableDevicePath ( IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { EFI_DEVICE_PATH_PROTOCOL *Node; ACPI_HID_DEVICE_PATH *Acpi; UART_DEVICE_PATH *Uart; UINTN Com; BM_TERMINAL_CONTEXT *NewTerminalContext; BM_MENU_ENTRY *NewMenuEntry; Node = DevicePath; Node = NextDevicePathNode (Node); Com = 0; while (!IsDevicePathEnd (Node)) { Acpi = (ACPI_HID_DEVICE_PATH *) Node; if (IsIsaSerialNode (Acpi)) { CopyMem (&Com, &Acpi->UID, sizeof (UINT32)); } if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { NewMenuEntry = BOpt_GetMenuEntry ( &TerminalMenu, Com ); ASSERT (NewMenuEntry != NULL); NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; Uart = (UART_DEVICE_PATH *) Node; CopyMem ( &Uart->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); CopyMem ( &Uart->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); CopyMem ( &Uart->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); CopyMem ( &Uart->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); } Node = NextDevicePathNode (Node); } }
/** Retrieve ACPI UID of UART from device path @param Handle The handle for the UART device. @param AcpiUid The ACPI UID on output. @retval TRUE Find valid UID from device path @retval FALSE Can't find **/ BOOLEAN RetrieveUartUid ( IN EFI_HANDLE Handle, IN OUT UINT32 *AcpiUid ) { EFI_STATUS Status; ACPI_HID_DEVICE_PATH *Acpi; EFI_DEVICE_PATH_PROTOCOL *DevicePath; Status = gBS->HandleProtocol ( Handle, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath ); if (EFI_ERROR (Status)) { return FALSE; } Acpi = NULL; for (; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) { if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_UART_DP)) { break; } // // Acpi points to the node before the Uart node // Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath; } if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) { if (AcpiUid != NULL) { CopyMem (AcpiUid, &Acpi->UID, sizeof (UINT32)); } return TRUE; } else { return FALSE; } }
/** Update the multi-instance device path of Terminal Device based on the global TerminalMenu. If ChangeTernimal is TRUE, the terminal device path in the Terminal Device in TerminalMenu is also updated. @param DevicePath The multi-instance device path. @param ChangeTerminal TRUE, then device path in the Terminal Device in TerminalMenu is also updated; FALSE, no update. @return EFI_SUCCESS The function completes successfully. **/ EFI_STATUS ChangeTerminalDevicePath ( IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, IN BOOLEAN ChangeTerminal ) { EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *Node1; ACPI_HID_DEVICE_PATH *Acpi; UART_DEVICE_PATH *Uart; UART_DEVICE_PATH *Uart1; UINTN Com; BM_TERMINAL_CONTEXT *NewTerminalContext; BM_MENU_ENTRY *NewMenuEntry; UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode; Node = *DevicePath; Node = NextDevicePathNode (Node); Com = 0; while (!IsDevicePathEnd (Node)) { Acpi = (ACPI_HID_DEVICE_PATH *) Node; if (IsIsaSerialNode (Acpi)) { CopyMem (&Com, &Acpi->UID, sizeof (UINT32)); } NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com); NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { Uart = (UART_DEVICE_PATH *) Node; CopyMem ( &Uart->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); CopyMem ( &Uart->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); CopyMem ( &Uart->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); CopyMem ( &Uart->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Node); if (IsUartFlowControlNode (FlowControlNode)) { FlowControlNode->FlowControlMap = NewTerminalContext->FlowControl; } else { // // Append the Flow control device node when user enable flow control. // if (NewTerminalContext->FlowControl != 0) { mFlowControlDevicePath.FlowControlMap = NewTerminalContext->FlowControl; *DevicePath = AppendDevicePathNode ( *DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) (&mFlowControlDevicePath) ); } } // // Change the device path in the ComPort // if (ChangeTerminal) { Node1 = NewTerminalContext->DevicePath; Node1 = NextDevicePathNode (Node1); while (!IsDevicePathEnd (Node1)) { if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) { Uart1 = (UART_DEVICE_PATH *) Node1; CopyMem ( &Uart1->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); CopyMem ( &Uart1->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); CopyMem ( &Uart1->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); CopyMem ( &Uart1->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); break; } // // end if // Node1 = NextDevicePathNode (Node1); } // // end while // break; } } Node = NextDevicePathNode (Node); } return EFI_SUCCESS; }
/** Test whether DevicePath is a valid Terminal @param DevicePath DevicePath to be checked @param Termi If DevicePath is valid Terminal, terminal type is returned. @param Com If DevicePath is valid Terminal, Com Port type is returned. @retval TRUE If DevicePath point to a Terminal. @retval FALSE If DevicePath does not point to a Terminal. **/ BOOLEAN IsTerminalDevicePath ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT TYPE_OF_TERMINAL *Termi, OUT UINTN *Com ) { BOOLEAN IsTerminal; EFI_DEVICE_PATH_PROTOCOL *Node; VENDOR_DEVICE_PATH *Vendor; UART_DEVICE_PATH *Uart; ACPI_HID_DEVICE_PATH *Acpi; IsTerminal = FALSE; Uart = NULL; Vendor = NULL; Acpi = NULL; for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) { // // Vendor points to the node before the End node // Vendor = (VENDOR_DEVICE_PATH *) Node; if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { Uart = (UART_DEVICE_PATH *) Node; } if (Uart == NULL) { // // Acpi points to the node before the UART node // Acpi = (ACPI_HID_DEVICE_PATH *) Node; } } if (Vendor == NULL || DevicePathType (Vendor) != MESSAGING_DEVICE_PATH || DevicePathSubType (Vendor) != MSG_VENDOR_DP || Uart == NULL) { return FALSE; } // // There are four kinds of Terminal types // check to see whether this devicepath // is one of that type // if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[0])) { *Termi = TerminalTypePcAnsi; IsTerminal = TRUE; } else { if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[1])) { *Termi = TerminalTypeVt100; IsTerminal = TRUE; } else { if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[2])) { *Termi = TerminalTypeVt100Plus; IsTerminal = TRUE; } else { if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[3])) { *Termi = TerminalTypeVtUtf8; IsTerminal = TRUE; } else { IsTerminal = FALSE; } } } } if (!IsTerminal) { return FALSE; } if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) { CopyMem (Com, &Acpi->UID, sizeof (UINT32)); } else { return FALSE; } return TRUE; }
/** Update Com Ports attributes from DevicePath @param DevicePath DevicePath that contains Com ports @retval EFI_SUCCESS The update is successful. @retval EFI_NOT_FOUND Can not find specific menu entry **/ EFI_STATUS UpdateComAttributeFromVariable ( EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *SerialNode; ACPI_HID_DEVICE_PATH *Acpi; UART_DEVICE_PATH *Uart; UART_DEVICE_PATH *Uart1; UINTN TerminalNumber; BM_MENU_ENTRY *NewMenuEntry; BM_TERMINAL_CONTEXT *NewTerminalContext; UINTN Index; UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode; BOOLEAN HasFlowControlNode; HasFlowControlNode = FALSE; Node = DevicePath; Node = NextDevicePathNode (Node); TerminalNumber = 0; for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { while (!IsDevicePathEnd (Node)) { Acpi = (ACPI_HID_DEVICE_PATH *) Node; if (IsIsaSerialNode (Acpi)) { CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32)); } if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { Uart = (UART_DEVICE_PATH *) Node; NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber); if (NULL == NewMenuEntry) { return EFI_NOT_FOUND; } NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; CopyMem ( &NewTerminalContext->BaudRate, &Uart->BaudRate, sizeof (UINT64) ); CopyMem ( &NewTerminalContext->DataBits, &Uart->DataBits, sizeof (UINT8) ); CopyMem ( &NewTerminalContext->Parity, &Uart->Parity, sizeof (UINT8) ); CopyMem ( &NewTerminalContext->StopBits, &Uart->StopBits, sizeof (UINT8) ); FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Node); if (IsUartFlowControlNode (FlowControlNode)) { HasFlowControlNode = TRUE; NewTerminalContext->FlowControl = (UINT8) ReadUnaligned32 (&FlowControlNode->FlowControlMap); } else if (NewTerminalContext->FlowControl != 0) { // // No Flow Control device path node, assumption no Flow control // NewTerminalContext->FlowControl = 0; } SerialNode = NewTerminalContext->DevicePath; SerialNode = NextDevicePathNode (SerialNode); while (!IsDevicePathEnd (SerialNode)) { if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) { // // Update following device paths according to // previous acquired uart attributes // Uart1 = (UART_DEVICE_PATH *) SerialNode; CopyMem ( &Uart1->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); CopyMem ( &Uart1->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); CopyMem ( &Uart1->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); CopyMem ( &Uart1->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (SerialNode); if (IsUartFlowControlNode (FlowControlNode)) { FlowControlNode->FlowControlMap = NewTerminalContext->FlowControl; } else { if (HasFlowControlNode) { mFlowControlDevicePath.FlowControlMap = NewTerminalContext->FlowControl; NewTerminalContext->DevicePath = AppendDevicePathNode ( NewTerminalContext->DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) (&mFlowControlDevicePath) ); } } break; } SerialNode = NextDevicePathNode (SerialNode); } // // end while // } Node = NextDevicePathNode (Node); } // // end while // } return EFI_SUCCESS; }
/** Build a list containing all serial devices. @retval EFI_SUCCESS The function complete successfully. @retval EFI_UNSUPPORTED No serial ports present. **/ EFI_STATUS LocateSerialIo ( VOID ) { UINTN Index; UINTN Index2; UINTN NoHandles; EFI_HANDLE *Handles; EFI_STATUS Status; ACPI_HID_DEVICE_PATH *Acpi; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_SERIAL_IO_PROTOCOL *SerialIo; EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *OutDevicePath; EFI_DEVICE_PATH_PROTOCOL *InpDevicePath; EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath; BM_MENU_ENTRY *NewMenuEntry; BM_TERMINAL_CONTEXT *NewTerminalContext; EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; VENDOR_DEVICE_PATH Vendor; UINT32 FlowControl; // // Get all handles that have SerialIo protocol installed // InitializeListHead (&TerminalMenu.Head); TerminalMenu.MenuNumber = 0; Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles ); if (EFI_ERROR (Status)) { // // No serial ports present // return EFI_UNSUPPORTED; } // // Sort Uart handles array with Acpi->UID from low to high // then Terminal menu can be built from low Acpi->UID to high Acpi->UID // SortedUartHandle (Handles, NoHandles); for (Index = 0; Index < NoHandles; Index++) { // // Check to see whether the handle has DevicePath Protocol installed // gBS->HandleProtocol ( Handles[Index], &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath ); Acpi = NULL; for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) { if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { break; } // // Acpi points to the node before Uart node // Acpi = (ACPI_HID_DEVICE_PATH *) Node; } if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) { NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT); if (NewMenuEntry == NULL) { FreePool (Handles); return EFI_OUT_OF_RESOURCES; } NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32)); NewTerminalContext->DevicePath = DuplicateDevicePath (DevicePath); // // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system! // coz' the misc data for each platform is not correct, actually it's the device path stored in // datahub which is not completed, so a searching for end of device path will enter a // dead-loop. // NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath); if (NULL == NewMenuEntry->DisplayString) { NewMenuEntry->DisplayString = DevicePathToStr (DevicePath); } NewMenuEntry->HelpString = NULL; gBS->HandleProtocol ( Handles[Index], &gEfiSerialIoProtocolGuid, (VOID **) &SerialIo ); CopyMem ( &NewTerminalContext->BaudRate, &SerialIo->Mode->BaudRate, sizeof (UINT64) ); CopyMem ( &NewTerminalContext->DataBits, &SerialIo->Mode->DataBits, sizeof (UINT8) ); CopyMem ( &NewTerminalContext->Parity, &SerialIo->Mode->Parity, sizeof (UINT8) ); CopyMem ( &NewTerminalContext->StopBits, &SerialIo->Mode->StopBits, sizeof (UINT8) ); NewTerminalContext->FlowControl = 0; SerialIo->GetControl(SerialIo, &FlowControl); if ((FlowControl & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) != 0) { NewTerminalContext->FlowControl = UART_FLOW_CONTROL_HARDWARE; } InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link); TerminalMenu.MenuNumber++; } } if (Handles != NULL) { FreePool (Handles); } // // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var // OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid); InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid); ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid); if (OutDevicePath != NULL) { UpdateComAttributeFromVariable (OutDevicePath); } if (InpDevicePath != NULL) { UpdateComAttributeFromVariable (InpDevicePath); } if (ErrDevicePath != NULL) { UpdateComAttributeFromVariable (ErrDevicePath); } for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index); if (NULL == NewMenuEntry) { return EFI_NOT_FOUND; } NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; NewTerminalContext->TerminalType = 0; NewTerminalContext->IsConIn = FALSE; NewTerminalContext->IsConOut = FALSE; NewTerminalContext->IsStdErr = FALSE; Vendor.Header.Type = MESSAGING_DEVICE_PATH; Vendor.Header.SubType = MSG_VENDOR_DP; for (Index2 = 0; Index2 < 4; Index2++) { CopyMem (&Vendor.Guid, &TerminalTypeGuid[Index2], sizeof (EFI_GUID)); SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH)); NewDevicePath = AppendDevicePathNode ( NewTerminalContext->DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &Vendor ); if (NewMenuEntry->HelpString != NULL) { FreePool (NewMenuEntry->HelpString); } // // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath); // NewMenuEntry->DisplayString = NewMenuEntry->HelpString; // NewMenuEntry->HelpString = NULL; if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) { NewTerminalContext->IsConOut = TRUE; NewTerminalContext->TerminalType = (UINT8) Index2; } if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) { NewTerminalContext->IsConIn = TRUE; NewTerminalContext->TerminalType = (UINT8) Index2; } if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) { NewTerminalContext->IsStdErr = TRUE; NewTerminalContext->TerminalType = (UINT8) Index2; } } } return EFI_SUCCESS; }
/** Update Com Ports attributes from DevicePath @param DevicePath DevicePath that contains Com ports @retval EFI_SUCCESS The update is successful. @retval EFI_NOT_FOUND Can not find specific menu entry **/ EFI_STATUS UpdateComAttributeFromVariable ( EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *SerialNode; ACPI_HID_DEVICE_PATH *Acpi; UART_DEVICE_PATH *Uart; UART_DEVICE_PATH *Uart1; UINTN TerminalNumber; BM_MENU_ENTRY *NewMenuEntry; BM_TERMINAL_CONTEXT *NewTerminalContext; UINTN Index; Node = DevicePath; Node = NextDevicePathNode (Node); TerminalNumber = 0; for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { while (!IsDevicePathEnd (Node)) { Acpi = (ACPI_HID_DEVICE_PATH *) Node; if (IsIsaSerialNode (Acpi)) { CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32)); } if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { Uart = (UART_DEVICE_PATH *) Node; NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber); if (NULL == NewMenuEntry) { return EFI_NOT_FOUND; } NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; CopyMem ( &NewTerminalContext->BaudRate, &Uart->BaudRate, sizeof (UINT64) ); CopyMem ( &NewTerminalContext->DataBits, &Uart->DataBits, sizeof (UINT8) ); CopyMem ( &NewTerminalContext->Parity, &Uart->Parity, sizeof (UINT8) ); CopyMem ( &NewTerminalContext->StopBits, &Uart->StopBits, sizeof (UINT8) ); SerialNode = NewTerminalContext->DevicePath; SerialNode = NextDevicePathNode (SerialNode); while (!IsDevicePathEnd (SerialNode)) { if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) { // // Update following device paths according to // previous acquired uart attributes // Uart1 = (UART_DEVICE_PATH *) SerialNode; CopyMem ( &Uart1->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); CopyMem ( &Uart1->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); CopyMem ( &Uart1->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); CopyMem ( &Uart1->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); break; } SerialNode = NextDevicePathNode (SerialNode); } // // end while // } Node = NextDevicePathNode (Node); } // // end while // } return EFI_SUCCESS; }
/** Update the multi-instance device path of Terminal Device based on the global TerminalMenu. If ChangeTernimal is TRUE, the terminal device path in the Terminal Device in TerminalMenu is also updated. @param DevicePath The multi-instance device path. @param ChangeTerminal TRUE, then device path in the Terminal Device in TerminalMenu is also updated; FALSE, no update. @return EFI_SUCCESS The function completes successfully. **/ EFI_STATUS ChangeTerminalDevicePath ( IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN ChangeTerminal ) { EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *Node1; ACPI_HID_DEVICE_PATH *Acpi; UART_DEVICE_PATH *Uart; UART_DEVICE_PATH *Uart1; UINTN Com; BM_TERMINAL_CONTEXT *NewTerminalContext; BM_MENU_ENTRY *NewMenuEntry; Node = DevicePath; Node = NextDevicePathNode (Node); Com = 0; while (!IsDevicePathEnd (Node)) { Acpi = (ACPI_HID_DEVICE_PATH *) Node; if (IsIsaSerialNode (Acpi)) { CopyMem (&Com, &Acpi->UID, sizeof (UINT32)); } NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com); NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { Uart = (UART_DEVICE_PATH *) Node; CopyMem ( &Uart->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); CopyMem ( &Uart->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); CopyMem ( &Uart->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); CopyMem ( &Uart->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); // // Change the device path in the ComPort // if (ChangeTerminal) { Node1 = NewTerminalContext->DevicePath; Node1 = NextDevicePathNode (Node1); while (!IsDevicePathEnd (Node1)) { if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) { Uart1 = (UART_DEVICE_PATH *) Node1; CopyMem ( &Uart1->BaudRate, &NewTerminalContext->BaudRate, sizeof (UINT64) ); CopyMem ( &Uart1->DataBits, &NewTerminalContext->DataBits, sizeof (UINT8) ); CopyMem ( &Uart1->Parity, &NewTerminalContext->Parity, sizeof (UINT8) ); CopyMem ( &Uart1->StopBits, &NewTerminalContext->StopBits, sizeof (UINT8) ); break; } // // end if // Node1 = NextDevicePathNode (Node1); } // // end while // break; } } Node = NextDevicePathNode (Node); } return EFI_SUCCESS; }