src/occ_405/proc/proc_pstate.c
// Function Specification
//
// Name: check_for_opal_updates
//
// Description: Checks if any of the dynamic fields in the opal shared memory
//              needs to be updated and updates if necessary.
//
// End Function Specification
Function Specification
Name: check_for_opal_updates

Checks if any of the dynamic fields in the opal shared memory
needs to be updated and updates if necessary.

End Function Specification
Function Specification Name : check_for_opal_updates Checks if any of the dynamic fields in the opal shared memory needs to be updated and updates if necessary . End Function Specification
void check_for_opal_updates(void)
{
    bool           dynamic_data_change = false;
    bool           l_log_crit_error = false;
    static uint8_t L_num_bce_checks = 0;
    static bool    L_first_throttle_trace = true;
    static bool    L_first_unthrottle_trace = true;
    static bool    L_first_mem_trace = true;
    if(G_opal_table_update_state == OPAL_TABLE_UPDATE_NOTIFY_HOST)
    {
         G_opal_table_update_state = OPAL_TABLE_UPDATE_IDLE;
         if(G_sysConfigData.system_type.kvm)  
         {
              notify_host(INTR_REASON_OPAL_SHARED_MEM_CHANGE);
         }
    }
    else if( (G_opal_table_update_state == OPAL_TABLE_UPDATE_DYNAMIC_COPY) ||
             (G_opal_dynamic_bce_req_scheduled && !(async_request_is_idle(&G_opal_dynamic_bce_req.request))) )
    {
         if(L_num_bce_checks <= OPAL_DYNAMIC_UPDATE_BCE_RETRIES)
         {
             L_num_bce_checks++;
         }
         else
         {
             TRAC_ERR("check_for_opal_updates: BCE not idle %u times, done retrying", L_num_bce_checks);
             l_log_crit_error = true;
         }
    }
    else if(G_opal_table_update_state == OPAL_TABLE_UPDATE_BCE_FAIL)
    {
         if(L_num_bce_checks <= OPAL_DYNAMIC_UPDATE_BCE_RETRIES)
         {
             dynamic_data_change = true;
         }
         else
         {
             TRAC_ERR("check_for_opal_updates: BCE failed %u times, done retrying", L_num_bce_checks);
             l_log_crit_error = true;
         }
    }
    else  
    {
        if( isSafeStateRequested() )
        {
            if(G_opal_dynamic_table.dynamic.proc_throt_status != OCC_RESET)
            {
                dynamic_data_change = true;
                TRAC_INFO("check_for_opal_updates: safe state processor throttle status change - 0x%02X->0x%02X",
                           G_opal_dynamic_table.dynamic.proc_throt_status, G_amec_opal_proc_throt_reason);
            }
        }
        else if(G_opal_dynamic_table.dynamic.proc_throt_status != G_amec_opal_proc_throt_reason)
        {
            dynamic_data_change = true;
            bool l_trace = false;
            if( (G_allow_trace_flags & ALLOW_OPAL_TRACE) ||
                (L_first_throttle_trace) )
            {
                l_trace = true;
                L_first_throttle_trace = false;
            }
            else if( (G_amec_opal_proc_throt_reason == 0) &&
                     (L_first_unthrottle_trace) )
            {
                    l_trace = true;
                    L_first_unthrottle_trace = false;
            }
            if(l_trace)
            {
                TRAC_INFO("check_for_opal_updates: "
                        "processor throttle status change - 0x%02X->0x%02X",
                        G_opal_dynamic_table.dynamic.proc_throt_status,
                        G_amec_opal_proc_throt_reason);
            }
        }
        if( (G_opal_dynamic_table.dynamic.mem_throt_status != G_amec_opal_mem_throt_reason) ||
            (G_opal_dynamic_table.dynamic.quick_power_drop != AMEC_INTF_GET_OVERSUBSCRIPTION()) )
        {
            dynamic_data_change = true;
            if( (G_allow_trace_flags & ALLOW_OPAL_TRACE  ) ||
                (L_first_mem_trace) ||
                (G_opal_dynamic_table.dynamic.quick_power_drop !=
                 AMEC_INTF_GET_OVERSUBSCRIPTION()) )
            {
               TRAC_INFO("check_for_opal_updates:"
                       " memory throttle status - 0x%02X->0x%02X"
                       " QPD - 0x%02X->0x%02X",
                       G_opal_dynamic_table.dynamic.mem_throt_status,
                       G_amec_opal_mem_throt_reason,
                       G_opal_dynamic_table.dynamic.quick_power_drop,
                       AMEC_INTF_GET_OVERSUBSCRIPTION());
                L_first_mem_trace = false;
            }
        }
        if(G_opal_dynamic_table.dynamic.occ_state != CURRENT_STATE())
        {
            dynamic_data_change = true;
            TRAC_INFO("check_for_opal_updates: OCC state change 0x%02X->0x%02X",
                       G_opal_dynamic_table.dynamic.occ_state, CURRENT_STATE());
        }
        if( (G_opal_dynamic_table.dynamic.min_power_cap      != G_sysConfigData.pcap.hard_min_pcap) ||
            (G_opal_dynamic_table.dynamic.max_power_cap      != G_sysConfigData.pcap.max_pcap)      ||
            (G_opal_dynamic_table.dynamic.soft_min_power_cap != G_sysConfigData.pcap.soft_min_pcap) ||
            (G_opal_dynamic_table.dynamic.power_shift_ratio  != G_sysConfigData.psr)                ||
            (G_opal_dynamic_table.dynamic.power_cap_type     != G_sysConfigData.pcap.source)        ||
            (G_opal_dynamic_table.dynamic.current_power_cap  != g_amec->pcap.active_node_pcap) )
        {
            dynamic_data_change = true;
            TRAC_INFO("check_for_opal_updates: soft min Pcap = 0x%04X->0x%04X hard min Pcap = 0x%04X->0x%04X",
                       G_opal_dynamic_table.dynamic.soft_min_power_cap, G_sysConfigData.pcap.soft_min_pcap,
                       G_opal_dynamic_table.dynamic.min_power_cap, G_sysConfigData.pcap.hard_min_pcap);
            TRAC_INFO("check_for_opal_updates: max Pcap = 0x%04X->0x%04X active Pcap = 0x%04X->0x%04X",
                       G_opal_dynamic_table.dynamic.max_power_cap, G_sysConfigData.pcap.max_pcap,
                       G_opal_dynamic_table.dynamic.current_power_cap, g_amec->pcap.active_node_pcap);
            TRAC_INFO("check_for_opal_updates: Pcap PSR = %u->%u Pcap source = %u->%u",
                       G_opal_dynamic_table.dynamic.power_shift_ratio, G_sysConfigData.psr,
                       G_opal_dynamic_table.dynamic.power_cap_type, G_sysConfigData.pcap.source);
        }
        if( (G_opal_dynamic_table.dynamic.dynamic_minor_version != DYNAMIC_MINOR_V_GPU_PRESENCE) &&
            (G_gpu_config_done) )
        {
            dynamic_data_change = true;
            TRAC_INFO("check_for_opal_updates: GPU presence determined = 0x%04X",
                       G_first_proc_gpu_config);
        }
    }  
    if(dynamic_data_change)
    {
        G_opal_table_update_state = OPAL_TABLE_UPDATE_DYNAMIC_COPY;
        update_dynamic_opal_data();
        if(G_opal_table_update_state == OPAL_TABLE_UPDATE_IDLE)
        {
            G_opal_table_update_state = OPAL_TABLE_UPDATE_BCE_FAIL;
            L_num_bce_checks++;
        }
        else
        {
            L_num_bce_checks = 0;
        }
    }
    else if(l_log_crit_error)
    {
         G_opal_table_update_state = OPAL_TABLE_UPDATE_CRITICAL_ERROR;
         if(G_sysConfigData.system_type.kvm)
         {
             errlHndl_t l_errl = createErrl(PROC_CHECK_FOR_OPAL_UPDATES_MOD, 
                                            OPAL_TABLE_UPDATE_ERROR,         
                                            ERC_GENERIC_TIMEOUT,             
                                            ERRL_SEV_UNRECOVERABLE,          
                                            NULL,                            
                                            DEFAULT_TRACE_SIZE,              
                                            0,                               
                                            0);                              
            addCalloutToErrl(l_errl,
                             ERRL_CALLOUT_TYPE_COMPONENT_ID,
                             ERRL_COMPONENT_ID_FIRMWARE,
                             ERRL_CALLOUT_PRIORITY_HIGH);
            addCalloutToErrl(l_errl,
                             ERRL_CALLOUT_TYPE_HUID,
                             G_sysConfigData.proc_huid,
                             ERRL_CALLOUT_PRIORITY_MED);
             commitErrl(&l_errl);
         }
    }
}
void check_for_opal_updates ( void ) { bool dynamic_data_change = false ; bool l_log_crit_error = false ; static uint8_t L_num_bce_checks = 0 ; static bool L_first_throttle_trace = true ; static bool L_first_unthrottle_trace = true ; static bool L_first_mem_trace = true ; if ( G_opal_table_update_state == OPAL_TABLE_UPDATE_NOTIFY_HOST ) { G_opal_table_update_state = OPAL_TABLE_UPDATE_IDLE ; if ( G_sysConfigData . system_type . kvm ) { notify_host ( INTR_REASON_OPAL_SHARED_MEM_CHANGE ) ; } } else if ( ( G_opal_table_update_state == OPAL_TABLE_UPDATE_DYNAMIC_COPY ) || ( G_opal_dynamic_bce_req_scheduled && ! ( async_request_is_idle ( & G_opal_dynamic_bce_req . request ) ) ) ) { if ( L_num_bce_checks <= OPAL_DYNAMIC_UPDATE_BCE_RETRIES ) { L_num_bce_checks ++ ; } else { TRAC_ERR ( " " , L_num_bce_checks ) ; l_log_crit_error = true ; } } else if ( G_opal_table_update_state == OPAL_TABLE_UPDATE_BCE_FAIL ) { if ( L_num_bce_checks <= OPAL_DYNAMIC_UPDATE_BCE_RETRIES ) { dynamic_data_change = true ; } else { TRAC_ERR ( " " , L_num_bce_checks ) ; l_log_crit_error = true ; } } else { if ( isSafeStateRequested ( ) ) { if ( G_opal_dynamic_table . dynamic . proc_throt_status != OCC_RESET ) { dynamic_data_change = true ; TRAC_INFO ( " " , G_opal_dynamic_table . dynamic . proc_throt_status , G_amec_opal_proc_throt_reason ) ; } } else if ( G_opal_dynamic_table . dynamic . proc_throt_status != G_amec_opal_proc_throt_reason ) { dynamic_data_change = true ; bool l_trace = false ; if ( ( G_allow_trace_flags & ALLOW_OPAL_TRACE ) || ( L_first_throttle_trace ) ) { l_trace = true ; L_first_throttle_trace = false ; } else if ( ( G_amec_opal_proc_throt_reason == 0 ) && ( L_first_unthrottle_trace ) ) { l_trace = true ; L_first_unthrottle_trace = false ; } if ( l_trace ) { TRAC_INFO ( " " " " , G_opal_dynamic_table . dynamic . proc_throt_status , G_amec_opal_proc_throt_reason ) ; } } if ( ( G_opal_dynamic_table . dynamic . mem_throt_status != G_amec_opal_mem_throt_reason ) || ( G_opal_dynamic_table . dynamic . quick_power_drop != AMEC_INTF_GET_OVERSUBSCRIPTION ( ) ) ) { dynamic_data_change = true ; if ( ( G_allow_trace_flags & ALLOW_OPAL_TRACE ) || ( L_first_mem_trace ) || ( G_opal_dynamic_table . dynamic . quick_power_drop != AMEC_INTF_GET_OVERSUBSCRIPTION ( ) ) ) { TRAC_INFO ( " " " " " " , G_opal_dynamic_table . dynamic . mem_throt_status , G_amec_opal_mem_throt_reason , G_opal_dynamic_table . dynamic . quick_power_drop , AMEC_INTF_GET_OVERSUBSCRIPTION ( ) ) ; L_first_mem_trace = false ; } } if ( G_opal_dynamic_table . dynamic . occ_state != CURRENT_STATE ( ) ) { dynamic_data_change = true ; TRAC_INFO ( " " , G_opal_dynamic_table . dynamic . occ_state , CURRENT_STATE ( ) ) ; } if ( ( G_opal_dynamic_table . dynamic . min_power_cap != G_sysConfigData . pcap . hard_min_pcap ) || ( G_opal_dynamic_table . dynamic . max_power_cap != G_sysConfigData . pcap . max_pcap ) || ( G_opal_dynamic_table . dynamic . soft_min_power_cap != G_sysConfigData . pcap . soft_min_pcap ) || ( G_opal_dynamic_table . dynamic . power_shift_ratio != G_sysConfigData . psr ) || ( G_opal_dynamic_table . dynamic . power_cap_type != G_sysConfigData . pcap . source ) || ( G_opal_dynamic_table . dynamic . current_power_cap != g_amec -> pcap . active_node_pcap ) ) { dynamic_data_change = true ; TRAC_INFO ( " " , G_opal_dynamic_table . dynamic . soft_min_power_cap , G_sysConfigData . pcap . soft_min_pcap , G_opal_dynamic_table . dynamic . min_power_cap , G_sysConfigData . pcap . hard_min_pcap ) ; TRAC_INFO ( " " , G_opal_dynamic_table . dynamic . max_power_cap , G_sysConfigData . pcap . max_pcap , G_opal_dynamic_table . dynamic . current_power_cap , g_amec -> pcap . active_node_pcap ) ; TRAC_INFO ( " " , G_opal_dynamic_table . dynamic . power_shift_ratio , G_sysConfigData . psr , G_opal_dynamic_table . dynamic . power_cap_type , G_sysConfigData . pcap . source ) ; } if ( ( G_opal_dynamic_table . dynamic . dynamic_minor_version != DYNAMIC_MINOR_V_GPU_PRESENCE ) && ( G_gpu_config_done ) ) { dynamic_data_change = true ; TRAC_INFO ( " " , G_first_proc_gpu_config ) ; } } if ( dynamic_data_change ) { G_opal_table_update_state = OPAL_TABLE_UPDATE_DYNAMIC_COPY ; update_dynamic_opal_data ( ) ; if ( G_opal_table_update_state == OPAL_TABLE_UPDATE_IDLE ) { G_opal_table_update_state = OPAL_TABLE_UPDATE_BCE_FAIL ; L_num_bce_checks ++ ; } else { L_num_bce_checks = 0 ; } } else if ( l_log_crit_error ) { G_opal_table_update_state = OPAL_TABLE_UPDATE_CRITICAL_ERROR ; if ( G_sysConfigData . system_type . kvm ) { errlHndl_t l_errl = createErrl ( PROC_CHECK_FOR_OPAL_UPDATES_MOD , OPAL_TABLE_UPDATE_ERROR , ERC_GENERIC_TIMEOUT , ERRL_SEV_UNRECOVERABLE , NULL , DEFAULT_TRACE_SIZE , 0 , 0 ) ; addCalloutToErrl ( l_errl , ERRL_CALLOUT_TYPE_COMPONENT_ID , ERRL_COMPONENT_ID_FIRMWARE , ERRL_CALLOUT_PRIORITY_HIGH ) ; addCalloutToErrl ( l_errl , ERRL_CALLOUT_TYPE_HUID , G_sysConfigData . proc_huid , ERRL_CALLOUT_PRIORITY_MED ) ; commitErrl ( & l_errl ) ; } } }
Function Specification
Name: check_for_opal_updates
Function Specification Name : check_for_opal_updates
// check if BCE for previous change finished and now need to notify host // regardless of if we notify host we are done with this change // only notify if OPAL // check if previous change is not complete // BCE failed re-populate the data and retry the BCE if under retry count // check if any of the data changed // check if processor throttle status changed if going to safe state check for reset status // else just check for any change since not in safe state // Only want to trace the first time we throttle, and the first // time we unthrottle. If ALLOW_OPAL_TRACE is set, trace every time // check if memory throttle status or Quick Power Drop changed // check for OCC state change // check for change in power cap data must look at slave copy // do NOT use G_master_pcap_data as that is not populated on slaves // check if GPU presence was determined // else check for changes // If there was a change copy to main memory and notify host when BCE finishes // if the BCE schedule fails the state will go back to IDLE, retry next time called // stop trying to update dynamic data, this only really matters on OPAL systems so // only log the error if OPAL // Create and commit error /* @
              * @errortype
              * @moduleid    PROC_CHECK_FOR_OPAL_UPDATES_MOD
              * @reasoncode  OPAL_TABLE_UPDATE_ERROR
              * @userdata1   0
              * @userdata2   0
              * @userdata4   ERC_GENERIC_TIMEOUT
              * @devdesc     BCE request failure to update dynamic opal table
              */ // Module ID // Reason code // Extended reason code // Severity // Trace Buffers // Trace Size // Userdata1 // Userdata2 // Callout firmware // Callout processor