diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2014-10-14 17:11:08 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-10-21 13:04:27 -0500 |
commit | 198e80b53d58c506c0db4d5de4eb5b8e4bed2aed (patch) | |
tree | 39584598948756cf0a4fa826f94fc9d75e0d0998 /src/usr/hwpf/hwp/nest_chiplets/nest_chiplets.C | |
parent | ffe1209fc922a571cc9fc6864c7f437b230aa8af (diff) | |
download | talos-hostboot-198e80b53d58c506c0db4d5de4eb5b8e4bed2aed.tar.gz talos-hostboot-198e80b53d58c506c0db4d5de4eb5b8e4bed2aed.zip |
Move FSP-only attributes to common targeting for Open Power
- Added default lane masks to Hostboot system XML files
- Added PCIE config related module IDs and reason codes
- Added new packing function to combine 4x uint8 into 1x uint32
- Added dynamic PCIE config for SP-less environments
- Moved PCIE attributes into common attribute definition
- Attached new PCIE attributes to common target definition
- Defaulted PCIE lanes per proc appropriately for all proc chips
- Added CDM_DOMAIN attribute into common attribute definition
- Attached + defaulted CDM domain in common target definition
- Updated common MRW parser to customize the new PCIE attributes
Change-Id: I3779ca6e6a4803d7e78e21e47a92e0b1a09e657d
RTC: 113488
CMVC-coreq: 942076
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13997
Tested-by: Jenkins Server
Reviewed-by: STEPHEN M. CPREK <smcprek@us.ibm.com>
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/nest_chiplets/nest_chiplets.C')
-rw-r--r-- | src/usr/hwpf/hwp/nest_chiplets/nest_chiplets.C | 810 |
1 files changed, 807 insertions, 3 deletions
diff --git a/src/usr/hwpf/hwp/nest_chiplets/nest_chiplets.C b/src/usr/hwpf/hwp/nest_chiplets/nest_chiplets.C index bd6dc5775..f94bf8fb5 100644 --- a/src/usr/hwpf/hwp/nest_chiplets/nest_chiplets.C +++ b/src/usr/hwpf/hwp/nest_chiplets/nest_chiplets.C @@ -45,6 +45,7 @@ #include <errl/errludtarget.H> #include <initservice/isteps_trace.H> +#include <initservice/initserviceif.H> // targeting support #include <targeting/common/commontargeting.H> @@ -782,6 +783,787 @@ void* call_proc_abus_scominit( void *io_pArgs ) return l_StepError.getErrorHandle(); } +//****************************************************************************** +// _queryIopsToBifurcateAndPhbsToDisable +//****************************************************************************** + +#ifdef DYNAMIC_BIFURCATION +// Normally a x16 PCIE adapter is driven by one PHB in the processor. +// Some x16 adapters have two logically different devices integrated +// onto the same adapter, each acting as a x8 PCIE endpoint driven by +// its own PHB. The ability to detect which type of PCIE adapter is +// present and dynamically reconfigure the PCIE langes / PHBs to support +// whatever is present is called 'dynamic bifurcation'. This feature is +// not officially supported however hooks remain in place to add that +// support easily. To enable it, define the DYNAMIC_BIFURCATION flag +// and implement the guts of the +// _queryIopsToBifurcateAndPhbsToDisable function. + +errlHndl_t _queryIopsToBifurcateAndPhbsToDisable( + TARGETING::ConstTargetHandle_t const i_pProcChipTarget, + BifurcatedIopsContainer& o_iopList, + TARGETING::ATTR_PROC_PCIE_PHB_ACTIVE_type& o_disabledPhbsMask) +{ + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK "_queryIopsToBifurcateAndPhbsToDisable: Proc chip target " + "HUID = 0x%08X.", + i_pProcChipTarget ? + i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>() : 0); + + errlHndl_t pError = NULL; + o_iopList.clear(); + o_disabledPhbsMask = 0; + + do { + + // Extension point to return bifurcated IOPs and PHBs to disable. + // Assuming no extensions are added, the function returns no IOPs to + // bifurcate and no PHBs to disable + + // If implemented, this function should only return error on software code + // bug. Any other condition should result in IOPs not being bifurcated and + // host taking care of that condition. + + } while(0); + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK "_queryIopsToBifurcateAndPhbsToDisable: EID = 0x%08X, " + "PLID = 0x%08X, RC = 0x%08X.", + ERRL_GETEID_SAFE(pError),ERRL_GETPLID_SAFE(pError), + ERRL_GETRC_SAFE(pError)); + + return pError; +} + +#endif + +//****************************************************************************** +// _deconfigPhbsBasedOnPciState +//****************************************************************************** + +void _deconfigPhbsBasedOnPciState( + TARGETING::ConstTargetHandle_t const i_pProcChipTarget, + TARGETING::ATTR_PROC_PCIE_PHB_ACTIVE_type& io_phbActiveMask) +{ + errlHndl_t pError = NULL; + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK "_deconfigPhbsBasedOnPciState: Proc chip target HUID = " + "0x%08X, PHB active mask = 0x%02X.", + i_pProcChipTarget ? + i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>() : 0, + io_phbActiveMask); + + // Get proc chip's functional PCI units + TARGETING::TargetHandleList funcPciList; + (void)TARGETING::getChildChiplets( + funcPciList,i_pProcChipTarget,TARGETING::TYPE_PCI); + + // Activate PHB mask bits based on functional PCI units + TARGETING::ATTR_PROC_PCIE_PHB_ACTIVE_type activePciMask = 0; + for (TARGETING::TargetHandleList::const_iterator pciItr + = funcPciList.begin(); + pciItr != funcPciList.end(); + ++pciItr) + { + // PCI chip unit to PHB mapping is as follows: + // + // PCI-0 => PHB0 + // PCI-1 => PHB1 + // PCI-2 => PHB2 + // + // Further, io_phbActiveMask and activePciMask are bitmasks whose + // leftmost bit corresponds to PHB0, followed by bits for PHB1 and PHB2. + // The remaining bits are ignored. + + // Compensate for the fact that PHB mask bits start on left side of the + // mask + const size_t bitsToLeftShift + = ((sizeof(activePciMask)*BITS_PER_BYTE) - 1); + + // Committing an error here because this would mean a read only + // attribute was set to a value which should be impossible, the + // side effect will be that whatever PHB this should really correspond + // to will not be enabled + if((*pciItr)->getAttr<TARGETING::ATTR_CHIP_UNIT>() > bitsToLeftShift) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK "_deconfigPhbsBasedOnPciState> " + "Code Bug! CHIP_UNIT attribute (%d) for PCI unit with HUID of " + "0x%08X was larger than max value of %d in " + "_deconfigPhbsBasedOnPciState().", + (*pciItr)->getAttr<TARGETING::ATTR_CHIP_UNIT>(), + (*pciItr)->getAttr<TARGETING::ATTR_HUID>(), + bitsToLeftShift ); + /*@ + * @errortype + * @moduleid ISTEP_DECONFIG_PHBS_BASED_ON_PCI_STATE + * @reasoncode ISTEP_TARGET_NULL + * @userdata1[0:31] HUID of PCI target with bad ATTR_CHIP_UNIT + * @userdata1[32:39] ATTR_CHIP_UNIT value + * @userdata2[40:47] # bits to shift + * @devdesc Attribute model inconsistency detected; Cannot + * represent PHB bitmask given the value of the + * PCI target's chip unit attribute. Continuing + * without PHB enabled + * @custdesc A problem isolated to firmware occurred during + * the IPL of the system. + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + ISTEP_DECONFIG_PHBS_BASED_ON_PCI_STATE, + ISTEP_TARGET_NULL, + TWO_UINT32_TO_UINT64( + (*pciItr)->getAttr<TARGETING::ATTR_HUID>(), + TWO_UINT16_TO_UINT32( + TWO_UINT8_TO_UINT16( + (*pciItr)->getAttr<TARGETING::ATTR_CHIP_UNIT>(), + bitsToLeftShift), + 0)), + 0, + true); + + ERRORLOG::ErrlUserDetailsTarget(*pciItr).addToLog(pError); + pError->collectTrace(ISTEP_COMP_NAME); + errlCommit(pError, ISTEP_COMP_ID); + + continue; + } + + activePciMask |= + (1 << ( bitsToLeftShift + - (*pciItr)->getAttr<TARGETING::ATTR_CHIP_UNIT>())); + } + + // Can never enable more PHBs than were supplied as input. It's conceivable + // that due to code bug in the chip unit attribute, the unit value + // corresponds to a non supported PHB. This masking will also prevent the + // error from propagating. There is no way to trap for valid PHBs that are + // cross-wired vis a vis the chip unit attribute. + io_phbActiveMask &= activePciMask; + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK "_deconfigPhbsBasedOnPciState: io_phbActiveMask = 0x%02X", + io_phbActiveMask); + + return; +} + +//****************************************************************************** +// Local logical equality operator for matching lane configuration rows +//****************************************************************************** + +inline bool operator==( + const laneConfigRow& i_lhs, + const laneConfigRow& i_rhs) +{ + return ( memcmp(i_lhs.laneSet,i_rhs.laneSet,sizeof(i_lhs.laneSet)) == 0); +} + +//****************************************************************************** +// _laneMaskToLaneWidth +//****************************************************************************** + +LaneWidth _laneMaskToLaneWidth(const uint16_t i_laneMask) +{ + LaneWidth laneWidth = LANE_WIDTH_NC; + if(i_laneMask == LANE_MASK_X16) + { + laneWidth = LANE_WIDTH_16X; + } + else if( (i_laneMask == LANE_MASK_X8_GRP0) + || (i_laneMask == LANE_MASK_X8_GRP1)) + { + laneWidth = LANE_WIDTH_8X; + } + + return laneWidth; +} + +//****************************************************************************** +// computeProcPcieConfigAttrs +//****************************************************************************** + +errlHndl_t computeProcPcieConfigAttrs( + TARGETING::TargetHandle_t const i_pProcChipTarget) +{ + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + ENTER_MRK "computeProcPcieConfigAttrs: Proc chip target HUID = " + "0x%08X.", + i_pProcChipTarget ? + i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>() : 0); + + // Currently there are two IOP config tables, one for procs with 24 usable + // PCIE lanes and one for proces with 32 usable PCIE lanes. In general, the + // code accumulates the current configuration of the IOPs from the MRW and + // other dynamic information (such as bifurcation, etc.), then matches that + // config to one of the rows in the table. Once a match is discovered, the + // IOP config value is pulled from the matching row and set in the + // attributes. + const laneConfigRow x24_laneConfigTable[] = + {{{{{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x0,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_NC,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x0,PHB0_MASK}, + + {{{{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x1,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_NC,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x1,PHB0_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x2,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x3,PHB0_MASK|PHB1_MASK|PHB2_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}, + {{LANE_WIDTH_NC,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x3,PHB0_MASK|PHB2_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x4,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x5,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x6,PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x7,PHB1_MASK|PHB2_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x8,PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x9,PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0xA,PHB2_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0xB,PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0xC,PHB1_MASK|PHB2_MASK}, + }; + + const laneConfigRow* x24_end = x24_laneConfigTable + + ( sizeof(x24_laneConfigTable) + / sizeof(x24_laneConfigTable[0])); + + const laneConfigRow x32_laneConfigTable[] = + {{{{{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x0,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}}, + 0x1,PHB0_MASK|PHB1_MASK|PHB2_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x2,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}}, + 0x3,PHB0_MASK|PHB1_MASK|PHB2_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x4,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}}, + 0x5,PHB0_MASK|PHB1_MASK|PHB2_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}, + {{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x6,PHB0_MASK|PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}}, + 0x7,PHB0_MASK|PHB1_MASK|PHB2_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_16X,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x8,PHB1_MASK}, + + {{{{LANE_WIDTH_8X,DSMP_ENABLE}, + {LANE_WIDTH_8X,DSMP_ENABLE}}, + {{LANE_WIDTH_8X,DSMP_DISABLE}, + {LANE_WIDTH_8X,DSMP_DISABLE}}}, + 0x9,PHB1_MASK|PHB2_MASK}, + }; + + const laneConfigRow* x32_end = x32_laneConfigTable + + ( sizeof(x32_laneConfigTable) + / sizeof(x32_laneConfigTable[0])); + + errlHndl_t pError = NULL; + const laneConfigRow* pLaneConfigTableBegin = NULL; + const laneConfigRow* pLaneConfigTableEnd = NULL; + + do + { + if(i_pProcChipTarget == NULL) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK "computeProcPcieConfigAttrs> " + "Code bug! Input processor target is NULL"); + + /*@ + * @errortype + * @moduleid ISTEP_COMPUTE_PCIE_CONFIG_ATTRS + * @reasoncode ISTEP_TARGET_NULL + * @devdesc Caller passed a NULL processor target + * @custdesc A problem isolated to firmware occurred during the + * IPL of the system. + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + ISTEP_COMPUTE_PCIE_CONFIG_ATTRS, + ISTEP_TARGET_NULL, + 0, + 0, + true); + pError->collectTrace(ISTEP_COMP_NAME); + break; + } + + const TARGETING::ATTR_CLASS_type targetClass + = i_pProcChipTarget->getAttr<TARGETING::ATTR_CLASS>(); + const TARGETING::ATTR_TYPE_type targetType + = i_pProcChipTarget->getAttr<TARGETING::ATTR_TYPE>(); + const bool targetPresent = + i_pProcChipTarget->getAttr<TARGETING::ATTR_HWAS_STATE>() + .present; + + if( (targetClass != TARGETING::CLASS_CHIP) + || (targetType != TARGETING::TYPE_PROC) + || (!targetPresent)) + { + const TARGETING::ATTR_HUID_type targetHuid + = i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>(); + + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK "computeProcPcieConfigAttrs> Code bug!" + "Input target is not a processor chip or is not present. " + "Class = 0x%08X, " + "Type = 0x%08X, HUID = 0x%08X, Present? = %d", + targetClass,targetType, + targetHuid, + targetPresent); + + /*@ + * @errortype + * @moduleid ISTEP_COMPUTE_PCIE_CONFIG_ATTRS + * @reasoncode ISTEP_INVALID_TARGET_TYPE + * @userdata1[0:31] Illegal target's class + * @userdata1[32:63] Illegal target's type + * @userdata2[0:31] Illegal target's HUID + * @userdata2[32:63] Illegal target's presence (0=no, 1=yes) + * @devdesc Caller passed a non-processor chip target or + * passed a processor chip target that was not + * present + * @custdesc A problem isolated to firmware occurred during + * the IPL of the system. + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + ISTEP_COMPUTE_PCIE_CONFIG_ATTRS, + ISTEP_INVALID_TARGET_TYPE, + TWO_UINT32_TO_UINT64( + targetClass,targetType), + TWO_UINT32_TO_UINT64( + targetHuid,targetPresent), + true); + ERRORLOG::ErrlUserDetailsTarget(i_pProcChipTarget).addToLog(pError); + pError->collectTrace(ISTEP_COMP_NAME); + break; + } + + // Pick the appropriate IOP configuration table + if( i_pProcChipTarget->getAttr<TARGETING::ATTR_IOP_LANES_PER_PROC>() + == IOP_LANES_PER_PROC_32X) + { + pLaneConfigTableBegin = x32_laneConfigTable; + pLaneConfigTableEnd = x32_end; + } + else if( i_pProcChipTarget->getAttr< + TARGETING::ATTR_IOP_LANES_PER_PROC>() + == IOP_LANES_PER_PROC_24X) + { + pLaneConfigTableBegin = x24_laneConfigTable; + pLaneConfigTableEnd = x24_end; + } + else + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK "computeProcPcieConfigAttrs> " + "Code bug! Unsupported ATTR_IOP_LANES_PER_PROC attribute for " + "processor with HUID of 0x%08X. Expected 24 or 32, but read " + "value of %d.", + i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>(), + i_pProcChipTarget->getAttr< + TARGETING::ATTR_IOP_LANES_PER_PROC>()); + + /*@ + * @errortype + * @moduleid ISTEP_COMPUTE_PCIE_CONFIG_ATTRS + * @reasoncode ISTEP_INVALID_ATTR_VALUE + * @userdata1[0:31] Target's HUID + * @userdata2[32:63] ATTR_IOP_LANES_PER_PROC attribute value + * @devdesc Illegal ATTR_IOP_LANES_PER_PROC attribute read + * from a processor chip target. + * @custdesc A problem isolated to firmware or firmware + * customization occurred during the IPL of the + * system. + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + ISTEP_COMPUTE_PCIE_CONFIG_ATTRS, + ISTEP_INVALID_ATTR_VALUE, + TWO_UINT32_TO_UINT64( + i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>(), + i_pProcChipTarget->getAttr< + TARGETING::ATTR_IOP_LANES_PER_PROC>()), + 0, + true); + ERRORLOG::ErrlUserDetailsTarget(i_pProcChipTarget).addToLog(pError); + pError->collectTrace(ISTEP_COMP_NAME); + break; + } + + TARGETING::ATTR_PROC_PCIE_PHB_ACTIVE_type disabledPhbs = 0; + +#ifdef DYNAMIC_BIFURCATION + + // Figure out which IOPs need bifurcation, and as a result, which PHBs + // to disable + BifurcatedIopsContainer iopList; + pError = _queryIopsToBifurcateAndPhbsToDisable( + i_pProcChipTarget, + iopList, + disabledPhbs); + if(pError!=NULL) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK "computeProcPcieConfigAttrs> " + "Failed in call to _queryIopsToBifurcateAndPhbsToDisable; " + "Proc HUID = 0x%08X.", + i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>()); + break; + } +#endif + + // Arrays require all try[Get|Set]Attr API calls in order to be able to + // read them properly. All attributes should exist, so assert if they + // do not. + TARGETING::ATTR_PROC_PCIE_LANE_MASK_NON_BIFURCATED_type + laneMaskNonBifurcated = {{0}}; + assert(i_pProcChipTarget->tryGetAttr< + TARGETING::ATTR_PROC_PCIE_LANE_MASK_NON_BIFURCATED>( + laneMaskNonBifurcated)); + + TARGETING::ATTR_PROC_PCIE_IOP_REVERSAL_NON_BIFURCATED_type + laneReversalNonBifrucated = {{0}}; + assert(i_pProcChipTarget->tryGetAttr< + TARGETING::ATTR_PROC_PCIE_IOP_REVERSAL_NON_BIFURCATED>( + laneReversalNonBifrucated)); + + TARGETING::ATTR_PROC_PCIE_IOP_SWAP_NON_BIFURCATED_type + laneSwapNonBifurcated = {{0}}; + assert(i_pProcChipTarget->tryGetAttr< + TARGETING::ATTR_PROC_PCIE_IOP_SWAP_NON_BIFURCATED>( + laneSwapNonBifurcated)); + + TARGETING::ATTR_PROC_PCIE_LANE_MASK_type + effectiveLaneMask = {{0}}; + memcpy(effectiveLaneMask,laneMaskNonBifurcated, + sizeof(effectiveLaneMask)); + + TARGETING::ATTR_PROC_PCIE_IOP_REVERSAL_type + effectiveLaneReversal = {{0}}; + memcpy(effectiveLaneReversal,laneReversalNonBifrucated, + sizeof(effectiveLaneReversal)); + + TARGETING::ATTR_PROC_PCIE_IOP_SWAP_type + effectiveLaneSwap = {0}; + + // Apply the non-bifurcated lane swap + for(size_t iop = 0; iop<MAX_IOPS_PER_PROC; ++iop) + { + uint8_t laneSwap = 0; + for(size_t laneGroup = 0; + laneGroup < + (sizeof(laneSwapNonBifurcated)/sizeof(effectiveLaneSwap)); + ++laneGroup) + { + // If lanes are used and swap not yet set, then set it + if( (effectiveLaneMask[iop][laneGroup]) + && (!laneSwap)) + { + laneSwap = + laneSwapNonBifurcated[iop][laneGroup]; + } + } + effectiveLaneSwap[iop] = laneSwap; + } + +#ifdef DYNAMIC_BIFURCATION + + TARGETING::ATTR_PROC_PCIE_LANE_MASK_BIFURCATED_type + laneMaskBifurcated = {{0}}; + assert(i_pProcChipTarget->tryGetAttr< + TARGETING::ATTR_PROC_PCIE_LANE_MASK_BIFURCATED>( + laneMaskBifurcated)); + + TARGETING::ATTR_PROC_PCIE_IOP_REVERSAL_BIFURCATED_type + laneReversalBifurcated = {{0}}; + assert(i_pProcChipTarget->tryGetAttr< + TARGETING::ATTR_PROC_PCIE_IOP_REVERSAL_BIFURCATED>( + laneReversalBifurcated)); + + TARGETING::ATTR_PROC_PCIE_IOP_SWAP_BIFURCATED_type + bifurcatedSwap = {{0}}; + assert(i_pProcChipTarget->tryGetAttr< + TARGETING::ATTR_PROC_PCIE_IOP_SWAP_BIFURCATED>( + bifurcatedSwap)); + + // Apply any IOP bifurcation settings + for(BifurcatedIopsContainer::const_iterator iopItr = iopList.begin(); + iopItr != iopList.end(); + ++iopItr) + { + BifurcatedIopsContainer::const_reference iop = *iopItr; + memcpy( + &effectiveLaneReversal[iop][0], + &laneReversalBifurcated[iop][0], + sizeof(effectiveLaneReversal)/MAX_IOPS_PER_PROC); + + memcpy( + &effectiveLaneMask[iop][0], + &laneMaskBifurcated[iop][0], + sizeof(effectiveLaneMask)/MAX_IOPS_PER_PROC); + + uint8_t laneSwap = 0; + for(size_t laneGroup=0; + laneGroup < + (sizeof(bifurcatedSwap)/sizeof(effectiveLaneSwap)); + ++laneGroup) + { + // If lanes are used and swap not yet set, then set it + if( (effectiveLaneMask[iop][laneGroup]) + && (!laneSwap)) + { + laneSwap = + bifurcatedSwap[iop][laneGroup]; + } + } + effectiveLaneSwap[iop] = laneSwap; + } +#endif + + i_pProcChipTarget->setAttr< + TARGETING::ATTR_PROC_PCIE_LANE_MASK>(effectiveLaneMask); + + i_pProcChipTarget->setAttr< + TARGETING::ATTR_PROC_PCIE_IOP_REVERSAL>(effectiveLaneReversal); + + i_pProcChipTarget->setAttr< + TARGETING::ATTR_PROC_PCIE_IOP_SWAP>(effectiveLaneSwap); + + TARGETING::ATTR_PROC_PCIE_DSMP_CAPABLE_type + dsmpCapable = {{0}}; + assert(i_pProcChipTarget->tryGetAttr< + TARGETING::ATTR_PROC_PCIE_DSMP_CAPABLE>(dsmpCapable)); + + TARGETING::ATTR_PROC_PCIE_PHB_ACTIVE_type phbActiveMask = 0; + TARGETING::ATTR_PROC_PCIE_IOP_CONFIG_type iopConfig = 0; + + laneConfigRow effectiveConfig = + {{{{LANE_WIDTH_NC,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}, + {{LANE_WIDTH_NC,DSMP_DISABLE}, + {LANE_WIDTH_NC,DSMP_DISABLE}}}, + 0x0,PHB_MASK_NA}; + + // Transform effective config to match lane config table format + for(size_t iop = 0; + iop < MAX_IOPS_PER_PROC; + ++iop) + { + for(size_t laneGroup = 0; + laneGroup < MAX_LANE_GROUPS_PER_IOP; + ++laneGroup) + { + effectiveConfig.laneSet[iop][laneGroup].width + = _laneMaskToLaneWidth(effectiveLaneMask[iop][laneGroup]); + effectiveConfig.laneSet[iop][laneGroup].dsmp + = dsmpCapable[iop][laneGroup]; + } + } + + const laneConfigRow* laneConfigItr = + std::find( + pLaneConfigTableBegin, + pLaneConfigTableEnd, + effectiveConfig); + + if(laneConfigItr != pLaneConfigTableEnd) + { + iopConfig = laneConfigItr->laneConfig; + phbActiveMask = laneConfigItr->phbActive; + + // Disable applicable PHBs + phbActiveMask &= (~disabledPhbs); + (void)_deconfigPhbsBasedOnPciState( + i_pProcChipTarget, + phbActiveMask); + } + else + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK "computeProcPcieConfigAttrs> " + "Code bug! Proc PCIE IOP configuration not found. Continuing " + "with no PHBs active. " + "IOP0 Lane set 0: Lane mask = 0x%04X, DSMP enable = 0x%02X. " + "IOP0 Lane set 1: Lane mask = 0x%04X, DSMP enable = 0x%02X. ", + effectiveLaneMask[0][0],dsmpCapable[0][0], + effectiveLaneMask[0][1],dsmpCapable[0][1]); + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "IOP1 Lane set 0: Lane mask = 0x%04X, DSMP enable = 0x%02X. " + "IOP1 Lane set 1: Lane mask = 0x%04X, DSMP enable = 0x%02X. ", + effectiveLaneMask[1][0],dsmpCapable[1][0], + effectiveLaneMask[1][1],dsmpCapable[1][1]); + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "Proc chip target HUID = 0x%08X.", + i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>()); + /*@ + * @errortype + * @moduleid ISTEP_COMPUTE_PCIE_CONFIG_ATTRS + * @reasoncode ISTEP_INVALID_CONFIGURATION + * @userdata1[0:31] Target processor chip's HUID + * @userdata1[32:39] IOP 0 lane set 0 DSMP enable + * @userdata1[40:47] IOP 0 lane set 1 DSMP enable + * @userdata1[48:55] IOP 1 lane set 0 DSMP enable + * @userdata1[56:63] IOP 1 lane set 1 DSMP enable + * @userdata2[0:15] IOP 0 lane set 0 lane mask + * @userdata2[16:31] IOP 0 lane set 1 lane mask + * @userdata2[32:47] IOP 1 lane set 0 lane mask + * @userdata2[48:63] IOP 1 lane set 1 lane mask + * @devdesc No valid PCIE IOP configuration found. All + * PHBs on the processor will be disabled. + * @custdesc A problem isolated to firmware or firmware + * customization occurred during the IPL of the + * system. + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + ISTEP_COMPUTE_PCIE_CONFIG_ATTRS, + ISTEP_INVALID_CONFIGURATION, + TWO_UINT32_TO_UINT64( + i_pProcChipTarget->getAttr<TARGETING::ATTR_HUID>(), + FOUR_UINT8_TO_UINT32( + dsmpCapable[0][0], + dsmpCapable[0][1], + dsmpCapable[1][0], + dsmpCapable[1][1])), + FOUR_UINT16_TO_UINT64( + effectiveLaneMask[0][0], + effectiveLaneMask[0][1], + effectiveLaneMask[1][0], + effectiveLaneMask[1][1]), + true); + ERRORLOG::ErrlUserDetailsTarget(i_pProcChipTarget).addToLog(pError); + pError->collectTrace(ISTEP_COMP_NAME); + errlCommit(pError, ISTEP_COMP_ID); + } + + i_pProcChipTarget->setAttr< + TARGETING::ATTR_PROC_PCIE_PHB_ACTIVE>(phbActiveMask); + i_pProcChipTarget->setAttr< + TARGETING::ATTR_PROC_PCIE_IOP_CONFIG>(iopConfig); + + } while(0); + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + EXIT_MRK "computeProcPcieConfigAttrs: EID = 0x%08X, PLID = 0x%08X, " + "RC = 0x%08X.", + ERRL_GETEID_SAFE(pError),ERRL_GETPLID_SAFE(pError), + ERRL_GETRC_SAFE(pError)); + + return pError; +} //***************************************************************************** // wrapper function to call proc_pcie_scominit @@ -791,8 +1573,7 @@ void* call_proc_pcie_scominit( void *io_pArgs ) errlHndl_t l_errl = NULL; IStepError l_StepError; - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "call_proc_pcie_scominit entry" ); + bool spBaseServicesEnabled = INITSERVICE::spBaseServicesEnabled(); TARGETING::TargetHandleList l_procTargetList; getAllChips(l_procTargetList, TYPE_PROC); @@ -802,7 +1583,30 @@ void* call_proc_pcie_scominit( void *io_pArgs ) l_iter != l_procTargetList.end(); ++l_iter ) { - const TARGETING::Target* l_proc_target = *l_iter; + TARGETING::Target* const l_proc_target = *l_iter; + + // Compute the PCIE attribute config on all non-SP systems, since SP + // won't be there to do it. + if(!spBaseServicesEnabled) + { + // Unlike SP which operates on all present procs, the SP-less + // algorithm only needs to operate on functional ones + l_errl = computeProcPcieConfigAttrs(l_proc_target); + if(l_errl != NULL) + { + // Any failure to configure PCIE that makes it to this handler + // implies a firmware bug that should be fixed, everything else + // is tolerated internally (usually as disabled PHBs) + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + ERR_MRK "call_proc_pcie_scominit> Failed in call to " + "computeProcPcieConfigAttrs for target with HUID = " + "0x%08X", + l_proc_target->getAttr<TARGETING::ATTR_HUID>()); + l_StepError.addErrorDetails(l_errl); + errlCommit( l_errl, ISTEP_COMP_ID ); + } + } + const fapi::Target l_fapi_proc_target( TARGET_TYPE_PROC_CHIP, ( const_cast<TARGETING::Target*>(l_proc_target) )); |