From 5c164e151c4047efc32f2bd0d6cad730e635c23c Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Sat, 17 Mar 2018 07:40:51 +0800 Subject: PurleySktPkg: Initial version. Cc: Isaac W Oram Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao Reviewed-by: Isaac W Oram --- .../Library/PcieAddressLib/PcieAddressLib.c | 311 +++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 Silicon/Intel/PurleySktPkg/Library/PcieAddressLib/PcieAddressLib.c (limited to 'Silicon/Intel/PurleySktPkg/Library/PcieAddressLib/PcieAddressLib.c') diff --git a/Silicon/Intel/PurleySktPkg/Library/PcieAddressLib/PcieAddressLib.c b/Silicon/Intel/PurleySktPkg/Library/PcieAddressLib/PcieAddressLib.c new file mode 100644 index 0000000000..456e5cf3ab --- /dev/null +++ b/Silicon/Intel/PurleySktPkg/Library/PcieAddressLib/PcieAddressLib.c @@ -0,0 +1,311 @@ +/** @file + +Copyright (c) 2018, 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 "PcieAddress.h" + +#if !defined(MINIBIOS_BUILD) && !defined(KTI_SW_SIMULATION) && !defined(SIM_BUILD) +#include +#endif + +#ifdef _MSC_VER +#pragma optimize ("",off) +#endif //_MSC_VER +////////////////////////////////////////////////////////////////////////// +// +// Common Silicon Address Library +// This Lib provide the way use platform Library instance +// +////////////////////////////////////////////////////////////////////////// + +PCIE_MMCFG_TABLE_TYPE mMmcfgTable =\ + { + { + {'M', 'C', 'F', 'G'}, // Signature + 0x00000090, // Length + 0x01, // Revision + 0x08, // The Maximum number of Segments + 0x00FF, // Valid Segment Bit Map, LSB Bit0 for Seg0, bit1 for seg1 ... + {0x00,0x00,0x00,0x00} // Reserved + }, + {{ + 0, //MMCFG_BASE_ADDRESS, // Base Address Low + 0x00000000, // Base Address High + 0x0000, // Segment 0 + 0x00, // Start Bus + 0xFF, // End Bus + {0x00,0x00,0x00,0x00} // Reserved + }} +}; +// +// Segment 1 ~ 7 +// +PCIE_MMCFG_BASE_ADDRESS_TYPE mMmcfgAddr[] = \ +{ + { + 0x00000000, // Base Address Low + 0x00000000, // Base Address High + 0x0001, // Segment 1 + 0x00, // Start Bus + 0xFF, // End Bus + {0x00,0x00,0x00,0x00} // Reserved + }, + { + 0x00000000, // Base Address Low + 0x00000000, // Base Address High + 0x0002, // Segment 2 + 0x00, // Start Bus + 0xFF, // End Bus + {0x00,0x00,0x00,0x00} // Reserved + }, + { + 0x00000000, // Base Address Low + 0x00000000, // Base Address High + 0x0003, // Segment 3 + 0x00, // Start Bus + 0xFF, // End Bus + {0x00,0x00,0x00,0x00} // Reserved + }, + + { + 0x00000000, // Base Address Low + 0x00000000, // Base Address High + 0x0004, // Segment 4 + 0x00, // Start Bus + 0xFF, // End Bus + {0x00,0x00,0x00,0x00} // Reserved + }, + { + 0x00000000, // Base Address Low + 0x00000000, // Base Address High + 0x0005, // Segment 5 + 0x00, // Start Bus + 0xFF, // End Bus + {0x00,0x00,0x00,0x00} // Reserved + }, + + { + 0x00000000, // Base Address Low + 0x00000000, // Base Address High + 0x0006, // Segment 6 + 0x00, // Start Bus + 0xFF, // End Bus + {0x00,0x00,0x00,0x00} // Reserved + }, + { + 0x00000000, // Base Address Low + 0x00000000, // Base Address High + 0x0007, // Segment 7 + 0x00, // Start Bus + 0xFF, // End Bus + {0x00,0x00,0x00,0x00} // Reserved + } +}; + + +/** + This Lib is used for platfor to set platform specific Pcie MMCFG Table + + @param MmcfgTable: A pointer of the MMCFG Table structure for PCIE_MMCFG_TABLE_TYPE type. + @param NumOfSeg: Sumber of Segments in the table. + + @retval <>NULL The function completed successfully. + @retval NULL Returen Error +**/ +UINTN +SetSocketMmcfgTable ( + IN UINT8 SocketLastBus[], + IN UINT8 SocketFirstBus[], + IN UINT8 segmentSocket[], + IN UINT32 mmCfgBaseH[], + IN UINT32 mmCfgBaseL[], + IN UINT8 NumOfSocket + ) +{ +#if !defined(MINIBIOS_BUILD) && !defined(KTI_SW_SIMULATION) && !defined(SIM_BUILD) + UINT32 MmcfgTableSize; + PCIE_MMCFG_TABLE_TYPE *HobMmcfgTable; + UINT8 i, *Dest, *Source; + + union { + UINT64 D64; + UINT32 D32[2]; + } Data; + + MmcfgTableSize = sizeof(PCIE_MMCFG_HEADER_TYPE) + (NumOfSocket * sizeof(PCIE_MMCFG_BASE_ADDRESS_TYPE)); + + HobMmcfgTable = (PCIE_MMCFG_TABLE_TYPE *) PcdGetPtr (PcdPcieMmcfgTablePtr); + ASSERT (MmcfgTableSize < PcdGetSize (PcdPcieMmcfgTablePtr)); + + Data.D64 = PcdGet64 (PcdPciExpressBaseAddress); + mMmcfgTable.MmcfgBase[0].BaseAddressL = Data.D32[0]; + mMmcfgTable.MmcfgBase[0].BaseAddressH = Data.D32[1]; + + //1. copy global variable mMcfgTable to HobMmcfgTable + // note that mMmcfgTable only has PCIE_MMCFG_BASE_ADDRESS_TYPE for segment 0 (for socket 0) + // need to copy base addresses for other segments corresponding to sockets 1 through NumOfSocket-1 + Dest = (UINT8*)HobMmcfgTable; + Source = (UINT8*)&mMmcfgTable; + for(i=0; i 1){ + Dest = (UINT8*)&HobMmcfgTable->MmcfgBase[1]; + Source = (UINT8*)&mMmcfgAddr[0];//array of base addresses starting with segment 1 (max segment = 7) + for(i = 0; i< (MmcfgTableSize - sizeof(PCIE_MMCFG_TABLE_TYPE)); i++){ + Dest[i] = Source[i]; + } + } + + HobMmcfgTable->Header.Length = MmcfgTableSize; + for(i=0; iMmcfgBase[i].StartBus = SocketFirstBus[i]; + HobMmcfgTable->MmcfgBase[i].EndBus = SocketLastBus[i]; + HobMmcfgTable->MmcfgBase[i].Segment = segmentSocket[i]; + HobMmcfgTable->MmcfgBase[i].BaseAddressH = mmCfgBaseH[i]; + HobMmcfgTable->MmcfgBase[i].BaseAddressL = mmCfgBaseL[i]; + } +#endif + return 0; +}; + + +/** + This Lib is used for platform to set platform specific Pcie MMCFG Table + + @param MmcfgTable: A pointer of the MMCFG Table structure for PCIE_MMCFG_TABLE_TYPE type. + @param NumOfSeg: Sumber of Segments in the table. + + @retval <>NULL The function completed successfully. + @retval NULL Returen Error +**/ +UINTN +EFIAPI +SetPcieSegMmcfgTable ( + IN PCIE_MMCFG_TABLE_TYPE *MmcfgTable, + IN UINT32 NumOfSeg + ) +{ +#if !defined(MINIBIOS_BUILD) && !defined(KTI_SW_SIMULATION) && !defined(SIM_BUILD) + UINT32 MmcfgTableSize; + PCIE_MMCFG_TABLE_TYPE *HobMmcfgTable; + + union { + UINT64 D64; + UINT32 D32[2]; + } Data; + + Data.D32[0] = Data.D32[1] = 0; + MmcfgTableSize = sizeof(PCIE_MMCFG_HEADER_TYPE) + (NumOfSeg * sizeof(PCIE_MMCFG_BASE_ADDRESS_TYPE)); + + HobMmcfgTable = (PCIE_MMCFG_TABLE_TYPE *) PcdGetPtr (PcdPcieMmcfgTablePtr); + //ASSERT (MmcfgTableSize < PcdGetSize (PcdPcieMmcfgTablePtr)); + + //InternalMemCopyMem(HobMmcfgTable, MmcfgTable, PcdGetSize (PcdPcieMmcfgTablePtr)); + MmcfgTable->Header.Length = MmcfgTableSize; + if((MmcfgTable->MmcfgBase[0].BaseAddressL == 0) && (MmcfgTable->MmcfgBase[0].BaseAddressH == 0)) + { + // + // The first time default should be the PcdPciExpressBaseAddress + // + Data.D64 = (UINTN) PcdGet64 (PcdPciExpressBaseAddress); + HobMmcfgTable->MmcfgBase[0].BaseAddressL = Data.D32[0]; + HobMmcfgTable->MmcfgBase[0].BaseAddressH = Data.D32[1]; + }; +#endif + return 0; +}; + + +/** + This Lib return PCIE MMCFG Base Address + + @param Address: A pointer of the address of the Common Address Structure for PCIE type. + @param Buffer: A pointer of buffer for the value read from platform. + + @retval <>NULL The function completed successfully. + @retval NULL Returen Error + **/ + +UINTN +EFIAPI +GetPcieSegMmcfgBaseAddress ( + IN USRA_ADDRESS *Address + ) +{ + UINT32 BaseAddressL=0; // Processor-relative Base Address (Lower 32-bit) for the Enhanced Configuration Access Mechanism + UINT32 BaseAddressH=0; + UINTN SegMmcfgBase; + +#if !defined(MINIBIOS_BUILD) && !defined(KTI_SW_SIMULATION) + PCIE_MMCFG_TABLE_TYPE *MmcfgTable=NULL; + union { + UINTN D64; + UINT32 D32[2]; + } Data; +#endif +#if !defined(MINIBIOS_BUILD) && !defined(KTI_SW_SIMULATION) + if(Address->Attribute.HostPtr == 0) { + MmcfgTable = (PCIE_MMCFG_TABLE_TYPE *) PcdGetPtr (PcdPcieMmcfgTablePtr); + if(MmcfgTable->Header.Length != 0) + { + BaseAddressH = MmcfgTable->MmcfgBase[Address->Pcie.Seg].BaseAddressH; + BaseAddressL = MmcfgTable->MmcfgBase[Address->Pcie.Seg].BaseAddressL; + } else { + // + // if it is not valid MMCFG pointer, initialize it to use the predefined default MMCFG Table + // + SetPcieSegMmcfgTable(&mMmcfgTable, PcdGet32 (PcdNumOfPcieSeg)); + BaseAddressH = mMmcfgTable.MmcfgBase[Address->Pcie.Seg].BaseAddressH; + BaseAddressL = mMmcfgTable.MmcfgBase[Address->Pcie.Seg].BaseAddressL; + + if((BaseAddressL == 0) && (BaseAddressH == 0)){ + Data.D32[0] = Data.D32[1] = 0; + Data.D64 = (UINTN) PcdGet64 (PcdPciExpressBaseAddress); + BaseAddressL = Data.D32[0]; + BaseAddressH = Data.D32[1]; + } + } + } + else +#endif + { + BaseAddressH = 0; + BaseAddressL = 0; + } + + if((BaseAddressL == 0) && (BaseAddressH == 0)) + { + +#if defined(MINIBIOS_BUILD) || defined(KTI_SW_SIMULATION) + BaseAddressL = 0x80000000; + BaseAddressH = 0; +#else + // + // The first time default should be the PcdPciExpressBaseAddress + // + Data.D32[0] = Data.D32[1] = 0; + Data.D64 = (UINTN) PcdGet64 (PcdPciExpressBaseAddress); + BaseAddressL = Data.D32[0]; + BaseAddressH = Data.D32[1]; +#endif + } + return SegMmcfgBase = BaseAddressL; + +}; + -- cgit v1.2.3