From 646b243c0e3ef49b98071ca2c3fec15299b4d72f Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Mon, 19 Jun 2017 10:55:06 +0800 Subject: Add KabylakeSiliconPkg reviewed-by: Jiewen Yao reviewed-by: Michael A Kubacki reviewed-by: Amy Chan reviewed-by: Rangasai V Chaganty reviewed-by: Chasel Chiu Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao Signed-off-by: Chasel Chiu --- .../PeiDxeSmmRstPrivateLib.c | 216 +++++++++++++++++++++ .../PeiDxeSmmRstPrivateLib.inf | 42 ++++ 2 files changed, 258 insertions(+) create mode 100644 Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.c create mode 100644 Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.inf (limited to 'Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib') diff --git a/Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.c b/Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.c new file mode 100644 index 0000000000..7436a76ec1 --- /dev/null +++ b/Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.c @@ -0,0 +1,216 @@ +/** @file + Routines for Rst remapping + +Copyright (c) 2017, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +/** + Checks whether device on given Root Port is remap capable + + @param[in] RpNumber Root Port Number + @param[in] TempPciBus Temporary Pci Bus + + @retval UINT8 Device Programming Interface +**/ +UINT8 +RstGetProgInterfaceForRemapDevice ( + IN UINT32 RpNumber, + IN UINT32 TempPciBus +) +{ + UINTN RpDevice; + UINTN RpFunction; + UINT8 BusNumber; + UINTN EpBase; + UINT8 PiInterface; + UINTN RpBase; + UINT8 ClassCode; + UINT8 SubClassCode; + + + DEBUG ((DEBUG_INFO, "Detect storage device on Rp: %d\n", RpNumber)); + + GetPchPcieRpDevFun (RpNumber, &RpDevice, &RpFunction); + BusNumber = DEFAULT_PCI_BUS_NUMBER_PCH; + PiInterface = RST_PCIE_STORAGE_INTERFACE_NONE; + RpBase = MmPciBase (BusNumber, (UINT32) RpDevice, (UINT32) RpFunction); + + if (MmioRead16 (RpBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) { + DEBUG((DEBUG_INFO, "RstGetProgInterfaceForRemapDevices: RootPort does not exists Rp = %d\n", RpNumber)); + + return PiInterface; + } + + // + // Assign Temporary Bus Number + // + MmioAndThenOr32 ( + RpBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, + (UINT32) ~B_PCI_BRIDGE_BNUM_SBBN_SCBN, + ((UINT32) (TempPciBus << 8)) | ((UINT32) (TempPciBus << 16)) + ); + + // + // A config write is required in order for the device to re-capture the Bus number, + // according to PCI Express Base Specification, 2.2.6.2 + // Write to a read-only register VendorID to not cause any side effects. + // + EpBase = MmPciBase (TempPciBus, 0, 0); + MmioWrite16 (EpBase + PCI_VENDOR_ID_OFFSET, 0); + + // + // Read Vendor Id to check if device exists + // if not clear bus number and return RST_PCIE_STORAGE_INTERFACE_NONE + // + if (MmioRead16 (EpBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) { + MmioAnd32 (RpBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, (UINT32) ~B_PCI_BRIDGE_BNUM_SBBN_SCBN); + return PiInterface; + } + + ClassCode = MmioRead8 (EpBase + R_PCI_BCC_OFFSET); + SubClassCode = MmioRead8 (EpBase + R_PCI_SCC_OFFSET); + PiInterface = MmioRead8 (EpBase + R_PCI_PI_OFFSET); + + if ( ClassCode == PCI_CLASS_MASS_STORAGE) { + DEBUG ((DEBUG_INFO, "RstGetProgInterfaceForRemapDevice: ClassCode = %X, SubClassCode = %X, PiInterface = %X\n", ClassCode, SubClassCode, PiInterface)); + + if (SubClassCode == PCI_CLASS_MASS_STORAGE_AHCI) { + if (PiInterface == RST_PCIE_STORAGE_INTERFACE_AHCI) { + DEBUG ((DEBUG_INFO, "RstGetProgInterfaceForRemapDevice: AHCI Card found on Rp: %d\n", RpNumber)); + + } + } else if (SubClassCode == PCI_CLASS_MASS_STORAGE_NVME) { + if (PiInterface == RST_PCIE_STORAGE_INTERFACE_NVME) { + DEBUG ((DEBUG_INFO, "RstGetProgInterfaceForRemapDevice: NVMe Card found on Rp: %d\n", RpNumber)); + + } + } else if (SubClassCode == PCI_CLASS_MASS_STORAGE_RAID) { + DEBUG ((DEBUG_INFO, "RstGetProgInterfaceForRemapDevice: RAID Card found on Rp: %d\n", RpNumber)); + + PiInterface = RST_PCIE_STORAGE_INTERFACE_NVME; + } + } + // + // Clear temporary bus number + // + MmioAnd32 (RpBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, (UINT32) ~B_PCI_BRIDGE_BNUM_SBBN_SCBN); + + return PiInterface; + +} + +/** + Check the lane occupied by certain root port according to the root port number and configuration strap + Return 8-bit bitmap where each bit represents the lane number (e.g.: return 00000011b means the root port owns 2 lane) + + @param[in] RootPortNum Root Port Number + + @retval UINT8 Lane Occupied by the Root Port (bitmap) +**/ +UINT8 +RstGetRpLaneOccupyMask ( + IN UINT32 RootPortNum + ) +{ + EFI_STATUS Status; + UINT32 CtrlNum; + UINT32 CtrlFirstRpNum; + UINT32 Data32; + UINT8 LaneOccupied; + + LaneOccupied = 0; + + CtrlNum = RootPortNum / PCH_PCIE_CONTROLLER_PORTS; + CtrlFirstRpNum = CtrlNum * PCH_PCIE_CONTROLLER_PORTS; + + // + // Read the Root Port Configuration Straps for the link width, and return LaneOccupied by the Root Port accordingly + // + Status = PchSbiRpPciRead32 (CtrlFirstRpNum, R_PCH_PCIE_STRPFUSECFG, &Data32); + ASSERT_EFI_ERROR (Status); + + switch ((Data32 & B_PCH_PCIE_STRPFUSECFG_RPC) >> N_PCH_PCIE_STRPFUSECFG_RPC) { + case V_PCH_PCIE_STRPFUSECFG_RPC_4: + if (RootPortNum % 4 == 0) { + LaneOccupied = (BIT3|BIT2|BIT1|BIT0); + } + break; + case V_PCH_PCIE_STRPFUSECFG_RPC_2_2: + if ((RootPortNum % 2 == 0)) { + LaneOccupied = (BIT1|BIT0); + } + break; + case V_PCH_PCIE_STRPFUSECFG_RPC_2_1_1: + if (RootPortNum % 4 == 0) { + LaneOccupied = (BIT1|BIT0); + } else if (RootPortNum % 4 != 1) { + LaneOccupied = BIT0; + } + break; + case V_PCH_PCIE_STRPFUSECFG_RPC_1_1_1_1: + LaneOccupied = BIT0; + break; + default: + break; + } + + return LaneOccupied; +} + +/** + Checks PCH generation and returns SATA's GCR.PLS bit number according to root port number with a PCIe storage device + connected to. + + @param[in] RootPortNum Root port number which PCIe storage device is connected to + + @retval UINT32 Number of GCR.PLS bit representing root port +**/ +UINT32 +RstPlsBitNumber ( + IN UINT32 RootPortNum + ) +{ + if ((GetPchGeneration () == KblPch) && (RstGetCycleRouterNumber (RootPortNum) == RST_PCIE_STORAGE_CR_2)) { + return RootPortNum - 2 * PCH_PCIE_CONTROLLER_PORTS; + } else { + return RootPortNum; + } +} + +/** + Checks if device with given PCI config space address is Intel's Stony Beach. + + @param[in] EndPointPciBase Address of device's PCI config space + + @retval BOOLEAN TRUE if device is Intel's Stony Beach, FALSE othrwise +**/ +BOOLEAN +RstIsStonyBeach ( + IN UINTN EndPointPciBase + ) +{ + UINT16 DeviceVendorId; + UINT16 DeviceDeviceId; + + DeviceVendorId = MmioRead16 (EndPointPciBase + PCI_VENDOR_ID_OFFSET); + DeviceDeviceId = MmioRead16 (EndPointPciBase + PCI_DEVICE_ID_OFFSET); + + if (DeviceVendorId == RST_STONY_BEACH_VENDOR_ID && DeviceDeviceId == RST_STONY_BEACH_DEVICE_ID) { + return TRUE; + } + + return FALSE; +} + + diff --git a/Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.inf b/Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.inf new file mode 100644 index 0000000000..1bbcc7eda7 --- /dev/null +++ b/Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.inf @@ -0,0 +1,42 @@ +## @file +# PCH Rst Library. +# +# All function in this library is available for PEI, DXE, and SMM, +# But do not support UEFI RUNTIME environment call. +# +# Copyright (c) 2017, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License which accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = PeiDxeSmmRstPrivateLib +FILE_GUID = FD2B63E7-FBBF-4D77-8A52-6702112EFDC1 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = RstPrivateLib + +[LibraryClasses] +BaseLib +IoLib +DebugLib +MmPciLib +PchInfoLib +PchPcieRpLib +PchInitCommonLib + +[Packages] +MdePkg/MdePkg.dec +KabylakeSiliconPkg/SiPkg.dec +KabylakeSiliconPkg/KabylakeSiliconPrivate.dec + +[Sources] +PeiDxeSmmRstPrivateLib.c -- cgit v1.2.3