src/occ_405/amec/amec_sensors_centaur.c
// Function Specification
//
// Name: amec_update_dimm_dts_sensors
//
// Description: Updates sensors that have data grabbed by the fast core data
// task.
//
// Thread: RealTime Loop
//
// End Function Specification
Function Specification
Name: amec_update_dimm_dts_sensors

Updates sensors that have data grabbed by the fast core data
task.



End Function Specification
Function Specification Name : amec_update_dimm_dts_sensors Updates sensors that have data grabbed by the fast core data task . End Function Specification
void amec_update_dimm_dts_sensors(CentaurMemData * i_sensor_cache, uint8_t i_centaur)
{
#define MIN_VALID_DIMM_TEMP 1
#define MAX_VALID_DIMM_TEMP 125 //according to Mike Pardiek
#define MAX_MEM_TEMP_CHANGE 2
    uint32_t k, l_hottest_dimm_temp;
    uint16_t l_dts[NUM_DIMMS_PER_CENTAUR] = {0};
    uint32_t l_hottest_dimm_loc = NUM_DIMMS_PER_CENTAUR;
    uint32_t l_sens_status;
    int32_t  l_dimm_temp, l_prev_temp;
    static uint8_t L_ran_once[MAX_NUM_CENTAURS] = {FALSE};
    for(k=0; k < NUM_DIMMS_PER_CENTAUR; k++)
    {
        if(!CENTAUR_SENSOR_ENABLED(i_centaur, k))
        {
            continue;
        }
        if (g_amec->proc[0].memctl[i_centaur].centaur.dimm_temps[k].temp_sid) 
        {
            if ((G_inject_dimm & ((uint64_t)1 << ((i_centaur * 8) + k))) == 0)
            {
                if (G_inject_dimm_trace[i_centaur][k] != 0)
                {
                    TRAC_INFO("amec_update_dimm_dts_sensors: stopping injection of errors for DIMM%04X", (i_centaur<<8)|k);
                    G_inject_dimm_trace[i_centaur][k] = 0;
                }
            }
            else
            {
                if (G_inject_dimm_trace[i_centaur][k] == 0)
                {
                    TRAC_INFO("amec_update_dimm_dts_sensors: injecting errors for DIMM%04X", (i_centaur<<8)|k);
                    G_inject_dimm_trace[i_centaur][k] = 1;
                }
                continue; 
            }
        }
        l_sens_status = i_sensor_cache->scache.dimm_thermal_sensor[k].fields.status;
        fru_temp_t* l_fru = &g_amec->proc[0].memctl[i_centaur].centaur.dimm_temps[k];
        l_dimm_temp = i_sensor_cache->scache.dimm_thermal_sensor[k].fields.temperature;
        l_prev_temp = l_fru->cur_temp;
        if(!l_prev_temp)
        {
            l_prev_temp = l_dimm_temp;
        }
        if(l_sens_status == DIMM_SENSOR_STATUS_VALID_NEW)
        {
            if(l_dimm_temp < MIN_VALID_DIMM_TEMP ||
               l_dimm_temp > MAX_VALID_DIMM_TEMP)
            {
                l_fru->flags |= FRU_TEMP_OUT_OF_RANGE;
                l_dts[k] = l_prev_temp;
            }
            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 rose faster than reasonable: cent[%d] dimm[%d] prev[%d] cur[%d]",
                                  i_centaur, 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: cent[%d] dimm[%d] prev[%d] cur[%d]",
                                  i_centaur, k, l_prev_temp, l_dimm_temp);
                        l_fru->flags |= FRU_TEMP_FAST_CHANGE;
                    }
                }
                else 
                {
                    l_dts[k] = l_dimm_temp;
                    l_fru->flags &= ~FRU_TEMP_FAST_CHANGE;
                }
                G_dimm_temp_updated_bitmap.bytes[i_centaur] |= DIMM_SENSOR0 >> k;
                l_fru->flags &= FRU_TEMP_FAST_CHANGE;
            }
        }
        else 
        {
            uint8_t l_status_flag = 1 << l_sens_status;
            if(L_ran_once[i_centaur])
            {
                if((l_sens_status != DIMM_SENSOR_STATUS_VALID_OLD) &&
                   !(l_status_flag & l_fru->flags))
                {
                    TRAC_INFO("Centaur%d sensor%d error: %d", i_centaur, k, l_sens_status);
                }
                l_fru->flags |= l_status_flag;
            }
            l_dts[k] = l_prev_temp;
            if(l_sens_status == DIMM_SENSOR_STATUS_ERROR)
            {
                G_centaur_needs_recovery |= CENTAUR0_PRESENT_MASK >> i_centaur;
            }
        }
        if(l_dts[k] >= g_amec->thermaldimm.ot_error)
        {
            G_dimm_overtemp_bitmap.bytes[i_centaur] |= 1 << k;
        }
    }
    for(l_hottest_dimm_temp = 0, k = 0; k < NUM_DIMMS_PER_CENTAUR; 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_centaur].centaur.dimm_temps[k].cur_temp =  l_dts[k];
    }
    amec_centaur_t* l_centaur_ptr = &g_amec->proc[0].memctl[i_centaur].centaur;
    if(l_hottest_dimm_temp > l_centaur_ptr->tempdimmax.sample_max)
    {
        sensor_update(&l_centaur_ptr->locdimmax, l_hottest_dimm_loc);
    }
    sensor_update(&l_centaur_ptr->tempdimmax, l_hottest_dimm_temp);
    L_ran_once[i_centaur] = TRUE;
    AMEC_DBG("Centaur[%d]: HotDimm=%d\n",i_centaur,l_hottest_dimm_temp);
}
void amec_update_dimm_dts_sensors ( CentaurMemData * i_sensor_cache , uint8_t i_centaur ) { #define MIN_VALID_DIMM_TEMP  1 #define MAX_VALID_DIMM_TEMP  125 //according to Mike Pardiek #define MAX_MEM_TEMP_CHANGE  2 uint32_t k , l_hottest_dimm_temp ; uint16_t l_dts [ NUM_DIMMS_PER_CENTAUR ] = { 0 } ; uint32_t l_hottest_dimm_loc = NUM_DIMMS_PER_CENTAUR ; uint32_t l_sens_status ; int32_t l_dimm_temp , l_prev_temp ; static uint8_t L_ran_once [ MAX_NUM_CENTAURS ] = { FALSE } ; for ( k = 0 ; k < NUM_DIMMS_PER_CENTAUR ; k ++ ) { if ( ! CENTAUR_SENSOR_ENABLED ( i_centaur , k ) ) { continue ; } if ( g_amec -> proc [ 0 ] . memctl [ i_centaur ] . centaur . dimm_temps [ k ] . temp_sid ) { if ( ( G_inject_dimm & ( ( uint64_t ) 1 << ( ( i_centaur * 8 ) + k ) ) ) == 0 ) { if ( G_inject_dimm_trace [ i_centaur ] [ k ] != 0 ) { TRAC_INFO ( " " , ( i_centaur << 8 ) | k ) ; G_inject_dimm_trace [ i_centaur ] [ k ] = 0 ; } } else { if ( G_inject_dimm_trace [ i_centaur ] [ k ] == 0 ) { TRAC_INFO ( " " , ( i_centaur << 8 ) | k ) ; G_inject_dimm_trace [ i_centaur ] [ k ] = 1 ; } continue ; } } l_sens_status = i_sensor_cache -> scache . dimm_thermal_sensor [ k ] . fields . status ; fru_temp_t * l_fru = & g_amec -> proc [ 0 ] . memctl [ i_centaur ] . centaur . dimm_temps [ k ] ; l_dimm_temp = i_sensor_cache -> scache . dimm_thermal_sensor [ k ] . fields . temperature ; l_prev_temp = l_fru -> cur_temp ; if ( ! l_prev_temp ) { l_prev_temp = l_dimm_temp ; } if ( l_sens_status == DIMM_SENSOR_STATUS_VALID_NEW ) { if ( l_dimm_temp < MIN_VALID_DIMM_TEMP || l_dimm_temp > MAX_VALID_DIMM_TEMP ) { l_fru -> flags |= FRU_TEMP_OUT_OF_RANGE ; l_dts [ k ] = l_prev_temp ; } 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 ( " " , i_centaur , 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 ( " " , i_centaur , k , l_prev_temp , l_dimm_temp ) ; l_fru -> flags |= FRU_TEMP_FAST_CHANGE ; } } else { l_dts [ k ] = l_dimm_temp ; l_fru -> flags &= ~ FRU_TEMP_FAST_CHANGE ; } G_dimm_temp_updated_bitmap . bytes [ i_centaur ] |= DIMM_SENSOR0 >> k ; l_fru -> flags &= FRU_TEMP_FAST_CHANGE ; } } else { uint8_t l_status_flag = 1 << l_sens_status ; if ( L_ran_once [ i_centaur ] ) { if ( ( l_sens_status != DIMM_SENSOR_STATUS_VALID_OLD ) && ! ( l_status_flag & l_fru -> flags ) ) { TRAC_INFO ( " " , i_centaur , k , l_sens_status ) ; } l_fru -> flags |= l_status_flag ; } l_dts [ k ] = l_prev_temp ; if ( l_sens_status == DIMM_SENSOR_STATUS_ERROR ) { G_centaur_needs_recovery |= CENTAUR0_PRESENT_MASK >> i_centaur ; } } if ( l_dts [ k ] >= g_amec -> thermaldimm . ot_error ) { G_dimm_overtemp_bitmap . bytes [ i_centaur ] |= 1 << k ; } } for ( l_hottest_dimm_temp = 0 , k = 0 ; k < NUM_DIMMS_PER_CENTAUR ; 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_centaur ] . centaur . dimm_temps [ k ] . cur_temp = l_dts [ k ] ; } amec_centaur_t * l_centaur_ptr = & g_amec -> proc [ 0 ] . memctl [ i_centaur ] . centaur ; if ( l_hottest_dimm_temp > l_centaur_ptr -> tempdimmax . sample_max ) { sensor_update ( & l_centaur_ptr -> locdimmax , l_hottest_dimm_loc ) ; } sensor_update ( & l_centaur_ptr -> tempdimmax , l_hottest_dimm_temp ) ; L_ran_once [ i_centaur ] = TRUE ; AMEC_DBG ( " \n " , i_centaur , l_hottest_dimm_temp ) ; }
Function Specification
Name: amec_update_dimm_dts_sensors
Function Specification Name : amec_update_dimm_dts_sensors
// Harvest thermal data for all dimms // DIMM has sensor ID // Skip this DIMM //Check DTS status bits. //make sure temperature is within a 'reasonable' range. //set a flag so that if we end up logging an error we have something to debug why //don't allow temp to change more than is reasonable for 2ms //reasonable amount of change occurred //Notify thermal thread that temperature has been updated //clear error flags //status was VALID_OLD, ERROR, or STALLED //convert status number to a flag //Trace the error if we haven't traced it already for this sensor //use last temperature //request recovery (disable and re-enable sensor cache collection) //Check if at or above the error temperature //Set a bit so that this dimm can be called out by the thermal thread // Find hottest temperature from all DIMMs for this centaur //only update location if hottest dimm temp is greater than previous maximum //update the max dimm temperature sensor for this centaur