/** * 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 = PcieConfigGetChildEngine (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); } }
/** * Enable lane reversal * * * @param[in] Wrapper Pointer to wrapper config descriptor * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieTopologySetLinkReversal ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Enter\n"); EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieLibIsEngineAllocated (EngineList)) { if (PcieLibIsPcieEngine (EngineList)) { if (EngineList->EngineData.StartLane > EngineList->EngineData.EndLane) { PciePortRegisterWriteField ( EngineList, DxF0xE4_xC1_ADDRESS, DxF0xE4_xC1_StrapReverseLanes_OFFSET, DxF0xE4_xC1_StrapReverseLanes_WIDTH, 0x1, FALSE, Pcie ); } } } EngineList = PcieLibGetNextDescriptor (EngineList); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySetLinkReversal Exit\n"); }
/** * Helper function to dump wrapper configuration * * * @param[in] WrapperList Wrapper Configuration */ VOID PcieConfigWrapperDebugDump ( IN PCIe_WRAPPER_CONFIG *WrapperList ) { PCIe_ENGINE_CONFIG *EngineList; IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config -------->\n", PcieFmDebugGetWrapperNameString (WrapperList) ); IDS_HDT_CONSOLE (PCIE_MISC, " Start PHY lane - %02d\n", WrapperList->StartPhyLane); IDS_HDT_CONSOLE (PCIE_MISC, " End PHY lane - %02d\n", WrapperList->EndPhyLane); IDS_HDT_CONSOLE (PCIE_MISC, " Descriptor Flags - 0x%08x\n", WrapperList->Header.DescriptorFlags); IDS_HDT_CONSOLE (PCIE_MISC, " PowerOffUnusedLanes - %x\n PowerOffUnusedPlls - %x\n ClkGating - %x\n" " LclkGating - %x\n TxclkGatingPllPowerDown - %x\n PllOffInL1 - %x\n", WrapperList->Features.PowerOffUnusedLanes, WrapperList->Features.PowerOffUnusedPlls, WrapperList->Features.ClkGating, WrapperList->Features.LclkGating, WrapperList->Features.TxclkGatingPllPowerDown, WrapperList->Features.PllOffInL1 ); IDS_HDT_CONSOLE (PCIE_MISC, " <---------Wrapper - %s Config End----->\n", PcieFmDebugGetWrapperNameString (WrapperList) ); EngineList = PcieConfigGetChildEngine (WrapperList); while (EngineList != NULL) { if (PcieLibIsEngineAllocated (EngineList)) { PcieConfigEngineDebugDump (EngineList); } EngineList = PcieLibGetNextDescriptor (EngineList); } }
/** * Get engine PHY lanes bitmap * * * * @param[in] Engine Pointer to engine config descriptor */ UINT32 PcieConfigGetEnginePhyLaneBitMap ( IN PCIe_ENGINE_CONFIG *Engine ) { UINT32 LaneBitMap; LaneBitMap = 0; if (PcieLibIsEngineAllocated (Engine)) { LaneBitMap = ((1 << PcieConfigGetNumberOfPhyLane (Engine)) - 1) << (PcieLibGetLoPhyLane (Engine) - PcieConfigGetParentWrapper (Engine)->StartPhyLane); } return LaneBitMap; }
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 = PcieConfigGetChildWrapper (Silicon); while (WrapperList != NULL) { EngineList = PcieConfigGetChildEngine (WrapperList); while (EngineList != NULL) { if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { Status = PcieFmMapPortPciAddress (EngineList); 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; }
VOID PcieFmEnableSlotPowerLimit ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { ASSERT (Engine->EngineData.EngineType == PciePortEngine); if (PcieLibIsEngineAllocated (Engine) && Engine->Type.Port.PortData.PortPresent != PortDisabled && !Engine->Type.Port.IsSB) { IDS_HDT_CONSOLE (PCIE_MISC, " Enable Slot Power Limit for Port % d\n", Engine->Type.Port.Address.Address.Device); GnbLibPciIndirectRMW ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), (D0F0x64_x55_ADDRESS + (Engine->Type.Port.Address.Address.Device - 4) * 2) | IOC_WRITE_ENABLE, AccessS3SaveWidth32, 0xffffffff, 1 << D0F0x64_x55_SetPowEn_OFFSET, GnbLibGetHeader (Pcie) ); } }
VOID PcieEnableSlotPowerLimitV5 ( IN PCIe_ENGINE_CONFIG *Engine, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_SILICON_CONFIG *Silicon; if (PcieLibIsEngineAllocated (Engine) && Engine->Type.Port.PortData.PortPresent != PortDisabled && !PcieConfigIsSbPcieEngine (Engine)) { IDS_HDT_CONSOLE (PCIE_MISC, " Enable Slot Power Limit for Port % d\n", Engine->Type.Port.Address.Address.Device); Silicon = PcieConfigGetParentSilicon (Engine); GnbLibPciIndirectRMW ( Silicon->Address.AddressValue | D0F0xC8_ADDRESS, D0F0xCC_x01_ADDRESS | ((Engine->Type.Port.PortData.DeviceNumber << 3 | Engine->Type.Port.PortData.FunctionNumber) << D0F0xC8_NB_DEV_IND_SEL_OFFSET), AccessS3SaveWidth32, 0xffffffff, 1 << D0F0xCC_x01_SetPowEn_OFFSET, GnbLibGetHeader (Pcie) ); } }
VOID PcieConfigRunProcForAllEngines ( IN UINT32 DescriptorFlags, IN PCIe_RUN_ON_ENGINE_CALLBACK Callback, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *Engine; Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetChild (DESCRIPTOR_ALL_ENGINES, &Pcie->Header); while (Engine != NULL) { if (!(PcieLibIsVirtualDesciptor (Engine) && (DescriptorFlags & DESCRIPTOR_VIRTUAL) == 0)) { if (!((DescriptorFlags & DESCRIPTOR_ALLOCATED) != 0 && !PcieLibIsEngineAllocated (Engine))) { if ((Engine->Header.DescriptorFlags & DESCRIPTOR_ALL_ENGINES & DescriptorFlags) != 0) { Callback (Engine, Buffer, Pcie); } } } Engine = (PCIe_ENGINE_CONFIG *) PcieConfigGetNextTopologyDescriptor (Engine, DESCRIPTOR_TERMINATE_TOPOLOGY); } }
VOID PcieTopologyApplyLaneMux ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT8 CurrentPhyLane; UINT8 CurrentCoreLane; UINT8 CoreLaneIndex; UINT8 PhyLaneIndex; UINT8 NumberOfPhyLane; UINT8 TxLaneMuxSelectorArray [sizeof (LaneMuxSelectorTable)]; UINT8 RxLaneMuxSelectorArray [sizeof (LaneMuxSelectorTable)]; UINT8 Index; UINT32 TxMaxSelectorValue; UINT32 RxMaxSelectorValue; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMux Enter\n"); if (PcieLibIsPcieWrapper (Wrapper)) { EngineList = PcieConfigGetChildEngine (Wrapper); LibAmdMemCopy ( &TxLaneMuxSelectorArray[0], &LaneMuxSelectorTable[0], sizeof (LaneMuxSelectorTable), GnbLibGetHeader (Pcie) ); LibAmdMemCopy ( &RxLaneMuxSelectorArray[0], &LaneMuxSelectorTable[0], sizeof (LaneMuxSelectorTable), GnbLibGetHeader (Pcie) ); while (EngineList != NULL) { if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { CurrentPhyLane = (UINT8) PcieLibGetLoPhyLane (EngineList) - Wrapper->StartPhyLane; NumberOfPhyLane = (UINT8) PcieConfigGetNumberOfPhyLane (EngineList); CurrentCoreLane = (UINT8) EngineList->Type.Port.StartCoreLane; if (PcieUtilIsLinkReversed (FALSE, EngineList, Pcie)) { CurrentCoreLane = CurrentCoreLane + PcieConfigGetNumberOfCoreLane (EngineList) - NumberOfPhyLane; } for (Index = 0; Index < NumberOfPhyLane; Index = Index + 2 ) { CoreLaneIndex = (CurrentCoreLane + Index) / 2; PhyLaneIndex = (CurrentPhyLane + Index) / 2; if (RxLaneMuxSelectorArray [CoreLaneIndex] != PhyLaneIndex) { RxLaneMuxSelectorArray [PcieTopologyLocateMuxIndex (RxLaneMuxSelectorArray, PhyLaneIndex)] = RxLaneMuxSelectorArray [CoreLaneIndex]; RxLaneMuxSelectorArray [CoreLaneIndex] = PhyLaneIndex; } if (TxLaneMuxSelectorArray [PhyLaneIndex] != CoreLaneIndex) { TxLaneMuxSelectorArray [PcieTopologyLocateMuxIndex (TxLaneMuxSelectorArray, CoreLaneIndex)] = TxLaneMuxSelectorArray [PhyLaneIndex]; TxLaneMuxSelectorArray [PhyLaneIndex] = CoreLaneIndex; } } } EngineList = PcieLibGetNextDescriptor (EngineList); } RxMaxSelectorValue = 0; TxMaxSelectorValue = 0; for (Index = 0; Index < sizeof (LaneMuxSelectorTable); Index++) { RxMaxSelectorValue |= (RxLaneMuxSelectorArray[Index] << (Index * 4)); TxMaxSelectorValue |= (TxLaneMuxSelectorArray[Index] << (Index * 4)); } PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8021_ADDRESS), TxMaxSelectorValue, FALSE, Pcie ); PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8022_ADDRESS), RxMaxSelectorValue, FALSE, Pcie ); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMux Exit\n"); }
VOID PcieTopologySelectMasterPll ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT16 MasterPhyLane; UINT16 MasterHotplugPhyLane; D0F0xE4_WRAP_8013_STRUCT D0F0xE4_WRAP_8013; EngineList = PcieWrapperGetEngineList (Wrapper); MasterPhyLane = 0xffff; MasterHotplugPhyLane = 0xffff; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); while (EngineList != NULL) { if (PcieLibIsEngineAllocated (EngineList)) { if (EngineList->EngineData.EngineType == PciePortEngine) { MasterPhyLane = EngineList->EngineData.StartLane; if (EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) { MasterHotplugPhyLane = MasterPhyLane; } } } EngineList = PcieLibGetNextDescriptor (EngineList); } if (MasterPhyLane == 0xffff) { MasterPhyLane = MasterHotplugPhyLane; if (MasterPhyLane == 0xffff) { MasterPhyLane = Wrapper->StartPhyLane; } } D0F0xE4_WRAP_8013.Value = PcieRegisterRead ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), Pcie ); MasterPhyLane = MasterPhyLane - Wrapper->StartPhyLane; if ( MasterPhyLane <= 3 ) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; } else if (MasterPhyLane <= 7) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; } else if (MasterPhyLane <= 11) { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x1; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x0; } else { D0F0xE4_WRAP_8013.Field.MasterPciePllA = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllB = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllC = 0x0; D0F0xE4_WRAP_8013.Field.MasterPciePllD = 0x1; } PcieRegisterWrite ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_8013_ADDRESS), D0F0xE4_WRAP_8013.Value, FALSE, Pcie ); IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologySelectMasterPll Enter\n"); }
VOID STATIC PcieTopologyApplyLaneMuxCZ ( IN PCIe_WRAPPER_CONFIG *Wrapper, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCIe_ENGINE_CONFIG *EngineList; UINT32 Index; UINT8 RxLaneMuxSelectorArray [sizeof (LaneMuxSelectorArrayCZ)]; UINT8 TxLaneMuxSelectorArray [sizeof (LaneMuxSelectorArrayCZ)]; IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMuxCZ Enter\n"); if (PcieLibIsPcieWrapper (Wrapper)) { LibAmdMemCopy ( &TxLaneMuxSelectorArray[0], &LaneMuxSelectorArrayCZ[0], sizeof (LaneMuxSelectorArrayCZ), GnbLibGetHeader (Pcie) ); LibAmdMemCopy ( &RxLaneMuxSelectorArray[0], &LaneMuxSelectorArrayCZ[0], sizeof (LaneMuxSelectorArrayCZ), GnbLibGetHeader (Pcie) ); EngineList = PcieConfigGetChildEngine (Wrapper); while (EngineList != NULL) { if (PcieLibIsPcieEngine (EngineList) && PcieLibIsEngineAllocated (EngineList)) { UINT32 CoreLaneBitmap; UINT32 PifLaneBitmap; UINT8 CurrentCoreLane; UINT8 CurrentPifLane; CoreLaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_CORE_ALLOC, 0, EngineList); PifLaneBitmap = PcieUtilGetEngineLaneBitMap (LANE_TYPE_PCIE_PHY_NATIVE, 0, EngineList); IDS_HDT_CONSOLE (GNB_TRACE, "CoreLaneBitmap - %x, CurrentPifLane - %x\n", CoreLaneBitmap, PifLaneBitmap); while (CoreLaneBitmap != 0) { CurrentCoreLane = LibAmdBitScanForward (CoreLaneBitmap); CurrentPifLane = LibAmdBitScanForward (PifLaneBitmap); if (TxLaneMuxSelectorArray[CurrentPifLane] != CurrentCoreLane) { TxLaneMuxSelectorArray[PcieTopologyLocateMuxIndexCZ (TxLaneMuxSelectorArray, CurrentCoreLane)] = TxLaneMuxSelectorArray[CurrentPifLane]; TxLaneMuxSelectorArray[CurrentPifLane] = CurrentCoreLane; } if (RxLaneMuxSelectorArray[CurrentCoreLane] != CurrentPifLane) { RxLaneMuxSelectorArray[PcieTopologyLocateMuxIndexCZ (RxLaneMuxSelectorArray, CurrentPifLane)] = RxLaneMuxSelectorArray[CurrentCoreLane]; RxLaneMuxSelectorArray[CurrentCoreLane] = CurrentPifLane; } CoreLaneBitmap &= (~ (1 << CurrentCoreLane)); PifLaneBitmap &= (~ (1 << CurrentPifLane)); } } EngineList = PcieLibGetNextDescriptor (EngineList); } for (Index = 0; Index < 2; ++Index) { PcieRegisterWrite ( Wrapper, CORE_SPACE (Wrapper->StartPcieCoreId, D0F0xE4_CORE_0121_ADDRESS + Index), ((UINT32 *) TxLaneMuxSelectorArray) [Index], FALSE, Pcie ); PcieRegisterWrite ( Wrapper, CORE_SPACE (Wrapper->StartPcieCoreId, D0F0xE4_CORE_0125_ADDRESS + Index), ((UINT32 *) RxLaneMuxSelectorArray) [Index], FALSE, Pcie ); } } IDS_HDT_CONSOLE (GNB_TRACE, "PcieTopologyApplyLaneMuxCZ Exit\n"); }
/** * 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; IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnWrapper Enter\n"); 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); } } 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 = PcieConfigGetChildEngine (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); } IDS_HDT_CONSOLE (GNB_TRACE, "PcieMapTopologyOnWrapper Exit [%d]\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 */ STATIC 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 = PcieConfigGetChildEngine (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; break; } } } else { PcieAllocateEngine ((UINT8) Index, EngineList); --Allocations; break; } } } //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; }