diff options
author | Douglas Gilbert <dgilbert@us.ibm.com> | 2018-08-20 12:00:00 -0500 |
---|---|---|
committer | William A. Bryan <wilbryan@us.ibm.com> | 2019-05-01 14:06:09 -0500 |
commit | afa37a7e9bc0fa22fb2271fb2e7ea2557376181e (patch) | |
tree | 5b39ee8a394474649721a51c1c0d4968e52cac08 /src/occ_405/amec/amec_sensors_ocmb.c | |
parent | a880ffe3a854a8eb219ea92e7fbc4845d8fa2511 (diff) | |
download | talos-occ-afa37a7e9bc0fa22fb2271fb2e7ea2557376181e.tar.gz talos-occ-afa37a7e9bc0fa22fb2271fb2e7ea2557376181e.zip |
Explorer MSBUF monitoring
Change-Id: Ia8e48ba5c3ad7836dbd249f3965768e79083c181
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/73263
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
Reviewed-by: Martha Broyles <mbroyles@us.ibm.com>
Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/occ_405/amec/amec_sensors_ocmb.c')
-rw-r--r-- | src/occ_405/amec/amec_sensors_ocmb.c | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/src/occ_405/amec/amec_sensors_ocmb.c b/src/occ_405/amec/amec_sensors_ocmb.c new file mode 100644 index 0000000..3e57266 --- /dev/null +++ b/src/occ_405/amec/amec_sensors_ocmb.c @@ -0,0 +1,634 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/occ_405/amec/amec_sensors_centaur.c $ */ +/* */ +/* OpenPOWER OnChipController Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/******************************************************************************/ +/* includes */ +/******************************************************************************/ +#include <occ_common.h> +#include <ssx.h> +#include <errl.h> // Error logging +#include "sensor.h" +#include "rtls.h" +#include "occ_sys_config.h" +#include "occ_service_codes.h" // for SSX_GENERIC_FAILURE +#include "dcom.h" +#include "memory.h" +#include "centaur_data.h" +#include "amec_smh.h" +#include "amec_slave_smh.h" +#include <trac.h> +#include "amec_sys.h" +#include "sensor_enum.h" +#include "amec_service_codes.h" +#include "amec_sensors_ocmb.h" +#include "ocmb_mem_data.h" + +/******************************************************************************/ +/* Globals */ +/******************************************************************************/ +extern dimm_sensor_flags_t G_dimm_overtemp_bitmap; +extern dimm_sensor_flags_t G_dimm_temp_updated_bitmap; +extern uint8_t G_cent_overtemp_bitmap; +extern uint8_t G_cent_temp_updated_bitmap; +extern uint8_t G_centaur_needs_recovery; +extern uint64_t G_inject_dimm; +extern uint32_t G_inject_dimm_trace[MAX_NUM_OCMBS][NUM_DIMMS_PER_OCMB]; + +uint32_t amec_diff_adjust_for_overflow(uint32_t i_new_value, uint32_t i_old_value); + +/******************************************************************************/ +/* Forward Declarations */ +/******************************************************************************/ +void amec_update_ocmb_dimm_dts_sensors(OcmbMemData * i_sensor_cache, uint8_t i_membuf); +void amec_update_ocmb_dts_sensors(OcmbMemData * i_sensor_cache, uint8_t i_membuf); +void amec_perfcount_ocmb_getmc( OcmbMemData * i_sensor_cache, uint8_t i_membuf); + +/******************************************************************************/ +/* Code */ +/******************************************************************************/ + +// Function Specification +// +// Name: amec_update_ocmb_dimm_dts_sensors +// +// Description: Updates sensors that have data grabbed by the fast core data +// task. +// +// Thread: RealTime Loop +// +// End Function Specification +void amec_update_ocmb_sensors(uint8_t i_membuf) +{ + if(CENTAUR_PRESENT(i_membuf)) + { + OcmbMemData * l_sensor_cache = + (OcmbMemData *)cent_get_centaur_data_ptr(i_membuf); + if(CENTAUR_UPDATED(i_membuf)) + { + amec_update_ocmb_dimm_dts_sensors(l_sensor_cache, i_membuf); + amec_update_ocmb_dts_sensors(l_sensor_cache, i_membuf); + amec_perfcount_ocmb_getmc(l_sensor_cache, i_membuf); + } + CLEAR_CENTAUR_UPDATED(i_membuf); + } +} + +// Function Specification +// +// Name: amec_update_ocmb_dimm_dts_sensors +// +// Description: Updates sensors that have data from the membuf sensor cache +// +// Thread: RealTime Loop +// +// Note: The ocmb cache data uses the same space as the Centaur +// membuf cache data, so some of the centaur attributes apply to +// Ocmb data as well as Centaur. +// +// End Function Specification +void amec_update_ocmb_dimm_dts_sensors(OcmbMemData * i_sensor_cache, uint8_t i_membuf) +{ +#define MIN_VALID_DIMM_TEMP 1 +#define MAX_VALID_DIMM_TEMP 125 //according to Mike Pardiek 04/23/2019 +#define MAX_MEM_TEMP_CHANGE 2 + + uint32_t k, l_hottest_dimm_temp; + uint16_t l_dts[NUM_DIMMS_PER_OCMB] = {0}; + uint32_t l_hottest_dimm_loc = NUM_DIMMS_PER_OCMB; + int32_t l_dimm_temp, l_prev_temp; + static uint8_t L_ran_once[MAX_NUM_OCMBS] = {FALSE}; + + // Harvest thermal data for all dimms + for(k=0; k < NUM_DIMMS_PER_OCMB; k++) + { + if(!CENTAUR_SENSOR_ENABLED(i_membuf, k)) + { + continue; + } + +#ifdef __INJECT_DIMM__ + if (g_amec->proc[0].memctl[i_membuf].centaur.dimm_temps[k].temp_sid) // DIMM has sensor ID + { + if ((G_inject_dimm & ((uint64_t)1 << ((i_membuf * 8) + k))) == 0) + { + if (G_inject_dimm_trace[i_membuf][k] != 0) + { + TRAC_INFO("amec_update_ocmb_dimm_dts_sensors: stopping injection of errors for DIMM%04X", (i_membuf<<8)|k); + G_inject_dimm_trace[i_membuf][k] = 0; + } + } + else + { + if (G_inject_dimm_trace[i_membuf][k] == 0) + { + TRAC_INFO("amec_update_ocmb_dimm_dts_sensors: injecting errors for DIMM%04X", (i_membuf<<8)|k); + G_inject_dimm_trace[i_membuf][k] = 1; + } + continue; // Skip this DIMM + } + } +#endif + + fru_temp_t* l_fru = &g_amec->proc[0].memctl[i_membuf].centaur.dimm_temps[k]; + + l_dimm_temp = i_sensor_cache->memdts[k]; + l_prev_temp = l_fru->cur_temp; + if(!l_prev_temp) + { + l_prev_temp = l_dimm_temp; + } + + //Check DTS status bits. VALID NEW if valid and !err + if((k == 0 && + i_sensor_cache->status.fields.memdts0_valid && + (!i_sensor_cache->status.fields.memdts0_err)) || + (k == 1 && + i_sensor_cache->status.fields.memdts1_valid && + (!i_sensor_cache->status.fields.memdts1_err))) + { + //make sure temperature is within a 'reasonable' range. + if(l_dimm_temp < MIN_VALID_DIMM_TEMP || + l_dimm_temp > MAX_VALID_DIMM_TEMP) + { + //set a flag so that if we end up logging an error we have something to debug why + l_fru->flags |= FRU_TEMP_OUT_OF_RANGE; + l_dts[k] = l_prev_temp; + } + else + { + //don't allow temp to change more than is reasonable for 2ms + if(l_dimm_temp > (l_prev_temp + MAX_MEM_TEMP_CHANGE)) + { + l_dts[k] = l_prev_temp + MAX_MEM_TEMP_CHANGE; + if(!l_fru->flags) + { + TRAC_INFO("dimm temp rose faster than reasonable: membuf[%d] dimm[%d] prev[%d] cur[%d]", + i_membuf, k, l_prev_temp, l_dimm_temp); + l_fru->flags |= FRU_TEMP_FAST_CHANGE; + } + } + else if (l_dimm_temp < (l_prev_temp - MAX_MEM_TEMP_CHANGE)) + { + l_dts[k] = l_prev_temp - MAX_MEM_TEMP_CHANGE; + if(!l_fru->flags) + { + TRAC_INFO("dimm temp fell faster than reasonable: membuf[%d] dimm[%d] prev[%d] cur[%d]", + i_membuf, k, l_prev_temp, l_dimm_temp); + l_fru->flags |= FRU_TEMP_FAST_CHANGE; + } + } + else //reasonable amount of change occurred + { + l_dts[k] = l_dimm_temp; + l_fru->flags &= ~FRU_TEMP_FAST_CHANGE; + } + + //Notify thermal thread that temperature has been updated + G_dimm_temp_updated_bitmap.bytes[i_membuf] |= DIMM_SENSOR0 >> k; + + //clear error flags + l_fru->flags &= FRU_TEMP_FAST_CHANGE; + } + } + else //status was VALID_OLD or ERROR + { + //convert status number to a flag + uint8_t l_status_flag = 0; + if((k == 0 && i_sensor_cache->status.fields.memdts0_err) || + (k == 1 && i_sensor_cache->status.fields.memdts1_err)) + { + l_status_flag = FRU_SENSOR_STATUS_ERROR; + } + else + { + l_status_flag = FRU_SENSOR_STATUS_VALID_OLD; + } + + if(L_ran_once[i_membuf]) + { + //Trace the error if we haven't traced it already for this sensor + if((l_status_flag != FRU_SENSOR_STATUS_VALID_OLD) && + !(l_status_flag & l_fru->flags)) + { + TRAC_ERR("Membuf %d dimm sensor%d reported an error.", i_membuf, k); + } + + l_fru->flags |= l_status_flag; + } + + //use last temperature + l_dts[k] = l_prev_temp; + + //request recovery (disable and re-enable sensor cache collection) + if(i_sensor_cache->status.fields.memdts0_err || + i_sensor_cache->status.fields.memdts1_err) + { + G_centaur_needs_recovery |= CENTAUR0_PRESENT_MASK >> i_membuf; + } + } + + //Check if at or above the error temperature + if(l_dts[k] >= g_amec->thermaldimm.ot_error) + { + //Set a bit so that this dimm can be called out by the thermal thread + G_dimm_overtemp_bitmap.bytes[i_membuf] |= 1 << k; + } + } + + // Find hottest temperature from all DIMMs for this centaur + for(l_hottest_dimm_temp = 0, k = 0; k < NUM_DIMMS_PER_OCMB; k++) + { + if(l_dts[k] > l_hottest_dimm_temp) + { + l_hottest_dimm_temp = l_dts[k]; + l_hottest_dimm_loc = k; + } + g_amec->proc[0].memctl[i_membuf].centaur.dimm_temps[k].cur_temp = l_dts[k]; + } + + amec_centaur_t* l_centaur_ptr = &g_amec->proc[0].memctl[i_membuf].centaur; + + //only update location if hottest dimm temp is greater than previous maximum + if(l_hottest_dimm_temp > l_centaur_ptr->tempdimmax.sample_max) + { + sensor_update(&l_centaur_ptr->locdimmax, l_hottest_dimm_loc); + } + + //update the max dimm temperature sensor for this centaur + sensor_update(&l_centaur_ptr->tempdimmax, l_hottest_dimm_temp); + + L_ran_once[i_membuf] = TRUE; + AMEC_DBG("Centaur[%d]: HotDimm=%d\n",i_membuf,l_hottest_dimm_temp); +} + +// Function Specification +// +// Name: amec_update_ocmb_dts_sensors +// +// Description: Updates sensors that have data grabbed by the fast core data +// +// Thread: RealTime Loop +// +// End Function Specification +void amec_update_ocmb_dts_sensors(OcmbMemData * i_sensor_cache, uint8_t i_membuf) +{ +#define MIN_VALID_MEMBUF_TEMP 1 +#define MAX_VALID_MEMBUF_TEMP 125 //according to Mike Pardiek + + uint16_t l_dts; + uint16_t l_sens_temp; + int32_t l_prev_temp; + static uint8_t L_ran_once[MAX_NUM_OCMBS] = {FALSE}; + + l_sens_temp = i_sensor_cache->ubdts0; + + fru_temp_t* l_fru = &g_amec->proc[0].memctl[i_membuf].centaur.centaur_hottest; + + l_prev_temp = l_fru->cur_temp; + if(!l_prev_temp) + { + l_prev_temp = l_sens_temp; + } + + //Check DTS status bits + if(i_sensor_cache->status.fields.ubdts0_valid && + (!i_sensor_cache->status.fields.ubdts0_err)) + { + //make sure temperature is within a 'reasonable' range. + if(l_sens_temp < MIN_VALID_MEMBUF_TEMP || + l_sens_temp > MAX_VALID_MEMBUF_TEMP) + { + //set a flag so that if we end up logging an error we have something to debug why + l_fru->flags |= FRU_TEMP_OUT_OF_RANGE; + l_dts = l_prev_temp; + } + else + { + //don't allow temp to change more than is reasonable for 2ms + if(l_sens_temp > (l_prev_temp + MAX_MEM_TEMP_CHANGE)) + { + l_dts = l_prev_temp + MAX_MEM_TEMP_CHANGE; + if(!l_fru->flags) + { + TRAC_INFO("membuf temp rose faster than reasonable: membuf[%d] prev[%d] cur[%d]", + i_membuf, l_prev_temp, l_sens_temp); + l_fru->flags |= FRU_TEMP_FAST_CHANGE; + } + } + else if (l_sens_temp < (l_prev_temp - MAX_MEM_TEMP_CHANGE)) + { + l_dts = l_prev_temp - MAX_MEM_TEMP_CHANGE; + if(!l_fru->flags) + { + TRAC_INFO("membuf temp fell faster than reasonable: cent[%d] prev[%d] cur[%d]", + i_membuf, l_prev_temp, l_sens_temp); + l_fru->flags |= FRU_TEMP_FAST_CHANGE; + } + } + else //reasonable amount of change occurred + { + l_dts = l_sens_temp; + l_fru->flags &= ~FRU_TEMP_FAST_CHANGE; + } + + //Notify thermal thread that temperature has been updated + G_cent_temp_updated_bitmap |= CENTAUR0_PRESENT_MASK >> i_membuf; + + //clear error flags + l_fru->flags &= FRU_TEMP_FAST_CHANGE; + } + } + else //status was INVALID + { + if(L_ran_once[i_membuf]) + { + //Trace the error if we haven't traced it already for this sensor + if(!(l_fru->flags & FRU_SENSOR_STATUS_INVALID) && + i_sensor_cache->status.fields.ubdts0_err) + { + TRAC_ERR("Membuf %d temp sensor error.", i_membuf); + } + + l_fru->flags |= FRU_SENSOR_STATUS_INVALID; + } + + //use last temperature + l_dts = l_prev_temp; + } + + L_ran_once[i_membuf] = TRUE; + + //Check if at or above the error temperature + if(l_dts >= g_amec->thermalcent.ot_error) + { + //Set a bit so that this dimm can be called out by the thermal thread + G_cent_overtemp_bitmap |= (CENTAUR0_PRESENT_MASK >> i_membuf); + } + + // Update Interim Data - later this will get picked up to form centaur sensor + g_amec->proc[0].memctl[i_membuf].centaur.centaur_hottest.cur_temp = l_dts; + + AMEC_DBG("Membuf[%d]: HotMembuf=%d\n",i_membuf,l_dts); +} + +// Function Specification +// +// Name: amec_update_ocmb_temp_sensors +// +// Description: Updates thermal sensors that have data grabbed by the centaur. +// +// Thread: RealTime Loop +// +// End Function Specification +void amec_update_ocmb_temp_sensors(void) +{ + uint32_t k; + uint32_t l_hot_dimm = 0; + uint32_t l_hot_mb = 0; + + // ----------------------------------------------------------- + // Find hottest temperature from all membufs for this Proc chip + // Find hottest temperature from all DIMMs for this Proc chip + // ----------------------------------------------------------- + for(k=0; k < MAX_NUM_OCMBS; k++) + { + if(g_amec->proc[0].memctl[k].centaur.centaur_hottest.cur_temp > l_hot_mb) + { + l_hot_mb = g_amec->proc[0].memctl[k].centaur.centaur_hottest.cur_temp; + } + if(g_amec->proc[0].memctl[k].centaur.tempdimmax.sample > l_hot_dimm) + { + l_hot_dimm = g_amec->proc[0].memctl[k].centaur.tempdimmax.sample; + } + } + sensor_update(&g_amec->proc[0].temp2mscent,l_hot_mb); + AMEC_DBG("HotMembuf=%d\n",l_hot_mb); + + sensor_update(&g_amec->proc[0].tempdimmthrm,l_hot_dimm); + AMEC_DBG("HotDimm=%d\n",l_hot_dimm); + +} + + +// Function Specification +// +// Name: amec_perfcount_ocmb_getmc +// +// Description: Updates performance sensors that have data grabbed by the +// centaur. +// +// Thread: RealTime Loop +// +// End Function Specification + +void amec_perfcount_ocmb_getmc( OcmbMemData * i_sensor_cache, + uint8_t i_membuf) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + uint32_t tempu = 0; + uint32_t templ = 0; + uint32_t temp32new = 0; + uint32_t temp32 = 0; + uint32_t tempreg = 0; + + #define AMECSENSOR_PORTPAIR_PTR(sensor_base,idx,idx2) \ + (&(g_amec->proc[0].memctl[idx].centaur.portpair[idx2].sensor_base)) + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + OcmbMemData * l_sensor_cache = i_sensor_cache; + + tempu = l_sensor_cache->mba_rd; + templ = l_sensor_cache->mba_wr; + + // --------------------------------------------------------------------------- + // Interim Calculation: MWRMx (0.01 Mrps) Memory write requests per sec + // --------------------------------------------------------------------------- + + // Extract write bandwidth + temp32new = (templ); + + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.wr_cnt_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.wr_cnt_accum = temp32new; // Save latest accumulator away for next time + + // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000) + tempreg = ((temp32*125)/10000); + + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.memwrite2ms = tempreg; + + // ------------------------------------------------------------------------- + // Interim Calculation: MRDMx (0.01 Mrps) Memory read requests per sec + // ------------------------------------------------------------------------- + + // Extract read bandwidth + temp32new = (tempu); + + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.rd_cnt_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.rd_cnt_accum = temp32new; // Save latest accumulator away for next time + + // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000) + tempreg = ((temp32*125)/10000); + + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.memread2ms = tempreg; + + // Go after second MC performance counter (power ups and activations) + tempu = l_sensor_cache->mba_act; + templ = l_sensor_cache->mba_powerups; + + // ---------------------------------------------------------------- + // Sensor: MPUMx (0.01 Mrps) Memory power-up requests per sec + // ---------------------------------------------------------------- + // Extract power up count + temp32new = (templ); // left shift into top 20 bits of 32 bits + + // For DD1.0, we only have 1 channel field that we use; DD2.0 we need to add another channel + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.pwrup_cnt_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.pwrup_cnt_accum = temp32new; // Save latest accumulator away for next time + tempreg=(uint16_t)(temp32>>12); // Select upper 20 bits + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.pwrup_cnt=(uint16_t)tempreg; + sensor_update(AMECSENSOR_PORTPAIR_PTR(mpu2ms,i_membuf,0), tempreg); + + // ------------------------------------------------------------------- + // Sensor: MACMx (0.01 Mrps) Memory activation requests per sec + // ------------------------------------------------------------------- + // Extract activation count + temp32 = templ; + temp32 += tempu; + + temp32new = (temp32); // left shift into top 20 bits of 32 bits + // For DD1.0, we only have 1 channel field that we use; DD2.0 we need to add another channel + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.act_cnt_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.act_cnt_accum = temp32new; // Save latest accumulator away for next time + tempreg=(uint16_t)(temp32>>12); // Select lower 16 of 20 bits + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.act_cnt=(uint16_t)tempreg; + sensor_update(AMECSENSOR_PORTPAIR_PTR(mac2ms,i_membuf,0), tempreg); + + // -------------------------------------------------------------------------- + // Sensor: MTS (count) Last received Timestamp (frame count) from Centaur + // -------------------------------------------------------------------------- + // Extract framecount (clock is 266.6666666MHz * 0.032 / 4096)=2083. + temp32new = l_sensor_cache->frame_count; + + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.fr2_cnt_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.fr2_cnt_accum = temp32new; // Save latest accumulator away for next time + tempreg=(uint16_t)(temp32>>12); // Select upper 20 bits + + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.fr2_cnt=(uint16_t)tempreg; + sensor_update(AMECSENSOR_PORTPAIR_PTR(mts2ms,i_membuf,0), tempreg); + + // ------------------------------------------------------------------------------ + // Sensor: MIRB (0.01 Mevents/s) Memory Inter-request arrival idle intervals + // ------------------------------------------------------------------------------ + temp32new = l_sensor_cache->mba_arr_cnt_base; + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_base_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_base_accum = temp32new; // Save latest accumulator away for next time + + // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000) + tempreg = ((temp32*125)/10000); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.mirb2ms = tempreg; + sensor_update(AMECSENSOR_PORTPAIR_PTR(mirb2ms,i_membuf,0), tempreg); + + // -------------------------------------------------------------------------------------------------------- + // Sensor: MIRL (0.01 Mevents/s) Memory Inter-request arrival idle intervals longer than low threshold + // -------------------------------------------------------------------------------------------------------- + temp32new = l_sensor_cache->mba_arr_cnt_low; + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_low_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_low_accum = temp32new; // Save latest accumulator away for next time + + // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000) + tempreg = ((temp32*125)/10000); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.mirl2ms = tempreg; + sensor_update(AMECSENSOR_PORTPAIR_PTR(mirl2ms,i_membuf,0), tempreg); + + // ----------------------------------------------------------------------------------------------------------- + // Sensor: MIRM (0.01 Mevents/s) Memory Inter-request arrival idle intervals longer than medium threshold + // ----------------------------------------------------------------------------------------------------------- + temp32new = l_sensor_cache->mba_arr_cnt_med; + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_med_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_med_accum = temp32new; // Save latest accumulator away for next time + + // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000) + tempreg = ((temp32*125)/10000); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.mirm2ms = tempreg; + sensor_update(AMECSENSOR_PORTPAIR_PTR(mirm2ms,i_membuf,0), tempreg); + + // --------------------------------------------------------------------------------------------------------- + // Sensor: MIRH (0.01 Mevents/s) Memory Inter-request arrival idle intervals longer than high threshold + // --------------------------------------------------------------------------------------------------------- + temp32new = l_sensor_cache->mba_arr_cnt_high; + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_high_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.intreq_high_accum = temp32new; // Save latest accumulator away for next time + + // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000) + tempreg = ((temp32*125)/10000); + g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.mirh2ms = tempreg; + sensor_update(AMECSENSOR_PORTPAIR_PTR(mirh2ms,i_membuf,0), tempreg); + + // ---------------------------------------------------- + // Sensor: MLP2 (events/s) Number of LP2 exits + // ---------------------------------------------------- + temp32new = l_sensor_cache->self_timed_refresh; + temp32 = g_amec->proc[0].memctl[i_membuf].centaur.perf.lp2exit_accum; + temp32 = amec_diff_adjust_for_overflow(temp32new, temp32); + g_amec->proc[0].memctl[i_membuf].centaur.perf.lp2exit_accum = temp32new; // Save latest accumulator away for next time + + // Read every 8 ms....to convert to 0.01 Mrps = ((8ms read * 125)/10000) + tempreg = ((temp32*125)/10000); + g_amec->proc[0].memctl[i_membuf].centaur.perf.mlp2_2ms = tempreg; + sensor_update((&(g_amec->proc[0].memctl[i_membuf].centaur.mlp2ms)), tempreg); + + // ------------------------------------------------------------ + // Sensor: MRDMx (0.01 Mrps) Memory read requests per sec + // ------------------------------------------------------------ + tempreg = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.memread2ms; + tempreg += g_amec->proc[0].memctl[i_membuf].centaur.portpair[1].perf.memread2ms; + sensor_update( (&(g_amec->proc[0].memctl[i_membuf].mrd)), tempreg); + + // ------------------------------------------------------------- + // Sensor: MWRMx (0.01 Mrps) Memory write requests per sec + // ------------------------------------------------------------- + tempreg = g_amec->proc[0].memctl[i_membuf].centaur.portpair[0].perf.memwrite2ms; + tempreg += g_amec->proc[0].memctl[i_membuf].centaur.portpair[1].perf.memwrite2ms; + sensor_update( (&(g_amec->proc[0].memctl[i_membuf].mwr)), tempreg); + + return; +} + +/*----------------------------------------------------------------------------*/ +/* End */ +/*----------------------------------------------------------------------------*/ |