blob: d6936d4f2469bad704bcfa6694a1e43d2ee947bd [file] [log] [blame]
/* $NoKeywords:$ */
/**
* @file
*
* Family specific function translation
*
*
*
* @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 "Gnb.h"
#include "GnbPcie.h"
#include "GnbPcieFamServices.h"
#include "GnbCommonLib.h"
#include "GnbPcieConfig.h"
#include "Filecode.h"
#define FILECODE PROC_GNB_MODULES_GNBFAMTRANSLATION_GNBPCIETRANSLATION_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
*----------------------------------------------------------------------------------------
*/
/*----------------------------------------------------------------------------------------*/
/**
* Configure engine list to support lane allocation according to configuration ID.
*
*
*
* @param[in] Wrapper Pointer to wrapper config descriptor
* @param[in] EngineType Engine Type
* @param[in] ConfigurationId Configuration ID
* @retval AGESA_SUCCESS Configuration successfully applied
* @retval AGESA_UNSUPPORTED No more configuration available for given engine type
* @retval AGESA_ERROR Requested configuration not supported
*/
AGESA_STATUS
PcieFmConfigureEnginesLaneAllocation (
IN PCIe_WRAPPER_CONFIG *Wrapper,
IN PCIE_ENGINE_TYPE EngineType,
IN UINT8 ConfigurationId
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_CONFIG_SERVICES *PcieConfigService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Wrapper->Header);
Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, (VOID **)&PcieConfigService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieConfigService->PcieFmConfigureEnginesLaneAllocation (Wrapper, EngineType, ConfigurationId);
}
return AGESA_ERROR;
}
/*----------------------------------------------------------------------------------------*/
/**
* Get core configuration value
*
*
*
* @param[in] Wrapper Pointer to internal configuration data area
* @param[in] CoreId Core ID
* @param[in] ConfigurationSignature Configuration signature
* @param[out] ConfigurationValue Configuration value (for core configuration)
* @retval AGESA_SUCCESS Configuration successfully applied
* @retval AGESA_ERROR Core configuration value can not be determined
*/
AGESA_STATUS
PcieFmGetCoreConfigurationValue (
IN PCIe_WRAPPER_CONFIG *Wrapper,
IN UINT8 CoreId,
IN UINT64 ConfigurationSignature,
IN UINT8 *ConfigurationValue
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_INIT_SERVICES *PcieInitService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Wrapper->Header);
Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, (VOID **)&PcieInitService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieInitService->PcieFmGetCoreConfigurationValue (Wrapper, CoreId, ConfigurationSignature, ConfigurationValue);
}
return AGESA_ERROR;
}
/*----------------------------------------------------------------------------------------*/
/**
* Check if engine can be remapped to Device/function number requested by user
* defined engine descriptor
*
* Function only called if requested device/function does not much native device/function
*
* @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
PcieFmCheckPortPciDeviceMapping (
IN PCIe_PORT_DESCRIPTOR *PortDescriptor,
IN PCIe_ENGINE_CONFIG *Engine
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_CONFIG_SERVICES *PcieConfigService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header);
Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, (VOID **)&PcieConfigService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieConfigService->PcieFmCheckPortPciDeviceMapping (PortDescriptor, Engine);
}
return FALSE;
}
/*----------------------------------------------------------------------------------------*/
/**
* Get core configuration string
*
* Debug function for logging configuration
*
* @param[in] Wrapper Pointer to internal configuration data area
* @param[in] ConfigurationValue Configuration value
* @retval Configuration string
*/
CONST CHAR8*
PcieFmDebugGetCoreConfigurationString (
IN PCIe_WRAPPER_CONFIG *Wrapper,
IN UINT8 ConfigurationValue
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_DEBUG_SERVICES *PcieDebugService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header);
Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, (VOID **)&PcieDebugService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieDebugService->PcieFmDebugGetCoreConfigurationString (Wrapper, ConfigurationValue);
}
return " !!! Something Wrong !!!";
}
/*----------------------------------------------------------------------------------------*/
/**
* Get wrapper name
*
* Debug function for logging wrapper name
*
* @param[in] Wrapper Pointer to internal configuration data area
* @retval Wrapper Name string
*/
CONST CHAR8*
PcieFmDebugGetWrapperNameString (
IN PCIe_WRAPPER_CONFIG *Wrapper
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_DEBUG_SERVICES *PcieDebugService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Wrapper->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header);
Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, (VOID **)&PcieDebugService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieDebugService->PcieFmDebugGetWrapperNameString (Wrapper);
}
return " !!! Something Wrong !!!";
}
/*----------------------------------------------------------------------------------------*/
/**
* Get register address name
*
* Debug function for logging register trace
*
* @param[in] Silicon Silicon config descriptor
* @param[in] AddressFrame Address Frame
* @retval Register address name
*/
CONST CHAR8*
PcieFmDebugGetHostRegAddressSpaceString (
IN PCIe_SILICON_CONFIG *Silicon,
IN UINT16 AddressFrame
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_DEBUG_SERVICES *PcieDebugService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Silicon->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header);
Status = GnbLibLocateService (GnbPcieFamDebugService, Complex->SocketId, (VOID **)&PcieDebugService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieDebugService->PcieFmDebugGetHostRegAddressSpaceString (Silicon, AddressFrame);
}
return " !!! Something Wrong !!!";
}
/*----------------------------------------------------------------------------------------*/
/**
* Check if the lane can be muxed by link width requested by user
* defined engine descriptor
*
* Check Engine StartCoreLane could be aligned by user requested link width(x1, x2, x4, x8, x16).
* Check Engine StartCoreLane could be aligned by user requested link width x2.
*
* @param[in] PortDescriptor Pointer to user defined engine descriptor
* @param[in] Engine Pointer engine configuration
* @retval TRUE Lane can be muxed
* @retval FALSE Lane can NOT be muxed
*/
BOOLEAN
PcieFmCheckPortPcieLaneCanBeMuxed (
IN PCIe_PORT_DESCRIPTOR *PortDescriptor,
IN PCIe_ENGINE_CONFIG *Engine
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_CONFIG_SERVICES *PcieConfigService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header);
Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, (VOID **)&PcieConfigService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieConfigService->PcieFmCheckPortPcieLaneCanBeMuxed (PortDescriptor, Engine);
}
return FALSE;
}
/*----------------------------------------------------------------------------------------*/
/**
* Map engine to specific PCI device address
*
*
*
* @param[in] Engine Pointer to engine configuration
* @retval AGESA_ERROR Fail to map PCI device address
* @retval AGESA_SUCCESS Successfully allocate PCI address
*/
AGESA_STATUS
PcieFmMapPortPciAddress (
IN PCIe_ENGINE_CONFIG *Engine
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_CONFIG_SERVICES *PcieConfigService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header);
Status = GnbLibLocateService (GnbPcieFamConfigService, Complex->SocketId, (VOID **)&PcieConfigService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieConfigService->PcieFmMapPortPciAddress (Engine);
}
return AGESA_ERROR;
}
/*----------------------------------------------------------------------------------------*/
/**
* Get total number of silicons/wrappers/engines for this complex
*
*
*
* @param[in] SocketId Socket ID.
* @param[out] Length Length of configuration info block
* @param[out] StdHeader Standard Configuration Header
* @retval AGESA_SUCCESS Configuration data length is correct
*/
AGESA_STATUS
PcieFmGetComplexDataLength (
IN UINT8 SocketId,
OUT UINTN *Length,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
AGESA_STATUS Status;
PCIe_FAM_CONFIG_SERVICES *PcieConfigService;
Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, (VOID **)&PcieConfigService, StdHeader);
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieConfigService->PcieFmGetComplexDataLength (SocketId, Length, StdHeader);
}
return Status;
}
/*----------------------------------------------------------------------------------------*/
/**
* Build configuration
*
*
* @param[in] SocketId Socket ID.
* @param[out] Buffer Pointer to buffer to build internal complex data structure
* @param[out] StdHeader Standard configuration header.
* @retval AGESA_SUCCESS Configuration data build successfully
*/
AGESA_STATUS
PcieFmBuildComplexConfiguration (
IN UINT8 SocketId,
OUT VOID *Buffer,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
AGESA_STATUS Status;
PCIe_FAM_CONFIG_SERVICES *PcieConfigService;
Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, (VOID **)&PcieConfigService, StdHeader);
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieConfigService->PcieFmBuildComplexConfiguration (SocketId, Buffer, StdHeader);
}
return Status;
}
/*----------------------------------------------------------------------------------------*/
/**
* Get max link speed capability supported by this port
*
*
*
* @param[in] Flags See Flags PCIE_PORT_GEN_CAP_BOOT / PCIE_PORT_GEN_CAP_MAX
* @param[in] Engine Pointer to engine config descriptor
* @retval PcieGen1/PcieGen2 Max supported link gen capability
*/
PCIE_LINK_SPEED_CAP
PcieFmGetLinkSpeedCap (
IN UINT32 Flags,
IN PCIe_ENGINE_CONFIG *Engine
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_INIT_SERVICES *PcieInitService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header);
Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, (VOID **)&PcieInitService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieInitService->PcieFmGetLinkSpeedCap (Flags, Engine);
}
return PcieGen1;
}
/*----------------------------------------------------------------------------------------*/
/**
* Get native PHY lane bitmap
*
*
* @param[in] PhyLaneBitmap Package PHY lane bitmap
* @param[in] Engine Standard configuration header.
* @retval Native PHY lane bitmap
*/
UINT32
PcieFmGetNativePhyLaneBitmap (
IN UINT32 PhyLaneBitmap,
IN PCIe_ENGINE_CONFIG *Engine
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_PLATFORM_CONFIG *Pcie;
PCIe_FAM_INIT_SERVICES *PcieInitService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header);
Pcie = (PCIe_PLATFORM_CONFIG *) PcieConfigGetParent (DESCRIPTOR_PLATFORM, &Complex->Header);
Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, (VOID **)&PcieInitService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieInitService->PcieFmGetNativePhyLaneBitmap (PhyLaneBitmap, Engine);
}
return 0x0;
}
/*----------------------------------------------------------------------------------------*/
/**
* Set current link speed
*
*
* @param[in] LinkSpeedCapability Link Speed Capability
* @param[in] Engine Pointer to engine configuration descriptor
* @param[in] Pcie Pointer to global PCIe configuration
*
*/
VOID
PcieFmSetLinkSpeedCap (
IN PCIE_LINK_SPEED_CAP LinkSpeedCapability,
IN PCIe_ENGINE_CONFIG *Engine,
IN PCIe_PLATFORM_CONFIG *Pcie
)
{
AGESA_STATUS Status;
PCIe_COMPLEX_CONFIG *Complex;
PCIe_FAM_INIT_SERVICES *PcieInitService;
Complex = (PCIe_COMPLEX_CONFIG *) PcieConfigGetParent (DESCRIPTOR_COMPLEX, &Engine->Header);
Status = GnbLibLocateService (GnbPcieFamInitService, Complex->SocketId, (VOID **)&PcieInitService, GnbLibGetHeader (Pcie));
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
PcieInitService->PcieFmSetLinkSpeedCap (LinkSpeedCapability, Engine, Pcie);
}
}
/*----------------------------------------------------------------------------------------*/
/**
* Get SB port info
*
*
* @param[out] SocketId Socket ID
* @param[out] SbPort Pointer to SB configuration descriptor
* @param[in] StdHeader Standard configuration header.
* @retval AGESA_SUCCESS SB configuration determined successfully
*/
AGESA_STATUS
PcieFmGetSbConfigInfo (
IN UINT8 SocketId,
OUT PCIe_PORT_DESCRIPTOR *SbPort,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
AGESA_STATUS Status;
PCIe_FAM_CONFIG_SERVICES *PcieConfigService;
Status = GnbLibLocateService (GnbPcieFamConfigService, SocketId, (VOID **)&PcieConfigService, StdHeader);
ASSERT (Status == AGESA_SUCCESS);
if (Status == AGESA_SUCCESS) {
return PcieConfigService->PcieFmGetSbConfigInfo (SocketId, SbPort, StdHeader);
}
return Status;
}