ICE_TEA_BIOS/Insyde/InsydeCrPkg/CrServiceDxe/CrVariableUpdate.c
LCFC\AiXia.Jiang a870bff2f4 1.Frist commit
2022-09-30 14:59:06 +08:00

844 lines
24 KiB
C

/** @file
CrVariableUpdate
;******************************************************************************
;* Copyright (c) 2012 - 2016, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "CrVariableUpdate.h"
CHAR16 *mConInVarName = L"ConIn";
CHAR16 *mConOutVarName = L"ConOut";
EFI_GUID *mConVarGuid = &gEfiGlobalVariableGuid;
CR_DEVICES_SETTING_HEAD_NODE mCrVarDeviceHead;
extern UINT32 mCrBaudRateTable[];
VOID
InitializeCrDeviceList (
VOID
)
{
InitializeListHead (&mCrVarDeviceHead.Link);
mCrVarDeviceHead.CrDevVarCount = 0;
}
/**
Status is Exist and Port enable
@param
@retval
**/
EFI_DEVICE_PATH*
BuildCrActiveDevicePath (
VOID
)
{
EFI_DEVICE_PATH_PROTOCOL *DevPath;
EFI_DEVICE_PATH_PROTOCOL *PrevDevPath;
UINTN DeviceCount;
LIST_ENTRY *Link;
CR_DEVICES_SETTING_NODE *CrDevNode;
DevPath = NULL;
PrevDevPath = NULL;
DeviceCount = 0;
Link = GetFirstNode (&mCrVarDeviceHead.Link);
while (!IsNull (&mCrVarDeviceHead.Link, Link)) {
CrDevNode = CR_DEVICE_SETTING_FROM_THIS (Link);
//
// **Note: The network device is independent control.
// So didn't add device path here.
//
if ( CrDevNode->CrSetting->Exist == FALSE ||
CrDevNode->CrSetting->Attribute.PortEnable == FALSE
) {
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
continue;
}
DevPath = AppendDevicePathInstance (PrevDevPath, GetDevicePathFromCrDevSetting (CrDevNode->CrSetting));
CrSafeFreePool (PrevDevPath);
PrevDevPath = DevPath;
CrDevNode->AddIntoConVar = TRUE;
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
}
return DevPath;
}
BOOLEAN
IsDevNodeInvalidOrAreadyUsed (
IN CR_DEVICES_SETTING_NODE *CrDevNode
)
{
if (CrDevNode->CrSetting->ItemType == ASTERISK_ITEM ||
CrDevNode->CrSetting->ItemType == INVALID_ITEM ||
CrDevNode->AddIntoConVar == TRUE
) {
return TRUE;
}
return FALSE;
}
VOID
UpdateDevicesExistStatus (
VOID
)
{
LIST_ENTRY *Link;
CR_DEVICES_SETTING_NODE *CrDevNode;
EFI_DEVICE_PATH *DevPath;
EFI_HANDLE Handle;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "\nCr << %a >>\n", __FUNCTION__));
Link = GetFirstNode (&mCrVarDeviceHead.Link);
while (!IsNull (&mCrVarDeviceHead.Link, Link)) {
CrDevNode = CR_DEVICE_SETTING_FROM_THIS (Link);
if (IsDevNodeInvalidOrAreadyUsed (CrDevNode) ) {
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
continue;
}
DevPath = GetDevicePathFromCrDevSetting (CrDevNode->CrSetting);
Status = gBS->LocateDevicePath (&gH2OCrUart16550AccessProtocolGuid, &DevPath, &Handle);
DEBUG ((DEBUG_INFO, " Not used CrDevVar%d : %s, Locate 16550:%r\n", CrDevNode->VarIndex, CrDevNode->CrSetting->DevName, Status));
if (Status == EFI_SUCCESS && CrDevNode->CrSetting->Exist == FALSE) {
DEBUG ((DEBUG_INFO, " ->Now appear\n"));
CrDevNode->CrSetting->Exist = TRUE;
UpdateOrDeleteCrDevVarWithDevInfo (CrDevNode->VarIndex ,CrDevNode->CrSetting);
} else if (EFI_ERROR(Status) && CrDevNode->CrSetting->Exist == TRUE){
DEBUG ((DEBUG_INFO, " ->Now disappear\n"));
CrDevNode->CrSetting->Exist = FALSE;
UpdateOrDeleteCrDevVarWithDevInfo (CrDevNode->VarIndex ,CrDevNode->CrSetting);
}
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
}
}
VOID
CheckAndSaveConnectResult (
IN CHAR16 *ConVarName,
IN EFI_GUID *ConVarGuid
)
{
LIST_ENTRY *Link;
CR_DEVICES_SETTING_NODE *CrDevNode;
EFI_DEVICE_PATH *VarConsole;
DEBUG ((DEBUG_INFO, "\nCr << %a >>\n", __FUNCTION__));
VarConsole = NULL;
VarConsole = CommonGetVariableData (ConVarName, ConVarGuid);
if (VarConsole == NULL) {
return;
}
Link = GetFirstNode (&mCrVarDeviceHead.Link);
while (!IsNull (&mCrVarDeviceHead.Link, Link)) {
CrDevNode = CR_DEVICE_SETTING_FROM_THIS (Link);
if (CrDevNode->AddIntoConVar == FALSE) {
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
continue;
}
if (!IsInclusiveOfSelectDevPath (VarConsole, GetDevicePathFromCrDevSetting (CrDevNode->CrSetting))) {
DEBUG ((EFI_D_INFO, " CrDevVar%d :%s not exist\n", CrDevNode->VarIndex, CrDevNode->CrSetting->DevName));
CrDevNode->AddIntoConVar = FALSE;
CrDevNode->CrSetting->Exist = FALSE;
CrDevNode->CrSetting->Attribute.PortEnable = FALSE;
//
// If device not exist and this device not in PCD, then delete this variable
//
UpdateOrDeleteCrDevVarWithDevInfo (CrDevNode->VarIndex ,CrDevNode->CrSetting);
}
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
}
CrSafeFreePool (VarConsole);
}
VOID
CreateCrDeviceVarList (
VOID
)
{
UINT8 Index;
CR_DEVICE_SETTING *CrSetting;
CR_DEVICES_SETTING_NODE *Node;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "\nCr << %a >>\n", __FUNCTION__));
if (!mCrEnable) {
mCrVarDeviceHead.CrDevVarCount = 0;
return;
}
for (Index = 0; Index < MAX_CR_DEVICE_VARIABLE; Index++) {
Status = GetCrDevInfoFromVariable (Index, &CrSetting);
if (EFI_ERROR(Status) || CrSetting == NULL) {
continue;
}
Node = AllocateZeroPool (sizeof (CR_DEVICES_SETTING_NODE));
if (Node == NULL) {
CrSafeFreePool (CrSetting);
ASSERT (0);
break;
}
Node->CrSetting = CrSetting;
Node->VarIndex = Index;
InsertTailList (&mCrVarDeviceHead.Link, &Node->Link);
mCrVarDeviceHead.CrDevVarCount ++;
}
}
VOID
FreeCrDevicesVarList (
VOID
)
{
LIST_ENTRY *Link;
CR_DEVICES_SETTING_NODE *CrDevNode;
Link = GetFirstNode (&mCrVarDeviceHead.Link);
while (!IsNull (&mCrVarDeviceHead.Link, Link)) {
CrDevNode = CR_DEVICE_SETTING_FROM_THIS (Link);
Link = RemoveEntryList (Link);
gBS->FreePool (CrDevNode->CrSetting);
gBS->FreePool (CrDevNode);
}
}
VOID
CreateNewActiveCrDevice (
VOID
)
{
EFI_DEVICE_PATH *NewCrActiveDevice;
UINTN Size;
NewCrActiveDevice = NULL;
NewCrActiveDevice = BuildCrActiveDevicePath ();
Size = (NewCrActiveDevice == NULL)? 0 : GetDevicePathSize (NewCrActiveDevice);
CommonSetVariable (
CR_ACTIVE_VARIABLE_NAME,
&gH2OCrConfigurationGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
Size,
NewCrActiveDevice
);
CrSafeFreePool (NewCrActiveDevice);
}
BOOLEAN
IsChildDevicePath (
IN EFI_DEVICE_PATH *ChildDevPath,
IN EFI_DEVICE_PATH *ParentDevPath
)
{
UINTN Size;
Size = GetDevicePathSize (ParentDevPath) - sizeof (EFI_DEVICE_PATH);
if (CompareMem (ChildDevPath, ParentDevPath, Size) == 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsDevicePathAlreadyInCrDevVar (
IN EFI_DEVICE_PATH *SubsetPath
)
{
LIST_ENTRY *Link;
CR_DEVICES_SETTING_NODE *CrDevNode;
Link = GetFirstNode (&mCrVarDeviceHead.Link);
while (!IsNull (&mCrVarDeviceHead.Link, Link)) {
CrDevNode = CR_DEVICE_SETTING_FROM_THIS (Link);
if (CrDevNode->CrSetting->ItemType == INVALID_ITEM ||
CrDevNode->CrSetting->ItemType == ASTERISK_ITEM
) {
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
continue;
}
if (IsChildDevicePath (GetDevicePathFromCrDevSetting (CrDevNode->CrSetting), SubsetPath)) {
return TRUE;
}
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
}
return FALSE;
}
BOOLEAN
IsChildDevPathOfAsteriskDevPath (
IN EFI_DEVICE_PATH *ChildDevPath
)
{
LIST_ENTRY *Link;
CR_DEVICES_SETTING_NODE *CrDevNode;
Link = GetFirstNode (&mCrVarDeviceHead.Link);
while (!IsNull (&mCrVarDeviceHead.Link, Link)) {
CrDevNode = CR_DEVICE_SETTING_FROM_THIS (Link);
if (CrDevNode->CrSetting->ItemType == ASTERISK_ITEM) {
return IsChildDevicePath (ChildDevPath, GetDevicePathFromCrDevSetting (CrDevNode->CrSetting) );
}
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
}
return FALSE;
}
VOID
FindAsteriskDevicePath (
VOID
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
EFI_DEVICE_PATH *ChildDevPath;
UINTN HandleCount;
UINTN Index;
H2O_UART_16550_ACCESS_PROTOCOL *Interface;
DEBUG ((DEBUG_INFO, "\nCr << %a >>\n", __FUNCTION__));
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gH2OCrUart16550AccessProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return;
}
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, &ChildDevPath);
DEBUG ((DEBUG_INFO, " 16550 DevPath: %s\n", ConvertDevicePathToText ((const EFI_DEVICE_PATH *)ChildDevPath, FALSE, TRUE)));
if (EFI_ERROR (Status)) {
continue;
}
if (IsDevicePathAlreadyInCrDevVar (ChildDevPath)) {
DEBUG ((EFI_D_INFO, " ->AlreadyInCrDevVar\n"));
continue;
}
if (IsChildDevPathOfAsteriskDevPath (ChildDevPath) == FALSE) {
DEBUG ((EFI_D_INFO, " ->Not Child DPath Of Asterisk DPath.\n"));
continue;
}
Status = gBS->HandleProtocol (HandleBuffer[Index], &gH2OCrUart16550AccessProtocolGuid, &Interface);
if (EFI_ERROR(Status)) {
continue;
}
CreateNewCrDeviceVariable (
Interface->DeviceInfo->DeviceName,
ChildDevPath
);
mCrVarDeviceHead.CrDevVarCount++;
}
CrSafeFreePool(HandleBuffer);
}
/**
@param
@retval
**/
VOID
UpdateConInConOutVarFromActiveDevicePath (
VOID
)
{
EFI_DEVICE_PATH *NewActiveDevPath;
EFI_DEVICE_PATH *OldActiveDevPath;
NewActiveDevPath = NULL;
OldActiveDevPath = NULL;
NewActiveDevPath = BuildCrActiveDevicePath ();
OldActiveDevPath = CommonGetVariableData (CR_ACTIVE_VARIABLE_NAME, &gH2OCrConfigurationGuid);
if (mCrVarDeviceHead.CrDevVarCount == 0 || mCrEnable == FALSE) {
//
// Delete Console Redirection device path from ComIn/Out Variable
//
if(OldActiveDevPath != NULL) {
UpdateConsoleVariable (mConInVarName, mConVarGuid, NULL, OldActiveDevPath);
UpdateConsoleVariable (mConOutVarName, mConVarGuid, NULL, OldActiveDevPath);
CommonSetVariable (
CR_ACTIVE_VARIABLE_NAME,
&gH2OCrConfigurationGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
OldActiveDevPath
);
}
} else {
//
// Update Console Redirection device path from ComIn/Out Variable
//
if (IsEqualDevicePath (NewActiveDevPath, OldActiveDevPath) == TRUE) {
UpdateConsoleVariable (mConInVarName, mConVarGuid, NewActiveDevPath, NULL);
UpdateConsoleVariable (mConOutVarName, mConVarGuid, NewActiveDevPath, NULL);
} else {
UpdateConsoleVariable (mConInVarName, mConVarGuid, NewActiveDevPath, OldActiveDevPath);
UpdateConsoleVariable (mConOutVarName, mConVarGuid, NewActiveDevPath, OldActiveDevPath);
CommonSetVariable (
CR_ACTIVE_VARIABLE_NAME,
&gH2OCrConfigurationGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
GetDevicePathSize (NewActiveDevPath),
NewActiveDevPath
);
}
}
CrSafeFreePool (NewActiveDevPath);
CrSafeFreePool (OldActiveDevPath);
}
EFI_STATUS
UpdateConsoleVariable (
IN CHAR16 *ConVarName,
IN EFI_GUID *ConVarGuid,
IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath
)
{
EFI_STATUS Status;
UINTN DevicePathSize;
BOOLEAN VarChanged;
EFI_DEVICE_PATH_PROTOCOL *VarConsole;
EFI_DEVICE_PATH_PROTOCOL *OldVarConsole;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
EFI_DEVICE_PATH_PROTOCOL *PrevDevicePath;
EFI_DEVICE_PATH_PROTOCOL *VarConsoleInstance;
EFI_DEVICE_PATH_PROTOCOL *CustomizedInstance;
VarChanged = FALSE;
VarConsole = NULL;
DevicePathSize = 0;
NewDevicePath = NULL;
Status = EFI_UNSUPPORTED;
if (CustomizedConDevicePath == ExclusiveDevicePath) {
return EFI_UNSUPPORTED;
}
VarConsole = CommonGetVariableData (ConVarName, ConVarGuid);
OldVarConsole = VarConsole;
if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
while (VarConsole != NULL) {
VarConsoleInstance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
if (!IsInclusiveOfSelectDevPath (ExclusiveDevicePath, VarConsoleInstance)) {
PrevDevicePath = NewDevicePath;
NewDevicePath = AppendDevicePathInstance (PrevDevicePath, VarConsoleInstance);
if (PrevDevicePath != NULL)
gBS->FreePool (PrevDevicePath);
}
else {
VarChanged = TRUE;
}
gBS->FreePool (VarConsoleInstance);
}
}
else {
NewDevicePath = DuplicateDevicePath (VarConsole);
}
while (CustomizedConDevicePath != NULL) {
CustomizedInstance = GetNextDevicePathInstance (&CustomizedConDevicePath, &DevicePathSize);
if (!IsInclusiveOfSelectDevPath (NewDevicePath, CustomizedInstance)) {
VarChanged = TRUE;
PrevDevicePath = NewDevicePath;
NewDevicePath = AppendDevicePathInstance (PrevDevicePath, CustomizedInstance);
if (PrevDevicePath != NULL)
gBS->FreePool (PrevDevicePath);
}
gBS->FreePool (CustomizedInstance);
}
if (OldVarConsole != NULL) {
gBS->FreePool (OldVarConsole);
}
//
// Update the variable of the default console
//
if (VarChanged) {
UINT32 Attributes;
CHAR16 *StringPtr;
StringPtr = ConVarName;
//
// If the variable includes "Dev" at last, we consider
// it does not support NV attribute.
//
while (*StringPtr != L'\0') {
StringPtr++;
}
if ( (((INTN)((UINTN)StringPtr - (UINTN)ConVarName) / sizeof (CHAR16)) > 3) &&
(*(StringPtr - 3) == L'D') &&
(*(StringPtr - 2) == L'e') &&
(*(StringPtr - 1) == L'v')
) {
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
} else {
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
}
CommonSetVariable (
ConVarName,
ConVarGuid,
Attributes,
GetDevicePathSize (NewDevicePath),
NewDevicePath
);
return EFI_SUCCESS;
}
return EFI_ABORTED;
}
/**
Function compares a device path data structure to that of all the nodes of a
second device path instance.
@param DevPathPool A pointer to a multi-instance device path data
structure.
@param Single A pointer to a single-instance device path data
structure.
@retval TRUE If the Single device path is contained within Multi device path.
@retval FALSE The Single device path is not match within Multi device path.
**/
BOOLEAN
EFIAPI
IsInclusiveOfSelectDevPath (
IN EFI_DEVICE_PATH_PROTOCOL *DevPathPool,
IN EFI_DEVICE_PATH_PROTOCOL *SelectDevPath
)
{
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
UINTN Size;
if (DevPathPool == NULL || SelectDevPath == NULL) {
return FALSE;
}
DevicePath = DevPathPool;
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
//
// Search for the match of 'Single' in 'DevPathPool'
//
while (DevicePathInst != NULL) {
//
// If the single device path is found in multiple device paths,
// return success
//
if (CompareMem (SelectDevPath, DevicePathInst, Size) == 0) {
FreePool (DevicePathInst);
return TRUE;
}
FreePool (DevicePathInst);
DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
}
return FALSE;
}
/**
Compare two device path instances
@param [in] DevicePath1 The first device path to be compared
@param [in] DevicePath2 The second device path to be compared
@return TRUE The two device paths are the same
@retval FALSE The two device paths are not the same
**/
BOOLEAN
IsEqualDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2
)
{
UINTN DevicePathSize1;
UINTN DevicePathSize2;
UINTN Value;
DevicePathSize1 = GetDevicePathSize (DevicePath1);
DevicePathSize2 = GetDevicePathSize (DevicePath2);
if (DevicePathSize1 != DevicePathSize2)
return FALSE;
if (DevicePathSize1 == 0)
return TRUE;
Value = CompareMem (DevicePath1, DevicePath2, DevicePathSize1);
if (Value == 0)
return TRUE;
return FALSE;
}
/**
Verify DataBits value
@param [in] DataBits The value which user want to set to DataBits field
@return UINT8 The valid DataBits value
**/
UINT8
VerifyDataBits (
IN UINT8 DataBits
)
{
if ((DataBits == 7) || (DataBits == 8)) {
return DataBits;
} else {
return 8;
}
}
/**
Verify StopBits value
@param [in] StopBits The value which user want to set to StopBits field
@return UINT8 The valid StopBits value
**/
UINT8
VerifyStopBits (
IN UINT8 StopBits
)
{
if ((StopBits == OneStopBit) || (StopBits == TwoStopBits)) {
return StopBits;
} else {
return OneStopBit;
}
}
/**
Verify Parity value
@param [in] Parity The value which user want to set to Parity field
@return UINT8 The valid Parity value
**/
UINT8
VerifyParity (
IN UINT8 Parity
)
{
if ((Parity >= NoParity) && (Parity <= OddParity)) {
return Parity;
} else {
return NoParity;
}
}
VOID
UpdateCrDeviceSetting (
VOID
)
{
EFI_DEVICE_PATH_PROTOCOL *DevPath;
EFI_DEVICE_PATH_PROTOCOL *TempPath;
UART_DEVICE_PATH *Uart;
CR_DEVICES_SETTING_NODE *CrDevNode;
EFI_STATUS Status;
LIST_ENTRY *Link;
BOOLEAN UpdateCrDev;
UINT8 Index;
H2O_SERIAL_ATTRIBS SerialAttribs;
DEBUG ((DEBUG_INFO, "\nCr << %a >>\n", __FUNCTION__));
DevPath = NULL;
TempPath = NULL;
Uart = NULL;
UpdateCrDev = FALSE;
Link = GetFirstNode (&mCrVarDeviceHead.Link);
while (!IsNull (&mCrVarDeviceHead.Link, Link)) {
CrDevNode = CR_DEVICE_SETTING_FROM_THIS (Link);
if ((CrDevNode->CrSetting->Exist == FALSE) ||
(CrDevNode->CrSetting->Attribute.PortEnable == FALSE)) {
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
continue;
}
DevPath = GetDevicePathFromCrDevSetting (CrDevNode->CrSetting);
DEBUG ((DEBUG_INFO, " %s\n", CrDevNode->CrSetting->DevName));
DEBUG ((DEBUG_INFO, " Old Setting\n"));
DEBUG ((DEBUG_INFO, " Exist:%d, ItemType:%d, PortEnable:%d, Global:%d, TerminalType:%d, BaudRate:%d, Parity:%d, DataBits:%d, StopBits:%d, FlowControl:%d\n",
CrDevNode->CrSetting->Exist,
CrDevNode->CrSetting->ItemType,
CrDevNode->CrSetting->Attribute.PortEnable,
CrDevNode->CrSetting->Attribute.UseGlobalSetting,
CrDevNode->CrSetting->Attribute.TerminalType,
CrDevNode->CrSetting->Attribute.BaudRate,
CrDevNode->CrSetting->Attribute.Parity,
CrDevNode->CrSetting->Attribute.DataBits,
CrDevNode->CrSetting->Attribute.StopBits,
CrDevNode->CrSetting->Attribute.FlowControl
));
DEBUG ((DEBUG_INFO, " DevicePath: %s\n", ConvertDevicePathToText ((const EFI_DEVICE_PATH *)DevPath, FALSE, TRUE)));
SerialAttribs.Size = sizeof (H2O_SERIAL_ATTRIBS);
SerialAttribs.BaudRate = mCrBaudRateTable[CrDevNode->CrSetting->Attribute.BaudRate];
SerialAttribs.Parity = CrDevNode->CrSetting->Attribute.Parity;
SerialAttribs.StopBits = CrDevNode->CrSetting->Attribute.StopBits;
SerialAttribs.DataBits = CrDevNode->CrSetting->Attribute.DataBits;
SerialAttribs.Present = CrDevNode->CrSetting->Attribute.PortEnable;
SerialAttribs.Timeout = 0;
SerialAttribs.ReceiveFifoDepth = 0;
SerialAttribs.TransmitFifoDepth = 0;
SerialAttribs.DevicePath = DevPath;
SerialAttribs.MaxDevicePathSize = 60;
Status = H2OGetSerialAttribsConfig (&SerialAttribs);
if (Status != EFI_MEDIA_CHANGED && Status != EFI_UNSUPPORTED) {
CrDevNode->CrSetting->Exist = FALSE;
CrDevNode->CrSetting->Attribute.PortEnable = FALSE;
} else {
for (Index = 0; mCrBaudRateTable[Index] != 0; Index++) {
if (SerialAttribs.BaudRate == mCrBaudRateTable[Index]) {
break;
}
}
CrDevNode->CrSetting->Attribute.BaudRate = (mCrBaudRateTable[Index] == 0) ? --Index : Index;
CrDevNode->CrSetting->Attribute.Parity = VerifyParity (SerialAttribs.Parity);
CrDevNode->CrSetting->Attribute.DataBits = VerifyDataBits (SerialAttribs.DataBits);
CrDevNode->CrSetting->Attribute.StopBits = VerifyStopBits (SerialAttribs.StopBits);
CrDevNode->CrSetting->Attribute.PortEnable = (SerialAttribs.Present == 0) ? 0 : 1;
if (Status == EFI_MEDIA_CHANGED) {
CrDevNode->CrSetting->Attribute.UseGlobalSetting = 0;
}
if (CrDevNode->CrSetting->Attribute.PortEnable == FALSE) {
CrDevNode->CrSetting->Exist = FALSE;
}
DEBUG ((DEBUG_INFO, " New CR Setting\n"));
DEBUG ((DEBUG_INFO, " Exist:%d, ItemType:%d, PortEnable:%d, Global:%d, TerminalType:%d, BaudRate:%d, Parity:%d, DataBits:%d, StopBits:%d, FlowControl:%d\n",
CrDevNode->CrSetting->Exist,
CrDevNode->CrSetting->ItemType,
CrDevNode->CrSetting->Attribute.PortEnable,
CrDevNode->CrSetting->Attribute.UseGlobalSetting,
CrDevNode->CrSetting->Attribute.TerminalType,
CrDevNode->CrSetting->Attribute.BaudRate,
CrDevNode->CrSetting->Attribute.Parity,
CrDevNode->CrSetting->Attribute.DataBits,
CrDevNode->CrSetting->Attribute.StopBits,
CrDevNode->CrSetting->Attribute.FlowControl
));
UpdateCrDev = TRUE;
}
if (UpdateCrDev) {
UpdateOrDeleteCrDevVarWithDevInfo (CrDevNode->VarIndex ,CrDevNode->CrSetting);
//
// Update UART node information
//
TempPath = DevPath;
while (!IsDevicePathEnd(TempPath)) {
if (TempPath->Type == MESSAGING_DEVICE_PATH && TempPath->SubType == MSG_UART_DP) {
Uart = (UART_DEVICE_PATH *)TempPath;
Uart->BaudRate = mCrBaudRateTable[CrDevNode->CrSetting->Attribute.BaudRate];
Uart->DataBits = CrDevNode->CrSetting->Attribute.DataBits;
Uart->StopBits = CrDevNode->CrSetting->Attribute.StopBits;
Uart->Parity = CrDevNode->CrSetting->Attribute.Parity;
break;
}
TempPath = NextDevicePathNode(TempPath);
}
DEBUG ((DEBUG_INFO, " New DevicePath: %s\n", ConvertDevicePathToText (GetDevicePathFromCrDevSetting (CrDevNode->CrSetting), FALSE, TRUE)));
UpdateCrDev = FALSE;
}
Link = GetNextNode (&mCrVarDeviceHead.Link, Link);
}
return;
}