summaryrefslogtreecommitdiff
path: root/Silicon/Intel/KabylakeSiliconPkg/Pch/PchInit/Dxe/PchRstPcieStorage.c
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/PchInit/Dxe/PchRstPcieStorage.c
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/PchInit/Dxe/PchRstPcieStorage.c')
-rw-r--r--Silicon/Intel/KabylakeSiliconPkg/Pch/PchInit/Dxe/PchRstPcieStorage.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/Silicon/Intel/KabylakeSiliconPkg/Pch/PchInit/Dxe/PchRstPcieStorage.c b/Silicon/Intel/KabylakeSiliconPkg/Pch/PchInit/Dxe/PchRstPcieStorage.c
new file mode 100644
index 0000000000..801abf2602
--- /dev/null
+++ b/Silicon/Intel/KabylakeSiliconPkg/Pch/PchInit/Dxe/PchRstPcieStorage.c
@@ -0,0 +1,286 @@
+/** @file
+ Configures the remapping for PCH Intel RST PCie Storage
+ In order to use this feature, Intel RST Driver is required
+
+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 "PchInit.h"
+#include <Library/RstPrivateLib.h>
+#include <PchPcieStorageDetectHob.h>
+
+//
+// Variables below indicate the memory range to be allocated to the PCIe storage device BAR usage when it is HIDDEN,
+// thus it does not overlapped with the SGREG_BAR from the host perspective
+//
+#define RST_PCIE_STORAGE_MEMORY_START_RANGE PCH_PCR_BASE_ADDRESS
+#define RST_PCIE_STORAGE_MEMORY_END_RANGE (PCH_PCR_BASE_ADDRESS + PCH_PCR_MMIO_SIZE - 1)
+
+#define PCI_CARD_PM_CAP_ID 0x01
+#define PCI_CARD_MSIX_CAP_ID 0x11
+#define PCI_CARD_SATA_CAP_ID 0x12
+#define PCI_CARD_BAR_TOTAL 6
+#define PCI_CARD_LINK_SPEED_GEN1_GEN2 0
+#define PCI_CARD_LINK_SPEED_GEN3 1
+#define PCI_CARD_LINK_WIDTH_1 0
+#define PCI_CARD_LINK_WIDTH_2 1
+#define PCI_CARD_LINK_WIDTH_4 2
+#define PCI_CARD_REVISION 0x08
+#define PCI_CARD_BASE_ADDR0 0x10
+#define PCI_CARD_BASE_ADDR1 0x14
+#define PCI_CARD_BASE_ADDR5 0x24
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_RST_PCIE_STORAGE_DETECTION mRstPcieStorageDetection [PCH_MAX_RST_PCIE_STORAGE_CR];
+
+UINT32 PchRstPcieStorageCurrentMemoryRange = RST_PCIE_STORAGE_MEMORY_START_RANGE;
+
+
+/**
+ Function to perform dump for PCH_RST_PCIE_STORAGE_DETECTION
+
+ @param[in] Index Index for RST PCIe Storage Cycle Router Instance
+
+ @retval None
+**/
+VOID
+PchRstPcieStorageRemappingDump (
+ IN UINTN Index
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ DEBUG ((DEBUG_INFO, "PchRstPcieStorageRemappingDump() Started\n"));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].SupportRstPcieStoragRemapping = %x\n", Index, mRstPcieStorageDetection[Index].SupportRstPcieStoragRemapping));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].RootPortNum = %x\n", Index, mRstPcieStorageDetection[Index].RootPortNum));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].RootPortLane = %x\n", Index, mRstPcieStorageDetection[Index].RootPortLane));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].DeviceInterface = %x\n", Index, mRstPcieStorageDetection[Index].DeviceInterface));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].IsMsixSupported = %x\n", Index, mRstPcieStorageDetection[Index].IsMsixSupported));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].MsixStartingVector = %x\n", Index, mRstPcieStorageDetection[Index].MsixStartingVector));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].MsixEndingVector = %x\n", Index, mRstPcieStorageDetection[Index].MsixEndingVector));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].EndPointBarSize = %x\n", Index, mRstPcieStorageDetection[Index].EndPointBarSize));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].EndPointUniqueMsixTableBar = %x\n", Index, mRstPcieStorageDetection[Index].EndPointUniqueMsixTableBar));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].EndPointUniqueMsixTableBarValue = %x\n", Index, mRstPcieStorageDetection[Index].EndPointUniqueMsixTableBarValue));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].EndPointUniqueMsixPbaBar = %x\n", Index, mRstPcieStorageDetection[Index].EndPointUniqueMsixPbaBar));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].EndPointUniqueMsixPbaBarValue = %x\n", Index, mRstPcieStorageDetection[Index].EndPointUniqueMsixPbaBarValue));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].EndPointBcc = %x\n", Index, mRstPcieStorageDetection[Index].EndPointBcc));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].EndPointScc = %x\n", Index, mRstPcieStorageDetection[Index].EndPointScc));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].EndPointPi = %x\n", Index, mRstPcieStorageDetection[Index].EndPointPi));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.PmCapPtr = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.PmCapPtr));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.PcieCapPtr = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.PcieCapPtr));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.L1ssCapPtr = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.L1ssCapPtr));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.EndpointL1ssControl2 = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.EndpointL1ssControl2));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.EndpointL1ssControl1 = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.EndpointL1ssControl1));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.LtrCapPtr = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.LtrCapPtr));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.EndpointLtrData = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.EndpointLtrData));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.EndpointLctlData16 = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.EndpointLctlData16));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.EndpointDctlData16 = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.EndpointDctlData16));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.EndpointDctl2Data16 = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.EndpointDctl2Data16));
+ DEBUG ((DEBUG_INFO, "mRstPcieStorageDetection[%d].PchRstPcieStorageSaveRestore.RootPortDctl2Data16 = %x\n", Index, mRstPcieStorageDetection[Index].PchRstPcieStorageSaveRestore.RootPortDctl2Data16));
+ DEBUG ((DEBUG_INFO, "PchRstPcieStorageRemappingDump() Ended\n"));
+ DEBUG_CODE_END ();
+}
+
+/**
+ Perform memory space allocation or free memory pool for AHCI BAR
+
+ @param[in] Operation True: Perform memory space allocation for AHCI BAR
+ False: Perform memory pool free for AHCI BAR
+ @param[in,out] MemBaseAddress The base memory address used by AHCI BAR
+**/
+VOID
+AbarMemorySpaceOperation (
+ IN BOOLEAN Operation,
+ IN OUT EFI_PHYSICAL_ADDRESS *MemBaseAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINTN AhciBarAlignment;
+ UINTN AhciBarLength;
+
+ //
+ // Assign a 512k size memory space to the ABAR when NVM Remapping is enabled
+ //
+ AhciBarAlignment = N_PCH_SATA_AHCI_BAR_ALIGNMENT_512K; // 2^19: 512K Alignment
+ AhciBarLength = V_PCH_SATA_AHCI_BAR_LENGTH_512K; // 512K Length
+
+
+ if (Operation == TRUE) {
+ ///
+ /// If MemBaseAddress is not allocated yet, allocate the AHCI BAR
+ ///
+ if ((PcdGet8 (PcdEfiGcdAllocateType) == EfiGcdAllocateMaxAddressSearchBottomUp) || (PcdGet8 (PcdEfiGcdAllocateType) == EfiGcdAllocateMaxAddressSearchTopDown)) {
+ BaseAddress = 0x0ffffffff;
+ }
+ Status = gDS->AllocateMemorySpace (
+ PcdGet8 (PcdEfiGcdAllocateType),
+ EfiGcdMemoryTypeMemoryMappedIo,
+ AhciBarAlignment,
+ AhciBarLength,
+ &BaseAddress,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ *MemBaseAddress = BaseAddress;
+ } else {
+ ///
+ /// Else, free the GCD pool
+ ///
+ gDS->FreeMemorySpace (
+ *MemBaseAddress,
+ AhciBarLength
+ );
+ }
+}
+
+/**
+ Function to perform memory allocation for PCIe storage device that support unique BAR
+
+ @param[in] BarSize The BAR size required for memory allocation
+ @param[in,out] AllocAddr The Address that been allocated by this function
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Memory or storage is not enough
+**/
+EFI_STATUS
+PchRstPcieStorageMemAllocation (
+ IN UINT32 BarSize,
+ IN OUT UINT32 *AllocAddr
+ )
+{
+ if ((PchRstPcieStorageCurrentMemoryRange + BarSize) > RST_PCIE_STORAGE_MEMORY_END_RANGE) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if ((PchRstPcieStorageCurrentMemoryRange & (BarSize - 1)) != 0) {
+ *AllocAddr = (PchRstPcieStorageCurrentMemoryRange + BarSize) & ~(BarSize-1);
+ } else {
+ *AllocAddr = PchRstPcieStorageCurrentMemoryRange;
+ }
+
+ PchRstPcieStorageCurrentMemoryRange = *AllocAddr + BarSize;
+ return EFI_SUCCESS;
+}
+
+/**
+ Check and detect PCIe storage device per policies, and if existed, indicate if it should be subjected for remapping
+ Populate the mRstPcieStorageDetection structure along with it for later usages
+
+ @param[in, out] RemappingRequired Boolean value with TRUE indicates that RST PCIe Storage Remapping is required
+ @param[in] TempPciBusMin The temporary minimum Bus number for root port initialization
+ @param[in] SataRegBase SATA Register Base
+
+ @retval None
+**/
+VOID
+DetectPcieStorageDevices (
+ IN OUT BOOLEAN *RemappingRequired,
+ IN UINT8 TempPciBusMin,
+ IN UINTN SataRegBase
+ )
+{
+ EFI_STATUS Status;
+ PCH_SERIES PchSeries;
+ UINT8 DeviceInterface;
+ UINT32 PortNum;
+ UINTN PciRootPortRegBase;
+ UINTN RpDev;
+ UINTN RpFunc;
+ UINT8 RootPortLane;
+ PCIE_STORAGE_INFO_HOB *PcieStorageInfoHob;
+ VOID *Hob;
+ UINT32 CycleRouterNum;
+
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: DetectPcieStorageDevices Started\n"));
+
+ Hob = NULL;
+ Hob = GetFirstGuidHob (&gPchPcieStorageDetectHobGuid);
+ if (Hob != NULL) {
+ PcieStorageInfoHob = (PCIE_STORAGE_INFO_HOB *) GET_GUID_HOB_DATA (Hob);
+ } else {
+ return;
+ }
+
+ PchSeries = GetPchSeries ();
+
+ for (PortNum = 0; PortNum < GetPchMaxPciePortNum (); PortNum++) {
+
+ //
+ // Check Info hob for Cycle Router avaliable
+ // skip to next root port if Cr is not avaliable
+ //
+ CycleRouterNum = PcieStorageInfoHob->RstCycleRouterMap[PortNum / 4];
+ if (CycleRouterNum == RST_PCIE_STORAGE_CR_INVALID) {
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: cycle router not avaliable on Rp = %d\n", PortNum));
+ continue;
+ }
+
+ Status = GetPchPcieRpDevFun (PortNum, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR (Status);
+
+ PciRootPortRegBase = MmPciBase (DEFAULT_PCI_BUS_NUMBER_PCH, (UINT32) RpDev, (UINT32) RpFunc);
+ RootPortLane = RstGetRpLaneOccupyMask (PortNum);
+
+
+ if (RootPortLane == 0) {
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: root port lane is not occupied\n"));
+ continue;
+ }
+
+ ///
+ /// Check if the RST PCIe Storage Cycle Router is enabled, continue to the next root port in the next x4 lane if it is disabled
+ ///
+ if (mPchConfigHob->Sata.RstPcieStorageRemap[CycleRouterNum].Enable == 0) {
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: RST PCIe Storage Cycle Router %d is disabled\n", CycleRouterNum));
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: Proceed to root port in the next x4 lane (@ port %d)\n", PortNum + 1));
+ PortNum += 3 - (PortNum % 4);
+ continue;
+ }
+
+ ///
+ /// Check if the current root port is matching selected root port from policy, continue to next port if they are not matched
+ ///
+ if ((mPchConfigHob->Sata.RstPcieStorageRemap[CycleRouterNum].RstPcieStoragePort != 0) &&
+ (mPchConfigHob->Sata.RstPcieStorageRemap[CycleRouterNum].RstPcieStoragePort != PortNum + 1)) {
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: root port %d not matched with selected root port, proceed to next port\n", PortNum + 1));
+ continue;
+ }
+
+
+ // Read device programming interface from info hob
+ // if no device is present continue
+ if (PcieStorageInfoHob->PcieStorageLinkWidth[PortNum]) {
+ DeviceInterface = PcieStorageInfoHob->PcieStorageProgrammingInterface[PortNum];
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: Device present on RP# %d, PiInterface = %d\n", PortNum + 1, DeviceInterface));
+ } else {
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: RP# %d no device present\n", PortNum + 1));
+ continue;
+ }
+
+
+ ///
+ /// Update the remapping detail for detected PCIe storage device, and move to the root port in the next x4 lane
+ ///
+ if ((DeviceInterface != RST_PCIE_STORAGE_INTERFACE_NONE)) {
+ mRstPcieStorageDetection[CycleRouterNum].SupportRstPcieStoragRemapping = TRUE;
+ mRstPcieStorageDetection[CycleRouterNum].RootPortNum = (UINT8) PortNum;
+ mRstPcieStorageDetection[CycleRouterNum].RootPortLane = RootPortLane;
+ mRstPcieStorageDetection[CycleRouterNum].DeviceInterface = DeviceInterface;
+ PortNum += 3 - (PortNum % 4);
+ *RemappingRequired = TRUE;
+ } else {
+ continue;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "DetectPcieStorageDevices: DetectPcieStorageDevices() Ended\n"));
+}
+
+