src/occ_405/pss/avsbus.c
// Read and return the voltage, current, or temperature for specified rail
// (voltage units are mV, current units are in 10mA, temperature in 0.1 C)
Read and return the voltage, current, or temperature for specified rail
(voltage units are mV, current units are in 10mA, temperature in 0.1 C)
Read and return the voltage current or temperature for specified rail ( voltage units are mV current units are in 10mA temperature in 0 . 1 C )
uint16_t avsbus_read(const avsbus_type_e i_type,
                     const avsbus_cmdtype_e i_cmdtype)
{
    if (isSafeStateRequested())
    {
        return 0;
    }
    uint16_t o_reading = 0;
    bool l_failure = FALSE;
    uint8_t l_cmd_index = 0;
    char l_trace_cmd = 'V';
    if (i_cmdtype == AVSBUS_CURRENT)
    {
        l_cmd_index = 1;
        l_trace_cmd = 'C';
    }
    else if (i_cmdtype == AVSBUS_TEMPERATURE)
    {
        l_cmd_index = 2;
        l_trace_cmd = 'T';
    }
    static uint32_t L_error_count[AVSBUS_TYPE_MAX][AVSBUS_CMDS_MAX] = {{0}};
    uint32_t *      l_error_count = &L_error_count[i_type][l_cmd_index];
    char l_trace_type = 'd';
    avsbusData_t l_data = G_sysConfigData.avsbus_vdd;
    if (AVSBUS_VDN == i_type)
    {
        l_trace_type = 'n';
        l_data = G_sysConfigData.avsbus_vdn;
    }
#ifdef AVSDEBUG
    static uint32_t L_trace_count[AVSBUS_TYPE_MAX][AVSBUS_CMDS_MAX] = {{0}};
    uint32_t *      l_trace_count = &L_trace_count[i_type][l_cmd_index];
    if (*l_trace_count < DEBUG_TRACE_MAX)
    {
        TRAC_INFO("avsbus_read: Vd%c %c - bus[%d] rail[%d]",
                  l_trace_type, l_trace_cmd, l_data.bus, l_data.rail);
    }
#endif
    enum occReasonCode rc = OCC_SUCCESS_REASON_CODE;
    uint32_t l_status = in32(OCB_O2SSTxB[l_data.bus]);
    DEBUG_IN32(OCB_O2SSTxB[l_data.bus], l_status, "OCB_O2SSTxB");
    if (0 != (l_status & AVSBUS_STATUS_ERRORS))
    {
        l_failure = TRUE;
        (*l_error_count)++;
        if ((*l_error_count == 1) || (*l_error_count == MAX_READ_ATTEMPTS))
        {
            TRAC_ERR("avsbus_read: Error found in Vd%c %c O2SST[0x%08X] = [0x%08X]",
                     l_trace_type, l_trace_cmd, OCB_O2SSTxB[l_data.bus], l_status);
            rc = AVSBUS_ERROR;
        }
    }
    else if (l_status & AVSBUS_STATUS_ONGOING) 
    {
         bit was still set (operation did not complete)
        l_failure = TRUE;
        (*l_error_count)++;
        if ((*l_error_count == 1) || (*l_error_count == MAX_READ_ATTEMPTS))
        {
            TRAC_ERR("avsbus_read: Vd%c %c timeout waiting for o2s_ongoing change O2SST[0x%08X] = [0x%08X]",
                     l_trace_type, l_trace_cmd, OCB_O2SSTxB[l_data.bus], l_status);
            rc = AVSBUS_TIMEOUT;
        }
    }
    if (FALSE == l_failure)
    {
        uint32_t value = in32(OCB_O2SRDxB[l_data.bus]);
        DEBUG_IN32(OCB_O2SRDxB[l_data.bus], value, "OCB_O2SRDxB");
        const uint32_t crc = avs_crc_calculate(value);
        if (crc != (value & AVS_CRC_MASK))
        {
            l_failure = TRUE;
            (*l_error_count)++;
            if ((*l_error_count == 1) || (*l_error_count == MAX_READ_ATTEMPTS))
            {
                TRAC_ERR("avsbus_read: CRC mismatch in Vd%c %c rsp O2SRD[0x%08X] = [0x%08X] (calculated CRC 0x%08X)",
                         l_trace_type, l_trace_cmd, OCB_O2SRDxB[l_data.bus], value, crc);
                rc = AVSBUS_CRC_ERROR;
            }
        }
        else if (0 == (value & 0xC0000000))
        {
            o_reading = (value >> 8) & 0x0000FFFF;
#ifdef AVSDEBUG
            if (*l_trace_count < DEBUG_TRACE_MAX)
            {
                if (i_cmdtype == AVSBUS_VOLTAGE)
                {
                    TRAC_INFO("avsbus_read: Successfully read Vd%c voltage %dmV [0x%08X]",
                              l_trace_type, o_reading, value);
                }
                else if (i_cmdtype == AVSBUS_CURRENT)
                {
                    TRAC_INFO("avsbus_read: Successfully read Vd%c current %dx10mA [0x%08X]",
                              l_trace_type, o_reading, value);
                }
            }
#endif
            if (i_cmdtype == AVSBUS_TEMPERATURE)
            {
#ifdef AVSDEBUG
                if (*l_trace_count < DEBUG_TRACE_MAX)
                {
                    TRAC_INFO("avsbus_read: Successfully read Vd%c temperature %d/10 C [0x%08X]",
                              l_trace_type, o_reading, value);
                }
#endif
                sensor_t * l_sensor = AMECSENSOR_PTR(TEMPVDD);
                sensor_update(l_sensor, (uint16_t)o_reading/10);
                G_vrm_vdd_temp_expired = false;
                amec_health_check_vrm_vdd_temp(l_sensor);
            }
            if (*l_error_count)
            {
                TRAC_INFO("avsbus_read: Successfully read Vd%c %c [0x%08X] (error count=%d)",
                          l_trace_type, l_trace_cmd, value, *l_error_count);
                *l_error_count = 0;
            }
        }
        else
        {
            l_failure = TRUE;
            (*l_error_count)++;
            if ((*l_error_count == 1) || (*l_error_count == MAX_READ_ATTEMPTS))
            {
                TRAC_ERR("avsbus_read: SlaveAck reported no action taken[0x%08X]", value);
                rc = AVSBUS_ERROR;
            }
        }
    }
    if (l_failure)
    {
        enum occExtReasonCode exrc = ERC_AVSBUS_VDD_VOLTAGE_FAILURE;
        if (AVSBUS_VDD == i_type)
        {
            if (i_cmdtype == AVSBUS_CURRENT)
            {
                exrc = ERC_AVSBUS_VDD_CURRENT_FAILURE;
                INCREMENT_ERR_HISTORY(ERRH_AVSBUS_VDD_CURRENT);
            }
            else if (i_cmdtype == AVSBUS_VOLTAGE)
            {
                INCREMENT_ERR_HISTORY(ERRH_AVSBUS_VDD_VOLTAGE);
            }
            else if (i_cmdtype == AVSBUS_TEMPERATURE)
            {
                exrc = ERC_AVSBUS_VDD_TEMPERATURE_FAILURE;
                INCREMENT_ERR_HISTORY(ERRH_AVSBUS_VDD_TEMPERATURE);
            }
        }
        else
        {
            if (i_cmdtype == AVSBUS_CURRENT)
            {
                exrc = ERC_AVSBUS_VDN_CURRENT_FAILURE;
                INCREMENT_ERR_HISTORY(ERRH_AVSBUS_VDN_CURRENT);
            }
            else if (i_cmdtype == AVSBUS_VOLTAGE)
            {
                exrc = ERC_AVSBUS_VDN_VOLTAGE_FAILURE;
                INCREMENT_ERR_HISTORY(ERRH_AVSBUS_VDN_VOLTAGE);
            }
        }
        if (*l_error_count == MAX_READ_ATTEMPTS)
        {
            TRAC_ERR("avsbus_read: Reached %d consecutive Vd%c %c errors, requesting reset",
                     *l_error_count, l_trace_type, l_trace_cmd);
            G_avsbus_vdd_monitoring = FALSE;
            G_avsbus_vdn_monitoring = FALSE;
            errlHndl_t l_err = createErrl(PSS_MID_AVSBUS_READ,
                                          rc,
                                          exrc,
                                          ERRL_SEV_PREDICTIVE,
                                          NULL,
                                          DEFAULT_TRACE_SIZE,
                                          (i_type << 16) | (l_data.bus << 8) | l_data.rail,
                                          l_status);
            addCalloutToErrl(l_err,
                             ERRL_CALLOUT_TYPE_HUID,
                             G_sysConfigData.proc_huid,
                             ERRL_CALLOUT_PRIORITY_MED);
            REQUEST_RESET(l_err);
        }
        else
        {
            avsbus_resync(l_data.bus);
        }
    }
#ifdef AVSDEBUG
    ++*l_trace_count;
#endif
    return o_reading;
}
uint16_t avsbus_read ( const avsbus_type_e i_type , const avsbus_cmdtype_e i_cmdtype ) { if ( isSafeStateRequested ( ) ) { return 0 ; } uint16_t o_reading = 0 ; bool l_failure = FALSE ; uint8_t l_cmd_index = 0 ; char l_trace_cmd = ' ' ; if ( i_cmdtype == AVSBUS_CURRENT ) { l_cmd_index = 1 ; l_trace_cmd = ' ' ; } else if ( i_cmdtype == AVSBUS_TEMPERATURE ) { l_cmd_index = 2 ; l_trace_cmd = ' ' ; } static uint32_t L_error_count [ AVSBUS_TYPE_MAX ] [ AVSBUS_CMDS_MAX ] = { { 0 } } ; uint32_t * l_error_count = & L_error_count [ i_type ] [ l_cmd_index ] ; char l_trace_type = ' ' ; avsbusData_t l_data = G_sysConfigData . avsbus_vdd ; if ( AVSBUS_VDN == i_type ) { l_trace_type = ' ' ; l_data = G_sysConfigData . avsbus_vdn ; } #ifdef AVSDEBUG static uint32_t L_trace_count [ AVSBUS_TYPE_MAX ] [ AVSBUS_CMDS_MAX ] = { { 0 } } ; uint32_t * l_trace_count = & L_trace_count [ i_type ] [ l_cmd_index ] ; if ( * l_trace_count < DEBUG_TRACE_MAX ) { TRAC_INFO ( " " , l_trace_type , l_trace_cmd , l_data . bus , l_data . rail ) ; } #endif enum occReasonCode rc = OCC_SUCCESS_REASON_CODE ; uint32_t l_status = in32 ( OCB_O2SSTxB [ l_data . bus ] ) ; DEBUG_IN32 ( OCB_O2SSTxB [ l_data . bus ] , l_status , " " ) ; if ( 0 != ( l_status & AVSBUS_STATUS_ERRORS ) ) { l_failure = TRUE ; ( * l_error_count ) ++ ; if ( ( * l_error_count == 1 ) || ( * l_error_count == MAX_READ_ATTEMPTS ) ) { TRAC_ERR ( " " , l_trace_type , l_trace_cmd , OCB_O2SSTxB [ l_data . bus ] , l_status ) ; rc = AVSBUS_ERROR ; } } else if ( l_status & AVSBUS_STATUS_ONGOING ) { l_failure = TRUE ; ( * l_error_count ) ++ ; if ( ( * l_error_count == 1 ) || ( * l_error_count == MAX_READ_ATTEMPTS ) ) { TRAC_ERR ( " " , l_trace_type , l_trace_cmd , OCB_O2SSTxB [ l_data . bus ] , l_status ) ; rc = AVSBUS_TIMEOUT ; } } if ( FALSE == l_failure ) { uint32_t value = in32 ( OCB_O2SRDxB [ l_data . bus ] ) ; DEBUG_IN32 ( OCB_O2SRDxB [ l_data . bus ] , value , " " ) ; const uint32_t crc = avs_crc_calculate ( value ) ; if ( crc != ( value & AVS_CRC_MASK ) ) { l_failure = TRUE ; ( * l_error_count ) ++ ; if ( ( * l_error_count == 1 ) || ( * l_error_count == MAX_READ_ATTEMPTS ) ) { TRAC_ERR ( " " , l_trace_type , l_trace_cmd , OCB_O2SRDxB [ l_data . bus ] , value , crc ) ; rc = AVSBUS_CRC_ERROR ; } } else if ( 0 == ( value & 0xC0000000 ) ) { o_reading = ( value >> 8 ) & 0x0000FFFF ; #ifdef AVSDEBUG if ( * l_trace_count < DEBUG_TRACE_MAX ) { if ( i_cmdtype == AVSBUS_VOLTAGE ) { TRAC_INFO ( " " , l_trace_type , o_reading , value ) ; } else if ( i_cmdtype == AVSBUS_CURRENT ) { TRAC_INFO ( " " , l_trace_type , o_reading , value ) ; } } #endif if ( i_cmdtype == AVSBUS_TEMPERATURE ) { #ifdef AVSDEBUG if ( * l_trace_count < DEBUG_TRACE_MAX ) { TRAC_INFO ( " " , l_trace_type , o_reading , value ) ; } #endif sensor_t * l_sensor = AMECSENSOR_PTR ( TEMPVDD ) ; sensor_update ( l_sensor , ( uint16_t ) o_reading / 10 ) ; G_vrm_vdd_temp_expired = false ; amec_health_check_vrm_vdd_temp ( l_sensor ) ; } if ( * l_error_count ) { TRAC_INFO ( " " , l_trace_type , l_trace_cmd , value , * l_error_count ) ; * l_error_count = 0 ; } } else { l_failure = TRUE ; ( * l_error_count ) ++ ; if ( ( * l_error_count == 1 ) || ( * l_error_count == MAX_READ_ATTEMPTS ) ) { TRAC_ERR ( " " , value ) ; rc = AVSBUS_ERROR ; } } } if ( l_failure ) { enum occExtReasonCode exrc = ERC_AVSBUS_VDD_VOLTAGE_FAILURE ; if ( AVSBUS_VDD == i_type ) { if ( i_cmdtype == AVSBUS_CURRENT ) { exrc = ERC_AVSBUS_VDD_CURRENT_FAILURE ; INCREMENT_ERR_HISTORY ( ERRH_AVSBUS_VDD_CURRENT ) ; } else if ( i_cmdtype == AVSBUS_VOLTAGE ) { INCREMENT_ERR_HISTORY ( ERRH_AVSBUS_VDD_VOLTAGE ) ; } else if ( i_cmdtype == AVSBUS_TEMPERATURE ) { exrc = ERC_AVSBUS_VDD_TEMPERATURE_FAILURE ; INCREMENT_ERR_HISTORY ( ERRH_AVSBUS_VDD_TEMPERATURE ) ; } } else { if ( i_cmdtype == AVSBUS_CURRENT ) { exrc = ERC_AVSBUS_VDN_CURRENT_FAILURE ; INCREMENT_ERR_HISTORY ( ERRH_AVSBUS_VDN_CURRENT ) ; } else if ( i_cmdtype == AVSBUS_VOLTAGE ) { exrc = ERC_AVSBUS_VDN_VOLTAGE_FAILURE ; INCREMENT_ERR_HISTORY ( ERRH_AVSBUS_VDN_VOLTAGE ) ; } } if ( * l_error_count == MAX_READ_ATTEMPTS ) { TRAC_ERR ( " " , * l_error_count , l_trace_type , l_trace_cmd ) ; G_avsbus_vdd_monitoring = FALSE ; G_avsbus_vdn_monitoring = FALSE ; errlHndl_t l_err = createErrl ( PSS_MID_AVSBUS_READ , rc , exrc , ERRL_SEV_PREDICTIVE , NULL , DEFAULT_TRACE_SIZE , ( i_type << 16 ) | ( l_data . bus << 8 ) | l_data . rail , l_status ) ; addCalloutToErrl ( l_err , ERRL_CALLOUT_TYPE_HUID , G_sysConfigData . proc_huid , ERRL_CALLOUT_PRIORITY_MED ) ; REQUEST_RESET ( l_err ) ; } else { avsbus_resync ( l_data . bus ) ; } } #ifdef AVSDEBUG ++ * l_trace_count ; #endif return o_reading ; }
Read and return the voltage, current, or temperature for specified rail
(voltage units are mV, current units are in 10mA, temperature in 0.1 C)
Read and return the voltage current or temperature for specified rail ( voltage units are mV current units are in 10mA temperature in 0 . 1 C )
// No need to process data if OCC will be reset // Static error counters for each type (Vdd/Vdn) and command (Voltage/Current) // HW: Wait for bus op to complete // HW: arbitration between two bridges // HW: o2s_ongoing: 0 -> 1 // HW: execution completes // HW: o2s_ongoing 1 -> 0 // Since read was started in previous tick, it should have already completed // (no need to poll/wait on o2s_ongoing) // OCC O2S Status Register //   0     o2s_ongoing //   1:4   reserved //   5     write_while_bridge_busy_error //   6     reserved //   7     FSM error //   8:63  reserved // GrrrrBrF rrrrrrrr rrrrrrrr rrrrrrrr // error bit was set /*
             * @errortype
             * @moduleid    PSS_MID_AVSBUS_READ
             * @reasoncode  AVSBUS_ERROR
             * @userdata1   AVS Bus type/bus/rail
             * @userdata2   status
             * @devdesc     Error encountered when reading AVS Bus
             */ // o2s_ongoing // o2s_ongoing bit was still set (operation did not complete) /*
             * @errortype
             * @moduleid    PSS_MID_AVSBUS_READ
             * @reasoncode  AVSBUS_TIMEOUT
             * @userdata1   AVS Bus type/bus/rail
             * @userdata2   status
             * @devdesc     Timeout when reading AVS Bus
             */ // Read the response data // AVS Bus response (read voltage, current, or temperature): //   0:1   SlaveAck (0b00 from slave indicates good CRC and action was taken) //   2     0 //   3:7   StatusResp //   8:23  CmdData (LSB = 1mV or 10mA or 0.1C) //   24:28 Reserved (must be all 1s) //   29:31 CRC //   AA0SSSSS VVVVVVVV VVVVVVVV 11111CCC // Validate CRC /*
                 * @errortype
                 * @moduleid    PSS_MID_AVSBUS_READ
                 * @reasoncode  AVSBUS_CRC_ERROR
                 * @userdata1   AVS Bus type/bus/rail
                 * @userdata2   status
                 * @devdesc     CRC error reading AVS Bus
                 */ // Check for valid command operation and extract read data // Update sensor (convert to degrees C) and validate it // Trace and clear the error count // add processor callout and request reset // Force a re-sync after any failure