/** @file PCIE root port library. 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 #include #include "PchPcieRpLibInternal.h" GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_CONTROLLER_INFO mPchPcieControllerInfo[] = { { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_1, PID_SPA, 0 }, { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_5, PID_SPB, 4 }, { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_9, PID_SPC, 8 }, { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_13, PID_SPD, 12 }, { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_17, PID_SPE, 16 }, // PCH-H only { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_21, PID_SPF, 20 } // PCH-H only }; /** Get Pch Pcie Root Port Device and Function Number by Root Port physical Number @param[in] RpNumber Root port physical number. (0-based) @param[out] RpDev Return corresponding root port device number. @param[out] RpFun Return corresponding root port function number. @retval EFI_SUCCESS Root port device and function is retrieved @retval EFI_INVALID_PARAMETER RpNumber is invalid **/ EFI_STATUS EFIAPI GetPchPcieRpDevFun ( IN UINTN RpNumber, OUT UINTN *RpDev, OUT UINTN *RpFun ) { UINTN Index; UINTN FuncIndex; UINT32 PciePcd; if (RpNumber >= GetPchMaxPciePortNum ()) { DEBUG ((DEBUG_ERROR, "GetPchPcieRpDevFun invalid RpNumber %x", RpNumber)); ASSERT (FALSE); return EFI_INVALID_PARAMETER; } Index = RpNumber / PCH_PCIE_CONTROLLER_PORTS; FuncIndex = RpNumber - mPchPcieControllerInfo[Index].RpNumBase; *RpDev = mPchPcieControllerInfo[Index].DevNum; PciePcd = PchPcrRead32 (mPchPcieControllerInfo[Index].Pid, R_SPX_PCR_PCD); *RpFun = (PciePcd >> (FuncIndex * S_SPX_PCR_PCD_RP_FIELD)) & B_SPX_PCR_PCD_RP1FN; return EFI_SUCCESS; } /** Get Root Port physical Number by Pch Pcie Root Port Device and Function Number @param[in] RpDev Root port device number. @param[in] RpFun Root port function number. @param[out] RpNumber Return corresponding physical Root Port index (0-based) @retval EFI_SUCCESS Physical root port is retrieved **/ EFI_STATUS EFIAPI GetPchPcieRpNumber ( IN UINTN RpDev, IN UINTN RpFun, OUT UINTN *RpNumber ) { UINT64 RpBase; RpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, RpDev, RpFun, 0); *RpNumber = (PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) >> N_PCH_PCIE_CFG_LCAP_PN) -1; return EFI_SUCCESS; } /** This function returns PID according to PCIe controller index @param[in] ControllerIndex PCIe controller index @retval PCH_SBI_PID Returns PID for SBI Access **/ PCH_SBI_PID PchGetPcieControllerSbiPid ( IN UINT32 ControllerIndex ) { ASSERT (ControllerIndex < ARRAY_SIZE (mPchPcieControllerInfo)); return mPchPcieControllerInfo[ControllerIndex].Pid; } /** This function returns PID according to Root Port Number @param[in] RpIndex Root Port Index (0-based) @retval PCH_SBI_PID Returns PID for SBI Access **/ PCH_SBI_PID GetRpSbiPid ( IN UINTN RpIndex ) { return PchGetPcieControllerSbiPid ((UINT32) (RpIndex / PCH_PCIE_CONTROLLER_PORTS)); }