/** @file
Initializes Serial IO Controllers.
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
typedef struct {
ACPI_HID_DEVICE_PATH RootPort;
ACPI_EXTENDED_HID_DEVICE_PATH AcpiDev;
CHAR8 HidString[8];
UINT16 DeviceId;
UINT8 UartIndex;
EFI_DEVICE_PATH_PROTOCOL End;
} SERIALIO_UART_DEVICE_PATH;
#define mPciRootBridge {{ACPI_DEVICE_PATH, ACPI_DP, {(UINT8)(sizeof (ACPI_HID_DEVICE_PATH)), 0}}, EISA_PNP_ID (0x0A03), 0}
#define mAcpiDev {{ACPI_DEVICE_PATH, ACPI_EXTENDED_DP, {(UINT8)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + (sizeof(CHAR8) * 8) + sizeof (UINT16) + sizeof (UINT8)), 0}},0,0,0}
#define mEndEntire {END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH, 0}}
GLOBAL_REMOVE_IF_UNREFERENCED SERIALIO_UART_DEVICE_PATH mSerialIoUartPath = {
mPciRootBridge,
mAcpiDev,
"UART\0\0\0",
0xFFFF,
0xFF,
mEndEntire
};
/**
Add Serial Io UART Hidden Handles
**/
VOID
CreateSerialIoUartHiddenHandle (
VOID
)
{
EFI_HANDLE NewHandle;
EFI_DEVICE_PATH_PROTOCOL *NewPath;
EFI_STATUS Status;
UINT8 Index;
UINT16 DeviceId;
DEBUG ((DEBUG_INFO, "CreateSerialIoUartHandle\n"));
for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
DEBUG ((DEBUG_INFO, "UART Index: %d Mode: %d\n", Index, mPchConfigHob->SerialIo.UartDeviceConfig[Index].Mode));
if (mPchConfigHob->SerialIo.UartDeviceConfig[Index].Mode == SerialIoUartHidden) {
NewHandle = NULL;
DeviceId = MmioRead16 (GetSerialIoUartFixedPciCfgAddress (Index) + PCI_DEVICE_ID_OFFSET);
DEBUG ((DEBUG_INFO, "Creating Handle for UART DEVICE_ID: 0x%X \n", DeviceId));
mSerialIoUartPath.AcpiDev.HID = 0x5432 + (Index << 16); //UAR
mSerialIoUartPath.HidString[4] = (CHAR8)('0' + Index);
mSerialIoUartPath.DeviceId = DeviceId;
mSerialIoUartPath.UartIndex = Index;
NewPath = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &mSerialIoUartPath);
Status = gBS->InstallMultipleProtocolInterfaces (
&NewHandle,
&gEfiDevicePathProtocolGuid,
NewPath,
NULL
);
DEBUG ((DEBUG_INFO, "CreateSerialIoUartHandle Status: %r\n", Status));
}
}
}
/**
Stores Pme Control Status and Command register values in S3 Boot Script
@param[in] S3PciCfgBase S3 Boot Script Pci Config Base
@param[in] Command Pci Command register data to save
@param[in] Pme Pci Pme Control register data to save
**/
VOID
STATIC
SerialIoS3Save (
IN UINTN S3PciCfgBase,
IN UINTN Command,
IN UINTN Pme
)
{
if (S3PciCfgBase != 0) {
S3BootScriptSavePciCfgWrite (S3BootScriptWidthUint32, S3PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Pme);
S3BootScriptSavePciCfgWrite (S3BootScriptWidthUint32, S3PciCfgBase + PCI_COMMAND_OFFSET, 1, &Command);
}
}
/**
Puts all SerialIo controllers (except UARTs in debug mode) in D3.
Clears MemoryEnable for all PCI-mode controllers on S3 resume
**/
VOID
ConfigureSerialIoAtS3Resume (
VOID
)
{
UINT8 Index;
UINTN S3PciCfgBase;
UINT32 Command;
UINT32 Pme;
S3PciCfgBase = 0;
for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
SerialIoSpiS3Handler (Index, &mPchConfigHob->SerialIo.SpiDeviceConfig[Index], &S3PciCfgBase, &Command, &Pme);
SerialIoS3Save (S3PciCfgBase, Command, Pme);
}
S3PciCfgBase = 0;
for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
SerialIoI2cS3Handler (Index, &mPchConfigHob->SerialIo.I2cDeviceConfig[Index], &S3PciCfgBase, &Command, &Pme);
SerialIoS3Save (S3PciCfgBase, Command, Pme);
}
S3PciCfgBase = 0;
for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
SerialIoUartS3Handler (Index, &mPchConfigHob->SerialIo.UartDeviceConfig[Index], &S3PciCfgBase, &Command, &Pme);
SerialIoS3Save (S3PciCfgBase, Command, Pme);
}
}