diff options
author | efdesign98 <efdesign98@gmail.com> | 2011-06-20 18:12:43 -0700 |
---|---|---|
committer | Marc Jones <marcj303@gmail.com> | 2011-06-22 01:35:45 +0200 |
commit | 621ca384a7a5efb2cc7597504dc17b741cd2df10 (patch) | |
tree | 01871adc6d39f48916b5625b3aa1a4b6d5ab9c92 /src/vendorcode/amd/agesa/f14/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c | |
parent | 05a89ab922473f375820a3bd68691bb085c62448 (diff) | |
download | coreboot-621ca384a7a5efb2cc7597504dc17b741cd2df10.tar.xz |
Move existing AMD Ffamily14 code to f14 folder
This change moves the AMD Family14 cpu Agesa code to
the vendorcode/amd/agesa/f14 folder to complete the
transition to the family oriented folder structure.
Change-Id: I211e80ee04574cc713f38b4cc1b767dbb2bfaa59
Signed-off-by: Frank Vibrans <frank.vibrans@amd.com>
Signed-off-by: efdesign98 <efdesign98@gmail.com>
Reviewed-on: http://review.coreboot.org/52
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marcj303@gmail.com>
Diffstat (limited to 'src/vendorcode/amd/agesa/f14/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f14/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c | 720 |
1 files changed, 720 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f14/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c b/src/vendorcode/amd/agesa/f14/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c new file mode 100644 index 0000000000..70215514e2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f14/Proc/GNB/Modules/GnbPcieConfig/PcieMapTopology.c @@ -0,0 +1,720 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Procedure to map user define topology to processor configuration + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39898 $ @e \$Date: 2010-10-15 17:08:45 -0400 (Fri, 15 Oct 2010) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2011, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * *************************************************************************** + * + */ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GeneralServices.h" +#include "PcieInputParser.h" +#include "PcieMapTopology.h" +#include GNB_MODULE_DEFINITIONS (GnbPcieConfig) +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIEMAPTOPOLOGY_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +AGESA_STATUS +STATIC +PcieMapPortsPciAddresses ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +AGESA_STATUS +PcieMapTopologyOnWrapper ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +VOID +PcieMapInitializeEngineData ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +BOOLEAN +PcieCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +VOID +PcieComplexConfigConfigDump ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +BOOLEAN +PcieIsDescriptorLinkWidthValid ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor + ); + +BOOLEAN +PcieCheckLanesMatch ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ); + +BOOLEAN +PcieCheckDescriptorMapsToWrapper ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ); + +VOID +PcieAllocateEngine ( + IN UINT8 DescriptorIndex, + IN PCIe_ENGINE_CONFIG *Engine + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in] Complex Pointer to complex descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ + +AGESA_STATUS +PcieMapTopologyOnComplex ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_COMPLEX_CONFIG *Complex, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *Silicon; + PCIe_WRAPPER_CONFIG *Wrapper; + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnComplex Enter\n"); + GNB_DEBUG_CODE ( + PcieComplexConfigConfigDump (ComplexDescriptor, Pcie); + ); + Silicon = PcieComplexGetSiliconList (Complex); + while (Silicon != NULL) { + Wrapper = PcieSiliconGetWrapperList (Silicon); + while (Wrapper != NULL) { + Status = PcieMapTopologyOnWrapper (ComplexDescriptor, Wrapper, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + PcieConfigDisableAllEngines (PciePortEngine | PcieDdiEngine, Wrapper); + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Fail to map topology on %s Wrapper\n", + PcieFmDebugGetWrapperNameString (Wrapper) + ); + ASSERT (FALSE); + } + Wrapper = PcieLibGetNextDescriptor (Wrapper); + } + Status = PcieMapPortsPciAddresses (Silicon, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + Silicon = PcieLibGetNextDescriptor (Silicon); + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnComplex Exit [%x]\n", AgesaStatus); + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * + * + * @param[in] EngineType Engine type + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in] Wrapper Pointer to wrapper config descriptor + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ +AGESA_STATUS +PcieEnginesToWrapper ( + IN PCIE_ENGINE_TYPE EngineType, + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + AGESA_STATUS Status; + PCIe_ENGINE_CONFIG *EngineList; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + UINT8 ConfigurationId; + UINT8 Allocations; + UINTN Index; + UINTN NumberOfDescriptors; + + ConfigurationId = 0; + Allocations = 0; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEnginesToWrapper Enter\n"); + NumberOfDescriptors = PcieInputParserGetNumberOfEngines (ComplexDescriptor); + do { + Status = PcieFmConfigureEnginesLaneAllocation (Wrapper, EngineType, ConfigurationId++); + + if (Status == AGESA_SUCCESS) { + Allocations = 0; + for (Index = 0; Index < NumberOfDescriptors; Index++) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, Index); + if (EngineDescriptor->EngineData.EngineType == EngineType) { + // Step 1, belongs to wrapper check. + if (PcieCheckDescriptorMapsToWrapper (EngineDescriptor, Wrapper)) { + ++Allocations; + EngineList = PcieWrapperGetEngineList (Wrapper); + while (EngineList != NULL) { + if (!PcieLibIsEngineAllocated (EngineList)) { + // Step 2.user descriptor less or equal to link width of engine + if (PcieCheckLanesMatch (EngineDescriptor, EngineList)) { + // Step 3, Check if link width is correct.x1, x2, x4, x8, x16. + if (!PcieIsDescriptorLinkWidthValid (EngineDescriptor)) { + PcieConfigDisableEngine (EngineList); + return AGESA_ERROR; + } + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + // Step 4, Family specifc, port device number match engine device + if (PcieCheckPortPciDeviceMapping ((PCIe_PORT_DESCRIPTOR*) EngineDescriptor, EngineList)) { + //Step 5, Family specifc, lanes can be muxed. + if (PcieFmCheckPortPcieLaneCanBeMuxed ((PCIe_PORT_DESCRIPTOR*) EngineDescriptor, EngineList)) { + PcieAllocateEngine ((UINT8) Index, EngineList); + --Allocations; + } + } + } else { + PcieAllocateEngine ((UINT8) Index, EngineList); + --Allocations; + } + } + }//end if PcieLibIsEngineAllocated + EngineList = PcieLibGetNextDescriptor (EngineList); + } + }//end if PcieCheckDescriptorMapsToWrapper + }// end if EngineType + }//end for + } + } while (Status == AGESA_SUCCESS && Allocations != 0); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieEnginesToWrapper Exit [%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if lane from user port descriptor (PCIe_PORT_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * + * + * @param[in] EngineDescriptor Pointer to used define engine descriptor + * @param[in] Wrapper Pointer to PCIe_WRAPPER_CONFIG + * @retval TRUE Belongs to wrapper + * @retval FALSE Not belongs to wrapper + */ +BOOLEAN +PcieCheckDescriptorMapsToWrapper ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_WRAPPER_CONFIG *Wrapper + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + Result = TRUE; + + if (!(DescriptorLoLane >= Wrapper->StartPhyLane && DescriptorHiLane <= Wrapper->EndPhyLane)) { + // Lanes of descriptor does not belongs to wrapper + Result = FALSE; + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Engine to be allocated. + * + * + * @param[in] DescriptorIndex UINT8 index + * @param[in] Engine Pointer to engine config + */ +VOID +PcieAllocateEngine ( + IN UINT8 DescriptorIndex, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + Engine->Flags |= DESCRIPTOR_ALLOCATED; + Engine->Scratch = DescriptorIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure engine list to support lane allocation according to configuration ID. + * + * PCIE port + * + * + * 1 Check if lane from user port descriptor (PCIe_PORT_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * 2 Check if link width from user descriptor less or equal to link width of engine (PCIe_ENGINE_CONFIG) + * 3 Check if link width is correct. Correct link width for PCIe port x1, x2, x4, x8, x16, correct link width for DDI x4, x8 + * 4 Check if user port device number (PCIe_PORT_DESCRIPTOR) match engine port device number (PCIe_ENGINE_CONFIG) + * 5 Check if lane can be muxed + * + * + * DDI Link + * + * 1 Check if lane from user port descriptor (PCIe_DDI_DESCRIPTOR) belongs to wrapper (PCIe_WRAPPER_CONFIG) + * 2 Check lane from (PCIe_DDI_DESCRIPTOR) match exactly phy lane (PCIe_ENGINE_CONFIG) + * + * + * + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in,out] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Topology successfully mapped + * @retval AGESA_ERROR Topology can not be mapped + */ +AGESA_STATUS +PcieMapTopologyOnWrapper ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS AgesaStatus; + AGESA_STATUS Status; + PCIe_ENGINE_CONFIG *EngineList; + UINT32 WrapperPhyLaneBitMap; + + AgesaStatus = AGESA_SUCCESS; + if (PcieLibIsPcieWrapper (Wrapper)) { + Status = PcieEnginesToWrapper (PciePortEngine, ComplexDescriptor, Wrapper); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + // If we can not map topology on wrapper we can not enable any engines. + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_PCIE_TOPOLOGY_CONFIGURATION, + Wrapper->WrapId, + Wrapper->StartPhyLane, + Wrapper->EndPhyLane, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableAllEngines (PciePortEngine, Wrapper); + } + EngineList = PcieWrapperGetEngineList (Wrapper); + // Assure SB is allocated + while (EngineList != NULL) { + if ((EngineList->EngineData.EngineType == PciePortEngine) && (EngineList->Type.Port.IsSB)) { + EngineList->Flags |= DESCRIPTOR_ALLOCATED; + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + } + if (PcieLibIsDdiWrapper (Wrapper)) { + Status = PcieEnginesToWrapper (PcieDdiEngine, ComplexDescriptor, Wrapper); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_ERROR) { + // If we can not map topology on wrapper we can not enable any engines. + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_DDI_TOPOLOGY_CONFIGURATION, + Wrapper->WrapId, + Wrapper->StartPhyLane, + Wrapper->EndPhyLane, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableAllEngines (PcieDdiEngine, Wrapper); + } + } + // Copy engine data + PcieMapInitializeEngineData (ComplexDescriptor, Wrapper, Pcie); + + EngineList = PcieWrapperGetEngineList (Wrapper); + // Verify if we oversubscribe lanes and PHY link width + WrapperPhyLaneBitMap = 0; + while (EngineList != NULL) { + UINT32 EnginePhyLaneBitMap; + if (PcieLibIsEngineAllocated (EngineList)) { + EnginePhyLaneBitMap = PcieConfigGetEnginePhyLaneBitMap (EngineList); + if ((WrapperPhyLaneBitMap & EnginePhyLaneBitMap) != 0) { + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Lanes double subscribe lanes [Engine Lanes %d..%d]\n", + EngineList->EngineData.StartLane, + EngineList->EngineData.EndLane + ); + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_LANES_CONFIGURATION, + EngineList->EngineData.StartLane, + EngineList->EngineData.EndLane, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + PcieConfigDisableEngine (EngineList); + Status = AGESA_ERROR; + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } else { + WrapperPhyLaneBitMap |= EnginePhyLaneBitMap; + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize engine data + * + * + * + * @param[in] ComplexDescriptor Pointer to user defined complex descriptor + * @param[in,out] Wrapper Pointer to wrapper config descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieMapInitializeEngineData ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN OUT PCIe_WRAPPER_CONFIG *Wrapper, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_CONFIG *EngineList; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + + EngineList = PcieWrapperGetEngineList (Wrapper); + while (EngineList != NULL) { + if (PcieLibIsEngineAllocated (EngineList)) { + if (EngineList->Scratch != 0xFF) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, EngineList->Scratch); + LibAmdMemCopy (&EngineList->EngineData, &EngineDescriptor->EngineData, sizeof (EngineDescriptor->EngineData), GnbLibGetHeader (Pcie)); + if (PcieLibIsDdiEngine (EngineList)) { + LibAmdMemCopy (&EngineList->Type.Ddi, &((PCIe_DDI_DESCRIPTOR*) EngineDescriptor)->Ddi, sizeof (PCIe_DDI_DATA), GnbLibGetHeader (Pcie)); + EngineList->Type.Ddi.DisplayPriorityIndex = (UINT8) EngineList->Scratch; + } else if (PcieLibIsPcieEngine (EngineList)) { + LibAmdMemCopy (&EngineList->Type.Port, &((PCIe_PORT_DESCRIPTOR*) EngineDescriptor)->Port, sizeof (PCIe_PORT_DATA), GnbLibGetHeader (Pcie)); + } + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate PCI addresses for all PCIe engines on silicon + * + * + * + * @param[in] PortDescriptor Pointer to user defined engine descriptor + * @param[in] Engine Pointer engine configuration + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieCheckPortPciDeviceMapping ( + IN PCIe_PORT_DESCRIPTOR *PortDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + BOOLEAN Result; + + if ((PortDescriptor->Port.DeviceNumber == Engine->Type.Port.NativeDevNumber && + PortDescriptor->Port.FunctionNumber == Engine->Type.Port.NativeFunNumber) || + (PortDescriptor->Port.DeviceNumber == 0 && PortDescriptor->Port.FunctionNumber == 0)) { + Result = TRUE; + } else { + Result = PcieFmCheckPortPciDeviceMapping (PortDescriptor, Engine); + } + + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate PCI addresses for all PCIe engines on silicon + * + * + * + * @param[in] Silicon Pointer to silicon configurration + * @param[in] Pcie Pointer PCIe configuration + * @retval AGESA_ERROR Fail to allocate PCI device address + * @retval AGESA_SUCCESS Successfully allocate PCI address for all PCIe ports + */ + +AGESA_STATUS +STATIC +PcieMapPortsPciAddresses ( + IN PCIe_SILICON_CONFIG *Silicon, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + PCIe_WRAPPER_CONFIG *WrapperList; + PCIe_ENGINE_CONFIG *EngineList; + AgesaStatus = AGESA_SUCCESS; + WrapperList = PcieSiliconGetWrapperList (Silicon); + while (WrapperList != NULL) { + EngineList = PcieWrapperGetEngineList (WrapperList); + while (EngineList != NULL) { + if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { + Status = PcieFmMapPortPciAddress (EngineList, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + EngineList->Type.Port.Address.AddressValue = MAKE_SBDFO ( + 0, + Silicon->Address.Address.Bus, + EngineList->Type.Port.PortData.DeviceNumber, + EngineList->Type.Port.PortData.FunctionNumber, + 0 + ); + } else { + EngineList->Type.Port.PortData.PortPresent = OFF; + IDS_HDT_CONSOLE (PCIE_MISC, " ERROR! Fail to allocate PCI address for PCIe port\n" + ); + //Report error + PutEventLog ( + AGESA_ERROR, + GNB_EVENT_INVALID_PCIE_PORT_CONFIGURATION, + EngineList->Type.Port.PortData.DeviceNumber, + 0, + 0, + 0, + GnbLibGetHeader (Pcie) + ); + } + } + EngineList = PcieLibGetNextDescriptor (EngineList); + } + WrapperList = PcieLibGetNextDescriptor (WrapperList); + } + return AgesaStatus; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * If link width from user descriptor less or equal to link width of engine + * + * + * @param[in] EngineDescriptor Pointer to used define engine descriptor + * @param[in] Engine Pointer to engine config + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieCheckLanesMatch ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor, + IN PCIe_ENGINE_CONFIG *Engine + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + Result = FALSE; + + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + // + // If link width from user descriptor less or equal to link width of engine (PCIe_ENGINE_CONFIG) + // + if (DescriptorNumberOfLanes <= PcieConfigGetNumberOfCoreLane (Engine)) { + Result = TRUE; + } + } else if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + // + //For Ddi, check lane from (PCIe_DDI_DESCRIPTOR) match exactly phy lane (PCIe_ENGINE_CONFIG) + // + if ((Engine->EngineData.StartLane == DescriptorLoLane) && (Engine->EngineData.EndLane == DescriptorHiLane)) { + Result = TRUE; + } + } + + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Correct link width for PCIe port x1, x2, x4, x8, x16, correct link width for DDI x4, x8 + * + * + * @param[in] EngineDescriptor A pointer of PCIe_ENGINE_DESCRIPTOR + * @retval TRUE Descriptor can be mapped to engine + * @retval FALSE Descriptor can NOT be mapped to engine + */ + +BOOLEAN +PcieIsDescriptorLinkWidthValid ( + IN PCIe_ENGINE_DESCRIPTOR *EngineDescriptor + ) +{ + BOOLEAN Result; + UINT16 DescriptorHiLane; + UINT16 DescriptorLoLane; + UINT16 DescriptorNumberOfLanes; + + Result = FALSE; + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorNumberOfLanes = DescriptorHiLane - DescriptorLoLane + 1; + + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + if (DescriptorNumberOfLanes == 1 || DescriptorNumberOfLanes == 2 || DescriptorNumberOfLanes == 4 || + DescriptorNumberOfLanes == 8 || DescriptorNumberOfLanes == 16) { + Result = TRUE; + } + } else if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + if (DescriptorNumberOfLanes == 4 || DescriptorNumberOfLanes == 8) { + Result = TRUE; + } + } + + GNB_DEBUG_CODE ( + if (!Result) { + IDS_HDT_CONSOLE (PCIE_MISC, " Invalid Link width [Engine Lanes %d..%d]\n", + DescriptorLoLane, + DescriptorHiLane + ); + } + ); + + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Helper function to dump input configuration to debug out + * + * + * @param[in] ComplexDescriptor Pointer to used define complex descriptor + * @param[in] Pcie Pointer to global PCIe configuration + */ +VOID +PcieComplexConfigConfigDump ( + IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + UINTN Index; + UINTN NumberOfEngines; + IDS_HDT_CONSOLE (PCIE_MISC, "<---------- PCIe User Config Start------------->\n"); + + NumberOfEngines = PcieInputParserGetNumberOfEngines (ComplexDescriptor); + IDS_HDT_CONSOLE (PCIE_MISC, " ComplexDescriptor SocketId - %d\n NumberOfEngines - %d\n", + ComplexDescriptor->SocketId, + NumberOfEngines + ); + + for (Index = 0; Index < NumberOfEngines; Index++) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (ComplexDescriptor, Index); + IDS_HDT_CONSOLE (PCIE_MISC, " Engine Type - %s\n", + (EngineDescriptor->EngineData.EngineType == PciePortEngine) ? "PCIe Port" : ( + (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) ? "DDI Link" : ( + (EngineDescriptor->EngineData.EngineType == PcieUnusedEngine) ? "Unused" : "Invalid")) + ); + IDS_HDT_CONSOLE (PCIE_MISC, " Start Phy Lane - %d\n End Phy Lane - %d\n", + EngineDescriptor->EngineData.StartLane, + EngineDescriptor->EngineData.EndLane + ); + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + IDS_HDT_CONSOLE (PCIE_MISC, " PortPresent - %d\n ChannelType - %d\n DeviceNumber - %d\n FunctionNumber - %d\n LinkSpeedCapability - %d\n LinkAspm - %d\n LinkHotplug - %d\n ResetId - %d\n" , + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.PortPresent, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.ChannelType, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.DeviceNumber, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.FunctionNumber, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkSpeedCapability, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkAspm, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.LinkHotplug, + ((PCIe_PORT_DESCRIPTOR *) EngineDescriptor)->Port.ResetId + ); + } + if (EngineDescriptor->EngineData.EngineType == PcieDdiEngine) { + IDS_HDT_CONSOLE (PCIE_MISC, " ConnectorType - %d\n AuxIndex - %d\n HdpIndex - %d\n" , + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.ConnectorType, + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.AuxIndex, + ((PCIe_DDI_DESCRIPTOR *) EngineDescriptor)->Ddi.HdpIndex + ); + } + } + IDS_HDT_CONSOLE (PCIE_MISC, "<---------- PCIe User Config End-------------->\n"); +} + |