From 52657feb150f316c79052a0e134cc57cfb6384ae Mon Sep 17 00:00:00 2001 From: tgingold Date: Mon, 12 Feb 2007 23:40:29 +0000 Subject: EdkGenericPlatformBdsLib added git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2368 6f19259b-4bc3-4df7-8a09-765794883524 --- .../BootMaint/ConsoleOption.c | 840 +++++++++++++++++++++ 1 file changed, 840 insertions(+) create mode 100644 EdkModulePkg/Library/EdkGenericPlatformBdsLib/BootMaint/ConsoleOption.c (limited to 'EdkModulePkg/Library/EdkGenericPlatformBdsLib/BootMaint/ConsoleOption.c') diff --git a/EdkModulePkg/Library/EdkGenericPlatformBdsLib/BootMaint/ConsoleOption.c b/EdkModulePkg/Library/EdkGenericPlatformBdsLib/BootMaint/ConsoleOption.c new file mode 100644 index 0000000000..297c2cfc55 --- /dev/null +++ b/EdkModulePkg/Library/EdkGenericPlatformBdsLib/BootMaint/ConsoleOption.c @@ -0,0 +1,840 @@ +/*++ +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + ConsoleOption.c + +Abstract: + + handles console redirection from boot manager + + +Revision History + +--*/ + +#include "BootMaint.h" + +EFI_DEVICE_PATH_PROTOCOL * +DevicePathInstanceDup ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath + ); + +EFI_STATUS +UpdateComAttributeFromVariable ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +EFI_STATUS +ChangeTerminalDevicePath ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath, + 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; + UINT32 Match; + BM_TERMINAL_CONTEXT *NewTerminalContext; + BM_MENU_ENTRY *NewMenuEntry; + + Match = EISA_PNP_ID (0x0501); + Node = DevicePath; + Node = NextDevicePathNode (Node); + Com = 0; + while (!IsDevicePathEnd (Node)) { + if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) { + Acpi = (ACPI_HID_DEVICE_PATH *) Node; + if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { + CopyMem (&Com, &Acpi->UID, sizeof (UINT32)); + } + } + + NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com); + if (NULL == NewMenuEntry) { + return EFI_NOT_FOUND; + } + + 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; + +} + +VOID +ChangeVariableDevicePath ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_DEVICE_PATH_PROTOCOL *Node; + ACPI_HID_DEVICE_PATH *Acpi; + UART_DEVICE_PATH *Uart; + UINTN Com; + UINT32 Match; + BM_TERMINAL_CONTEXT *NewTerminalContext; + BM_MENU_ENTRY *NewMenuEntry; + + Match = EISA_PNP_ID (0x0501); + Node = DevicePath; + Node = NextDevicePathNode (Node); + Com = 0; + while (!IsDevicePathEnd (Node)) { + if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) { + Acpi = (ACPI_HID_DEVICE_PATH *) Node; + if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { + CopyMem (&Com, &Acpi->UID, sizeof (UINT32)); + } + } + + if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) { + NewMenuEntry = BOpt_GetMenuEntry ( + &TerminalMenu, + Com + ); + 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); + } + + return ; +} + +BOOLEAN +IsTerminalDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT TYPE_OF_TERMINAL *Termi, + OUT UINTN *Com + ); + +EFI_STATUS +LocateSerialIo ( + VOID + ) +/*++ + +Routine Description: + Build a list containing all serial devices + +Arguments: + +Returns: + +--*/ +{ + UINT8 *Ptr; + UINTN Index; + UINTN Index2; + UINTN NoHandles; + EFI_HANDLE *Handles; + EFI_STATUS Status; + ACPI_HID_DEVICE_PATH *Acpi; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINT32 Match; + EFI_SERIAL_IO_PROTOCOL *SerialIo; + 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; + // + // 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; + } + + for (Index = 0; Index < NoHandles; Index++) { + // + // Check to see whether the handle has DevicePath Protocol installed + // + gBS->HandleProtocol ( + Handles[Index], + &gEfiDevicePathProtocolGuid, + (VOID**) &DevicePath + ); + Ptr = (UINT8 *) DevicePath; + while (*Ptr != END_DEVICE_PATH_TYPE) { + Ptr++; + } + + Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH); + Acpi = (ACPI_HID_DEVICE_PATH *) Ptr; + Match = EISA_PNP_ID (0x0501); + + if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { + NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT); + if (!NewMenuEntry) { + return EFI_OUT_OF_RESOURCES; + } + + NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext; + CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32)); + NewTerminalContext->DevicePath = DevicePathInstanceDup (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) + ); + InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link); + TerminalMenu.MenuNumber++; + } + } + // + // 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) { + UpdateComAttributeFromVariable (OutDevicePath); + } + + if (InpDevicePath) { + UpdateComAttributeFromVariable (InpDevicePath); + } + + if (ErrDevicePath) { + 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, &Guid[Index2], sizeof (EFI_GUID)); + SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH)); + NewDevicePath = AppendDevicePathNode ( + NewTerminalContext->DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &Vendor + ); + SafeFreePool (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; +} + +EFI_STATUS +UpdateComAttributeFromVariable ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +/*++ + +Routine Description: + Update Com Ports attributes from DevicePath + +Arguments: + DevicePath - DevicePath that contains Com ports + +Returns: + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *Node; + EFI_DEVICE_PATH_PROTOCOL *SerialNode; + ACPI_HID_DEVICE_PATH *Acpi; + UART_DEVICE_PATH *Uart; + UART_DEVICE_PATH *Uart1; + UINT32 Match; + UINTN TerminalNumber; + BM_MENU_ENTRY *NewMenuEntry; + BM_TERMINAL_CONTEXT *NewTerminalContext; + UINTN Index; + + Match = EISA_PNP_ID (0x0501); + Node = DevicePath; + Node = NextDevicePathNode (Node); + TerminalNumber = 0; + for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) { + while (!IsDevicePathEnd (Node)) { + if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) { + Acpi = (ACPI_HID_DEVICE_PATH *) Node; + if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { + 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; +} + +EFI_DEVICE_PATH_PROTOCOL * +DevicePathInstanceDup ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath + ) +/*++ + +Routine Description: + Function creates a device path data structure that identically matches the + device path passed in. + +Arguments: + DevPath - A pointer to a device path data structure. + +Returns: + + The new copy of DevPath is created to identically match the input. + Otherwise, NULL is returned. + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *NewDevPath; + EFI_DEVICE_PATH_PROTOCOL *DevicePathInst; + EFI_DEVICE_PATH_PROTOCOL *Temp; + UINT8 *Ptr; + UINTN Size; + + // + // get the size of an instance from the input + // + Temp = DevPath; + DevicePathInst = GetNextDevicePathInstance (&Temp, &Size); + + // + // Make a copy and set proper end type + // + NewDevPath = NULL; + if (Size) { + NewDevPath = AllocateZeroPool (Size); + ASSERT (NewDevPath != NULL); + } + + if (NewDevPath) { + CopyMem (NewDevPath, DevicePathInst, Size); + Ptr = (UINT8 *) NewDevPath; + Ptr += Size - sizeof (EFI_DEVICE_PATH_PROTOCOL); + Temp = (EFI_DEVICE_PATH_PROTOCOL *) Ptr; + SetDevicePathEndNode (Temp); + } + + return NewDevPath; +} + +EFI_STATUS +GetConsoleMenu ( + IN UINTN ConsoleMenuType + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *AllDevicePath; + EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePathInst; + UINTN Size; + UINTN AllCount; + UINTN Index; + UINTN Index2; + BM_MENU_ENTRY *NewMenuEntry; + BM_CONSOLE_CONTEXT *NewConsoleContext; + BM_TERMINAL_CONTEXT *NewTerminalContext; + TYPE_OF_TERMINAL Terminal; + BM_MENU_ENTRY *NewTerminalMenuEntry; + UINTN Com; + BM_MENU_OPTION *ConsoleMenu; + + DevicePath = NULL; + AllDevicePath = NULL; + AllCount = 0; + switch (ConsoleMenuType) { + case BM_CONSOLE_IN_CONTEXT_SELECT: + ConsoleMenu = &ConsoleInpMenu; + DevicePath = EfiLibGetVariable ( + L"ConIn", + &gEfiGlobalVariableGuid + ); + + AllDevicePath = EfiLibGetVariable ( + L"ConInDev", + &gEfiGlobalVariableGuid + ); + break; + + case BM_CONSOLE_OUT_CONTEXT_SELECT: + ConsoleMenu = &ConsoleOutMenu; + DevicePath = EfiLibGetVariable ( + L"ConOut", + &gEfiGlobalVariableGuid + ); + + AllDevicePath = EfiLibGetVariable ( + L"ConOutDev", + &gEfiGlobalVariableGuid + ); + break; + + case BM_CONSOLE_ERR_CONTEXT_SELECT: + ConsoleMenu = &ConsoleErrMenu; + DevicePath = EfiLibGetVariable ( + L"ErrOut", + &gEfiGlobalVariableGuid + ); + + AllDevicePath = EfiLibGetVariable ( + L"ErrOutDev", + &gEfiGlobalVariableGuid + ); + break; + + default: + return EFI_UNSUPPORTED; + } + + if (NULL == AllDevicePath) { + return EFI_NOT_FOUND; + } + + InitializeListHead (&ConsoleMenu->Head); + + AllCount = EfiDevicePathInstanceCount (AllDevicePath); + ConsoleMenu->MenuNumber = 0; + // + // Following is menu building up for Console Out Devices + // + MultiDevicePath = AllDevicePath; + Index2 = 0; + for (Index = 0; Index < AllCount; Index++) { + DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size); + + NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT); + if (NULL == NewMenuEntry) { + return EFI_OUT_OF_RESOURCES; + } + + NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext; + NewMenuEntry->OptionNumber = Index2; + + NewConsoleContext->DevicePath = DevicePathInstanceDup (DevicePathInst); + NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath); + if (NULL == NewMenuEntry->DisplayString) { + NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath); + } + + NewConsoleContext->IsTerminal = IsTerminalDevicePath ( + NewConsoleContext->DevicePath, + &Terminal, + &Com + ); + + NewConsoleContext->IsActive = BdsLibMatchDevicePaths ( + DevicePath, + NewConsoleContext->DevicePath + ); + NewTerminalMenuEntry = NULL; + NewTerminalContext = NULL; + + if (NewConsoleContext->IsTerminal) { + BOpt_DestroyMenuEntry (NewMenuEntry); + } else { + Index2++; + ConsoleMenu->MenuNumber++; + InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link); + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +GetAllConsoles ( + VOID + ) +/*++ + +Routine Description: + Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu + +Arguments: + +Returns: + EFI_SUCCESS + Others + +--*/ +{ + GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT); + GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT); + GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT); + return EFI_SUCCESS; +} + +EFI_STATUS +FreeAllConsoles ( + VOID + ) +/*++ + +Routine Description: + Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu + +Arguments: + +Returns: + EFI_SUCCESS + Others + +--*/ +{ + BOpt_FreeMenu (&ConsoleOutMenu); + BOpt_FreeMenu (&ConsoleInpMenu); + BOpt_FreeMenu (&ConsoleErrMenu); + BOpt_FreeMenu (&TerminalMenu); + return EFI_SUCCESS; +} + +BOOLEAN +IsTerminalDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT TYPE_OF_TERMINAL *Termi, + OUT UINTN *Com + ) +/*++ + +Routine Description: + Test whether DevicePath is a valid Terminal + +Arguments: + DevicePath - DevicePath to be checked + Termi - If is terminal, give its type + Com - If is Com Port, give its type + +Returns: + TRUE - If DevicePath point to a Terminal + FALSE + +--*/ +{ + UINT8 *Ptr; + BOOLEAN IsTerminal; + VENDOR_DEVICE_PATH *Vendor; + ACPI_HID_DEVICE_PATH *Acpi; + UINT32 Match; + EFI_GUID TempGuid; + + IsTerminal = FALSE; + + // + // Parse the Device Path, should be change later!!! + // + Ptr = (UINT8 *) DevicePath; + while (*Ptr != END_DEVICE_PATH_TYPE) { + Ptr++; + } + + Ptr = Ptr - sizeof (VENDOR_DEVICE_PATH); + Vendor = (VENDOR_DEVICE_PATH *) Ptr; + + // + // There are four kinds of Terminal types + // check to see whether this devicepath + // is one of that type + // + CopyMem (&TempGuid, &Vendor->Guid, sizeof (EFI_GUID)); + + if (CompareGuid (&TempGuid, &Guid[0])) { + *Termi = PC_ANSI; + IsTerminal = TRUE; + } else { + if (CompareGuid (&TempGuid, &Guid[1])) { + *Termi = VT_100; + IsTerminal = TRUE; + } else { + if (CompareGuid (&TempGuid, &Guid[2])) { + *Termi = VT_100_PLUS; + IsTerminal = TRUE; + } else { + if (CompareGuid (&TempGuid, &Guid[3])) { + *Termi = VT_UTF8; + IsTerminal = TRUE; + } else { + IsTerminal = FALSE; + } + } + } + } + + if (!IsTerminal) { + return FALSE; + } + + Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH); + Acpi = (ACPI_HID_DEVICE_PATH *) Ptr; + Match = EISA_PNP_ID (0x0501); + if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) { + CopyMem (Com, &Acpi->UID, sizeof (UINT32)); + } else { + return FALSE; + } + + return TRUE; +} -- cgit v1.2.3