diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c | 561 |
1 files changed, 561 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c b/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c new file mode 100644 index 0000000000..febae7f986 --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieConfig/PcieConfigData.c @@ -0,0 +1,561 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * GNB function to create/locate PCIe configuration data area + * + * Contain code that create/locate and rebase configuration data area. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $ + * + */ +/* +***************************************************************************** +* +* Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved. +* +* AMD is granting you permission to use this software (the Materials) +* pursuant to the terms and conditions of your Software License Agreement +* with AMD. This header does *NOT* give you permission to use the Materials +* or any rights under AMD's intellectual property. Your use of any portion +* of these Materials shall constitute your acceptance of those terms and +* conditions. If you do not agree to the terms and conditions of the Software +* License Agreement, please do not use any portion of these Materials. +* +* CONFIDENTIALITY: The Materials and all other information, identified as +* confidential and provided to you by AMD shall be kept confidential in +* accordance with the terms and conditions of the Software License Agreement. +* +* LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION +* PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED +* WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF +* MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE, +* OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE. +* IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER +* (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS +* INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE, +* GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER +* RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE +* EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, +* THE ABOVE LIMITATION MAY NOT APPLY TO YOU. +* +* AMD does not assume any responsibility for any errors which may appear in +* the Materials or any other related information provided to you by AMD, or +* result from use of the Materials or any related information. +* +* You agree that you will not reverse engineer or decompile the Materials. +* +* NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any +* further information, software, technical information, know-how, or show-how +* available to you. Additionally, AMD retains the right to modify the +* Materials at any time, without notice, and is not obligated to provide such +* modified Materials to you. +* +* U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with +* "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is +* subject to the restrictions as set forth in FAR 52.227-14 and +* DFAR252.227-7013, et seq., or its successor. Use of the Materials by the +* Government constitutes acknowledgement of AMD's proprietary rights in them. +* +* EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any +* direct product thereof will be exported directly or indirectly, into any +* country prohibited by the United States Export Administration Act and the +* regulations thereunder, without the required authorization from the U.S. +* government nor will be used for any purpose prohibited by the same. +* *************************************************************************** +* +*/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "OptionGnb.h" +#include "Gnb.h" +#include "GnbPcie.h" +#include "GnbPcieFamServices.h" +#include "GnbFamServices.h" +#include "cpuServices.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "PcieMapTopology.h" +#include "PcieInputParser.h" +#include "PcieConfigLib.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBPCIECONFIG_PCIECONFIGDATA_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +extern BUILD_OPT_CFG UserOptions; +extern GNB_BUILD_OPTIONS ROMDATA GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +#define PcieConfigAttachChild(P, C) (P)->Child = (UINT16) ((UINT8 *) C - (UINT8 *) P); +#define PcieConfigAttachParent(P, C) (C)->Parent = (UINT16) ((UINT8 *) C - (UINT8 *) P); + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +VOID +STATIC +PcieConfigAttachComplexes ( + IN OUT PCIe_COMPLEX_CONFIG *Base, + IN OUT PCIe_COMPLEX_CONFIG *New + ); + +AGESA_STATUS +PcieUpdateConfigurationData ( + IN PCIe_PLATFORM_CONFIG *Pcie + ); + +PCIe_COMPLEX_DESCRIPTOR * +PcieConfigProcessUserConfig ( + IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieConfigurationInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +PcieConfigurationMap ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * Create internal PCIe configuration topology + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_SUCCESS Configuration data successfully allocated. + * @retval AGESA_FATAL Configuration data allocation failed. + */ + +AGESA_STATUS +PcieConfigurationInit ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_SILICON_CONFIG *Silicon; + UINT8 SocketId; + UINTN CurrentComplexesDataLength; + UINTN ComplexesDataLength; + UINT8 ComplexIndex; + VOID *Buffer; + ComplexesDataLength = 0; + Status = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Enter\n"); + for (SocketId = 0; SocketId < GetPlatformNumberOfSockets (); SocketId++) { + if (IsProcessorPresent (SocketId, StdHeader)) { + Status = PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader); + ASSERT (Status == AGESA_SUCCESS); + ComplexesDataLength += CurrentComplexesDataLength; + } + } + ComplexIndex = 0; + Pcie = GnbAllocateHeapBufferAndClear (AMD_PCIE_COMPLEX_DATA_HANDLE, sizeof (PCIe_PLATFORM_CONFIG) + ComplexesDataLength, StdHeader); + ASSERT (Pcie != NULL); + if (Pcie != NULL) { + PcieConfigAttachChild (&Pcie->Header, &Pcie->ComplexList[ComplexIndex].Header); + PcieConfigSetDescriptorFlags (Pcie, DESCRIPTOR_PLATFORM | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_TOPOLOGY); + Buffer = (UINT8 *) (Pcie) + sizeof (PCIe_PLATFORM_CONFIG); + for (SocketId = 0; SocketId < GetPlatformNumberOfSockets (); SocketId++) { + if (IsProcessorPresent (SocketId, StdHeader)) { + Pcie->ComplexList[ComplexIndex].SocketId = SocketId; + //Attache Comples to Silicon which will be created by PcieFmBuildComplexConfiguration + PcieConfigAttachChild (&Pcie->ComplexList[ComplexIndex].Header, &((PCIe_SILICON_CONFIG *) Buffer)->Header); + //Attach Comples to Pcie + PcieConfigAttachParent (&Pcie->Header, &Pcie->ComplexList[ComplexIndex].Header); + PcieConfigSetDescriptorFlags (&Pcie->ComplexList[ComplexIndex], DESCRIPTOR_COMPLEX | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_GNB | DESCRIPTOR_TERMINATE_TOPOLOGY); + PcieFmBuildComplexConfiguration (SocketId, Buffer, StdHeader); + Silicon = PcieConfigGetChildSilicon (&Pcie->ComplexList[ComplexIndex]); + while (Silicon != NULL) { + PcieConfigAttachParent (&Pcie->ComplexList[ComplexIndex].Header, &Silicon->Header); + GetNodeId (SocketId, Silicon->SiliconId, &Silicon->NodeId, StdHeader); + GnbFmGetLinkId ((GNB_HANDLE*) Silicon, &Silicon->LinkId, StdHeader); + Silicon = (PCIe_SILICON_CONFIG *) PcieConfigGetNextTopologyDescriptor (Silicon, DESCRIPTOR_TERMINATE_TOPOLOGY); + } + + if (ComplexIndex > 0) { + PcieConfigAttachComplexes (&Pcie->ComplexList[ComplexIndex - 1], &Pcie->ComplexList[ComplexIndex]); + } + PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader); + Buffer = (VOID *) ((UINT8 *) Buffer + CurrentComplexesDataLength); + ComplexIndex++; + } + } + } else { + Status = AGESA_FATAL; + } + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Exit [0x%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Create internal PCIe configuration topology + * + * + * + * @param[in] StdHeader Standard configuration header + * @retval AGESA_SUCCESS Configuration data successfully allocated. + * @retval AGESA_FATAL Configuration data allocation failed. + */ + +AGESA_STATUS +PcieConfigurationMap ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AMD_EARLY_PARAMS *EarlyParamsPtr; + PCIe_COMPLEX_DESCRIPTOR *PcieComplexList; + PCIe_PLATFORM_CONFIG *Pcie; + PCIe_COMPLEX_CONFIG *Complex; + PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor; + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + UINTN Index; + UINTN NumberOfComplexes; + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationMap Enter\n"); + AgesaStatus = AGESA_SUCCESS; + EarlyParamsPtr = (AMD_EARLY_PARAMS *) StdHeader; + PcieComplexList = PcieConfigProcessUserConfig (EarlyParamsPtr->GnbConfig.PcieComplexList, StdHeader); + GNB_DEBUG_CODE ( + if (PcieComplexList != NULL) { + PcieUserConfigConfigDump (PcieComplexList); + } + ); + Status = PcieLocateConfigurationData (StdHeader, &Pcie); + ASSERT (Status == AGESA_SUCCESS); + if (Status == AGESA_SUCCESS) { + Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetChild (DESCRIPTOR_COMPLEX, &Pcie->Header); + NumberOfComplexes = PcieInputParserGetNumberOfComplexes (PcieComplexList); + while (Complex != NULL) { + for (Index = 0; Index < NumberOfComplexes; Index++) { + ComplexDescriptor = PcieInputParserGetComplexDescriptor (PcieComplexList, Index); + if (ComplexDescriptor->SocketId == Complex->SocketId) { + Status = PcieMapTopologyOnComplex (ComplexDescriptor, Complex, Pcie); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + } + Complex = PcieLibGetNextDescriptor (Complex); + } + } + Pcie->LinkReceiverDetectionPooling = GnbBuildOptions.CfgGnbLinkReceiverDetectionPooling; + Pcie->LinkL0Pooling = GnbBuildOptions.CfgGnbLinkL0Pooling; + Pcie->LinkGpioResetAssertionTime = GnbBuildOptions.CfgGnbLinkGpioResetAssertionTime; + Pcie->LinkResetToTrainingTime = GnbBuildOptions.CfgGnbLinkResetToTrainingTime; + Pcie->GfxCardWorkaround = GfxWorkaroundEnable; + Pcie->TrainingExitState = LinkStateTrainingCompleted; + Pcie->TrainingAlgorithm = GnbBuildOptions.CfgGnbTrainingAlgorithm; + if ((UserOptions.CfgAmdPlatformType & AMD_PLATFORM_MOBILE) != 0) { + Pcie->GfxCardWorkaround = GfxWorkaroundDisable; + } + Pcie->PsppPolicy = EarlyParamsPtr->GnbConfig.PsppPolicy; + IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_PCIE_PLATFORM_CONFIG, Pcie, StdHeader); + GNB_DEBUG_CODE ( + PcieConfigDebugDump (Pcie); + ); + HeapDeallocateBuffer (AMD_GNB_TEMP_DATA_HANDLE, StdHeader); + IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Exit [0x%x]\n", AgesaStatus); + return AgesaStatus; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate global PCIe configuration data + * + * + * + * @param[in] PcieComplexList User PCIe topology configuration + * @param[out] StdHeader Standard configuration header + * @retval Updated topology configuration + */ +PCIe_COMPLEX_DESCRIPTOR * +PcieConfigProcessUserConfig ( + IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Node0SocketId; + UINT32 Node0SiliconId; + UINTN NumberOfComplexes; + UINTN NumberOfPorts; + UINTN Index; + UINT16 DescriptorLoLane; + UINT16 DescriptorHiLane; + PCIe_COMPLEX_DESCRIPTOR *ResultComplexConfig; + PCIe_COMPLEX_DESCRIPTOR *SbComplexDescriptor; + PCIe_PORT_DESCRIPTOR *SbPortDescriptor; + PCIe_PORT_DESCRIPTOR DefaultSbPortDescriptor; + PCIe_ENGINE_DESCRIPTOR *EngineDescriptor; + AGESA_STATUS Status; + SbPortDescriptor = NULL; + GetSocketModuleOfNode (0, &Node0SocketId, &Node0SiliconId, StdHeader); + Status = PcieFmGetSbConfigInfo ((UINT8) Node0SocketId, &DefaultSbPortDescriptor, StdHeader); + if (Status == AGESA_UNSUPPORTED) { + return PcieComplexList; + } + if (PcieComplexList == NULL) { + // No complex descriptor for any silicon was provided + // 1. Create complex descriptor + // 2. Create SB port descriptor + // 3. Attach SB descriptor to complex descriptor created in step #1 + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBufferAndClear ( + AMD_GNB_TEMP_DATA_HANDLE, + sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + SbComplexDescriptor = ResultComplexConfig; + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8 *) ResultComplexConfig + sizeof (PCIe_COMPLEX_DESCRIPTOR)); + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + SbPortDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + // Attach post array to complex descriptor + SbComplexDescriptor->PciePortList = SbPortDescriptor; + SbComplexDescriptor->SocketId = Node0SocketId; + SbComplexDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + } else { + NumberOfComplexes = PcieInputParserGetNumberOfComplexes (PcieComplexList); + SbComplexDescriptor = PcieInputParserGetComplexDescriptorOfSocket (PcieComplexList, Node0SocketId); + if (SbComplexDescriptor == NULL) { + // No complex descriptor for silicon that have SB attached. + // 1. Create complex descriptor. Will be first one in the list + // 2. Create SB port descriptor + // 3. Attach SB descriptor to complex descriptor created in step #1 + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBufferAndClear ( + AMD_GNB_TEMP_DATA_HANDLE, + (NumberOfComplexes + 1) * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + SbComplexDescriptor = ResultComplexConfig; + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8 *) ResultComplexConfig + (NumberOfComplexes + 1) * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + SbPortDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + // Attach post array to complex descriptor + SbComplexDescriptor->PciePortList = SbPortDescriptor; + SbComplexDescriptor->SocketId = Node0SocketId; + SbComplexDescriptor->Flags |= DESCRIPTOR_TERMINATE_LIST; + LibAmdMemCopy ( + (UINT8 *) ResultComplexConfig + sizeof (PCIe_COMPLEX_DESCRIPTOR), + PcieComplexList, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + StdHeader + ); + + } else { + // Complex descriptor that represent silicon that have SB attached exist + // 1. Determine if complex have descriptor for SB + // 2. Create new descriptor for SB if needed + NumberOfPorts = PcieInputParserGetLengthOfPcieEnginesList (SbComplexDescriptor); + ResultComplexConfig = (PCIe_COMPLEX_DESCRIPTOR *) GnbAllocateHeapBuffer ( + AMD_GNB_TEMP_DATA_HANDLE, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + (NumberOfPorts + 1) * sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Copy complex descriptor array + LibAmdMemCopy ( + ResultComplexConfig, + PcieComplexList, + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + StdHeader + ); + if (NumberOfPorts != 0) { + // Copy port descriptor array associated with complex with SB attached + LibAmdMemCopy ( + (UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR), + SbComplexDescriptor->PciePortList, + NumberOfPorts * sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Update SB complex pointer on in memory list + SbComplexDescriptor = PcieInputParserGetComplexDescriptorOfSocket ((PCIe_COMPLEX_DESCRIPTOR *) ResultComplexConfig, Node0SocketId); + // Attach port descriptor array to complex + SbComplexDescriptor->PciePortList = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR) + sizeof (PCIe_PORT_DESCRIPTOR)); + for (Index = 0; Index < NumberOfPorts; ++Index) { + EngineDescriptor = PcieInputParserGetEngineDescriptor (SbComplexDescriptor, Index); + if (EngineDescriptor->EngineData.EngineType == PciePortEngine) { + DescriptorLoLane = MIN (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + DescriptorHiLane = MAX (EngineDescriptor->EngineData.StartLane, EngineDescriptor->EngineData.EndLane); + if (DescriptorLoLane >= DefaultSbPortDescriptor.EngineData.StartLane && DescriptorLoLane <= DefaultSbPortDescriptor.EngineData.EndLane) { + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) EngineDescriptor; + } + } + } + } + if (SbPortDescriptor == NULL) { + // No descriptor that represent SB where found, create new one, will be first one in list + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + // Copy default config info + LibAmdMemCopy (SbPortDescriptor, &DefaultSbPortDescriptor, sizeof (PCIe_PORT_DESCRIPTOR), StdHeader); + // Reattach descriptor list to complex + SbComplexDescriptor->PciePortList = SbPortDescriptor; + } else { + // Move SB descriptor to be first one in array + LibAmdMemCopy ( + (UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR), + SbPortDescriptor, + sizeof (PCIe_PORT_DESCRIPTOR), + StdHeader + ); + // Disable original SB descriptor + SbPortDescriptor->EngineData.EngineType = PcieUnusedEngine; + //Update pointer to new SB descriptor + SbPortDescriptor = (PCIe_PORT_DESCRIPTOR *) ((UINT8*) ResultComplexConfig + NumberOfComplexes * sizeof (PCIe_COMPLEX_DESCRIPTOR)); + //It is no longer a descriptor that terminates list + SbPortDescriptor->Flags &= (~ DESCRIPTOR_TERMINATE_LIST); + // Reattach descriptor list to complex + SbComplexDescriptor->PciePortList = SbPortDescriptor; + } + } + } + // Mark descriptor as SB link + SbPortDescriptor->Port.MiscControls.SbLink = 0x1; + return ResultComplexConfig; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Locate global PCIe configuration data + * + * + * + * @param[in] StdHeader Standard configuration header + * @param[out] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Configuration data successfully located + * @retval AGESA_FATAL Configuration can not be located. + */ +AGESA_STATUS +PcieLocateConfigurationData ( + IN AMD_CONFIG_PARAMS *StdHeader, + OUT PCIe_PLATFORM_CONFIG **Pcie + ) +{ + *Pcie = GnbLocateHeapBuffer (AMD_PCIE_COMPLEX_DATA_HANDLE, StdHeader); + if (*Pcie == NULL) { + IDS_ERROR_TRAP; + return AGESA_FATAL; + } + (*Pcie)->StdHeader = /* (PVOID) */ (UINT32)StdHeader; + PcieUpdateConfigurationData (*Pcie); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attache descriptors + * + * + * @param[in] Type Descriptor type + * @param[in,out] Base Base descriptor + * @param[in,out] New New descriptor + */ +VOID +STATIC +PcieConfigAttachDescriptors ( + IN UINT32 Type, + IN OUT PCIe_DESCRIPTOR_HEADER *Base, + IN OUT PCIe_DESCRIPTOR_HEADER *New + ) +{ + PCIe_DESCRIPTOR_HEADER *Left; + PCIe_DESCRIPTOR_HEADER *Right; + + Left = PcieConfigGetPeer (DESCRIPTOR_TERMINATE_GNB, PcieConfigGetChild (Type, Base)); + ASSERT (Left != NULL); + Right = PcieConfigGetChild (Type, New); + Left->Peer = (UINT16) ((UINT8 *) Right - (UINT8 *) Left); + PcieConfigResetDescriptorFlags (Left, DESCRIPTOR_TERMINATE_TOPOLOGY); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach configurations of two GNB to each other. + * + * Function will link all data structure to linked lists + * + * @param[in,out] Base Base complex descriptor + * @param[in,out] New New complex descriptor + */ +VOID +STATIC +PcieConfigAttachComplexes ( + IN OUT PCIe_COMPLEX_CONFIG *Base, + IN OUT PCIe_COMPLEX_CONFIG *New + ) +{ + // Connect Complex + Base->Header.Peer = (UINT16) ((UINT8 *) New - (UINT8 *) Base); + PcieConfigResetDescriptorFlags (Base, DESCRIPTOR_TERMINATE_TOPOLOGY); + // Connect Silicon + PcieConfigAttachDescriptors (DESCRIPTOR_SILICON, &Base->Header, &New->Header); + // Connect Wrappers + PcieConfigAttachDescriptors (DESCRIPTOR_PCIE_WRAPPER | DESCRIPTOR_DDI_WRAPPER, &Base->Header, &New->Header); + // Connect Engines + PcieConfigAttachDescriptors (DESCRIPTOR_PCIE_ENGINE | DESCRIPTOR_DDI_ENGINE, &Base->Header, &New->Header); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Update configuration data + * + * Puprouse of this structure to update config data that base on programming of + * other silicon compoments. For instance PCI address of GNB and PCIe ports + * can change by AGESA or external agent + * + * + * @param[in,out] Pcie Pointer to global PCIe configuration + * @retval AGESA_SUCCESS Configuration data successfully update + * @retval AGESA_FATAL Failt to update configuration + */ +AGESA_STATUS +PcieUpdateConfigurationData ( + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + PCIe_SILICON_CONFIG *Silicon; + PCIe_ENGINE_CONFIG *Engine; + PCI_ADDR NewAddress; + // Update silicon configuration + Silicon = PcieConfigGetChildSilicon (Pcie); + while (Silicon != NULL) { + NewAddress = GnbFmGetPciAddress ((GNB_HANDLE *) PcieConfigGetParentComplex (Silicon), GnbLibGetHeader (Pcie)); + if (Silicon->Address.AddressValue != NewAddress.AddressValue) { + Silicon->Address.AddressValue = NewAddress.AddressValue; + Engine = PcieConfigGetChildEngine (Silicon); + while (Engine != NULL) { + if (PcieConfigIsPcieEngine (Engine)) { + Engine->Type.Port.Address.Address.Bus = Silicon->Address.Address.Bus; + } + Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (Engine, DESCRIPTOR_TERMINATE_GNB); + } + } + Silicon = (PCIe_SILICON_CONFIG *) PcieConfigGetNextTopologyDescriptor (Silicon, DESCRIPTOR_TERMINATE_TOPOLOGY); + } + return AGESA_SUCCESS; +} |