From 919b78927d26c079ac3234128e09c548920f3487 Mon Sep 17 00:00:00 2001 From: mbroyles Date: Thu, 8 Feb 2018 16:47:04 -0600 Subject: Characterization state meltbox support Prevent temperature timeout errors during state transition Misc state characterization and observation state change fixes Change-Id: Ideeaab96689b145ed960aef5743b8c3947e4ffeb Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/53674 Tested-by: FSP CI Jenkins Reviewed-by: Andres A. Lugo-Reyes Reviewed-by: Christopher J. Cain --- src/occ_405/cmdh/cmdh_fsp_cmds.c | 3 + src/occ_405/dcom/dcom_thread.c | 6 + src/occ_405/main.c | 14 +- src/occ_405/pgpe/pgpe_interface.c | 32 +-- src/occ_405/proc/proc_data_control.c | 67 +---- src/occ_405/proc/proc_pstate.c | 5 +- src/occ_405/state.c | 510 +++++++++++++++++------------------ src/occ_405/wof/wof.c | 2 +- 8 files changed, 300 insertions(+), 339 deletions(-) diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.c b/src/occ_405/cmdh/cmdh_fsp_cmds.c index c1f29cf..326190b 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds.c @@ -56,6 +56,7 @@ extern dimm_sensor_flags_t G_dimm_temp_expired_bitmap; extern bool G_vrm_thermal_monitoring; extern uint32_t G_first_proc_gpu_config; extern bool G_vrm_vdd_temp_expired; +extern bool G_reset_prep; #include @@ -834,6 +835,8 @@ errlHndl_t cmdh_reset_prep (const cmdh_fsp_cmd_t * i_cmd_ptr, TRAC_IMP("cmdh_reset_prep: Prep for reset command received! reason[0x%.2X]", l_cmd_ptr->reason); + G_reset_prep = true; + // Command Handling switch( l_cmd_ptr->reason ) { diff --git a/src/occ_405/dcom/dcom_thread.c b/src/occ_405/dcom/dcom_thread.c index 2b9dcb7..43ad4a4 100755 --- a/src/occ_405/dcom/dcom_thread.c +++ b/src/occ_405/dcom/dcom_thread.c @@ -38,6 +38,9 @@ #include #include +// Reset Prep command received from (H)TMGT? +bool G_reset_prep = false; + // Debug Counter to make sure dcom thread is running uint16_t G_dcom_thread_counter = 0; @@ -127,6 +130,9 @@ void Dcom_thread_routine(void *arg) // Override State if we are in SAFE state already l_newOccState = ( OCC_STATE_SAFE == CURRENT_STATE() ) ? OCC_STATE_NOCHANGE : l_newOccState; + // Don't allow state change if reset prep was recieved + l_newOccState = G_reset_prep ? OCC_STATE_NOCHANGE : l_newOccState; + if( (OCC_STATE_NOCHANGE != l_newOccState) || (OCC_MODE_NOCHANGE != l_newOccMode) ) { diff --git a/src/occ_405/main.c b/src/occ_405/main.c index 3ab97cd..a871e26 100755 --- a/src/occ_405/main.c +++ b/src/occ_405/main.c @@ -73,7 +73,7 @@ extern uint32_t G_occ_phantom_critical_count; extern uint32_t G_occ_phantom_noncritical_count; extern uint8_t G_occ_interrupt_type; extern uint8_t G_occ_role; -extern pstateStatus G_proc_pstate_status; +extern volatile pstateStatus G_proc_pstate_status; extern GpeRequest G_meas_start_request; extern GpeRequest G_meas_cont_request; @@ -99,7 +99,7 @@ ppmr_header_t G_ppmr_header; // PPMR Header layout format pgpe_header_data_t G_pgpe_header; // Selected fields from PGPE Header OCCPstateParmBlock G_oppb; // OCC Pstate Parameters Block Structure extern uint16_t G_proc_fmax_mhz; // max(turbo,uturbo) frequencies -extern int G_ss_pgpe_rc; +extern volatile int G_ss_pgpe_rc; // Buffer to hold the wof header DMA_BUFFER(temp_bce_request_buffer_t G_temp_bce_buff) = {{0}}; @@ -1198,7 +1198,8 @@ void hmon_routine() //if we are in observation, characterization, or activate state, then monitor the processor //and VRM Vdd temperatures for timeout conditions - if( (IS_OCC_STATE_OBSERVATION() || IS_OCC_STATE_ACTIVE() || IS_OCC_STATE_CHARACTERIZATION()) && (!SMGR_is_state_transitioning()) ) + if( (IS_OCC_STATE_OBSERVATION() || IS_OCC_STATE_ACTIVE() || IS_OCC_STATE_CHARACTERIZATION()) && + (!SMGR_is_state_transitioning()) ) { amec_health_check_proc_timeout(); amec_health_check_vrm_vdd_temp_timeout(); @@ -1207,7 +1208,7 @@ void hmon_routine() //if we are in observation, characterization, or active state with memory temperature data // being collected then monitor the temperature collections for overtemp and timeout conditions if( (IS_OCC_STATE_OBSERVATION() || IS_OCC_STATE_ACTIVE() || IS_OCC_STATE_CHARACTERIZATION()) && - (rtl_task_is_runnable(TASK_ID_DIMM_SM)) && (!SMGR_is_state_transitioning()) ) + (rtl_task_is_runnable(TASK_ID_DIMM_SM)) && (!SMGR_is_state_transitioning()) ) { // For Cumulus systems only, check for centaur timeout and overtemp errors if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type) @@ -1491,7 +1492,6 @@ void Main_thread_routine(void *private) if (G_simics_environment) { - extern pstateStatus G_proc_pstate_status; // TEMP Hack to enable Active State, until PGPE is ready G_proc_pstate_status = PSTATES_ENABLED; @@ -1702,8 +1702,10 @@ void Main_thread_routine(void *private) if( (G_proc_pstate_status == PSTATES_FAILED) && (FALSE == isSafeStateRequested()) && (CURRENT_STATE() != OCC_STATE_SAFE) && - (CURRENT_STATE() != OCC_STATE_STANDBY) ) + (CURRENT_STATE() != OCC_STATE_STANDBY) && + (!SMGR_is_state_transitioning()) ) { + MAIN_TRAC_ERR("Pstate start/suspend command failed PGPE RC[0x%04X]", G_ss_pgpe_rc); /* @ * @errortype * @moduleid MAIN_THRD_ROUTINE_MID diff --git a/src/occ_405/pgpe/pgpe_interface.c b/src/occ_405/pgpe/pgpe_interface.c index 991f6cf..625978d 100644 --- a/src/occ_405/pgpe/pgpe_interface.c +++ b/src/occ_405/pgpe/pgpe_interface.c @@ -43,8 +43,9 @@ // Maximum waiting time (usec) for clip update IPC task #define CLIP_UPDATE_TIMEOUT 100 // maximum waiting time (usec) for clip update IPC task -extern pstateStatus G_proc_pstate_status; -extern PMCR_OWNER G_proc_pmcr_owner; +extern volatile pstateStatus G_proc_pstate_status; +extern volatile PMCR_OWNER G_proc_pmcr_owner; +extern volatile bool G_set_pStates; extern uint16_t G_proc_fmax_mhz; extern uint32_t G_present_cores; @@ -66,8 +67,8 @@ GPE_BUFFER(ipcmsg_start_stop_t G_start_suspend_parms); GPE_BUFFER(ipcmsg_wof_control_t G_wof_control_parms); GPE_BUFFER(ipcmsg_wof_vfrt_t G_wof_vfrt_parms); -// Used to track failure of start_suspend callback -int G_ss_pgpe_rc; // pgpe return codes +// Used to track PGPE return code of start_suspend callback +volatile int G_ss_pgpe_rc = PGPE_RC_SUCCESS; // Function Specification @@ -644,9 +645,10 @@ int pgpe_clip_update(void) G_clip_update_parms.ps_val_clip_max[quad] = G_desired_pstate[quad]; } - - if (pstate_list != L_last_list) + // Always send request on PowerVM, on OPAL only send the request if there was a change or need to force a send + if( (pstate_list != L_last_list) || (!G_sysConfigData.system_type.kvm) || (G_set_pStates) ) { + G_set_pStates = FALSE; if (L_first_trace) { TRAC_IMP("pgpe_clip_update: Scheduling clip update: min[0x%02X], max[0x%08X%04X]", @@ -654,20 +656,18 @@ int pgpe_clip_update(void) WORD_HIGH(pstate_list), WORD_LOW(pstate_list)>>16); L_first_trace = FALSE; } - else + // always trace change on PowerVM since setting clips is very rare with PowerVM which uses PMCR set + else if( (G_allow_trace_flags & ALLOW_CLIP_TRACE) || (!G_sysConfigData.system_type.kvm) ) { - if(G_allow_trace_flags & ALLOW_CLIP_TRACE) - { - TRAC_INFO("pgpe_clip_update: Scheduling clip update: min[0x%02X], max[0x%08X%04X]", - G_clip_update_parms.ps_val_clip_min[0], - WORD_HIGH(pstate_list), WORD_LOW(pstate_list)>>16); - } + TRAC_INFO("pgpe_clip_update: Scheduling clip update: min[0x%02X], max[0x%08X%04X]", + G_clip_update_parms.ps_val_clip_min[0], + WORD_HIGH(pstate_list), WORD_LOW(pstate_list)>>16); } L_last_list = pstate_list; - } - // Schedule PGPE clip update IPC task - schedule_rc = pgpe_request_schedule(&G_clip_update_req); + // Schedule PGPE clip update IPC task + schedule_rc = pgpe_request_schedule(&G_clip_update_req); + } } else { diff --git a/src/occ_405/proc/proc_data_control.c b/src/occ_405/proc/proc_data_control.c index 2b793d0..df79096 100755 --- a/src/occ_405/proc/proc_data_control.c +++ b/src/occ_405/proc/proc_data_control.c @@ -54,13 +54,11 @@ extern GpeRequest G_pmcr_set_req; // this must give the PGPE at least 1ms, doubling that time to 2ms to be safe #define SUPPRESS_PGPE_ERR_WAIT_TICKS 4 // 2ms -extern bool G_state_transition_occuring; // A state transition is currently going on? - +// A state transition is currently going on? +extern volatile bool G_state_transition_occuring; +// Need to send Pstates even if they didn't "change"? +extern volatile bool G_set_pStates; extern uint16_t G_allow_trace_flags; -// a global flag used by task_core_data_control() to indicate -// that the OCC is ready to transition to observation state -// (after initiatibg a clip update IPC task if needed) -bool G_active_to_observation_ready = false; // Only allow pstates after mode change. bool G_allowPstates = FALSE; @@ -77,7 +75,6 @@ void task_core_data_control( task_t * i_task ) errlHndl_t err = NULL; //Error handler static bool L_trace_logged = false; // trace logging to avoid unnecessarily repeating logs static bool L_current_timeout_recorded = FALSE; - Pstate l_pstate; static uint64_t L_last = 0xFFFFFFFFFFFFFFFF; static uint64_t L_ignore_wait_count = 0; // number of consecutive ticks IPC task failed bool l_check_failure = false; @@ -91,54 +88,13 @@ void task_core_data_control( task_t * i_task ) // with the task_core_data_control IPC tasks. if(G_state_transition_occuring) { + L_ignore_wait_count = 0; + L_current_timeout_recorded = FALSE; if(L_trace_logged == false) { TRAC_INFO("task_core_data_control: Pstate Control stopped because a state transition started."); L_trace_logged = true; } - - // Only Transitioning to Observation state necessitates clip update - // (if the last clip update was higher than legacy turbo). - if ((G_occ_master_state == OCC_STATE_OBSERVATION) && - !G_active_to_observation_ready) - { - // confirm that the last clip update IPC successfully completed on PGPE (with no errors) - if( async_request_is_idle(&G_clip_update_req.request) && //clip_update/set_clip_ranges completed - (G_clip_update_parms.msg_cb.rc == PGPE_RC_SUCCESS) ) // with no errors - { - uint8_t quad = 0; - Pstate pclip = 0xff; // Initialize pclip to 0xff (lowest possible frequency) - - // Only if last clip update sent to PGPE is larger than legacy turbo, - // send new clips with legacy turbo values, otherwise, no action needed. - for (quad = 0; quad < MAXIMUM_QUADS; quad++) - { - if(G_clip_update_parms.ps_val_clip_max[quad] < pclip) - { - // minimum pclip value corresponds to pstate of maximum frequency - pclip = G_clip_update_parms.ps_val_clip_max[quad]; - } - } - l_pstate = proc_freq2pstate(G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO]); - // pclip of highest quad frequency corresponds to a frequency higher than legacy turbo - if(pclip < l_pstate) - { - if( G_allow_trace_flags & ALLOW_CLIP_TRACE ) - { - TRAC_INFO("task_core_data_control: updating clip max to pstate 0x%02X (from 0x%02X)", l_pstate, pclip); - } - // set the all quads to same pstate - memset(G_desired_pstate, l_pstate, MAXIMUM_QUADS); - //call PGPE IPC function to update the clips - pgpe_clip_update(); - } - - //Whether clips have been lowered from frequencies higher than legacy turbo - //frequency, or already lower than turbo frequency, OCC is now ready to - //transition to Observation state. - G_active_to_observation_ready = true; - } - } } // if in state transition else { @@ -193,9 +149,12 @@ void task_core_data_control( task_t * i_task ) G_pmcr_set_parms.pmcr[quad] = ((uint64_t) G_desired_pstate[quad] << 48) | 1; } - // Only send pstates if they changed - if (L_last != pstateList) + // Only send pstates if they changed or first time after going active from char state + // in characterization state the user is writing the PMCR, need to make sure we write + // it back to desired Pstates + if( (L_last != pstateList) || (G_set_pStates) ) { + G_set_pStates = FALSE; L_last = pstateList; if( G_allow_trace_flags & ALLOW_PMCR_TRACE ) @@ -237,8 +196,8 @@ void task_core_data_control( task_t * i_task ) { if(!ignore_pgpe_error()) { - TRAC_ERR("task_core_data_control: pstate update IPC task did not complete successfully, idle?[%d] rc[%08X]", - l_request_is_idle, l_request_rc); + TRAC_ERR("task_core_data_control: pstate[0x%02X] update IPC task did not complete successfully, idle?[%d] rc[%08X]", + G_desired_pstate[0], l_request_is_idle, l_request_rc); err = createErrl( RTLS_TASK_CORE_DATA_CONTROL_MOD, //ModId diff --git a/src/occ_405/proc/proc_pstate.c b/src/occ_405/proc/proc_pstate.c index f78eb41..5f0cad7 100755 --- a/src/occ_405/proc/proc_pstate.c +++ b/src/occ_405/proc/proc_pstate.c @@ -61,11 +61,10 @@ uint8_t G_desired_pstate[MAXIMUM_QUADS]; // initialized to PSTATES_DISABLED, turns to PSTATES_ENABLED only after // the PGPE IPC that enable pstates completes successfully. While the IPC // task is still running, this variable be set to PSTATES_IN_TRANSITION -pstateStatus G_proc_pstate_status = PSTATES_DISABLED; - +volatile pstateStatus G_proc_pstate_status = PSTATES_DISABLED; // A Global parameter indicating the owner of the PMCR. -PMCR_OWNER G_proc_pmcr_owner = PMCR_OWNER_HOST; +volatile PMCR_OWNER G_proc_pmcr_owner = PMCR_OWNER_HOST; // OPAL Dynamic data, updated whenever any OCC G_opal_table.dynamic parameter change // Since this is happening multiple times need to keep track of it being scheduled diff --git a/src/occ_405/state.c b/src/occ_405/state.c index ea8219a..ca503e0 100755 --- a/src/occ_405/state.c +++ b/src/occ_405/state.c @@ -43,23 +43,20 @@ #include "wof.h" // Maximum time to wait for a PGPE task before timeout -// must wait at least 1 tick time to ensure proc_data_control() runs to set -// clips on active->obs state transition -#define WAIT_PGPE_TASK_TIMEOUT (MICS_PER_TICK + 20) +#define WAIT_PGPE_TASK_TIMEOUT (MICS_PER_TICK * 4) extern bool G_mem_monitoring_allowed; extern task_t G_task_table[TASK_END]; // Global task table extern bool G_simics_environment; -extern pstateStatus G_proc_pstate_status; +extern volatile pstateStatus G_proc_pstate_status; extern uint16_t G_proc_fmax_mhz; extern GpeRequest G_clip_update_req; extern GPE_BUFFER(ipcmsg_clip_update_t* G_clip_update_parms_ptr); +extern volatile int G_ss_pgpe_rc; -// OCC is ready to transition to observation state? -extern bool G_active_to_observation_ready; // bit mask of configured cores extern uint32_t G_present_cores; -extern PMCR_OWNER G_proc_pmcr_owner; +extern volatile PMCR_OWNER G_proc_pmcr_owner; // State that OCC is currently in OCC_STATE G_occ_internal_state = OCC_STATE_STANDBY; @@ -71,7 +68,10 @@ OCC_STATE G_occ_internal_req_state = OCC_STATE_NOCHANGE; OCC_STATE G_occ_external_req_state = OCC_STATE_NOCHANGE; // Indicates if we are currently in a state transition -bool G_state_transition_occuring = FALSE; +volatile bool G_state_transition_occuring = FALSE; + +// Indicates if we need to force sending Pstates on a state change +volatile bool G_set_pStates = FALSE; // State that OCC Master is requesting OCC_STATE G_occ_master_state = OCC_STATE_NOCHANGE; @@ -207,66 +207,92 @@ errlHndl_t SMGR_standby_to_characterization() errlHndl_t l_errlHndl = NULL; int rc = 0; static bool L_error_logged = FALSE; // To prevent trace and error log happened over and over - Pstate l_pstate; + do { - // characterization state will have Pstate protocol enabled check that all data for active - // is available (frequency points) - if( SMGR_MASK_ACTIVE_READY == - (SMGR_validate_get_valid_states() & SMGR_MASK_ACTIVE_READY)) + // Must be active ready if transitioning to characterization state + if( (SMGR_MASK_ACTIVE_READY != + (SMGR_validate_get_valid_states() & SMGR_MASK_ACTIVE_READY)) ) + { + TRAC_ERR("SMGR: failed to transition to characterization state " + "since OCC is not active ready."); + rc = INTERNAL_FAILURE; + break; + } + + L_error_logged = FALSE; + TRAC_IMP("SMGR: Standby to Characterization State Transition Started"); + + if(G_present_cores == 0) { - L_error_logged = FALSE; - TRAC_IMP("SMGR: Standby to Characterization State Transition Started"); + TRAC_IMP("SMGR_standby_to_characterization: No configured cores, skipping PGPE calls"); + break; + } - // set pstate clips - l_pstate = proc_freq2pstate(G_proc_fmax_mhz); - rc = pgpe_set_clip_blocking(l_pstate); + // set pstate clips to full range of max Pstate 0 to support meltbox + rc = pgpe_set_clip_blocking(0); + + if(rc) + { + TRAC_ERR("SMGR: failed to set pstate clips. rc[0x%08X] OCCFLG[0x%08X]", + rc, in32(OCB_OCCFLG)); + break; + } + else // successfully set clips; enable pstates + { + // Start pstates on PGPE and set Characterization as owner + rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_CHAR); if(rc) { - TRAC_ERR("SMGR: failed to set pstate clips. rc[0x%08X] OCCFLG[0x%08X]", - rc, in32(OCB_OCCFLG)); + TRAC_ERR("SMGR: failed to start the pstate protocol for char owner on PGPE. rc[0x%08X] OCCFLG[0x%08X]", + rc, in32(OCB_OCCFLG)); break; } - else // successfully set clips; enable pstates, then start transition + else // Request successfully scheduled on PGPE now verify it completed { - - // Start pstates on PGPE and set Characterization as owner - rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_CHAR); - - if(rc) - { - TRAC_ERR("SMGR: failed to start the pstate protocol for char owner on PGPE. rc[0x%08X] OCCFLG[0x%08X]", - rc, in32(OCB_OCCFLG)); - break; - } - else // Clips set and pstates started successfully, start transition - { - memory_init(); - - // Set the RTL Flags to indicate which tasks can run - // - Set OBSERVATION flags in Characterization State - rtl_clr_run_mask_deferred(RTL_FLAG_STANDBY); - rtl_set_run_mask_deferred(RTL_FLAG_OBS); - - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_CHARACTERIZATION; - - TRAC_IMP("SMGR: Standby to Characterization Transition Completed"); - } + // Wait for ownership change to complete + SsxTimebase start = ssx_timebase_get(); + SsxInterval timeout = SSX_SECONDS(5); + while( ! proc_is_hwpstate_enabled() ) + { + if ((ssx_timebase_get() - start) > timeout) + { + rc = 1; + TRAC_ERR("SMGR_standby_to_char: Timeout waiting for PMCR ownership change. rc[0x%08X] OCCFLG[0x%08X]", + rc, in32(OCB_OCCFLG)); + break; + } + ssx_sleep(SSX_MICROSECONDS(10)); + } } } } while (0); - if(l_errlHndl && (false == L_error_logged)) + if(!rc) + { + // Clips set and pstates started successfully (or no cores) finish the state change + memory_init(); + + // Set the RTL Flags to indicate which tasks can run + // - Set OBSERVATION flags in Characterization State + rtl_clr_run_mask_deferred(RTL_FLAG_STANDBY); + rtl_set_run_mask_deferred(RTL_FLAG_OBS); + + // Set the actual STATE now that we have finished everything else + CURRENT_STATE() = OCC_STATE_CHARACTERIZATION; + + TRAC_IMP("SMGR: Standby to Characterization Transition Completed"); + } + else if(false == L_error_logged) { L_error_logged = TRUE; - TRAC_ERR("SMGR: Standby to Characterization Transition Failed due to not ACTIVE_READY"); + TRAC_ERR("SMGR: Standby to Characterization Transition Failed"); /* @ * @errortype * @moduleid MAIN_STATE_TRANSITION_MID * @reasoncode INTERNAL_FAILURE - * @userdata1 none + * @userdata1 rc * @userdata4 ERC_STATE_FROM_STB_TO_CHR_FAILURE * @devdesc Failed changing from standby to characterization */ @@ -276,7 +302,7 @@ errlHndl_t SMGR_standby_to_characterization() ERRL_SEV_UNRECOVERABLE, //Severity NULL, //Trace Buf DEFAULT_TRACE_SIZE, //Trace Size - 0, //userdata1 + rc, //userdata1 0); //userdata2 // Callout firmware @@ -299,7 +325,7 @@ errlHndl_t SMGR_standby_to_characterization() // End Function Specification errlHndl_t SMGR_all_to_standby() { - uint8_t wait_time = 0; + uint32_t wait_time = 0; int rc; TRAC_IMP("SMGR: Transition from State (%d) to Standby Started", CURRENT_STATE()); @@ -371,6 +397,13 @@ errlHndl_t SMGR_characterization_to_observation() do { + if(G_present_cores == 0) + { + // no configured cores, skip all PGPE comm + TRAC_IMP("SMGR_characterization_to_observation: No configured cores, skipping PGPE calls"); + break; + } + // set clips to legacy turbo l_pstate = proc_freq2pstate(G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO]); rc = pgpe_set_clip_blocking(l_pstate); @@ -389,13 +422,6 @@ errlHndl_t SMGR_characterization_to_observation() rc, in32(OCB_OCCFLG)); break; } - else // Clips tightened successfully, and pstates disabled: perform transition - { - // No RTL Flag changes; only state change - CURRENT_STATE() = OCC_STATE_OBSERVATION; - - TRAC_IMP("SMGR: Characterization to Observation Transition Completed"); - } } } while (0); @@ -426,6 +452,13 @@ errlHndl_t SMGR_characterization_to_observation() ERRL_COMPONENT_ID_FIRMWARE, ERRL_CALLOUT_PRIORITY_HIGH); } + else // Clips set and pstates disabled (or no cores) + { + // No RTL Flag changes; only state change + CURRENT_STATE() = OCC_STATE_OBSERVATION; + + TRAC_IMP("SMGR: Characterization to Observation Transition Completed"); + } return l_errlHndl; } @@ -443,7 +476,6 @@ errlHndl_t SMGR_observation_to_characterization() int rc = 0; errlHndl_t l_errlHndl = NULL; static bool L_error_logged = FALSE; // To prevent trace and error logging over and over - Pstate l_pstate; TRAC_IMP("SMGR: Observation to Characterization Transition Started"); // no change in RTL flags, just turn-on pstate protocol, and set clips @@ -456,12 +488,19 @@ errlHndl_t SMGR_observation_to_characterization() { TRAC_ERR("SMGR: failed to transition to characterization state " "since OCC is not active ready."); + rc = INTERNAL_FAILURE; break; } - // set pstate clips - l_pstate = proc_freq2pstate(G_proc_fmax_mhz); - rc = pgpe_set_clip_blocking(l_pstate); + if(G_present_cores == 0) + { + // no configured cores, skip all PGPE comm + TRAC_IMP("SMGR_observation_to_characterization: No configured cores, skipping PGPE calls"); + break; + } + + // set pstate clips to full range of max Pstate 0 to support meltbox + rc = pgpe_set_clip_blocking(0); if(rc) { @@ -469,7 +508,7 @@ errlHndl_t SMGR_observation_to_characterization() rc, in32(OCB_OCCFLG)); break; } - else // successfully set clips; enable pstates, then start transition + else // successfully set clips; enable pstates with characterization as owner { // Start pstates on PGPE and set Characterization as owner rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_CHAR); @@ -480,17 +519,34 @@ errlHndl_t SMGR_observation_to_characterization() rc, in32(OCB_OCCFLG)); break; } - else // Clips set successfully and pstates enabled; complete transition + else // Request successfully scheduled on PGPE now verify it completed { - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_CHARACTERIZATION; - - TRAC_IMP("SMGR: Observation to Characterization Transition Completed"); + // Wait for ownership change to complete + SsxTimebase start = ssx_timebase_get(); + SsxInterval timeout = SSX_SECONDS(5); + while( ! proc_is_hwpstate_enabled() ) + { + if ((ssx_timebase_get() - start) > timeout) + { + rc = 1; + TRAC_ERR("SMGR_obs_to_char: Timeout waiting for PMCR ownership change. rc[0x%08X] OCCFLG[0x%08X]", + rc, in32(OCB_OCCFLG)); + break; + } + ssx_sleep(SSX_MICROSECONDS(10)); + } } } } while (0); - if(rc && (false == L_error_logged)) + if(!rc) + { + // Clips and PMCR owner set (or no cores) finish the state change + CURRENT_STATE() = OCC_STATE_CHARACTERIZATION; + + TRAC_IMP("SMGR: Observation to Characterization Transition Completed"); + } + else if(false == L_error_logged) { L_error_logged = TRUE; TRAC_ERR("SMGR: Observation to Characterization Transition Failed"); @@ -587,6 +643,8 @@ errlHndl_t SMGR_observation_to_active() } else // Clips set with no errors, enable Pstates on PGPE { + TRAC_IMP("SMGR_obs_to_active: Successfully set Pstate clip max[0x%02X]", l_pstate); + // Pstates are enabled via an IPC call to PGPE, which will set the // G_proc_pstate_status flag. PMCR owner is set based on system type. if(G_sysConfigData.system_type.kvm) @@ -686,17 +744,21 @@ errlHndl_t SMGR_observation_to_active() { TRAC_IMP("SMGR_obs_to_active: Pstates are enabled, continuing with state trans"); + // Pstates enabled, update OPAL static table in main memory with pState info + proc_pstate_kvm_setup(); + L_error_logged = FALSE; + // force a set of Pstates for first time going active, handle case where coming from + // characterization state where user was manually writing Pstates + G_set_pStates = TRUE; + // Set the RTL Flags to indicate which tasks can run // - Clear OBSERVATION b/c not in OBSERVATION State // - Set ACTIVE b/c we're in ACTIVE State rtl_clr_run_mask_deferred(RTL_FLAG_OBS); rtl_set_run_mask_deferred(RTL_FLAG_ACTIVE); - // Pstates enabled, update OPAL static table in main memory with pState info - proc_pstate_kvm_setup(); - // Set the actual STATE now that we have finished everything else CURRENT_STATE() = OCC_STATE_ACTIVE; TRAC_IMP("SMGR: Observation to Active Transition Completed. OCC role = %d", G_occ_role); @@ -772,105 +834,22 @@ errlHndl_t SMGR_observation_to_active() // End Function Specification errlHndl_t SMGR_characterization_to_active() { - int rc = 0; errlHndl_t l_errlHndl = NULL; - static bool L_error_logged = FALSE; // To prevent trace and error log happened over and over TRAC_IMP("SMGR: Characterization to Active Transition Started"); - do - { - // Clear STATE_CHANGE WOF disabled flag - set_clear_wof_disabled( CLEAR, WOF_RC_STATE_CHANGE ); - // change PMCR ownership via an IPC call to PGPE based on system type. - if(G_sysConfigData.system_type.kvm) - { - rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_HOST); - } - else - { - rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_OCC); - } - if(rc) - { - TRAC_ERR("SMGR_char_to_active: Failed to change PMCR ownership rc[0x%08X] OCCFLG[0x%08X]", - rc, in32(OCB_OCCFLG)); - break; - } - - // If there are no cores configured, do not wait for PSTATES to - // become enabled. - if(G_present_cores != 0) - { - // Wait for ownership change to complete - SsxTimebase start = ssx_timebase_get(); - SsxInterval timeout = SSX_SECONDS(5); - while( ! proc_is_hwpstate_enabled() ) - { - if ((ssx_timebase_get() - start) > timeout) - { - rc = 1; - TRAC_ERR("SMGR_char_to_active: Timeout waiting for PMCR ownership change. OCCFLG[0x%08X]", - in32(OCB_OCCFLG)); - break; - } - ssx_sleep(SSX_MICROSECONDS(10)); - } - - if(proc_is_hwpstate_enabled()) - { - L_error_logged = FALSE; - - // Set the RTL Flags to indicate which tasks can run - // - Clear OBSERVATION b/c not in CHARACTERIZATION State - // - Set ACTIVE b/c we're in ACTIVE State - rtl_clr_run_mask_deferred(RTL_FLAG_OBS); - rtl_set_run_mask_deferred(RTL_FLAG_ACTIVE); - - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_ACTIVE; - TRAC_IMP("SMGR: Characterization to Active Transition Completed"); - } - } - else // We have no cores configured - { - // Set rtl flags to indicate which tasks can run since - // we do not have to wait for pstates to be enabled - rtl_clr_run_mask_deferred(RTL_FLAG_OBS); - rtl_set_run_mask_deferred(RTL_FLAG_ACTIVE); - - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_ACTIVE; - TRAC_IMP("SMGR: Characterization to Active Transition Completed"); - } - } while (0); + // Characterization is really the same as observation state to the OCC, perform obs to active transition + // to move from char to active + l_errlHndl = SMGR_observation_to_active(); - if(rc && (false == L_error_logged)) + if(l_errlHndl) { - L_error_logged = TRUE; - /* @ - * @errortype - * @moduleid MAIN_STATE_TRANSITION_MID - * @reasoncode INTERNAL_FAILURE - * @userdata1 rc - * @userdata2 valid states - * @userdata4 ERC_STATE_FROM_CHR_TO_ACT_FAILURE - * @devdesc Failed changing from characterization to active - */ - l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId - INTERNAL_FAILURE, //reasoncode - ERC_STATE_FROM_CHR_TO_ACT_FAILURE, //Extended reason code - ERRL_SEV_UNRECOVERABLE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - rc, //userdata1 - SMGR_validate_get_valid_states()); //userdata2 + TRAC_ERR("SMGR: Characterization to Active Transition Failed"); + } - // Callout firmware - addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_COMPONENT_ID, - ERRL_COMPONENT_ID_FIRMWARE, - ERRL_CALLOUT_PRIORITY_HIGH); + else + { + TRAC_IMP("SMGR: Characterization to Active Transition Completed"); } return l_errlHndl; @@ -889,7 +868,8 @@ errlHndl_t SMGR_active_to_observation() int rc = 0; enum occExtReasonCode ext_rc = OCC_NO_EXTENDED_RC; errlHndl_t l_errlHndl = NULL; - uint8_t wait_time = 0; + uint32_t wait_time = 0; + Pstate l_pstate; TRAC_IMP("SMGR: Active to Observation Transition Started"); @@ -897,60 +877,37 @@ errlHndl_t SMGR_active_to_observation() { // Set STATE_CHANGE WOF disabled set_clear_wof_disabled( SET, WOF_RC_STATE_CHANGE ); - // wait until task_core_data_control() declares that - // OCC is ready to transition to Observation state - while(!G_active_to_observation_ready) - { - if(wait_time > WAIT_PGPE_TASK_TIMEOUT) - { - break; - } - // Sleep enables context switching. - ssx_sleep(SSX_MICROSECONDS(10)); - wait_time += 10; + if(G_present_cores == 0) + { + TRAC_IMP("SMGR_active_to_observation: No configured cores, skipping PGPE calls"); + break; } - // check for timeout while waiting for pgpe_start_suspend() IPC completion - if(wait_time > WAIT_PGPE_TASK_TIMEOUT) + // set clips to legacy turbo + l_pstate = proc_freq2pstate(G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO]); + rc = pgpe_set_clip_blocking(l_pstate); + if(rc) { - TRAC_ERR("SMGR_act_to_obs: Timeout waiting for G_active_to_observation_ready flag. OCCFLG[0x%08X]", - in32(OCB_OCCFLG)); - - /* @ - * @errortype - * @moduleid MAIN_STATE_TRANSITION_MID - * @reasoncode PGPE_FAILURE - * @userdata1 wait_time - * @userdata4 ERC_PGPE_ACTIVE_TO_OBSERVATION_TIMEOUT - * @devdesc timeout waiting for pstates start/suspend task - */ - ext_rc = ERC_PGPE_ACTIVE_TO_OBSERVATION_TIMEOUT; - rc = PGPE_FAILURE; + TRAC_ERR("SMGR_active_to_observation: failed to set pstate clip to legacy turbo rc[%08X] OCCFLG[0x%08X]", + rc, in32(OCB_OCCFLG)); break; } - wait_time = 0; - - // wait until clip update task is done - while(!async_request_is_idle(&G_clip_update_req.request)) + // make sure start_suspend task is idle + while( (G_proc_pstate_status == PSTATES_IN_TRANSITION) && + (wait_time < WAIT_PGPE_TASK_TIMEOUT) ) { - if(wait_time > WAIT_PGPE_TASK_TIMEOUT) - { - break; - } - - // wait until pgpe_start_suspend call is completed. - // Sleep enables context switching. + // wait until pgpe_start_suspend call is completed. Sleep enables context switching. ssx_sleep(SSX_MICROSECONDS(10)); wait_time += 10; } - // check for timeout while waiting for Pstate clips IPC completion + // check for timeout while waiting for pgpe_start_suspend() IPC completion if(wait_time > WAIT_PGPE_TASK_TIMEOUT) { - TRAC_ERR("SMGR_act_to_obs: Timeout waiting for clip update IPC task OCCFLG[0x%08X]", - in32(OCB_OCCFLG)); + TRAC_ERR("SMGR_act_to_obs: Timeout waiting for Pstates start/suspend IPC task. OCCFLG[0x%08X]", + in32(OCB_OCCFLG)); /* @ * @errortype @@ -968,26 +925,31 @@ errlHndl_t SMGR_active_to_observation() rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_STOP, G_proc_pmcr_owner); if(rc) { - TRAC_ERR("SMGR_act_to_obs: failed to stop the pstate protocol on PGPE rc[0x%08X] OCCFLG[0x%08X]", + TRAC_ERR("SMGR_act_to_obs: failed to stop PGPE pstate protocol rc[0x%08X] OCCFLG[0x%08X]", rc, in32(OCB_OCCFLG)); - ext_rc = ERC_PGPE_TASK_TIMEOUT; + ext_rc = ERC_PGPE_START_SUSPEND_FAILURE; rc = PGPE_FAILURE; break; } - else // Pstates Disabled and clips set successfully, perform state transition + else // Wait for Pstates to be Disabled then perform state transition { - // Set the RTL Flags to indicate which tasks can run - // - Set OBSERVATION b/c in OBSERVATION State - // - Clear ACTIVE b/c not in ACTIVE State - rtl_clr_run_mask_deferred(RTL_FLAG_ACTIVE); - rtl_set_run_mask_deferred(RTL_FLAG_OBS); - - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_OBSERVATION; - - // clear G_active_to_observation_ready flag again - // (for next active_to_observation transition) - G_active_to_observation_ready = false; + wait_time = 0; + while( (G_proc_pstate_status != PSTATES_DISABLED) && + (wait_time < WAIT_PGPE_TASK_TIMEOUT) ) + { + ssx_sleep(SSX_MICROSECONDS(10)); + wait_time += 10; + } + + // check for timeout while waiting for pgpe_start_suspend() IPC completion + if(wait_time >= WAIT_PGPE_TASK_TIMEOUT) + { + TRAC_ERR("SMGR_active_to_observation: Timeout waiting for Pstate protocol disable. RC[0x%04X] OCCFLG[0x%08X]", + G_ss_pgpe_rc, in32(OCB_OCCFLG)); + ext_rc = ERC_PGPE_ACTIVE_TO_OBSERVATION_TIMEOUT; + rc = PGPE_FAILURE; + break; + } } } while (0); @@ -1012,6 +974,14 @@ errlHndl_t SMGR_active_to_observation() } else { + // Set the RTL Flags to indicate which tasks can run + // - Set OBSERVATION b/c in OBSERVATION State + // - Clear ACTIVE b/c not in ACTIVE State + rtl_clr_run_mask_deferred(RTL_FLAG_ACTIVE); + rtl_set_run_mask_deferred(RTL_FLAG_OBS); + + // Set the actual STATE now that we have finished everything else + CURRENT_STATE() = OCC_STATE_OBSERVATION; TRAC_IMP("SMGR: Active to Observation Transition Completed"); } @@ -1029,8 +999,8 @@ errlHndl_t SMGR_active_to_observation() errlHndl_t SMGR_active_to_characterization() { int rc = 0; + uint32_t wait_time = 0; errlHndl_t l_errlHndl = NULL; - Pstate l_pstate; TRAC_IMP("SMGR: Active to Characterization Transition Started"); @@ -1038,9 +1008,16 @@ errlHndl_t SMGR_active_to_characterization() { // set STATE_CHANGE WOF disabled flag set_clear_wof_disabled( SET, WOF_RC_STATE_CHANGE ); - // set pstate clips - l_pstate = proc_freq2pstate(G_proc_fmax_mhz); - rc = pgpe_set_clip_blocking(l_pstate); + + if(G_present_cores == 0) + { + // no configured cores, skip all PGPE comm + TRAC_IMP("SMGR_active_to_characterization: No configured cores, skipping PGPE calls"); + break; + } + + // set pstate clips to full range of max Pstate 0 to support meltbox + rc = pgpe_set_clip_blocking(0); if(rc) { @@ -1048,44 +1025,50 @@ errlHndl_t SMGR_active_to_characterization() rc, in32(OCB_OCCFLG)); break; } - else // clips set successfully, keep pstates enabled, but change ownership + + // make sure start_suspend task is idle + while( (G_proc_pstate_status == PSTATES_IN_TRANSITION) && + (wait_time < WAIT_PGPE_TASK_TIMEOUT) ) { - rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_CHAR); + // wait until pgpe_start_suspend call is completed. Sleep enables context switching. + ssx_sleep(SSX_MICROSECONDS(10)); + wait_time += 10; + } - if(rc) - { - TRAC_ERR("SMGR: failed to change PMCR ownership. rc[0x%08X] OCCFLG[0x%08X]", - rc, in32(OCB_OCCFLG)); - break; - } - else // Request successfully scheduled on PGPE now verify it completed - { - // Wait for ownership change to complete - SsxTimebase start = ssx_timebase_get(); - SsxInterval timeout = SSX_SECONDS(5); - while( ! proc_is_hwpstate_enabled() ) - { - if ((ssx_timebase_get() - start) > timeout) - { - rc = 1; - TRAC_ERR("SMGR_active_to_char: Timeout waiting for PMCR ownership change. rc[0x%08X] OCCFLG[0x%08X]", - rc, in32(OCB_OCCFLG)); - break; - } - ssx_sleep(SSX_MICROSECONDS(10)); - } - if(proc_is_hwpstate_enabled()) - { - // Set the RTL Flags to indicate which tasks can run - // - Set OBSERVATION RTL flags for Characterization State - // - Clear ACTIVE b/c not in ACTIVE State - rtl_clr_run_mask_deferred(RTL_FLAG_ACTIVE); - rtl_set_run_mask_deferred(RTL_FLAG_OBS); - - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_CHARACTERIZATION; - } - } + // check for timeout while waiting for pgpe_start_suspend() IPC completion + if(wait_time >= WAIT_PGPE_TASK_TIMEOUT) + { + TRAC_ERR("SMGR_active_to_characterization: Timeout waiting for Pstates start/suspend IPC task. OCCFLG[0x%08X]", + in32(OCB_OCCFLG)); + rc = PGPE_FAILURE; + break; + } + + // change PMCR ownership to characterization + rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_CHAR); + + if(rc) + { + TRAC_ERR("SMGR_active_to_char: failed to change PMCR ownership. rc[0x%08X] OCCFLG[0x%08X]", + rc, in32(OCB_OCCFLG)); + break; + } + else // Request successfully scheduled on PGPE now verify it completed + { + // Wait for ownership change to complete + SsxTimebase start = ssx_timebase_get(); + SsxInterval timeout = SSX_SECONDS(5); + while( ! proc_is_hwpstate_enabled() ) + { + if ((ssx_timebase_get() - start) > timeout) + { + rc = 1; + TRAC_ERR("SMGR_active_to_char: Timeout waiting for PMCR ownership change. rc[0x%08X] OCCFLG[0x%08X]", + rc, in32(OCB_OCCFLG)); + break; + } + ssx_sleep(SSX_MICROSECONDS(10)); + } } } while (0); @@ -1117,6 +1100,15 @@ errlHndl_t SMGR_active_to_characterization() } else { + // successfully changed to characterization state + // Set the RTL Flags to indicate which tasks can run + // - Set OBSERVATION RTL flags for Characterization State + // - Clear ACTIVE b/c not in ACTIVE State + rtl_clr_run_mask_deferred(RTL_FLAG_ACTIVE); + rtl_set_run_mask_deferred(RTL_FLAG_OBS); + + // Set the actual STATE now that we have finished everything else + CURRENT_STATE() = OCC_STATE_CHARACTERIZATION; TRAC_IMP("SMGR: Active to Characterization Transition Completed"); } diff --git a/src/occ_405/wof/wof.c b/src/occ_405/wof/wof.c index ce8e925..9995266 100644 --- a/src/occ_405/wof/wof.c +++ b/src/occ_405/wof/wof.c @@ -47,7 +47,7 @@ extern GPE_BUFFER(ipcmsg_wof_control_t G_wof_control_parms); extern GpeRequest G_wof_vfrt_req; extern GpeRequest G_wof_control_req; extern uint32_t G_nest_frequency_mhz; -extern pstateStatus G_proc_pstate_status; +extern volatile pstateStatus G_proc_pstate_status; extern uint8_t G_occ_interrupt_type; //****************************************************************************** // Globals -- cgit v1.2.1