/** @file
Serial IO Private Lib implementation - UART part
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
#include
#include
/**
Checks if UART is Hidden, and it's Pci Config space available
@param[in] UartNumber Selects Serial IO UART device
@retval TRUE UART is in hidden mode
@retval FALSE UART is not in hidden mode
**/
BOOLEAN
IsSerialIoUartHidden (
IN UINT8 UartNumber
)
{
if (MmioRead16 (GetSerialIoUartFixedPciCfgAddress (UartNumber) + PCI_DEVICE_ID_OFFSET) == GetSerialIoUartDeviceId (UartNumber)) {
return TRUE;
}
return FALSE;
}
/**
Configures Serial IO Controller before control is passd to the OS
@param[in] UartNumber UART Number
@param[in] UartDeviceConfig SerialIo UART Config
**/
VOID
SerialIoUartBootHandler (
IN UINT8 UartNumber,
IN SERIAL_IO_UART_CONFIG *UartDeviceConfig
)
{
UINT64 PciCfgBase;
BOOLEAN TurnOff;
TurnOff = FALSE;
//
// Even if Uart is Hidden and in D3 SerialIoUartLib is capable of setting D0 during each write/read.
// In case it is required for Os Debug DBG2 must be set to TRUE.
//
if (UartDeviceConfig->Mode == SerialIoUartPci || UartDeviceConfig->Mode == SerialIoUartHidden) {
TurnOff = TRUE;
}
//
// Uart in Com mode will be placed in D3 depending on PG configuration through ACPI _PS3
//
if ((UartDeviceConfig->Mode == SerialIoUartDisabled) && (SerialIoUartFuncNumber (UartNumber) == 0x0)) {
if (SerialIoHigherFunctionsEnabled (SerialIoUartDevNumber (UartNumber))) {
TurnOff = TRUE;
}
}
if (UartDeviceConfig->DBG2 == TRUE) {
TurnOff = FALSE;
}
if (TurnOff) {
PciCfgBase = GetSerialIoUartPciCfg (UartNumber);
SerialIoSetD3 (PciCfgBase);
if ((UartDeviceConfig->Mode == SerialIoUartPci) || (UartDeviceConfig->Mode == SerialIoUartDisabled)) {
SerialIoMmioDisable (PciCfgBase, TRUE);
}
}
}
/**
Sets Pme Control Status and Command register values required for S3 Boot Script
@param[in] UartNumber UART Number
@param[in] UartDeviceConfig SerialIo UART Config
@param[in/out] S3PciCfgBase S3 Boot Script Pci Config Base
@param[in/out] Command Pci Command register data to save
@param[in/out] Pme Pci Pme Control register data to save
**/
VOID
SerialIoUartS3Handler (
IN UINT8 UartNumber,
IN SERIAL_IO_UART_CONFIG *UartDeviceConfig,
IN OUT UINT64 *S3PciCfgBase,
IN OUT UINT32 *Command,
IN OUT UINT32 *Pme
)
{
BOOLEAN TurnOff;
UINT64 PciCfgBase;
*S3PciCfgBase = 0;
TurnOff = FALSE;
if (UartDeviceConfig->Mode == SerialIoUartPci) {
TurnOff = TRUE;
}
if ((UartDeviceConfig->Mode == SerialIoUartDisabled) && (SerialIoUartFuncNumber (UartNumber) == 0x0)) {
if (SerialIoHigherFunctionsEnabled (SerialIoUartDevNumber (UartNumber))) {
TurnOff = TRUE;
}
}
if (TurnOff) {
*S3PciCfgBase = GetSerialIoUartS3PciBase (UartNumber);
PciCfgBase = GetSerialIoUartPciCfg (UartNumber);
*Pme = PciSegmentRead32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
*Pme = *Pme | BIT0 | BIT1;
*Command = PciSegmentRead32 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET);
*Command = *Command & (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
}
}