diff options
author | Josh Rispoli <jprispol@us.ibm.com> | 2014-09-19 11:50:50 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-09-22 13:32:36 -0500 |
commit | ce53b72773377075da4e6d05a2b5b77e8d217748 (patch) | |
tree | 55ab18f8824883f908e6ebeac7fca98938bde563 | |
parent | d001febf0b5594120dd422bcbe5736221471e0ca (diff) | |
download | talos-hostboot-ce53b72773377075da4e6d05a2b5b77e8d217748.tar.gz talos-hostboot-ce53b72773377075da4e6d05a2b5b77e8d217748.zip |
SW268888: INITPROC: Hostboot - DDR4 updates to dynamic VID (In design discussion
CQ:SW268888
Change-Id: I060c7823c53bedc16502f38106d68e65eda06c48
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13186
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Tested-by: Thi N. Tran <thi@us.ibm.com>
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13500
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
5 files changed, 259 insertions, 116 deletions
diff --git a/src/usr/hwpf/hwp/mc_config/mss_volt/memory_mss_volt_vddr_offset.xml b/src/usr/hwpf/hwp/mc_config/mss_volt/memory_mss_volt_vddr_offset.xml index ed32b14c9..79186ae46 100644 --- a/src/usr/hwpf/hwp/mc_config/mss_volt/memory_mss_volt_vddr_offset.xml +++ b/src/usr/hwpf/hwp/mc_config/mss_volt/memory_mss_volt_vddr_offset.xml @@ -24,7 +24,7 @@ <!-- IBM_PROLOG_END_TAG --> <hwpErrors> -<!-- $Id: memory_mss_volt_vddr_offset.xml,v 1.4 2014/07/16 18:15:16 sglancy Exp $ --> +<!-- $Id: memory_mss_volt_vddr_offset.xml,v 1.5 2014/09/04 16:14:43 sglancy Exp $ --> <!-- For file ../../ipl/fapi/mss_volt_vddr_offset.C --> <!-- // *! OWNER NAME : Stephen Glancy (sglancy@us.ibm.com) --> <!-- // *! BACKUP NAME : Jacob Sloat (jdsloat@us.ibm.com) --> @@ -38,22 +38,27 @@ <ffdc>DRAM_GEN_START</ffdc> <ffdc>CEN_MBA_NUM</ffdc> <ffdc>CEN_TARGET_NUM</ffdc> - <!-- Deconfigure DIMM or Centaur --> - <deconfigure> - <target>CHIP_TARGET</target> - </deconfigure> </hwpError> <hwpError> - <rc>RC_VDDR_NONFUNCTIONAL_DIMM_VPD_READ_ERROR</rc> + <rc>RC_VDDR_FUNCTIONAL_DIMM_VPD_READ_ERROR</rc> <description>Unable to read the VPD from a non-functional dimm.</description> <ffdc>TARGET_POSITION</ffdc> <ffdc>MBA_POSITION</ffdc> <ffdc>DIMM_POSITION</ffdc> <callout> <target>TARGET_DIMM_ERROR</target> - <priority>LOW</priority> + <priority>HIGH</priority> </callout> + + <deconfigure> + <target>MBA_TARGET</target> + </deconfigure> + </hwpError> + + <hwpError> + <rc>RC_VOLT_VDDR_FUNCTIONAL_CENTAUR_NOT_FOUND</rc> + <description>Code did not find a functional centaur.</description> <callout> <procedure>CODE</procedure> <priority>HIGH</priority> diff --git a/src/usr/hwpf/hwp/mc_config/mss_volt/memory_mss_volt_vpp_offset.xml b/src/usr/hwpf/hwp/mc_config/mss_volt/memory_mss_volt_vpp_offset.xml index d9e822462..43f0014d7 100644 --- a/src/usr/hwpf/hwp/mc_config/mss_volt/memory_mss_volt_vpp_offset.xml +++ b/src/usr/hwpf/hwp/mc_config/mss_volt/memory_mss_volt_vpp_offset.xml @@ -24,13 +24,23 @@ <!-- IBM_PROLOG_END_TAG --> <hwpErrors> -<!-- $Id: memory_mss_volt_vpp_offset.xml,v 1.4 2014/07/16 18:15:25 sglancy Exp $ --> +<!-- $Id: memory_mss_volt_vpp_offset.xml,v 1.6 2014/09/08 20:53:44 sglancy Exp $ --> <!-- For file ../../ipl/fapi/mss_volt_vpp_offset.C --> <!-- // *! OWNER NAME : Stephen Glancy (sglancy@us.ibm.com) --> <!-- // *! BACKUP NAME : Jacob Sloat (jdsloat@us.ibm.com) --> <!-- Original Source for RC_MSS_VOLT_TOLERATED_VOLTAGE_VIOLATION memory_errors.xml --> + + <hwpError> + <rc>RC_VOLT_VPP_FUNCTIONAL_CENTAUR_NOT_FOUND</rc> + <description>Code did not find a functional centaur.</description> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <hwpError> <rc>RC_MSS_VOLT_VPP_OFFSET_DRAM_GEN_MISCOMPARE</rc> <description>One or more DIMMs has a different generation of DRAM technology level.</description> @@ -38,14 +48,10 @@ <ffdc>DRAM_GEN_START</ffdc> <ffdc>CEN_MBA_NUM</ffdc> <ffdc>CEN_TARGET_NUM</ffdc> - <!-- Deconfigure DIMM or Centaur --> - <deconfigure> - <target>CHIP_TARGET</target> - </deconfigure> </hwpError> <hwpError> - <rc>RC_VPP_NONFUNCTIONAL_DIMM_VPD_READ_ERROR</rc> + <rc>RC_VPP_FUNCTIONAL_DIMM_VPD_READ_ERROR</rc> <description>Unable to read the VPD from a non-functional dimm.</description> <ffdc>TARGET_POSITION</ffdc> <ffdc>MBA_POSITION</ffdc> @@ -53,12 +59,26 @@ <ffdc>FAILING_ATTRIBUTE</ffdc> <callout> <target>TARGET_DIMM_ERROR</target> - <priority>LOW</priority> + <priority>HIGH</priority> </callout> + <deconfigure> + <target>MBA_TARGET</target> + </deconfigure> + </hwpError> + + <hwpError> + <rc>RC_VPP_FUNCTIONAL_CENTAUR_VPD_READ_ERROR</rc> + <description>Unable to read the VPD from a non-functional dimm.</description> + <ffdc>TARGET_POSITION</ffdc> + <ffdc>MBA_POSITION</ffdc> + <ffdc>FAILING_ATTRIBUTE</ffdc> <callout> - <procedure>CODE</procedure> + <target>TARGET_CEN_ERROR</target> <priority>HIGH</priority> </callout> + <deconfigure> + <target>MBA_TARGET</target> + </deconfigure> </hwpError> <hwpError> diff --git a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vddr_offset.C b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vddr_offset.C index fdbd587c0..c07b4b9f3 100644 --- a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vddr_offset.C +++ b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vddr_offset.C @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_volt_vddr_offset.C,v 1.12 2014/07/16 18:16:08 sglancy Exp $ +// $Id: mss_volt_vddr_offset.C,v 1.19 2014/09/12 15:38:08 sglancy Exp $ /* File mss_volt_vddr_offset.C created by Stephen Glancy on Tue 20 May 2014. */ //------------------------------------------------------------------------------ @@ -45,6 +45,13 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|----------|----------------------------------------------- +// 1.19 | sglancy | 09/12/14 | Removed references to EFF attributes +// 1.18 | sglancy | 09/11/14 | Fixed bugs and fixed typos +// 1.17 | sglancy | 09/10/14 | Added additional checks for bad master power values +// 1.16 | sglancy | 09/08/14 | Updated to fix FW compile and logic bugs +// 1.15 | sglancy | 09/03/14 | Updated to go with new HWP design and added updates to code for new idle uplift attribute +// 1.14 | sglancy | 08/27/14 | Changed code to set VDDR offset value to 0 if code is unable to read the VPD of all DIMMs, which should disable the VDDR plane +// 1.13 | sglancy | 08/22/14 | Changed code to make the risky assumption that the box is running DDR3 if code is unable to read the VPD of all DIMMs // 1.12 | sglancy | 07/16/14 | Fixed attribute name bug // 1.11 | sglancy | 06/30/14 | Adds DDR4 support // 1.10 | sglancy | 06/25/14 | Fixed targetting bug @@ -80,23 +87,21 @@ fapi::ReturnCode mss_volt_vddr_offset(std::vector<fapi::Target> & i_targets) { //declares variables - fapi::ReturnCode l_rc; + fapi::ReturnCode l_rc, bad_vpd_rc; uint32_t vpd_master_power_slope, vpd_master_power_intercept, volt_util_active, volt_util_inactive, volt_slope, volt_intercept; + uint32_t good_master_power_slope, good_master_power_intercept, num_dimms_to_add; + good_master_power_slope = good_master_power_intercept = 0; + vpd_master_power_slope = vpd_master_power_intercept = volt_util_active = volt_util_inactive = volt_slope = volt_intercept = 0; uint32_t var_power_on_vddr = 0; uint32_t data_bus_util; uint32_t num_logical_dimms; uint8_t dram_gen , cur_dram_gen; bool dram_gen_found = false; uint8_t enable, is_functional; - uint8_t percent_uplift; + uint8_t num_non_functional = 0; + uint8_t percent_uplift,percent_uplift_idle; std::vector<fapi::Target> l_mbaChiplets; std::vector<fapi::Target> l_dimm_targets; - - //gets the attributes and computes var_power_on based upon whether the DRAM type is DDR3 or DDR4 - l_rc=fapiGetChildChiplets(i_targets[0], fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets, fapi::TARGET_STATE_PRESENT); - if(l_rc) return l_rc; - l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN,&l_mbaChiplets[0],dram_gen); - if(l_rc) return l_rc; //checks to make sure that all of the DRAM generation attributes are the same, if not error out for(uint32_t i = 0; i < i_targets.size();i++) { @@ -105,33 +110,45 @@ fapi::ReturnCode mss_volt_vddr_offset(std::vector<fapi::Target> & i_targets) //found an error if(l_rc) return l_rc; + //found a non-functional DIMM, add it to the count + if(is_functional != fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { + num_non_functional++; + } + //loops through all MBA chiplets to compare the DRAM technology generation attribute l_mbaChiplets.clear(); l_rc=fapiGetChildChiplets(i_targets[i], fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets, fapi::TARGET_STATE_PRESENT); + if(l_rc) return l_rc; for(uint32_t mba=0;mba<l_mbaChiplets.size();mba++) { //gets the dimm level target l_dimm_targets.clear(); //gets the number of declared dimms l_rc = fapiGetAssociatedDimms(l_mbaChiplets[mba], l_dimm_targets); + if(l_rc) return l_rc; for(uint32_t dimm=0;dimm<l_dimm_targets.size();dimm++) { //gets the attributes and computes var_power_on based upon whether the DRAM type is DDR3 or DDR4 l_rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_DEVICE_TYPE,&l_dimm_targets[dimm],cur_dram_gen); //found an error reading the VPD if(l_rc) { - //if the dimm is non-functional, assume that it's bad VPD was the reason that it crashed, then log an error and exit out - if(is_functional != fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { - FAPI_ERR("Problem reading VPD on non-functional DIMM. Logging error and proceding to the next DIMM"); - fapi::ReturnCode temp_rc; + //if the dimm is non-functional, assume that it's bad VPD was the reason that it crashed, then skip this DIMM with a FAPI INF note + if(is_functional == fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { + FAPI_ERR("Problem reading VPD on functional DIMM. Logging error and proceding to the next DIMM."); + if(bad_vpd_rc) { + fapiLogError(bad_vpd_rc); + } + const fapi::Target & TARGET_DIMM_ERROR = l_dimm_targets[dimm]; + const fapi::Target & MBA_TARGET = l_mbaChiplets[mba]; const uint32_t MBA_POSITION = mba; const uint32_t TARGET_POSITION = i; const uint32_t DIMM_POSITION = dimm; - FAPI_SET_HWP_ERROR(temp_rc, RC_VDDR_NONFUNCTIONAL_DIMM_VPD_READ_ERROR); - fapiLogError(temp_rc, fapi::FAPI_ERRL_SEV_RECOVERED); + FAPI_SET_HWP_ERROR(bad_vpd_rc, RC_VDDR_FUNCTIONAL_DIMM_VPD_READ_ERROR); + continue; + } + else { + FAPI_INF("Problem reading VPD on non-functional DIMM. Skipping current DIMM and proceding to the next DIMM."); continue; } - //otherwise, just return the error code - return l_rc; } //if this is the first DIMM that has a valid DRAM Technology level, then set the level and continue //otherwise throw an error and exit @@ -143,13 +160,12 @@ fapi::ReturnCode mss_volt_vddr_offset(std::vector<fapi::Target> & i_targets) //values are not equal -> set the fapi RC and exit out if(cur_dram_gen != dram_gen){ // this just needs to be deconfiged at the dimm level - const fapi::Target & CHIP_TARGET = i_targets[i]; const uint8_t &DRAM_GEN_MISCOMPARE = cur_dram_gen; const uint8_t &DRAM_GEN_START = dram_gen; const uint32_t &CEN_MBA_NUM = mba; const uint32_t &CEN_TARGET_NUM = i; FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_VDDR_OFFSET_DRAM_GEN_MISCOMPARE); - FAPI_ERR("Not all DRAM technology generations are the same.\nExiting...."); + FAPI_ERR("Not all DRAM technology generations are the same. Exiting...."); return l_rc; }//end if }//end else @@ -157,10 +173,23 @@ fapi::ReturnCode mss_volt_vddr_offset(std::vector<fapi::Target> & i_targets) }//end for }//end for - //checks to make sure that the code actually found a dimm with a value for it's dram generation. if not throw an error and exit out + //found a bad VPD + if(bad_vpd_rc) { + FAPI_ERR("Bad VPD found on a functional DIMM"); + return bad_vpd_rc; + } + + //did not find a valid DRAM generation + if(num_non_functional >= i_targets.size()) { + FAPI_ERR("No functional centaurs found! Exiting...."); + FAPI_SET_HWP_ERROR(l_rc, RC_VOLT_VDDR_FUNCTIONAL_CENTAUR_NOT_FOUND); + return l_rc; + } + + //checks to make sure that the code actually found a dimm with a value for its dram generation. if not, exit out if(!dram_gen_found) { + FAPI_ERR("No DRAM generation found! Exiting...."); FAPI_SET_HWP_ERROR(l_rc, RC_VOLT_VDDR_DRAM_GEN_NOT_FOUND); - FAPI_ERR("Could not find a DIMM with a valid DRAM Generation.\nExiting...."); return l_rc; } @@ -193,6 +222,8 @@ fapi::ReturnCode mss_volt_vddr_offset(std::vector<fapi::Target> & i_targets) if(l_rc) return l_rc; l_rc = FAPI_ATTR_GET(ATTR_MRW_DIMM_POWER_CURVE_PERCENT_UPLIFT,NULL,percent_uplift); if(l_rc) return l_rc; + l_rc = FAPI_ATTR_GET(ATTR_MRW_DIMM_POWER_CURVE_PERCENT_UPLIFT_IDLE,NULL,percent_uplift_idle); + if(l_rc) return l_rc; volt_util_active = data_bus_util; volt_util_inactive = 0; @@ -202,49 +233,79 @@ fapi::ReturnCode mss_volt_vddr_offset(std::vector<fapi::Target> & i_targets) const uint32_t &VDDR_SLOPE_INACTIVE = volt_slope; const uint32_t &VDDR_SLOPE_INTERCEPT = volt_intercept; FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_VDDR_OFFSET_VALUE_ERROR); - FAPI_ERR("One or more dynamic VDD attributes is 0.\nExiting...."); + FAPI_ERR("One or more dynamic VDD attributes is 0. Exiting...."); return l_rc; } //debug print FAPI_INF("data_bus_util %d per 10k volt_util_active: %d per 10k volt_util_inactive: %d per 10k",data_bus_util,volt_util_active,volt_util_inactive); - + + + num_dimms_to_add = 1; //computes the preliminary VDDR value for(uint32_t i=0;i<i_targets.size();i++) { - //gets the power slope values and does error checks - l_rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_MASTER_POWER_SLOPE,&i_targets[i],vpd_master_power_slope); + //gets the functional attribute to check for an active centaur + l_rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL,&i_targets[i],is_functional); + //found an error if(l_rc) return l_rc; + + //gets the power slope values and does error checks if this card is functional, as it should have good VPD. if the card is non-functional, continue using good VPD power slope values + l_rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_MASTER_POWER_SLOPE,&i_targets[i],vpd_master_power_slope); + if(l_rc && (is_functional == fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL)) return l_rc; l_rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_MASTER_POWER_INTERCEPT,&i_targets[i],vpd_master_power_intercept); - if(l_rc) return l_rc; + if(l_rc && (is_functional == fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL)) return l_rc; //removes leading bits from the VPD MASTER POWER attributes, leaving only the values needed for the power calculations vpd_master_power_slope &= 0x1FFF; vpd_master_power_intercept &= 0x1FFF; - //checks to make sure that the attribute values are non-zero - if((vpd_master_power_slope * vpd_master_power_intercept) == 0 ) { - const fapi::Target & CHIP_TARGET = i_targets[i]; + //checks to make sure that the attribute values are non-zero - calls out all bad DIMMs + if(((vpd_master_power_slope * vpd_master_power_intercept) == 0) && (is_functional == fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL)) { + if(bad_vpd_rc) { + fapiLogError(bad_vpd_rc); + } + + const fapi::Target & CHIP_TARGET = i_targets[i]; const uint32_t &VPD_MASTER_POWER_SLOPE = vpd_master_power_slope; const uint32_t &VPD_MASTER_POWER_INTERCEPT = vpd_master_power_intercept; const uint32_t &CEN_TARGET_NUM = i; - FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_VDDR_OFFSET_VPD_VALUE_ERROR); - FAPI_ERR("One or more VPD Power slope attributes is 0.\nExiting...."); - return l_rc; + FAPI_SET_HWP_ERROR(bad_vpd_rc, RC_MSS_VOLT_VDDR_OFFSET_VPD_VALUE_ERROR); + FAPI_ERR("One or more VPD Power slope attributes is 0. Logging error and looking for additional bad DIMMs."); + continue; + } + //one or more DIMM has already been called out, skip doing the calculation and continue to try to find bad DIMMs + else if(bad_vpd_rc) { + FAPI_INF("Already found a bad DIMM. Skipping calculations on this DIMM."); + continue; + } + //has not found good master_power_slopes and has bad master power slopes + else if(((good_master_power_slope * good_master_power_intercept) == 0) && ((vpd_master_power_slope * vpd_master_power_intercept) == 0)) { + num_dimms_to_add++; + FAPI_INF("Found bad vpd_master_power_slope or vpd_master_power_intercept values on non-functional DIMM. Program has not found good values yet, adding one more DIMM to run when good values are found. Currently going to run %d DIMMs in the next dimm.",num_dimms_to_add); + continue; + } + //found bad master power slope or power intercept but has good master power slope or intercepts + else if(((vpd_master_power_slope * vpd_master_power_intercept) == 0) && ((good_master_power_slope * good_master_power_intercept) > 0)) { + //uses assumed (last good master power slope and intercept) values for these calculations + FAPI_INF("Found bad vpd_master_power_slope or vpd_master_power_intercept values on non-functional DIMM. Program is using the last good values for the calculations for this DIMM."); + vpd_master_power_slope = good_master_power_slope; + vpd_master_power_intercept = good_master_power_intercept; + } + //found good master power slopes -> set the good master power slope values + else if((vpd_master_power_slope * vpd_master_power_intercept) > 0 ){ + good_master_power_slope = vpd_master_power_slope; + good_master_power_intercept = vpd_master_power_intercept; } - - //gets the functional attribute to check for an active centaur - l_rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL,&i_targets[i],is_functional); - //found an error - if(l_rc) return l_rc; //loops through all MBA chiplets to compare the compute the total number of logical dimms on a dimm l_mbaChiplets.clear(); l_rc=fapiGetChildChiplets(i_targets[i], fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets, fapi::TARGET_STATE_PRESENT); + if(l_rc) return l_rc; num_logical_dimms = 0; for(uint32_t mba=0;mba<l_mbaChiplets.size();mba++) { l_dimm_targets.clear(); //gets the number of declared dimms - l_rc = fapiGetAssociatedDimms(l_mbaChiplets[mba], l_dimm_targets); + l_rc = fapiGetAssociatedDimms(l_mbaChiplets[mba], l_dimm_targets); if(l_rc) return l_rc; num_logical_dimms += l_dimm_targets.size(); }//end for @@ -252,20 +313,24 @@ fapi::ReturnCode mss_volt_vddr_offset(std::vector<fapi::Target> & i_targets) //found an active centaur //multiply by total number of active logical dimms if(is_functional == fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { - var_power_on_vddr += (vpd_master_power_slope*volt_util_active/10000+vpd_master_power_intercept)*num_logical_dimms; - FAPI_INF("var_power_on_vddr: %d cW vpd_master_power_slope: %d cW volt_util_active: %d per 10k vpd_master_power_intercept %d cW num_logical_dimms %d",var_power_on_vddr,vpd_master_power_slope,volt_util_active,vpd_master_power_intercept,num_logical_dimms); + var_power_on_vddr += num_dimms_to_add*((vpd_master_power_slope*volt_util_active/10000+vpd_master_power_intercept)*num_logical_dimms*(100+percent_uplift)/100); + FAPI_INF("var_power_on_vddr: %d cW vpd_master_power_slope: %d cW volt_util_active: %d per 10k vpd_master_power_intercept %d cW num_logical_dimms %d percent_uplift %d %%",var_power_on_vddr,vpd_master_power_slope,volt_util_active,vpd_master_power_intercept,num_logical_dimms,percent_uplift); } //centaur must be inactive else { - var_power_on_vddr += (vpd_master_power_slope*volt_util_inactive/10000+vpd_master_power_intercept)*num_logical_dimms; - FAPI_INF("var_power_on_vddr: %d cW vpd_master_power_slope: %d cW volt_util_inactive: %d per 10k vpd_master_power_intercept %d cW num_logical_dimms %d",var_power_on_vddr,vpd_master_power_slope,volt_util_inactive,vpd_master_power_intercept,num_logical_dimms); + var_power_on_vddr += num_dimms_to_add*((vpd_master_power_slope*volt_util_inactive/10000+vpd_master_power_intercept)*num_logical_dimms*(100+percent_uplift_idle)/100); + FAPI_INF("var_power_on_vddr: %d cW vpd_master_power_slope: %d cW volt_util_inactive: %d per 10k vpd_master_power_intercept %d cW num_logical_dimms %d percent_uplift_idle %d %%",var_power_on_vddr,vpd_master_power_slope,volt_util_inactive,vpd_master_power_intercept,num_logical_dimms,percent_uplift_idle); } + + //resets the number of DIMMs to add. + num_dimms_to_add = 1; }//end for - //debug print - FAPI_INF("var_power_on_vddr: %d cW percent_uplift: %d %%",var_power_on_vddr,percent_uplift); - //does computes the uplift - var_power_on_vddr = ((100 + percent_uplift) * var_power_on_vddr) / 100; + //found a bad DIMM, exit + if(bad_vpd_rc) { + FAPI_ERR("Found one or more functional DIMM with bad VPD. Exiting...."); + return bad_vpd_rc; + } //debug print FAPI_INF("var_power_on_vddr: %d cW volt_slope: %d uV/W volt_intercept: %d mV",var_power_on_vddr,volt_slope,volt_intercept); diff --git a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vpp_offset.C b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vpp_offset.C index f236cc55c..26ef2938e 100644 --- a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vpp_offset.C +++ b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vpp_offset.C @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_volt_vpp_offset.C,v 1.10 2014/07/16 18:16:01 sglancy Exp $ +// $Id: mss_volt_vpp_offset.C,v 1.18 2014/09/12 15:37:51 sglancy Exp $ /* File mss_volt_vpp_offset.C created by Stephen Glancy on Tue 20 May 2014. */ //------------------------------------------------------------------------------ @@ -45,6 +45,14 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|----------|----------------------------------------------- +// 1.18 | sglancy | 09/12/14 | Removed references to EFF attributes +// 1.17 | sglancy | 09/12/14 | Fixed bugs +// 1.16 | sglancy | 09/11/14 | Fixed bugs +// 1.15 | sglancy | 09/09/14 | Fixed bug +// 1.14 | sglancy | 09/08/14 | Updated to fix FW compile and logic bugs +// 1.13 | sglancy | 09/03/14 | Updated to go with a new HWP design +// 1.12 | sglancy | 08/27/14 | Changed code to set VPP offset value to 0 if code is unable to read the VPD of all DIMMs, which should disable the VPP plane +// 1.11 | sglancy | 08/22/14 | Changed code to make the risky assumption that the box is running DDR3 if code is unable to read the VPD of all DIMMs // 1.10 | sglancy | 07/16/14 | Fixed attribute name bug // 1.9 | sglancy | 07/01/14 | Included updates for DDR4 // 1.8 | sglancy | 06/25/14 | Commented out DRAM_GEN checking section of the code and forced it to default DDR3 - WILL UPDATE TO CHECK THE DRAM GENERATIONS FOR FUTURE CODE GENERATIONS @@ -77,22 +85,17 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) { //declares variables - fapi::ReturnCode l_rc; + fapi::ReturnCode l_rc, bad_vpd_rc; uint32_t num_chips = 0; uint32_t vpp_slope, vpp_intercept; uint8_t dram_width, enable, dram_gen; uint8_t cur_dram_gen, is_functional; bool dram_gen_found = false; uint8_t num_spares[2][2][4]; - uint8_t rank_config; + uint8_t rank_config, num_non_functional; + num_non_functional = 0; std::vector<fapi::Target> l_mbaChiplets; std::vector<fapi::Target> l_dimm_targets; - - //gets the attributes and computes var_power_on based upon whether the DRAM type is DDR3 or DDR4 - l_rc=fapiGetChildChiplets(i_targets[0], fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets, fapi::TARGET_STATE_PRESENT); - if(l_rc) return l_rc; - l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN,&l_mbaChiplets[0],dram_gen); - if(l_rc) return l_rc; //checks to make sure that all of the DRAM generation attributes are the same, if not error out for(uint32_t i = 0; i < i_targets.size();i++) { @@ -101,34 +104,46 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) //found an error if(l_rc) return l_rc; + //found a non-functional DIMM, add it to the count + if(is_functional != fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { + num_non_functional++; + } + //loops through all MBA chiplets to compare the DRAM technology generation attribute l_mbaChiplets.clear(); l_rc=fapiGetChildChiplets(i_targets[i], fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets, fapi::TARGET_STATE_PRESENT); + if(l_rc) return l_rc; for(uint32_t mba=0;mba<l_mbaChiplets.size();mba++) { //gets the dimm level target l_dimm_targets.clear(); //gets the number of declared dimms l_rc = fapiGetAssociatedDimms(l_mbaChiplets[mba], l_dimm_targets); + if(l_rc) return l_rc; for(uint32_t dimm=0;dimm<l_dimm_targets.size();dimm++) { //gets the attributes and computes var_power_on based upon whether the DRAM type is DDR3 or DDR4 l_rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_DEVICE_TYPE,&l_dimm_targets[dimm],cur_dram_gen); //found an error reading the VPD if(l_rc) { - //if the dimm is non-functional, assume that it's bad VPD was the reason that it crashed, then log an error and exit out - if(is_functional != fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { - FAPI_ERR("Problem reading VPD on non-functional DIMM. Logging error and proceding to the next DIMM"); - fapi::ReturnCode temp_rc; + //if the dimm is non-functional, assume that it's bad VPD was the reason that it crashed, then skip this DIMM with a FAPI INF note + if(is_functional == fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { + FAPI_ERR("Problem reading VPD on functional DIMM. Logging error and proceding to the next DIMM."); + if(bad_vpd_rc) { + fapiLogError(bad_vpd_rc); + } + const fapi::Target & TARGET_DIMM_ERROR = l_dimm_targets[dimm]; + const fapi::Target & MBA_TARGET = l_mbaChiplets[mba]; const uint32_t MBA_POSITION = mba; const uint32_t TARGET_POSITION = i; const uint32_t DIMM_POSITION = dimm; const uint32_t FAILING_ATTRIBUTE = fapi::ATTR_SPD_DRAM_DEVICE_TYPE; - FAPI_SET_HWP_ERROR(temp_rc, RC_VPP_NONFUNCTIONAL_DIMM_VPD_READ_ERROR); - fapiLogError(temp_rc, fapi::FAPI_ERRL_SEV_RECOVERED); + FAPI_SET_HWP_ERROR(bad_vpd_rc, RC_VPP_FUNCTIONAL_DIMM_VPD_READ_ERROR); + continue; + } + else { + FAPI_INF("Problem reading VPD on non-functional DIMM. Skipping current DIMM and proceding to the next DIMM."); continue; } - //otherwise, just return the error code - return l_rc; } //if this is the first DIMM that has a valid DRAM Technology level, then set the level and continue //otherwise throw an error and exit @@ -140,7 +155,6 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) //values are not equal -> set the fapi RC and exit out if(cur_dram_gen != dram_gen){ // this just needs to be deconfiged at the dimm level - const fapi::Target & CHIP_TARGET = i_targets[i]; const uint8_t &DRAM_GEN_MISCOMPARE = cur_dram_gen; const uint8_t &DRAM_GEN_START = dram_gen; const uint32_t &CEN_MBA_NUM = mba; @@ -154,10 +168,23 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) }//end for }//end for - //checks to make sure that the code actually found a dimm with a value for it's dram generation. if not throw an error and exit out + //found a bad VPD + if(bad_vpd_rc) { + FAPI_ERR("Bad VPD found on a functional DIMM"); + return bad_vpd_rc; + } + + //did not find a valid DRAM generation + if(num_non_functional >= i_targets.size()) { + FAPI_ERR("No functional centaurs found! Exiting...."); + FAPI_SET_HWP_ERROR(l_rc, RC_VOLT_VPP_FUNCTIONAL_CENTAUR_NOT_FOUND); + return l_rc; + } + + //checks to make sure that the code actually found a dimm with a value for its dram generation. if not, exit out if(!dram_gen_found) { + FAPI_ERR("No DRAM generation found! Exiting...."); FAPI_SET_HWP_ERROR(l_rc, RC_VOLT_VPP_DRAM_GEN_NOT_FOUND); - FAPI_ERR("Could not find a DIMM with a valid DRAM Generation.\nExiting...."); return l_rc; } @@ -204,6 +231,7 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) //resets the number of ranks and spares l_mbaChiplets.clear(); l_rc=fapiGetChildChiplets(i_targets[i], fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets, fapi::TARGET_STATE_PRESENT); + if(l_rc) return l_rc; //loops through the each MBA chiplet to get the number of ranks and the number of spares for(uint32_t mba = 0;mba<l_mbaChiplets.size();mba++) { //gets the dimm level target @@ -212,15 +240,7 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) if(l_rc) { //if the dimm is non-functional, assume that it's bad VPD was the reason that it crashed, then log an error and exit out if(is_functional != fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { - FAPI_ERR("Problem reading VPD on non-functional DIMM. Logging error and proceding to the next DIMM"); - fapi::ReturnCode temp_rc; - const fapi::Target & TARGET_DIMM_ERROR = l_mbaChiplets[mba]; - const uint32_t MBA_POSITION = mba; - const uint32_t TARGET_POSITION = i; - const uint32_t DIMM_POSITION = 0xff; - const uint32_t FAILING_ATTRIBUTE = fapi::ATTR_VPD_DIMM_SPARE; - FAPI_SET_HWP_ERROR(temp_rc, RC_VPP_NONFUNCTIONAL_DIMM_VPD_READ_ERROR); - fapiLogError(temp_rc, fapi::FAPI_ERRL_SEV_RECOVERED); + FAPI_INF("Problem reading VPD on non-functional DIMM. Using default values for the number of spares"); //uses assumed value for(uint32_t port=0;port<2;port++) { for(uint32_t dimm=0;dimm<2;dimm++) { @@ -231,12 +251,26 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) } } //otherwise, just return the error code - else return l_rc; + else { + FAPI_ERR("Problem reading VPD on functional DIMM. Logging error and proceding to the next DIMM."); + if(bad_vpd_rc) { + fapiLogError(bad_vpd_rc); + } + + const fapi::Target & TARGET_CEN_ERROR = i_targets[i]; + const fapi::Target & MBA_TARGET = l_mbaChiplets[mba]; + const uint32_t MBA_POSITION = mba; + const uint32_t TARGET_POSITION = i; + const uint32_t FAILING_ATTRIBUTE = fapi::ATTR_VPD_DIMM_SPARE; + FAPI_SET_HWP_ERROR(bad_vpd_rc, RC_VPP_FUNCTIONAL_CENTAUR_VPD_READ_ERROR); + continue; + } } l_dimm_targets.clear(); //gets the number of declared dimms l_rc = fapiGetAssociatedDimms(l_mbaChiplets[mba], l_dimm_targets); + if(l_rc) return l_rc; for(uint32_t dimm=0;dimm<l_dimm_targets.size();dimm++) { //gets if the centaur is a x4 or a x8 l_rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_WIDTH,&l_dimm_targets[dimm],dram_width); @@ -244,40 +278,51 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) if(l_rc) { //if the dimm is non-functional, assume that it's bad VPD was the reason that it crashed, then log an error and exit out if(is_functional != fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { - FAPI_ERR("Problem reading VPD on non-functional DIMM. Logging error and proceding to the next DIMM"); - fapi::ReturnCode temp_rc; - const fapi::Target & TARGET_DIMM_ERROR = l_dimm_targets[dimm]; - const uint32_t MBA_POSITION = mba; - const uint32_t TARGET_POSITION = i; - const uint32_t DIMM_POSITION = dimm; - const uint32_t FAILING_ATTRIBUTE = fapi::ATTR_SPD_DRAM_WIDTH; - FAPI_SET_HWP_ERROR(temp_rc, RC_VPP_NONFUNCTIONAL_DIMM_VPD_READ_ERROR); - fapiLogError(temp_rc, fapi::FAPI_ERRL_SEV_RECOVERED); + FAPI_INF("Problem reading VPD on non-functional DIMM. Using default value for DRAM_WIDTH"); //uses assumed value dram_width = DRAM_WIDTH_DEFAULT; } - //otherwise, just return the error code - else return l_rc; + //otherwise, callout and deconfigure the DIMM + else { + FAPI_ERR("Problem reading VPD on functional DIMM. Logging error and proceding to the next DIMM."); + if(bad_vpd_rc) { + fapiLogError(bad_vpd_rc); + } + + const fapi::Target & TARGET_DIMM_ERROR = l_dimm_targets[dimm]; + const fapi::Target & MBA_TARGET = l_mbaChiplets[mba]; + const uint32_t MBA_POSITION = mba; + const uint32_t TARGET_POSITION = i; + const uint32_t DIMM_POSITION = dimm; + const uint32_t FAILING_ATTRIBUTE = fapi::ATTR_SPD_DRAM_WIDTH; + FAPI_SET_HWP_ERROR(bad_vpd_rc, RC_VPP_FUNCTIONAL_DIMM_VPD_READ_ERROR); + continue; + } } l_rc = FAPI_ATTR_GET(ATTR_SPD_NUM_RANKS,&l_dimm_targets[dimm],rank_config); //found an error reading the VPD if(l_rc) { //if the dimm is non-functional, assume that it's bad VPD was the reason that it crashed, then log an error and exit out if(is_functional != fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL) { - FAPI_ERR("Problem reading VPD on non-functional DIMM. Logging error and proceding to the next DIMM"); - fapi::ReturnCode temp_rc; - const fapi::Target & TARGET_DIMM_ERROR = l_dimm_targets[dimm]; - const uint32_t MBA_POSITION = mba; - const uint32_t TARGET_POSITION = i; - const uint32_t DIMM_POSITION = dimm; - const uint32_t FAILING_ATTRIBUTE = fapi::ATTR_SPD_NUM_RANKS; - FAPI_SET_HWP_ERROR(temp_rc, RC_VPP_NONFUNCTIONAL_DIMM_VPD_READ_ERROR); - fapiLogError(temp_rc, fapi::FAPI_ERRL_SEV_RECOVERED); + FAPI_INF("Problem reading VPD on non-functional DIMM. Using default value for DRAM_WIDTH"); //uses assumed value rank_config = NUM_RANKS_PER_DIMM_DEFAULT; } - //otherwise, just return the error code - else return l_rc; + //otherwise, callout and deconfigure the DIMM + else { + FAPI_ERR("Problem reading VPD on functional DIMM. Logging error and proceding to the next DIMM."); + if(bad_vpd_rc) { + fapiLogError(bad_vpd_rc); + } + const fapi::Target & TARGET_DIMM_ERROR = l_dimm_targets[dimm]; + const fapi::Target & MBA_TARGET = l_mbaChiplets[mba]; + const uint32_t MBA_POSITION = mba; + const uint32_t TARGET_POSITION = i; + const uint32_t DIMM_POSITION = dimm; + const uint32_t FAILING_ATTRIBUTE = fapi::ATTR_SPD_NUM_RANKS; + FAPI_SET_HWP_ERROR(bad_vpd_rc, RC_VPP_FUNCTIONAL_DIMM_VPD_READ_ERROR); + continue; + } } //adjusts the number of ranks so it's the actual number of ranks on the DIMM rank_config++; @@ -312,7 +357,13 @@ fapi::ReturnCode mss_volt_vpp_offset(std::vector<fapi::Target> & i_targets) } } } - + + //found a bad VPD + if(bad_vpd_rc) { + FAPI_ERR("Bad VPD found on a functional DIMM or centaur"); + return bad_vpd_rc; + } + FAPI_INF("vpp_slope: %d uV/DRAM chip vpp_intercept: %d mV num_chips: %d DRAM chips\n",vpp_slope,vpp_intercept,num_chips); //does the final computation diff --git a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vpp_offset.H b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vpp_offset.H index 732ff2a90..4d0453421 100644 --- a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vpp_offset.H +++ b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt_vpp_offset.H @@ -22,7 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_volt_vpp_offset.H,v 1.5 2014/07/09 15:24:55 sglancy Exp $ +// $Id: mss_volt_vpp_offset.H,v 1.6 2014/09/10 15:48:07 sglancy Exp $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 // *! All Rights Reserved -- Property of IBM @@ -43,6 +43,7 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|----------|----------------------------------------------- +// 1.6 | sglancy | 09/10/14 | Updated default attribute values // 1.5 | sglancy | 07/09/14 | Added Default attribute values // 1.4 | sglancy | 06/16/14 | Updated to fix formatting // 1.3 | sglancy | 06/04/14 | Updated to account for output attribute @@ -53,8 +54,9 @@ #include <fapi.H> +//assumes 128GB values except for spare byte -> uses a full spare byte in the case of x8 DRAM with good DRAM width but bad spare byte values #define DRAM_WIDTH_DEFAULT fapi::ENUM_ATTR_SPD_DRAM_WIDTH_W4 -#define NUM_RANKS_PER_DIMM_DEFAULT fapi::ENUM_ATTR_SPD_NUM_RANKS_R1 +#define NUM_RANKS_PER_DIMM_DEFAULT fapi::ENUM_ATTR_SPD_NUM_RANKS_R4 #define DIMM_SPARE_DEFAULT fapi::ENUM_ATTR_VPD_DIMM_SPARE_FULL_BYTE typedef fapi::ReturnCode (*mss_volt_vpp_offset_FP_t)(std::vector<fapi::Target> &); |