blob: d69a8966453f95e5e3eb5a3f38c5e99ad65791b6 [file] [log] [blame]
/* $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: 49916 $ @e \$Date: 2011-03-30 19:03:54 +0800 (Wed, 30 Mar 2011) $
*
*/
/*
*****************************************************************************
*
* 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 "heapManager.h"
#include "OptionGnb.h"
#include "Gnb.h"
#include "GnbPcie.h"
#include "GnbPcieFamServices.h"
#include "cpuRegisters.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
*----------------------------------------------------------------------------------------
*/
/*----------------------------------------------------------------------------------------
* 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
PcieConfigurationInit (
IN AMD_CONFIG_PARAMS *StdHeader
);
VOID
STATIC
PcieConfigAttachComplexes (
IN OUT PCIe_COMPLEX_CONFIG *Base,
IN OUT PCIe_COMPLEX_CONFIG *New
);
AGESA_STATUS
PcieUpdateConfigurationData (
IN PCIe_PLATFORM_CONFIG *Pcie
);
AGESA_STATUS
STATIC
PcieConfigBuildData (
IN AMD_EARLY_PARAMS *EarlyParamsPtr,
IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList,
IN AMD_CONFIG_PARAMS *StdHeader
);
PCIe_COMPLEX_DESCRIPTOR *
PcieConfigProcessUserConfig (
IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList,
IN AMD_CONFIG_PARAMS *StdHeader
);
/*----------------------------------------------------------------------------------------*/
/**
* Create internal PCIe configuration data
*
*
*
* @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
)
{
AMD_EARLY_PARAMS *EarlyParamsPtr;
PCIe_COMPLEX_DESCRIPTOR *PcieComplexList;
AGESA_STATUS Status;
EarlyParamsPtr = (AMD_EARLY_PARAMS *) StdHeader;
PcieComplexList = PcieConfigProcessUserConfig (EarlyParamsPtr->GnbConfig.PcieComplexList, StdHeader);
if (PcieComplexList == NULL) {
return AGESA_FATAL;
}
GNB_DEBUG_CODE (
PcieUserConfigConfigDump (PcieComplexList);
);
Status = PcieConfigBuildData (EarlyParamsPtr, PcieComplexList, StdHeader);
HeapDeallocateBuffer (AMD_GNB_TEMP_DATA_HANDLE, StdHeader);
return Status;
}
/*----------------------------------------------------------------------------------------*/
/**
* Create internal PCIe configuration data
*
*
*
* @param[in] StdHeader Standard configuration header
* @retval AGESA_SUCCESS Configuration data successfully allocated.
* @retval AGESA_FATAL Configuration data allocation failed.
*/
AGESA_STATUS
STATIC
PcieConfigBuildData (
IN AMD_EARLY_PARAMS *EarlyParamsPtr,
IN PCIe_COMPLEX_DESCRIPTOR *PcieComplexList,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
PCIe_PLATFORM_CONFIG *Pcie;
AGESA_STATUS AgesaStatus;
AGESA_STATUS Status;
PCIe_COMPLEX_DESCRIPTOR *ComplexDescriptor;
UINTN ComplexesDataLength;
UINTN ComplexIndex;
UINTN NumberOfComplexes;
VOID *Buffer;
UINTN Index;
UINT32 NumberOfSockets;
UINT8 SocketId;
PCIe_SILICON_CONFIG *Silicon;
UINTN CurrentComplexesDataLength;
IDS_HDT_CONSOLE (GNB_TRACE, "PcieConfigurationInit Enter\n");
AgesaStatus = AGESA_SUCCESS;
ComplexesDataLength = 0;
NumberOfSockets = GnbGetNumberOfSockets (StdHeader);
for (SocketId = 0; SocketId < NumberOfSockets; SocketId++) {
if (GnbIsDevicePresentInSocket (SocketId, StdHeader)) {
Status = PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader);
ASSERT (Status == AGESA_SUCCESS);
ComplexesDataLength += CurrentComplexesDataLength;
}
}
NumberOfComplexes = PcieInputParserGetNumberOfComplexes (PcieComplexList);
Pcie = GnbAllocateHeapBuffer (AMD_PCIE_COMPLEX_DATA_HANDLE, sizeof (PCIe_PLATFORM_CONFIG) + ComplexesDataLength, StdHeader);
if (Pcie == NULL) {
IDS_ERROR_TRAP;
return AGESA_FATAL;
}
LibAmdMemFill (Pcie, 0x00, sizeof (PCIe_PLATFORM_CONFIG) + ComplexesDataLength, StdHeader);
Pcie->StdHeader = (PVOID) (intptr_t) StdHeader;
Pcie->Header.Child = offsetof (PCIe_PLATFORM_CONFIG, ComplexList);
PcieConfigSetDescriptorFlags (Pcie, DESCRIPTOR_PLATFORM | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_TOPOLOGY);
Buffer = (UINT8 *) (Pcie) + sizeof (PCIe_PLATFORM_CONFIG);
ComplexIndex = 0;
for (SocketId = 0; SocketId < NumberOfSockets; SocketId++) {
if (GnbIsDevicePresentInSocket (SocketId, StdHeader)) {
if (ComplexIndex > MAX_NUMBER_OF_COMPLEXES) {
IDS_ERROR_TRAP;
return AGESA_FATAL;
}
Pcie->ComplexList[ComplexIndex].Header.Child = (UINT16) ((UINT8 *) Buffer - (UINT8 *) &Pcie->ComplexList[ComplexIndex]);
Pcie->ComplexList[ComplexIndex].Header.Parent = (UINT16) ((UINT8 *) &Pcie->ComplexList[ComplexIndex] - (UINT8 *) Pcie);
PcieConfigSetDescriptorFlags (&Pcie->ComplexList[ComplexIndex], DESCRIPTOR_COMPLEX | DESCRIPTOR_TERMINATE_LIST | DESCRIPTOR_TERMINATE_GNB | DESCRIPTOR_TERMINATE_TOPOLOGY);
PcieFmBuildComplexConfiguration (SocketId, Buffer, StdHeader);
Silicon = PcieConfigGetChildSilicon (&Pcie->ComplexList[ComplexIndex]);
Silicon->Header.Parent = (UINT16) ((UINT8 *) Silicon - (UINT8 *) &Pcie->ComplexList[ComplexIndex]);
for (Index = 0; Index < NumberOfComplexes; Index++) {
ComplexDescriptor = PcieInputParserGetComplexDescriptor (PcieComplexList, Index);
if (ComplexDescriptor->SocketId == SocketId) {
Status = PcieMapTopologyOnComplex (ComplexDescriptor, &Pcie->ComplexList[ComplexIndex], Pcie);
Pcie->ComplexList[ComplexIndex].SocketId = SocketId;
AGESA_STATUS_UPDATE (Status, AgesaStatus);
if (ComplexIndex > 0) {
PcieConfigAttachComplexes (&Pcie->ComplexList[ComplexIndex - 1], &Pcie->ComplexList[ComplexIndex]);
}
}
}
PcieFmGetComplexDataLength (SocketId, &CurrentComplexesDataLength, StdHeader);
Buffer = (VOID *) ((UINT8 *) Buffer + CurrentComplexesDataLength);
ComplexIndex++;
}
}
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);
);
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;
}
PcieUpdateConfigurationData (*Pcie);
(*Pcie)->StdHeader = (PVOID) (intptr_t) StdHeader;
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));
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 = GnbGetPciAddress (PcieConfigGetParentComplex (Silicon)->SocketId, Silicon->SiliconId, 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;
}