From ee8bac060be43708f0e0fc2a0e47877954cdcf78 Mon Sep 17 00:00:00 2001 From: mbroyles Date: Tue, 12 Dec 2017 09:37:26 -0600 Subject: Ignore bad quad and nest DTS Correct DTS readings to be 8 bit with msb signed Change-Id: Ib5d74535abd17696e9b30d63ccd28273ef4ddc61 CQ: SW410935 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/50807 Tested-by: FSP CI Jenkins Reviewed-by: Christopher J. Cain Reviewed-by: Andres A. Lugo-Reyes Reviewed-by: William A. Bryan Reviewed-by: Martha Broyles --- src/occ_405/amec/amec_sensors_core.c | 29 +++++++++++------- src/occ_405/proc/proc_data.c | 58 +++++++++++++++++++++++++++++------- src/occ_405/proc/proc_data.h | 4 +++ 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/occ_405/amec/amec_sensors_core.c b/src/occ_405/amec/amec_sensors_core.c index b723366..2dbeb15 100755 --- a/src/occ_405/amec/amec_sensors_core.c +++ b/src/occ_405/amec/amec_sensors_core.c @@ -76,6 +76,7 @@ void amec_update_proc_core_sensors(uint8_t i_core) CoreData *l_core_data_ptr; uint32_t l_temp32 = 0; uint16_t l_core_temp = 0; + uint16_t l_quad_temp = 0; uint16_t l_temp16 = 0; uint16_t l_core_util = 0; uint16_t l_core_freq = 0; @@ -183,9 +184,11 @@ void amec_update_proc_core_sensors(uint8_t i_core) // Determine "core" temperature that will be returned in the poll for fan control // If there is at least 1 core online within the same quad use the quad temp else use the nest - if(QUAD_ONLINE(l_quad)) + // verify quad temp is valid (not zero) this may be 0 if there were no valid quad DTS + l_quad_temp = AMECSENSOR_ARRAY_PTR(TEMPQ0, l_quad)->sample; + if( (QUAD_ONLINE(l_quad)) && l_quad_temp ) { - l_core_temp = AMECSENSOR_ARRAY_PTR(TEMPQ0, l_quad)->sample; + l_core_temp = l_quad_temp; } else { @@ -265,8 +268,6 @@ void amec_calc_dts_sensors(CoreData * i_core_data_ptr, uint8_t i_core) { #define DTS_PER_CORE 2 #define QUAD_DTS_PER_CORE 2 -#define DTS_INVALID_MASK 0x0C00 - uint32_t l_coreTemp = 0; uint8_t k = 0; @@ -297,12 +298,13 @@ void amec_calc_dts_sensors(CoreData * i_core_data_ptr, uint8_t i_core) //Check validity if (i_core_data_ptr->dts.core[k].fields.valid) { - l_coreDts[k] = i_core_data_ptr->dts.core[k].fields.reading; + // temperature is only 8 bits of reading field + l_coreDts[k] = (i_core_data_ptr->dts.core[k].fields.reading & 0xFF); l_coreDtsCnt++; - //Hardware bug workaround: Temperatures reaching 0 degrees C - //can show up as negative numbers. To fix this, we discount - //values that have the 2 MSB's set. + //Hardware bug workaround: Module test will detect bad DTS and write coefficients + //to force a reading of 0 or negative to indicate the DTS is bad. + //Throw out any DTS that is bad if(((l_coreDts[k] & DTS_INVALID_MASK) == DTS_INVALID_MASK) || (l_coreDts[k] == 0)) { @@ -338,13 +340,20 @@ void amec_calc_dts_sensors(CoreData * i_core_data_ptr, uint8_t i_core) // DTS values regardless of weight. for (k = 0; k < QUAD_DTS_PER_CORE; k++) { - if (i_core_data_ptr->dts.cache[k].fields.valid) + // temperature is only 8 bits of reading field + l_quadDtsTemp = (i_core_data_ptr->dts.cache[k].fields.reading & 0xFF); + + if( (i_core_data_ptr->dts.cache[k].fields.valid) && + ((l_quadDtsTemp & DTS_INVALID_MASK) != DTS_INVALID_MASK) && + (l_quadDtsTemp != 0) ) { - l_quadDts[k] = i_core_data_ptr->dts.cache[k].fields.reading; + l_quadDts[k] = l_quadDtsTemp; l_quadDtsCnt++; } } + l_quadDtsTemp = 0; + if(l_quadDtsCnt) { if (G_data_cnfg->thrm_thresh.proc_quad_weight) diff --git a/src/occ_405/proc/proc_data.c b/src/occ_405/proc/proc_data.c index 660cefd..f6694ef 100755 --- a/src/occ_405/proc/proc_data.c +++ b/src/occ_405/proc/proc_data.c @@ -513,10 +513,16 @@ CoreData * proc_get_bulk_core_data_ptr( const uint8_t i_occ_core_id ) // End Function Specification void task_nest_dts( task_t * i_task ) { +#define MAX_NUM_NEST_DTS 3 + errlHndl_t l_err = NULL; // Error handler int l_rc = 0; // Return code ipc_nest_dts_parms_t * l_parms = (ipc_nest_dts_parms_t*)(G_nest_dts_gpe_req.cmd_data); uint16_t l_avg = 0; + uint16_t l_nestDtsTemp = 0; + uint8_t l_nestDtsCnt = 0; // Number of valid Nest DTSs + uint8_t k = 0; + bool l_nestDtsValid = FALSE; static bool L_scheduled = FALSE; static bool L_idle_trace = FALSE; static bool L_incomplete_trace = FALSE; @@ -544,15 +550,47 @@ void task_nest_dts( task_t * i_task ) if ((ASYNC_REQUEST_STATE_COMPLETE == G_nest_dts_gpe_req.request.completion_state) && (0 == G_nest_dts_parms.error.error)) { - if (l_parms->data.sensor0.fields.valid && - l_parms->data.sensor1.fields.valid && - l_parms->data.sensor2.fields.valid) + for (k = 0; k < MAX_NUM_NEST_DTS; k++) + { + // check valid and temperature for current nest DTS being processed + if(k == 0) + { + l_nestDtsValid = l_parms->data.sensor0.fields.valid; + // temperature is only 8 bits of reading field + l_nestDtsTemp = (l_parms->data.sensor0.fields.reading & 0xFF); + } + else if(k == 1) + { + l_nestDtsValid = l_parms->data.sensor1.fields.valid; + // temperature is only 8 bits of reading field + l_nestDtsTemp = (l_parms->data.sensor1.fields.reading & 0xFF); + } + else if(k == 2) + { + l_nestDtsValid = l_parms->data.sensor2.fields.valid; + // temperature is only 8 bits of reading field + l_nestDtsTemp = (l_parms->data.sensor2.fields.reading & 0xFF); + } + else // shouldn't happen + { + break; + } + + //Hardware bug workaround: Module test will detect bad DTS and write coefficients + //to force a reading of 0 or negative to indicate the DTS is bad. + //Ignore any DTS that is not valid or marked bad + if( (l_nestDtsValid) && ( (l_nestDtsTemp & DTS_INVALID_MASK) != DTS_INVALID_MASK) && + (l_nestDtsTemp != 0) ) + { + l_avg += l_nestDtsTemp; + l_nestDtsCnt++; + } + } //for loop + + if(l_nestDtsCnt) { - // Calculate the average of the 3 Nest DTS temps - l_avg = l_parms->data.sensor0.fields.reading + - l_parms->data.sensor1.fields.reading + - l_parms->data.sensor2.fields.reading; - l_avg = l_avg / 3; + // Calculate the average of the valid Nest DTS temps + l_avg = l_avg / l_nestDtsCnt; // Mark the data as valid and update sensor G_nest_dts_data_valid = TRUE; @@ -560,10 +598,10 @@ void task_nest_dts( task_t * i_task ) } else { - // Mark the data as invalid + // No valid nest DTS, Mark the data as invalid G_nest_dts_data_valid = FALSE; } - } + } // if request completed without error else { // Async request not finished, mark data invalid diff --git a/src/occ_405/proc/proc_data.h b/src/occ_405/proc/proc_data.h index f8b7870..afabbb1 100755 --- a/src/occ_405/proc/proc_data.h +++ b/src/occ_405/proc/proc_data.h @@ -46,6 +46,10 @@ #define THREADS_PER_CORE 4 +// A dts should be considered invalid if it is returning a negative reading the dts reading is +// actually only 8 bits (not 12 as the structure has) the signed bit is msb of the 8 bit reading +#define DTS_INVALID_MASK 0x80 + #define NUM_CORE_DATA_BUFF 7 #define NUM_CORE_DATA_DOUBLE_BUF 2 #define NUM_CORE_DATA_EMPTY_BUF 1 -- cgit v1.2.1