/** @file
Serial IO Private Lib implementation.
All function in this library is available for PEI, DXE, and SMM,
But do not support UEFI RUNTIME environment call.
Copyright (c) 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
Checks if higher functions are enabled.
Used for Function 0 Serial Io Device disabling
@param[in] DeviceNum Device Number
@retval TRUE At least one higher function device is enabled
FALSE Higher functions are disabled
**/
BOOLEAN
SerialIoHigherFunctionsEnabled (
IN UINT8 DeviceNum
)
{
UINT8 FuncNum;
//
// Check all other func devs(1 to 7) status except func 0.
//
for (FuncNum = 1; FuncNum <= PCI_MAX_FUNC; FuncNum++) {
if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH,
DEFAULT_PCI_BUS_NUMBER_PCH,
DeviceNum,
FuncNum,
PCI_DEVICE_ID_OFFSET)
) != 0xFFFF) {
return TRUE;
}
}
return FALSE;
}
/**
Places SerialIo device in D3
@param[in] PciCfgBase Pci Config Offset
**/
VOID
SerialIoSetD3 (
IN UINT64 PciCfgBase
)
{
if (PciCfgBase < PCH_SERIAL_IO_BASE_ADDRESS) {
PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | BIT0);
} else {
MmioOr8 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | BIT0);
//
// Reading back value after write to ensure bridge observes the BAR1 write access
//
MmioRead8 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
}
}
/**
Places SerialIo device in D0
@param[in] PciCfgBase Pci Config Offset
**/
VOID
SerialIoSetD0 (
IN UINT64 PciCfgBase
)
{
if (PciCfgBase < PCH_SERIAL_IO_BASE_ADDRESS) {
PciSegmentAnd32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, (UINT32) ~(BIT1 | BIT0));
} else {
MmioAnd32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, (UINT32) ~(BIT1 | BIT0));
//
// Reading back value after write to ensure bridge observes the BAR1 write access
//
MmioRead32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
}
}
/**
Allows memory access
@param[in] PciCfgBase Pci Config Offset
@param[in] Hidden Mode that determines access type
**/
VOID
SerialIoEnableMse (
IN UINT64 PciCfgBase,
IN BOOLEAN Hidden
)
{
if (Hidden) {
MmioOr16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
//
// Reading back value after write to ensure bridge observes the BAR1 write access
//
MmioRead16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET);
} else {
PciSegmentOr16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
}
}
/**
Disable SerialIo memory access
@param[in] PciCfgBase Pci Config Offset
**/
VOID
SerialIoDisableMse (
IN UINT64 PciCfgBase
)
{
PciSegmentAnd16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE);
}
/**
Disable SerialIo memory encoding
Designated for Pci modes
@param[in] PciCfgBase Pci Config Offset
@param[in] RemoveTempBar Remove temporary mem base address or not
**/
VOID
SerialIoMmioDisable (
IN UINT64 PciCfgBase,
IN BOOLEAN RemoveBar
)
{
SerialIoDisableMse (PciCfgBase);
if (RemoveBar == TRUE) {
PciSegmentWrite32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW, 0x0);
PciSegmentWrite32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0);
}
}