/** @file Initializes Serial IO Controllers. Copyright (c) 2019 Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include "PchInit.h" #include #include #include #include typedef struct { ACPI_HID_DEVICE_PATH RootPort; ACPI_EXTENDED_HID_DEVICE_PATH AcpiDev; CHAR8 HidString[8]; CHAR8 UidString; CHAR8 CidString; EFI_DEVICE_PATH_PROTOCOL End; } SERIALIO_DEVICE_PATH; #define gPciRootBridge {{ACPI_DEVICE_PATH, ACPI_DP, {(UINT8)(sizeof(ACPI_HID_DEVICE_PATH)), 0}}, EISA_PNP_ID (0x0A03), 0} #define gAcpiDev {{ACPI_DEVICE_PATH,ACPI_EXTENDED_DP,{(UINT8)(sizeof(ACPI_EXTENDED_HID_DEVICE_PATH)+SERIALIO_TOTAL_ID_LENGTH),0}},0,0,0} #define gEndEntire {END_DEVICE_PATH_TYPE,END_ENTIRE_DEVICE_PATH_SUBTYPE,{END_DEVICE_PATH_LENGTH,0}} GLOBAL_REMOVE_IF_UNREFERENCED SERIALIO_DEVICE_PATH gSerialIoPath = { gPciRootBridge, gAcpiDev, "\0\0\0\0\0\0\0", '\0', '\0', gEndEntire }; /** Mark memory used by SerialIo devices in ACPI mode as allocated @retval EFI_SUCCESS The function completed successfully **/ EFI_STATUS AllocateSerialIoMemory ( VOID ) { PCH_SERIAL_IO_CONTROLLER i; UINT8 BarNumber; UINTN Bar; EFI_STATUS Status; for (i=0; iSerialIo.DevMode[i] == PchSerialIoHidden || mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoAcpi) { for (BarNumber = 0; BarNumber<=1; BarNumber++) { Bar = FindSerialIoBar (i,BarNumber); Status = gDS->AddMemorySpace ( EfiGcdMemoryTypeReserved, Bar, V_SERIAL_IO_CFG_BAR_SIZE, 0 ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } Status = gDS->AllocateMemorySpace ( EfiGcdAllocateAddress, EfiGcdMemoryTypeReserved, N_SERIAL_IO_CFG_BAR_ALIGNMENT, V_SERIAL_IO_CFG_BAR_SIZE, &Bar, mImageHandle, NULL ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } } } } return EFI_SUCCESS; } VOID CreateSerialIoHandles ( VOID ) { EFI_HANDLE NewHandle; EFI_DEVICE_PATH_PROTOCOL *NewPath; UINT32 Controller; for (Controller = 0; Controller < PchSerialIoIndexMax; Controller++) { if (mPchConfigHob->SerialIo.DevMode[Controller] == PchSerialIoAcpi) { NewHandle = NULL; CopyMem (gSerialIoPath.HidString, GetSerialIoAcpiHid (Controller), SERIALIO_HID_LENGTH); NewPath = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*)&gSerialIoPath); gBS->InstallMultipleProtocolInterfaces ( &NewHandle, &gEfiDevicePathProtocolGuid, NewPath, NULL ); } } } /** Puts all SerialIo controllers (except UARTs in debug mode) in D3. Clears MemoryEnable for all PCI-mode controllers on S3 resume **/ VOID ConfigureSerialIoAtS3Resume ( VOID ) { PCH_SERIAL_IO_CONTROLLER Index; UINTN PciCfgBase; UINT32 Data32; for (Index = 0; Index < PchSerialIoIndexMax; Index++) { if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) { if (IsSerialIoFunctionZero (Index)) { if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index), GetSerialIoFunctionNumber (Index))) { PciCfgBase = FindSerialIoBar (Index,1); Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS); Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST; S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32); } } continue; } if ((Index >= PchSerialIoIndexUart0) && (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) && (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0))) { continue; } PciCfgBase = FindSerialIoBar (Index,1); Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS); Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST; S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32); if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) { Data32 = MmioRead32 (PciCfgBase + PCI_COMMAND_OFFSET); Data32 &= (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER); S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + PCI_COMMAND_OFFSET, 1, &Data32); } } }