summaryrefslogtreecommitdiff
path: root/Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib
diff options
context:
space:
mode:
authorJiewen Yao <jiewen.yao@intel.com>2017-06-19 10:55:06 +0800
committerJiewen Yao <jiewen.yao@intel.com>2017-06-20 15:12:29 +0800
commit646b243c0e3ef49b98071ca2c3fec15299b4d72f (patch)
tree00d62812fcedd3d1bf49692b863bb48a826f3ab0 /Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib
parentf98787b719524d7ba9f2cefac0e8c8b8698cb02c (diff)
downloadedk2-platforms-646b243c0e3ef49b98071ca2c3fec15299b4d72f.tar.xz
Add KabylakeSiliconPkg
reviewed-by: Jiewen Yao <jiewen.yao@intel.com> reviewed-by: Michael A Kubacki <michael.a.kubacki@intel.com> reviewed-by: Amy Chan <amy.chan@intel.com> reviewed-by: Rangasai V Chaganty <rangasai.v.chaganty@intel.com> reviewed-by: Chasel Chiu <chasel.chiu@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
Diffstat (limited to 'Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib')
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.c216
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/Pch/LibraryPrivate/PeiDxeSmmRstPrivateLib/PeiDxeSmmRstPrivateLib.inf42
2 files changed, 258 insertions, 0 deletions
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.<BR>
+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 <Library/RstPrivateLib.h>
+#include <PchPcieStorageDetectHob.h>
+
+/**
+ 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.<BR>
+#
+# 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