Skip to content

Commit

Permalink
Only compare a proc's omi freq if it has functional OCMB children
Browse files Browse the repository at this point in the history
There are checks we do during the memory intialization where we check
to make sure that both processors have the same frequence set for
their OMI traffic. If a processor has no OCMB targets then its
OMI frequence will not get set so we should ignore those processors
for this comparison.

Change-Id: Id00f01756b431695e92a15872ebe00fd18306c4f
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/81462
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Roland Veloz <rveloz@us.ibm.com>
Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
  • Loading branch information
crgeddes authored and dcrowell77 committed Aug 9, 2019
1 parent aade92a commit a789214
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 82 deletions.
10 changes: 10 additions & 0 deletions src/include/usr/fapi2/attribute_service.H
Expand Up @@ -521,6 +521,16 @@ ReturnCode platGetMBvpdSlopeInterceptData(
const uint32_t i_attr,
uint32_t& o_val);

/// @brief This function is called by the FAPI_ATTR_GET functions that lookup
/// values in the MEM_PLL_FREQ_BUCKETS tree. The key's used to lookup values in that
/// tree are the ATTR_FREQ_OMI_MHZ and ATTR_OMI_PLL_VCO attributes. These are on the
/// processor target but it is expected that all of the values match.
/// @param[out] o_omiFreq OMI Frequency of the system
/// @param[out] o_omiVco OMI VCO of the system
/// @return ReturnCode Zero on success, else platform specified error.
errlHndl_t getOmiFreqAndVco(TARGETING::ATTR_FREQ_OMI_MHZ_type & o_omiFreq,
TARGETING::ATTR_OMI_PLL_VCO_type & o_omiVco);

/// @brief This function is called by the FAPI_ATTR_GET macro when getting
// ATTR_FREQ_MCA_MHZ
// @param[in] i_fapiTarget FAPI2 Target pointer
Expand Down
6 changes: 2 additions & 4 deletions src/include/usr/isteps/istep_reasoncodes.H
Expand Up @@ -68,8 +68,7 @@ namespace ISTEP
MOD_MSS_SCRUB = 0x25,
MOD_CALL_UPDATE_UCD_FLASH = 0x26,
MOD_LOAD_HCODE = 0x27,
MOD_GET_OMI_FREQ = 0x28,
MOD_DISCOVER_TARGETS = 0x29,
MOD_DISCOVER_TARGETS = 0x28,
};

/**
Expand Down Expand Up @@ -144,8 +143,7 @@ namespace ISTEP
RC_SLAVE_CORE_WAKEUP_ERROR = ISTEP_COMP_ID | 0x4E,
RC_UCD_IMG_NOT_IN_CONTAINER = ISTEP_COMP_ID | 0x4F,
RC_MM_UNMAP_FAILED = ISTEP_COMP_ID | 0x50,
RC_OMI_FREQ_MISMATCH = ISTEP_COMP_ID | 0x51,
RC_CANNOT_BOOT_WITH_MISMATCHED_BARS = ISTEP_COMP_ID | 0x52,
RC_CANNOT_BOOT_WITH_MISMATCHED_BARS = ISTEP_COMP_ID | 0x51,
};

};
Expand Down
27 changes: 21 additions & 6 deletions src/usr/fapi2/attribute_service.C
Expand Up @@ -2766,9 +2766,9 @@ ReturnCode platGetFreqMcaMhz(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
/// values in the MEM_PLL_FREQ_BUCKETS tree. The key's used to lookup values in that
/// tree are the ATTR_FREQ_OMI_MHZ and ATTR_OMI_PLL_VCO attributes. These are on the
/// processor target but it is expected that all of the values match.
// @param[out] o_omiFreq OMI Frequency of the system
// @param[out] o_omiVco OMI VCO of the system
// @return ReturnCode Zero on success, else platform specified error.
/// @param[out] o_omiFreq OMI Frequency of the system
/// @param[out] o_omiVco OMI VCO of the system
/// @return ReturnCode Zero on success, else platform specified error.
errlHndl_t getOmiFreqAndVco(TARGETING::ATTR_FREQ_OMI_MHZ_type & o_omiFreq,
TARGETING::ATTR_OMI_PLL_VCO_type & o_omiVco)
{
Expand All @@ -2777,16 +2777,31 @@ errlHndl_t getOmiFreqAndVco(TARGETING::ATTR_FREQ_OMI_MHZ_type & o_omiFreq,
// Get all functional Proc targets
TARGETING::TargetHandleList l_procsList;
getAllChips(l_procsList, TARGETING::TYPE_PROC);
uint8_t l_firstValidProc = 0;
bool l_outValueSet = false;

// Until we are told we need to support individual processor frequency
// assert that all of the processors have the same values
for(uint8_t i = 0; i < l_procsList.size(); i++)
{
// First processor's value will be used to compare against all other processors
if(i == 0)
// Get a list of functional OCMB targets under this processor
TARGETING::TargetHandleList l_childOcmbList;
TARGETING::getChildAffinityTargets(l_childOcmbList, l_procsList[i],
TARGETING::CLASS_CHIP,
TARGETING::TYPE_OCMB_CHIP);
// If there are no OCMB children for this processor then ignore it;
if(l_childOcmbList.size() == 0)
{
continue;
}

// First valid processor's values will be used to compare against all other processors
if(!l_outValueSet)
{
o_omiFreq = l_procsList[i]->getAttr<TARGETING::ATTR_FREQ_OMI_MHZ>();
o_omiVco = l_procsList[i]->getAttr<TARGETING::ATTR_OMI_PLL_VCO>();
l_outValueSet = true;
l_firstValidProc = i;
continue;
}

Expand All @@ -2801,7 +2816,7 @@ errlHndl_t getOmiFreqAndVco(TARGETING::ATTR_FREQ_OMI_MHZ_type & o_omiFreq,
FAPI_ERR("platGetMcPllBucket: Detected two processors with difference OMI VCO / FREQ combinations."
" Proc 0x%.08X has OMI freq = %d and OMI vco = %d. "
" Proc 0x%.08X has OMI freq = %d and OMI vco = %d. " ,
get_huid(l_procsList[0]), o_omiFreq, o_omiVco,
get_huid(l_procsList[l_firstValidProc]), o_omiFreq, o_omiVco,
get_huid(l_procsList[i]), l_omiFreqToCmp, l_omiVcoToCmp );

/*@
Expand Down
83 changes: 11 additions & 72 deletions src/usr/isteps/istep07/call_mss_freq.C
Expand Up @@ -72,18 +72,6 @@ using namespace ISTEP_ERROR;
using namespace ERRORLOG;
using namespace TARGETING;

#ifdef CONFIG_AXONE
/**
* @brief Look at all FREQ_OMI_MHZ attribute on all processors, make sure
* they are the same and return the value.
* @param[out] o_omiFreq the frequency of the OMI link between proc and ocmbs
* @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
*
* @note returns error if all OMIs do not have matching frequency set
*/
errlHndl_t getOmiFreq(TARGETING::ATTR_FREQ_OMI_MHZ_type & o_omiFreq);
#endif

//
// Wrapper function to call mss_freq
//
Expand Down Expand Up @@ -261,13 +249,14 @@ void* call_mss_freq( void *io_pArgs )
TARGETING::Target * l_sys = nullptr;
TARGETING::targetService().getTopLevelTarget( l_sys );

uint32_t l_originalNestFreq = Util::getBootNestFreq();
TARGETING::ATTR_FREQ_PB_MHZ_type l_originalNestFreq = Util::getBootNestFreq();

// Omi Freq is only used in P9a and beyond, to limit #ifdef
// craziness below just leave it at 0 so it never changes
uint32_t l_originalOmiFreq = 0;
TARGETING::ATTR_FREQ_OMI_MHZ_type l_originalOmiFreq = 0;
#ifdef CONFIG_AXONE
l_err = getOmiFreq(l_originalOmiFreq);
TARGETING::ATTR_OMI_PLL_VCO_type l_originalOmiVco = 0; // unused but needed for func call
l_err = fapi2::platAttrSvc::getOmiFreqAndVco(l_originalOmiFreq, l_originalOmiVco);
if(l_err)
{
l_StepError.addErrorDetails( l_err );
Expand All @@ -277,7 +266,7 @@ void* call_mss_freq( void *io_pArgs )
#endif

// Read MC_SYNC_MODE from SBE itself and set the attribute
uint8_t l_bootSyncMode = 0;
TARGETING::ATTR_MC_SYNC_MODE_type l_bootSyncMode = 0;
l_err = SBE::getBootMcSyncMode( l_bootSyncMode );
if( l_err )
{
Expand Down Expand Up @@ -381,12 +370,12 @@ void* call_mss_freq( void *io_pArgs )
}

// Get latest MC_SYNC_MODE and FREQ_PB_MHZ
uint8_t l_mcSyncMode = l_masterProc->getAttr<TARGETING::ATTR_MC_SYNC_MODE>();
uint32_t l_newOmiFreq = 0;

uint32_t l_newNestFreq = l_sys->getAttr<TARGETING::ATTR_FREQ_PB_MHZ>();
TARGETING::ATTR_MC_SYNC_MODE_type l_mcSyncMode = l_masterProc->getAttr<TARGETING::ATTR_MC_SYNC_MODE>();
TARGETING::ATTR_FREQ_OMI_MHZ_type l_newOmiFreq = 0;
TARGETING::ATTR_FREQ_PB_MHZ_type l_newNestFreq = l_sys->getAttr<TARGETING::ATTR_FREQ_PB_MHZ>();
#ifdef CONFIG_AXONE
l_err = getOmiFreq(l_newOmiFreq);
TARGETING::ATTR_OMI_PLL_VCO_type l_newOmiVco = 0; // unused but needed for func call
l_err = fapi2::platAttrSvc::getOmiFreqAndVco(l_newOmiFreq, l_newOmiVco);
if(l_err)
{
l_StepError.addErrorDetails( l_err );
Expand Down Expand Up @@ -502,54 +491,4 @@ void* call_mss_freq( void *io_pArgs )
return l_StepError.getErrorHandle();
}

#ifdef CONFIG_AXONE
errlHndl_t getOmiFreq(TARGETING::ATTR_FREQ_OMI_MHZ_type & o_omiFreq)
{
errlHndl_t l_err = nullptr;
TARGETING::TargetHandleList l_procTargetList;
getAllChips(l_procTargetList, TYPE_PROC);

assert( l_procTargetList.size() > 0, "getOmiFreq: Expected at least one functional processor");

o_omiFreq = l_procTargetList[0]->getAttr<TARGETING::ATTR_FREQ_OMI_MHZ>();
// Until we are told we need to support individual processor frequency
// assert that all of the processors have the same values
for(uint8_t i = 1; i < l_procTargetList.size(); i++)
{

TARGETING::ATTR_FREQ_OMI_MHZ_type l_tmpFreq =
l_procTargetList[i]->getAttr<TARGETING::ATTR_FREQ_OMI_MHZ>();

if(o_omiFreq != l_tmpFreq)
{
/*@
* @errortype ERRL_SEV_UNRECOVERABLE
* @moduleid MOD_GET_OMI_FREQ
* @reasoncode RC_OMI_FREQ_MISMATCH
* @userdata1[0:31] First OMI freq found
* @userdata1[32:63] Mismatched OMI freq found
* @userdata2[0:31] Huid of first proc found
* @userdata2[32:63] Huid of proc w/ mismatched OMI freq
* @devdesc Processor have mismatch OMI freq
* @custdesc Invalid processor frequency settings
*/
l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
MOD_GET_OMI_FREQ,
RC_OMI_FREQ_MISMATCH,
TWO_UINT32_TO_UINT64(
TO_UINT32(o_omiFreq),
TO_UINT32(l_tmpFreq)),
TWO_UINT32_TO_UINT64(
get_huid(l_procTargetList[0]),
get_huid(l_procTargetList[i])),
ErrlEntry::ADD_SW_CALLOUT);

break;
}
}

return l_err;
}
#endif

}; // end namespace
}; // end namespace

0 comments on commit a789214

Please sign in to comment.