diff options
author | Fadi Kassem <fmkassem@us.ibm.com> | 2015-11-24 12:53:55 -0600 |
---|---|---|
committer | Wael Elessawy <welessa@us.ibm.com> | 2015-11-25 11:01:55 -0600 |
commit | 74ad39e79ccd4d423adea15d82a87fa70ec9b56f (patch) | |
tree | 3b68128274cd4c0cef4d0f7f5550b14e83c99c41 /src/occ_405/amec/amec_sensors_core.c | |
parent | 7e5cdacb586068de60e1d10cb2e04ff7fb737e96 (diff) | |
download | talos-occ-74ad39e79ccd4d423adea15d82a87fa70ec9b56f.tar.gz talos-occ-74ad39e79ccd4d423adea15d82a87fa70ec9b56f.zip |
Enable Slave DTS calculation and sensor update.
Change-Id: I0feb572e650322326ce9a6c7b2affd9e58cd6b8d
RTC:140183
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/22303
Reviewed-by: Wael Elessawy <welessa@us.ibm.com>
Tested-by: Wael Elessawy <welessa@us.ibm.com>
Diffstat (limited to 'src/occ_405/amec/amec_sensors_core.c')
-rwxr-xr-x | src/occ_405/amec/amec_sensors_core.c | 237 |
1 files changed, 76 insertions, 161 deletions
diff --git a/src/occ_405/amec/amec_sensors_core.c b/src/occ_405/amec/amec_sensors_core.c index bdea518..37452e6 100755 --- a/src/occ_405/amec/amec_sensors_core.c +++ b/src/occ_405/amec/amec_sensors_core.c @@ -26,7 +26,7 @@ /******************************************************************************/ /* Includes */ /******************************************************************************/ -#include <occ_common.h> +//#include <occ_common.h> #include <ssx.h> #include <errl.h> // Error logging #include "sensor.h" @@ -43,6 +43,7 @@ #include "amec_service_codes.h" #include <amec_sensors_core.h> #include "amec_perfcount.h" +#include "proc_shared.h" /******************************************************************************/ /* Globals */ @@ -52,7 +53,6 @@ /* Forward Declarations */ /******************************************************************************/ void amec_calc_dts_sensors(gpe_bulk_core_data_t * i_core_data_ptr, uint8_t i_core); -//void amec_calc_cpm_sensors(gpe_bulk_core_data_t * i_core_data_ptr, uint8_t i_core); //CPM - Commented out as requested by Malcolm void amec_calc_freq_and_util_sensors(gpe_bulk_core_data_t * i_core_data_ptr, uint8_t i_core); void amec_calc_ips_sensors(gpe_bulk_core_data_t * i_core_data_ptr, uint8_t i_core); void amec_calc_spurr(uint8_t i_core); @@ -63,48 +63,6 @@ void amec_calc_spurr(uint8_t i_core); // Function Specification // -// Name: amec_update_fast_core_data_sensors -// -// Description: Updates sensors that have data grabbed by the fast core data -// task. -// -// Thread: RealTime Loop -// -// End Function Specification -void amec_update_fast_core_data_sensors(void) -{ - // ------------------------------------------------------ - // Update Fast Core Data Sensors - // ------------------------------------------------------ - // SensorNameCx = PCBS Local Pstate Freq Target (per core) - // TODclock = TOD Clock? - - // Need to comment this out because l_tod is always zero, which messes - // up proper sensor updates. Proper updating is done below in the core level - // sensor updates. - - //gpe_fast_core_data_t * l_core = proc_get_fast_core_data_ptr(); - // uint32_t l_tod = l_core->tod; - - //if( l_core != NULL) - //{ - // GPEtickdur0 = duration of last tick's PORE-GPE0 duration - // sensor_update( AMECSENSOR_PTR(TODclock0), CONVERT_UINT32_UINT8_UPPER_HIGH(l_tod) ); - // sensor_update( AMECSENSOR_PTR(TODclock1), CONVERT_UINT32_UINT16_MIDDLE(l_tod) ); - // sensor_update( AMECSENSOR_PTR(TODclock2), ((uint16_t) (CONVERT_UINT32_UINT8_LOWER_LOW(l_tod))) << 8); - //} - - // TODO: Don't know what to update from the PCBS LPstate Target Freq Status Reg - //for(int i=0; i++; i<MAX_NUM_HW_CORES) - //{ - // sensor_update(&sensor, - // G_read_fast_core_data_ptr->core_data[i].pcbs_lpstate_freq_target_sr); - //} -} - - -// Function Specification -// // Name: amec_update_proc_core_sensors // // Description: Update all the sensors for a given proc @@ -114,10 +72,9 @@ void amec_update_fast_core_data_sensors(void) // End Function Specification void amec_update_proc_core_sensors(uint8_t i_core) { - gpe_bulk_core_data_t * l_core_data_ptr; - int i; - uint16_t l_temp16 = 0; - uint32_t l_temp32 = 0; + gpe_bulk_core_data_t *l_core_data_ptr; + uint16_t l_temp16 = 0; + uint32_t l_temp32 = 0; // Make sure the core is present, and that it has updated data. if(CORE_PRESENT(i_core) && CORE_UPDATED(i_core)) @@ -133,11 +90,7 @@ void amec_update_proc_core_sensors(uint8_t i_core) //------------------------------------------------------- amec_calc_dts_sensors(l_core_data_ptr, i_core); - //------------------------------------------------------- - //CPM - Commented out as requested by Malcolm - // ------------------------------------------------------ - // amec_calc_cpm_sensors(l_core_data_ptr, i_core); - +/* //------------------------------------------------------- // Util / Freq //------------------------------------------------------- @@ -146,12 +99,12 @@ void amec_update_proc_core_sensors(uint8_t i_core) { amec_calc_freq_and_util_sensors(l_core_data_ptr,i_core); } - + //------------------------------------------------------- // Performance counter - This function should be called // after amec_calc_freq_and_util_sensors(). //------------------------------------------------------- - amec_calc_dps_util_counters(i_core); + //amec_calc_dps_util_counters(i_core); //------------------------------------------------------- // IPS @@ -165,7 +118,7 @@ void amec_update_proc_core_sensors(uint8_t i_core) //------------------------------------------------------- // SPURR //------------------------------------------------------- - amec_calc_spurr(i_core); + //amec_calc_spurr(i_core); // ------------------------------------------------------ // Update PREVIOUS values for next time @@ -188,7 +141,7 @@ void amec_update_proc_core_sensors(uint8_t i_core) { g_amec->proc[0].core[i_core].thread[i].prev_PC_RUN_Th_CYCLES = l_core_data_ptr->per_thread[i].run_cycles; } - +*/ // Final step is to update TOD sensors // Extract 32 bits with 16usec resolution l_temp32 = (uint32_t)(G_dcom_slv_inbox_doorbell_rx.tod>>13); @@ -205,6 +158,13 @@ void amec_update_proc_core_sensors(uint8_t i_core) } +// Core Weight - Weight factor for core DTS used to calculate a core temp +// TODO - fmk - to be changed once we have TMGT config data with weights. +// Suggest adding core weight to g_amec struct +// TEMP - Using the same weight for all cores. +uint8_t G_coreWeight = 2; +uint8_t G_quadWeight = 1; + // Function Specification // // Name: amec_calc_dts_sensors @@ -212,141 +172,93 @@ void amec_update_proc_core_sensors(uint8_t i_core) // Description: Compute core temperature. This function is called every // 2ms/core. // +// PreCondition: The core is present. +// // Thread: RealTime Loop // // End Function Specification void amec_calc_dts_sensors(gpe_bulk_core_data_t * i_core_data_ptr, uint8_t i_core) { -#define DTS_PER_CORE 4 +#define DTS_PER_CORE 2 #define DTS_INVALID_MASK 0x0C00 - uint32_t k, l_core_avg, l_core_hot, l_sensor_count; - uint32_t l_oha_status_reg = 0; - uint32_t l_pm_state_hist_reg = 0; - uint16_t l_dts[DTS_PER_CORE]; - BOOLEAN l_update_sensor = FALSE; - - // Build up array of DTS values - // DTS sensors are in the format of uint64_t dts0 : 12; - // uint64_t thermal_trip0 : 2; - // uint64_t spare0 : 1; - // uint64_t valid0 : 1; - // - // so we will need to convert them before they are used in loop below. - l_dts[0] = i_core_data_ptr->dts_cpm.sensors_v0.fields.dts0; - l_dts[1] = i_core_data_ptr->dts_cpm.sensors_v0.fields.dts1; - l_dts[2] = i_core_data_ptr->dts_cpm.sensors_v0.fields.dts2; - l_dts[3] = i_core_data_ptr->dts_cpm.sensors_v1.fields.dts4; - // Read the low-order bytes of the OHA Status register - l_oha_status_reg = i_core_data_ptr->oha.oha_ro_status_reg.words.low_order; + uint32_t l_coreTemp = 0; + uint8_t k = 0; + uint16_t l_dts[DTS_PER_CORE]; + uint16_t l_quadDts = 0; + BOOLEAN l_update_sensor = FALSE; + uint16_t l_core_hot = 0; + uint8_t l_dtsCnt = 0; //Number of valid Core DTSs - // Read the high-order bytes of PM State History register for this core - l_pm_state_hist_reg = i_core_data_ptr->pcb_slave.pm_history.words.high_order; + //Clear DTS array. + memset((void *)&(l_dts[0]), 0, sizeof(l_dts)); - // Check if we were able to collect core data - if(l_oha_status_reg & CORE_DATA_CORE_SENSORS_COLLECTED) + if (i_core_data_ptr != NULL) { - // Check if all DTS readings in the core are valid. The field sensors_v0 - // contains core-related data - if(i_core_data_ptr->dts_cpm.sensors_v0.fields.valid0 || - i_core_data_ptr->dts_cpm.sensors_v0.fields.valid1 || - i_core_data_ptr->dts_cpm.sensors_v0.fields.valid2) - { - l_update_sensor = TRUE; - } - } - // Check if we were able to collect L3 data - if(l_oha_status_reg & CORE_DATA_L3_SENSORS_COLLECTED) - { - // Check if DTS reading in the L3 is valid. The field sensors_v1 contains - // L3-related data - if(i_core_data_ptr->dts_cpm.sensors_v1.fields.valid4) + //the Core DTS temperatures are considered in the calculation only if: + // - They are valid. + // - Non-zero + // - Non-negative + for (k = 0; k < DTS_PER_CORE; k++) + { + //Check validity + if (i_core_data_ptr->dts.core[k].fields.valid) { - l_update_sensor = TRUE; - } - } - // Check if this core has been in fast winkle OR deep winkle - if(((l_pm_state_hist_reg & OCC_PM_STATE_MASK) == OCC_PAST_FAST_WINKLE) || - ((l_pm_state_hist_reg & OCC_PM_STATE_MASK) == OCC_PAST_DEEP_WINKLE)) - { - l_update_sensor = TRUE; - } + l_dts[k] = i_core_data_ptr->dts.core[k].fields.reading; + l_dtsCnt++; - // Update the thermal sensor associated with this core - if(l_update_sensor) - { - //calculate average temperature from all DTS's for this core - for(l_sensor_count = DTS_PER_CORE, l_core_hot = 0, - l_core_avg = 0, k = 0; - k < DTS_PER_CORE; k++) - { //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. - if((l_dts[k] & DTS_INVALID_MASK) == DTS_INVALID_MASK) + if(((l_dts[k] & DTS_INVALID_MASK) == DTS_INVALID_MASK) || + (l_dts[k] == 0)) { - l_dts[k] = 0; + l_dts[k] = 0; + l_dtsCnt--; } - l_core_avg += l_dts[k]; - if(l_dts[k] > l_core_hot) - { - l_core_hot = l_dts[k]; - } - // Assume 0 degrees to mean bad sensor and don't let it bring the - // average reading down. - else if(l_dts[k] == 0) + if (l_dts[k] > l_core_hot) { - l_sensor_count--; + l_core_hot = l_dts[k]; } } + } //for loop - if(l_sensor_count == DTS_PER_CORE) - { - //For the common case, compiler converts this to a fast multiplication - //operation when one of the operands is a constant. - l_core_avg /= DTS_PER_CORE; - } - else if(l_sensor_count) //prevent div by 0 if all sensors are zero + //The core DTSs are considered only if we have at least 1 valid core DTS and + //a non-zero G_coreWeight. + if (l_dtsCnt && G_coreWeight) + { + l_update_sensor = TRUE; + } + + //The Quad DTS value is considered only if we have a valid Quad DTS and + //a non-zero quad weight. + if (i_core_data_ptr->dts.cache.fields.valid && G_quadWeight) + { + l_quadDts = i_core_data_ptr->dts.cache.fields.reading; + l_update_sensor = TRUE; + } + + // Update the thermal sensor associated with this core + if(l_update_sensor) + { + //Formula: + // (Cwt(CoreDTS1 + CoreDTS2) + (Qwt*QuadDTS)) + // ------------------------------------------ + // (2*Cwt + Qwt) + if ((G_coreWeight && l_dtsCnt) || G_quadWeight) { - //otherwise, use the slower division routine when both operands are - //unknown at compile time. - l_core_avg /= l_sensor_count; + l_coreTemp = ((G_coreWeight *(l_dts[0] + l_dts[1])) + (G_quadWeight * l_quadDts)) + / ((l_dtsCnt * G_coreWeight) + G_quadWeight); } // Update sensors & Interim Data - sensor_update( AMECSENSOR_ARRAY_PTR(TEMP2MSP0C0,i_core), l_core_avg); + sensor_update( AMECSENSOR_ARRAY_PTR(TEMP4MSP0C0,i_core), l_coreTemp); g_amec->proc[0].core[i_core].dts_hottest = l_core_hot; - } -} - - -//CPM - Commented out as requested by Malcolm -/* void amec_calc_cpm_sensors(gpe_bulk_core_data_t * i_core_data_ptr, uint8_t i_core) -{ -#define CPM_PER_CORE 4 - - uint32_t k, l_cpm_min = 0xffffffff; - uint16_t l_cpm[CPM_PER_CORE]; - - l_cpm[0] = i_core_data_ptr->dts_cpm.sensors_v8.fields.encoded_cpm0; - l_cpm[1] = i_core_data_ptr->dts_cpm.sensors_v8.fields.encoded_cpm1; - l_cpm[2] = i_core_data_ptr->dts_cpm.sensors_v8.fields.encoded_cpm2; - l_cpm[3] = i_core_data_ptr->dts_cpm.sensors_v9.fields.encoded_cpm4; - - //calculate min CPM from all CPM's for this core - for(k = 0; k < CPM_PER_CORE; k++) - { - if(l_cpm[k] < l_cpm_min) - { - l_cpm_min = l_cpm[k]; } } - - sensor_update( AMECSENSOR_ARRAY_PTR(CPM2MSP0C0,i_core), l_cpm_min); } -*/ // Function Specification // @@ -358,6 +270,8 @@ void amec_calc_dts_sensors(gpe_bulk_core_data_t * i_core_data_ptr, uint8_t i_cor // Thread: RealTime Loop // // End Function Specification +// TEMP - Not supported yet. +#if 0 void amec_calc_freq_and_util_sensors(gpe_bulk_core_data_t * i_core_data_ptr, uint8_t i_core) { BOOLEAN l_core_sleep_winkle = FALSE; @@ -876,6 +790,7 @@ void amec_calc_spurr(uint8_t i_core) sensor_update( AMECSENSOR_ARRAY_PTR(SPURR2MSP0C0,i_core), (uint16_t) temp32); } } +#endif /*----------------------------------------------------------------------------*/ /* End */ |