/** @file
Common Serial IO Private Lib implementation - SPI 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 SPI is Hidden, and it's Pci Config space available
@param[in] SpiNumber Selects Serial IO SPI device
@retval TRUE SPI is in hidden mode
@retval FALSE SPI is not in hidden mode
**/
BOOLEAN
IsSerialIoSpiHidden (
IN UINT8 SpiNumber
)
{
if (MmioRead16 (GetSerialIoSpiFixedPciCfgAddress (SpiNumber) + PCI_DEVICE_ID_OFFSET) == GetSerialIoSpiDeviceId (SpiNumber)) {
return TRUE;
}
return FALSE;
}
/**
Configures Serial IO Controller before control is passd to the OS
@param[in] SpiNumber SPI Number
@param[in] SpiDeviceConfig SerialIo SPI Config
**/
VOID
SerialIoSpiBootHandler (
IN UINT8 SpiNumber,
IN SERIAL_IO_SPI_CONFIG *SpiDeviceConfig
)
{
UINT64 PciCfgBase;
BOOLEAN TurnOff;
TurnOff = FALSE;
if (SpiDeviceConfig->Mode == SerialIoSpiPci) {
TurnOff = TRUE;
}
if ((SpiDeviceConfig->Mode == SerialIoSpiDisabled) && (SerialIoSpiFuncNumber (SpiNumber) == 0x0)) {
if (SerialIoHigherFunctionsEnabled (SerialIoSpiDevNumber (SpiNumber))) {
TurnOff = TRUE;
}
}
if (TurnOff) {
PciCfgBase = GetSerialIoSpiPciCfg (SpiNumber);
SerialIoSetD3 (PciCfgBase);
SerialIoMmioDisable (PciCfgBase, TRUE);
}
}
/**
Sets Pme Control Status and Command register values required for S3 Boot Script
@param[in] SpiNumber SPI Number
@param[in] SpiDeviceConfig SerialIo SPI 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
SerialIoSpiS3Handler (
IN UINT8 SpiNumber,
IN SERIAL_IO_SPI_CONFIG *SpiDeviceConfig,
IN OUT UINT64 *S3PciCfgBase,
IN OUT UINT32 *Command,
IN OUT UINT32 *Pme
)
{
BOOLEAN TurnOff;
UINT64 PciCfgBase;
*S3PciCfgBase = 0;
TurnOff = FALSE;
if (SpiDeviceConfig->Mode == SerialIoSpiPci) {
TurnOff = TRUE;
}
if ((SpiDeviceConfig->Mode == SerialIoSpiDisabled) && (SerialIoSpiFuncNumber (SpiNumber) == 0x0)) {
if (SerialIoHigherFunctionsEnabled (SerialIoSpiDevNumber (SpiNumber))) {
TurnOff = TRUE;
}
}
if (TurnOff) {
*S3PciCfgBase = GetSerialIoSpiS3PciBase (SpiNumber);
PciCfgBase = GetSerialIoSpiPciCfg (SpiNumber);
*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);
}
}