blob: 30451717a09c9fa3795066cc621b7f66decac60c [file] [log] [blame]
/* $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
PcieEnginesToWrapper (
IN PCIE_ENGINE_TYPE EngineType,
IN PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor,
IN PCIe_WRAPPER_CONFIG *Wrapper
);
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");
}