Пример #1
0
/**
 * 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);
    }
}
Пример #2
0
/**
 * 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");
}
Пример #3
0
/**
 * 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);
  }
}
Пример #4
0
/**
 * 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;
}
Пример #5
0
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;
}
Пример #6
0
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)
    );
  }
}
Пример #7
0
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)
    );
  }
}
Пример #8
0
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);
  }
}
Пример #9
0
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");
}
Пример #10
0
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");
}
Пример #11
0
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");
}
Пример #12
0
/**
 * 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;
}
Пример #13
0
/**
 * 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;
}