From 574d17e95e5f640054c0e11a6fb9206e61e4bc81 Mon Sep 17 00:00:00 2001 From: Bill Schwartz Date: Sat, 23 Aug 2014 11:28:58 -0500 Subject: Only Calculate ISDIMM Power Curves if needed Calculate ISDIMM power curve value if the calcuation algorithm or calculation dependenices change or if there is a hw change. Change-Id: I74826c2d9079a7c35271671626ee1dc922a9d552 RTC: 67641 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/12968 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- src/usr/hwpf/hwp/dram_training/dram_training.C | 368 ++++++++++++++++++--- .../mss_dimm_power_test/mss_dimm_power_test.C | 93 +++++- .../mss_dimm_power_test/mss_dimm_power_test.H | 42 ++- 3 files changed, 440 insertions(+), 63 deletions(-) (limited to 'src/usr/hwpf/hwp/dram_training') diff --git a/src/usr/hwpf/hwp/dram_training/dram_training.C b/src/usr/hwpf/hwp/dram_training/dram_training.C index 0c88ac5d5..04f415ff9 100644 --- a/src/usr/hwpf/hwp/dram_training/dram_training.C +++ b/src/usr/hwpf/hwp/dram_training/dram_training.C @@ -37,6 +37,7 @@ // Includes /******************************************************************************/ #include +#include #include #include @@ -795,86 +796,357 @@ void* call_mss_draminit_mc( void *io_pArgs ) "SUCCESS : mss_draminit_mc HWP( )" ); } - } // End memBuf loop + } // End; memBuf loop TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit_mc exit" ); return l_stepError.getErrorHandle(); } + // -// Wrapper function to call mss_dimm_power_test +// support functions for mss_dimm_power_test wrapper // -void* call_mss_dimm_power_test( void *io_pArgs ) +typedef bool (*mss_dimm_power_test_helper_t) (TARGETING::Target*, bool &); + +// helper function to set the change bit for present non-functional targets +bool mss_dimm_power_test_set (TARGETING::Target* i_target, + bool &o_keepChecking) { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "call_mss_dimm_power_test entry" ); + bool l_changed = false; + o_keepChecking = true; - errlHndl_t l_err = NULL; + if ((!i_target->getAttr().functional) && + (i_target->getAttr().present)) + { + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "===== membuf %.8x non func change flag set", + get_huid(i_target)); - // get a list of mba targets - IStepError l_stepError; + update_hwas_changed_mask( i_target, + HWAS_CHANGED_BIT_DIMM_POWER_TEST); - TARGETING::TargetHandleList l_mbaTargetList; - TARGETING::TargetHandleList::const_iterator pRangeLimitItr; - TARGETING::TargetHandleList::const_iterator pTargetItr; + l_changed = true; + } + return l_changed; +} - // Get all MBA targets - getAllChiplets(l_mbaTargetList, TYPE_MBA, true); +// helper function to check if change bit set, stop checking if found +bool mss_dimm_power_test_check (TARGETING::Target* i_target, + bool &o_keepChecking) +{ + bool l_changed = false; + o_keepChecking = true; - // Limit the number of MBAs to run in VPO environment to save time. - uint8_t l_mbaLimit = l_mbaTargetList.size(); - if (TARGETING::is_vpo() && (VPO_NUM_OF_MBAS_TO_RUN < l_mbaLimit)) + ATTR_HWAS_STATE_CHANGED_FLAG_type hwChangeFlag; + hwChangeFlag=i_target->getAttr(); + + if(HWAS_CHANGED_BIT_DIMM_POWER_TEST & hwChangeFlag) { - // limit the range to VPO_NUM_OF_MBAS_TO_RUN - pRangeLimitItr = l_mbaTargetList.begin() + VPO_NUM_OF_MBAS_TO_RUN; + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "===== membuf %.8x change flag set", + get_huid(i_target)); + l_changed = true; + o_keepChecking = false; } - else + return l_changed; +}; + +// helpfer function to clear any set change bits +bool mss_dimm_power_test_clear (TARGETING::Target* i_target, + bool &o_keepChecking) +{ + bool l_changed = false; + o_keepChecking = true; + + ATTR_HWAS_STATE_CHANGED_FLAG_type hwChangeFlag; + hwChangeFlag=i_target->getAttr(); + + if(HWAS_CHANGED_BIT_DIMM_POWER_TEST & hwChangeFlag) { - // process all targets - pRangeLimitItr = l_mbaTargetList.end(); + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "===== membuf %.8x clear set change bit", + get_huid(i_target)); + + clear_hwas_changed_bit( i_target, + HWAS_CHANGED_BIT_DIMM_POWER_TEST); + l_changed = true; } - // process each target till we reach the limit set above - for ( TARGETING::TargetHandleList::const_iterator pTargetItr - = l_mbaTargetList.begin(); - pTargetItr != pRangeLimitItr; pTargetItr++) + return l_changed; +}; + +// Process change bits on Membuf, MBA, and associated DIMMs +// i_membufTargetList - list of membufs to transverse +// i_cmd - mss_dimm_power_test_cmds + +enum mss_dimm_power_test_cmds +{ + MSS_DIMM_POWER_TEST_SETNONFUNCTIONAL, //set change if present non-functional + // return true if any are set + MSS_DIMM_POWER_TEST_CHECK, //check if any change bits set + // return true if any set + MSS_DIMM_POWER_TEST_CLEAR, //clear all change bits + // return true if any cleared +}; +bool mss_dimm_power_test_process_change_bits ( + TARGETING::TargetHandleList * i_pMembufTargetList, + mss_dimm_power_test_cmds i_cmd) +{ + bool l_change = false; // return value. Found any? + bool l_keepChecking = true; // loop exit control + mss_dimm_power_test_helper_t (l_pFunction) = &mss_dimm_power_test_check; + + bool l_functional = true; //default to functional search + + // set up function controls + switch (i_cmd) { - // make a local copy of the target for ease of use - const TARGETING::Target* l_mba_target = *pTargetItr; + case MSS_DIMM_POWER_TEST_SETNONFUNCTIONAL: + l_functional = false; // get all targets, not just functional + l_pFunction = &mss_dimm_power_test_set; + break; + case MSS_DIMM_POWER_TEST_CHECK: + l_pFunction = &mss_dimm_power_test_check; + break; + case MSS_DIMM_POWER_TEST_CLEAR: + l_pFunction = &mss_dimm_power_test_clear; + break; + } - // Dump current run on target - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "Running mss_dimm_power_test HWP on " - "target HUID %.8X", TARGETING::get_huid(l_mba_target)); + // process membufs and downstream MBAs and DIMMs + for (TargetHandleList::const_iterator + l_membuf_iter = (*i_pMembufTargetList).begin(); + l_membuf_iter != (*i_pMembufTargetList).end(); + ++l_membuf_iter) + { + l_change |= (*l_pFunction) (*l_membuf_iter,l_keepChecking); + if (!l_keepChecking) break; + + // process MBAs and downstream DIMMs + TARGETING::TargetHandleList l_mbaTargetList; + getChildAffinityTargets(l_mbaTargetList,*l_membuf_iter, + CLASS_UNIT,TYPE_MBA, + l_functional); + for (TargetHandleList::const_iterator + l_mba_iter = l_mbaTargetList.begin(); + l_mba_iter != l_mbaTargetList.end(); + ++l_mba_iter) + { + l_change |= (*l_pFunction) (*l_mba_iter,l_keepChecking); + if (!l_keepChecking) break; + + // process DIMMs + TARGETING::TargetHandleList l_dimmTargetList; + getChildAffinityTargets(l_dimmTargetList, *l_mba_iter, + CLASS_LOGICAL_CARD, TYPE_DIMM, + l_functional); + for (TargetHandleList::const_iterator + l_dimm_iter = l_dimmTargetList.begin(); + l_dimm_iter != l_dimmTargetList.end(); + ++l_dimm_iter) + { + l_change |= (*l_pFunction) (*l_dimm_iter,l_keepChecking); + if (!l_keepChecking) break; + } // loop on DIMMS associated with MBA + if (!l_keepChecking) break; // no need to check any further + } // loop on MBAs off membuf + if (!l_keepChecking) break; // no need to check any further + } // loop on passed mem buf list + + return l_change; +} - // Cast to a FAPI type of target. - const fapi::Target l_fapi_mba_target( TARGET_TYPE_MBA_CHIPLET, - (const_cast(l_mba_target)) ); +// +// Wrapper function to call mss_dimm_power_test +// +void* call_mss_dimm_power_test( void *io_pArgs ) +{ + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_mss_dimm_power_test entry" ); - // call the HWP with each fapi::Target - FAPI_INVOKE_HWP(l_err, mss_dimm_power_test, l_fapi_mba_target); + IStepError l_stepError; + errlHndl_t l_err = NULL; + //---------------------------------------------------------------------- + // only calculate the ISDIMM power curves if needed. + // The version of the calculation algorithm and dependent attribute + // values are hashed and saved to see if anything has changed. + // If the saved version has changed, then a recalcuation is advised. + // If hardware has changed, then recalcuation is advised. + //---------------------------------------------------------------------- + do + { + uint32_t l_persistentAlgorithmVersion = ALGORITHM_RESET; + uint32_t l_hwpAlgorithmVersion = ALGORITHM_RESET; + bool l_versionChange = false; + bool l_anyCalculationErrors = false; + + // Get saved algorithm version + TargetHandle_t top = 0; + targetService().getTopLevelTarget(top); + + l_persistentAlgorithmVersion = + top->getAttr(); + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_mss_dimm_power_test entry persistent algorithm version=%d", + l_persistentAlgorithmVersion ); + + // Get current hwp algorithm version + std::vector l_membufFapiTargets; + bool l_dc = false; + FAPI_INVOKE_HWP ( l_err, + mss_dimm_power_test, + l_membufFapiTargets, // empty list + RETURN_ALGORITHM_VERSION, + l_hwpAlgorithmVersion, + l_dc) // don't care parm if (l_err) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR 0x%.8X: mss_dimm_power_test HWP returns error", - l_err->reasonCode()); + "ERROR 0x%.8X: call_mss_dimm_power_test HWP get version error", + l_err->reasonCode()); + // Create IStep error log and cross reference error that occurred + l_stepError.addErrorDetails(l_err); + // Commit Error + errlCommit(l_err, HWPF_COMP_ID); - // capture the target data in the elog - ErrlUserDetailsTarget(l_mba_target).addToLog( l_err ); + break; // fail istep + } + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_mss_dimm_power_test entry hwp algorithm version=%d", + l_hwpAlgorithmVersion ); - // Create IStep error log and cross reference to error that occurred - l_stepError.addErrorDetails( l_err ); + // advise hwp to recalculate if stored version does not match current + l_versionChange = l_persistentAlgorithmVersion != l_hwpAlgorithmVersion; + + //---------------------------------------------------------------------- + // Set the change bit for all present non-functional Membufs, MBA, and + // DIMMs. In case they come back, want to be sure to recalculate + //---------------------------------------------------------------------- + TARGETING::TargetHandleList l_membufTargetList; + getAllChips(l_membufTargetList, TYPE_MEMBUF,false); + + mss_dimm_power_test_process_change_bits ( + &l_membufTargetList, + MSS_DIMM_POWER_TEST_SETNONFUNCTIONAL); + + l_membufTargetList.clear(); + + //---------------------------------------------------------------------- + // Call mss_dimm_power_test with lists of fucntional mem buffs that + // the have the same vmem id. + // For each group, check for hardware changes + //---------------------------------------------------------------------- + getAllChips(l_membufTargetList, TYPE_MEMBUF,true); //just functional + + // Build a map of unique vmem ids to the list of mem buffs with that + // vmem id. + std::map + l_vmemidTargetlistMap; + for (TargetHandleList::const_iterator + l_membuf_iter = l_membufTargetList.begin(); + l_membuf_iter != l_membufTargetList.end(); + ++l_membuf_iter) + { + TARGETING::ATTR_VMEM_ID_type l_VmemID = + (*l_membuf_iter)->getAttr(); + + l_vmemidTargetlistMap[l_VmemID].push_back(*l_membuf_iter); - // Commit Error - errlCommit( l_err, HWPF_COMP_ID ); } - else + + // For the subset list of mem buffs for each unique vmem id, + // check for hw changes on those targets (membuf, MBA, + // DIMMs). Then call the hwp to calculate the power curve, advising + // if the algorithm version has changed or if there are hw changes. + std::map::iterator + l_vmemidItr; + for (l_vmemidItr = l_vmemidTargetlistMap.begin(); + l_vmemidItr != l_vmemidTargetlistMap.end(); + ++l_vmemidItr) { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "SUCCESS : call_mss_dimm_power_test HWP( )" ); + std::vector l_membufFapiTargets; // to pass to hwp + TARGETING::TargetHandleList * l_pMembufSubsetList = + &(l_vmemidItr->second);//list of membufs for this vmem id + + // make a list of fapi targets to pass to the hwp + for (TargetHandleList::const_iterator + l_membuf_iter = (*l_pMembufSubsetList).begin(); + l_membuf_iter != (*l_pMembufSubsetList).end(); + ++l_membuf_iter) + { + + fapi::Target l_membuf_fapi_target + (fapi::TARGET_TYPE_MEMBUF_CHIP, + (const_cast(*l_membuf_iter)) ); + + l_membufFapiTargets.push_back( l_membuf_fapi_target ); + } + + // check for hw changes + bool l_hwChange = mss_dimm_power_test_process_change_bits ( + l_pMembufSubsetList, + MSS_DIMM_POWER_TEST_CHECK); + + // advise recalculation when: + // 1) The stored algorthim and dependencies have changed + // 2) Hardware has changed + bool l_recalc = l_hwChange || l_versionChange; + + uint32_t l_dc = ALGORITHM_RESET; + FAPI_INVOKE_HWP ( l_err, + mss_dimm_power_test, + l_membufFapiTargets, //list of membufs + CALCULATE, + l_dc, // don't care about version parm + l_recalc); + if ( l_err ) + { + l_anyCalculationErrors = true; // don't update algorithm version + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: from mss_dimm_power_test HWP( ) ", + l_err->reasonCode()); + + // Create IStep error log and cross reference + // to error that occurred + l_stepError.addErrorDetails( l_err ); + + // Commit Error, and keep going + errlCommit( l_err, HWPF_COMP_ID ); + } + else + { + // success, so clear change flags if any set + if (l_hwChange) + { + mss_dimm_power_test_process_change_bits ( + l_pMembufSubsetList, + MSS_DIMM_POWER_TEST_CLEAR); + } + } + + } // for each unique vme_id + + //---------------------------------------------------------------------- + // If there have not been any errors, update the saved + // algorithm version. + //---------------------------------------------------------------------- + + if (!l_anyCalculationErrors && + (l_persistentAlgorithmVersion != l_hwpAlgorithmVersion) ) + { + top->setAttr + (l_hwpAlgorithmVersion); + + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "call_mss_dimm_power_test set persistent algorithm version=%d", + l_hwpAlgorithmVersion ); } - } // end l_mbaNum loop + + } while (0); + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_dimm_power_test exit" ); diff --git a/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test/mss_dimm_power_test.C b/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test/mss_dimm_power_test.C index 7c2d7443f..e3156b45e 100644 --- a/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test/mss_dimm_power_test.C +++ b/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test/mss_dimm_power_test.C @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_dimm_power_test.C,v 1.1 2013/04/18 14:14:10 joabhend Exp $ +// $Id: mss_dimm_power_test.C,v 1.4 2014/09/08 21:15:02 whs Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_dimm_power_test.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -48,6 +48,7 @@ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- // 1.1 | joabhend |04-APR-13| Shell code - Only returns success +// 1.2 | whs |27-AUG-14| Update Shell to new interface @@ -63,22 +64,94 @@ extern "C" { // Procedures in this file - fapi::ReturnCode mss_dimm_power_test(const fapi::Target & i_target); - - +fapi::ReturnCode mss_dimm_power_test( + std::vector & i_targets, + const mss_dimm_power_test_command i_command, + uint32_t &io_version, + bool i_recalc); //****************************************************************************** // //****************************************************************************** - -fapi::ReturnCode mss_dimm_power_test(const fapi::Target & i_target) +fapi::ReturnCode mss_dimm_power_test( + std::vector & i_targets, + const mss_dimm_power_test_command i_command, + uint32_t &io_version, + bool i_recalc) { - // Target is centaur.mba - fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS; - + + + FAPI_IMP ("mss_dimm_power_test command=%d",i_command); + switch (i_command) + { + + // return calculation dependencies hashed into an algorithm version + case RETURN_ALGORITHM_VERSION: + { + struct calculation_dependencies // example dependencies + { + uint8_t mrwDimmPowerCurvePercentUplift; + uint32_t mrwMemThrottleDenominator; + uint32_t mrwMaxDramDataBusUtil; + uint32_t algorithmVersion; + } cd; + + io_version = ALGORITHM_RESET; // initialize to invalid version + + l_rc = FAPI_ATTR_GET(ATTR_MRW_DIMM_POWER_CURVE_PERCENT_UPLIFT, + NULL, cd.mrwDimmPowerCurvePercentUplift); + if (l_rc) break; // exit with error + + l_rc = FAPI_ATTR_GET(ATTR_MRW_MEM_THROTTLE_DENOMINATOR, + NULL, cd.mrwMemThrottleDenominator); + if (l_rc) break; // exit with error + + l_rc = FAPI_ATTR_GET(ATTR_MRW_MAX_DRAM_DATABUS_UTIL, + NULL, cd.mrwMaxDramDataBusUtil); + if (l_rc) break; // exit with error + + cd.algorithmVersion = ALGORITHM_VERSION; + + // Hwp writer: insert hash of dependent attributes + // and version here .. + // io_verion = FAPI_GEN_HASH(FAPI::HASH::CRC32, + // cd, + // sizeof(cd); + io_version = ALGORITHM_VERSION; // fake return value for testing + // Hwp writer: replace with + // hashed value. + } + break; + + // calculate power curves if advised due to algorithm change or hw + // change. Validate existing values if not advised, and recalculate + // if necessary. + case CALCULATE: + { + bool l_recalc = i_recalc; + // validate values if not advised to recalculate + if (!l_recalc) + { + // Hwp writer: insert validation here + FAPI_DBG ("mss_dimm_power_test validate power curves"); + l_recalc = true; //if necessary to recalculate + } + if (l_recalc) + { + //Hwp writer: insert calculation of power curve values + FAPI_DBG ("mss_dimm_power_test calculate power curves"); + } + } + break; + default: + { + FAPI_ERR ("mss_dimm_power_test unexpected command %d", + i_command); + // Hwp writer: l_rc = error + } + } return l_rc; } - } //end extern C diff --git a/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test/mss_dimm_power_test.H b/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test/mss_dimm_power_test.H index 48722fcb1..8ee67e7f5 100644 --- a/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test/mss_dimm_power_test.H +++ b/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test/mss_dimm_power_test.H @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_dimm_power_test.H,v 1.1 2013/04/18 14:14:50 joabhend Exp $ +// $Id: mss_dimm_power_test.H,v 1.2 2014/08/27 20:13:20 whs Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_dimm_power_test.H,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -45,7 +45,7 @@ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- // 1.1 | joabhend |04-APR-13| First Draft. - +// 1.2 | whs |27-AUG-14| Update Shell to new interface #ifndef MSS_DIMM_POWER_TEST_H_ @@ -60,15 +60,30 @@ // Defines //---------------------------------------------------------------------- + const uint32_t ALGORITHM_RESET = 0; // invalid algorithm version + + // change this value for each new algorithm version + const uint32_t ALGORITHM_VERSION = 1; + //---------------------------------------------------------------------- // ENUMs //---------------------------------------------------------------------- + enum mss_dimm_power_test_command + { + RETURN_ALGORITHM_VERSION, // return hwp algorithm version + CALCULATE, // calculate and save power curve + }; + //---------------------------------------------------------------------- // Data Types //---------------------------------------------------------------------- -typedef fapi::ReturnCode (*mss_dimm_power_test_FP_t)(const fapi::Target & i_target); +typedef fapi::ReturnCode (*mss_dimm_power_test_FP_t) + (std::vector &, + const mss_dimm_power_test_command i_command, + uint32_t &io_version, + bool i_recalc); extern "C" { @@ -76,12 +91,29 @@ extern "C" /** * @brief mss_dimm_power_test procedure. Run power test on ISDIMMs to determine max power draw * - * @param[in] i_target Reference to centaur.mba target + * @param[in] std::vector l_targets Reference to vector + * of Centaur Targets in a particular power domain + * RETURN_ALGORITHM_VERSION - empty list + * CALCULATE - list of mem buff targets with same vme_id + * @param[in] i_command mss_dimm_power_test_command + * @param[in,out] io_version + * RETURN_ALGORITHM_VERSION -input is persistent algorithm version + * output is current hwp algorithm version + * CALCULATE - NA + * @param[in] i_recalc advise a recalculation + * RETURN_ALGORITHM_VERSION - NA + * CALCULATE - true: versions don't match or hardware has changed + false: versions match and no hardware has changed * * @return ReturnCode */ - fapi::ReturnCode mss_dimm_power_test(const fapi::Target & i_target); + fapi::ReturnCode mss_dimm_power_test( + std::vector & i_targets, + const mss_dimm_power_test_command i_command, + uint32_t &io_version, + bool i_recalc); + } // extern "C" -- cgit v1.2.1