summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormbroyles <mbroyles@us.ibm.com>2018-02-08 16:47:04 -0600
committerChristopher J. Cain <cjcain@us.ibm.com>2018-02-16 15:33:29 -0500
commit919b78927d26c079ac3234128e09c548920f3487 (patch)
tree01bee21ecf054f12029392122073af008d28a413
parentfca494dbdcf944718a577bfe0e3c6c01aabb1a69 (diff)
downloadtalos-occ-919b78927d26c079ac3234128e09c548920f3487.tar.gz
talos-occ-919b78927d26c079ac3234128e09c548920f3487.zip
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 <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Andres A. Lugo-Reyes <aalugore@us.ibm.com> Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
-rwxr-xr-xsrc/occ_405/cmdh/cmdh_fsp_cmds.c3
-rwxr-xr-xsrc/occ_405/dcom/dcom_thread.c6
-rwxr-xr-xsrc/occ_405/main.c14
-rw-r--r--src/occ_405/pgpe/pgpe_interface.c32
-rwxr-xr-xsrc/occ_405/proc/proc_data_control.c67
-rwxr-xr-xsrc/occ_405/proc/proc_pstate.c5
-rwxr-xr-xsrc/occ_405/state.c510
-rw-r--r--src/occ_405/wof/wof.c2
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 <gpe_export.h>
@@ -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 <proc_pstate.h>
#include <amec_freq.h>
+// 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
OpenPOWER on IntegriCloud