diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/pstate_pgpe_occ_api.h | 53 | ||||
-rwxr-xr-x | src/occ_405/amec/amec_data.c | 8 | ||||
-rwxr-xr-x | src/occ_405/amec/amec_freq.c | 3 | ||||
-rwxr-xr-x | src/occ_405/amec/amec_slave_smh.c | 10 | ||||
-rwxr-xr-x | src/occ_405/main.c | 12 | ||||
-rw-r--r-- | src/occ_405/occ_service_codes.h | 17 | ||||
-rw-r--r-- | src/occ_405/pgpe/pgpe_interface.c | 325 | ||||
-rw-r--r-- | src/occ_405/pgpe/pgpe_interface.h | 15 | ||||
-rw-r--r-- | src/occ_405/pgpe/pgpe_service_codes.h | 3 | ||||
-rwxr-xr-x | src/occ_405/proc/proc_data_control.c | 243 | ||||
-rwxr-xr-x | src/occ_405/state.c | 971 | ||||
-rwxr-xr-x | src/occ_405/state.h | 32 | ||||
-rwxr-xr-x | src/occ_405/thread/chom.c | 6 |
13 files changed, 1287 insertions, 411 deletions
diff --git a/src/include/pstate_pgpe_occ_api.h b/src/include/pstate_pgpe_occ_api.h index 0b0415e..e1c18f9 100644 --- a/src/include/pstate_pgpe_occ_api.h +++ b/src/include/pstate_pgpe_occ_api.h @@ -1,25 +1,19 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/include/pstate_pgpe_occ_api.h $ */ +/* $Source: chips/p9/common/pmlib/include/pstate_pgpe_occ_api.h $ */ /* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ -/* [+] International Business Machines Corp. */ +/* IBM CONFIDENTIAL */ /* */ +/* EKB Project */ /* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ +/* COPYRIGHT 2015,2017 */ +/* [+] International Business Machines Corp. */ /* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ /* */ /* IBM_PROLOG_END_TAG */ /// @file p9_pstates_pgpe_occ_api.h @@ -41,9 +35,6 @@ extern "C" { #endif -// Maximum Number of Quads supported -#define MAX_QUADS 6 - //--------------- // IPC from 405 @@ -62,11 +53,19 @@ enum MESSAGE_ID_IPI2HI // // Return Codes // -#define PGPE_RC_SUCCESS 0x01 -#define PGPE_WOF_RC_NOT_ENABLED 0x10 +//\todo +//Get feedback from Martha and Greg on these return codes +// +#define PGPE_RC_SUCCESS 0x01 +#define PGPE_WOF_RC_NOT_ENABLED 0x10 +#define PGPE_RC_PSTATES_DISABLED 0x11 +#define PGPE_RC_REQ_PSTATE_ALREADY_STARTED 0x12 +#define PGPE_RC_REQ_PSTATE_ALREADY_SUSPENDED 0x13 +#define PGPE_RC_OCC_NOT_PMCR_OWNER 0x14 // Active quad mismatch with requested active quads. PGPE did not switch // to using the new VFRT. The original VFRT is still being used. #define PGPE_WOF_RC_VFRT_QUAD_MISMATCH 0x20 +#define PGPE_RC_REQ_WHILE_PENDING_ACK 0x21 // // PMCR Owner @@ -74,7 +73,8 @@ enum MESSAGE_ID_IPI2HI typedef enum { PMCR_OWNER_HOST = 0, - PMCR_OWNER_OCC = 1 + PMCR_OWNER_OCC = 1, + PMCR_OWNER_CHAR = 2 } PMCR_OWNER; @@ -88,14 +88,14 @@ typedef struct ipcmsg_base // Start Suspend Actions // #define PGPE_ACTION_PSTATE_START 0 -#define PGPE_ACTION_PSTATE_SUSPEND 1 +#define PGPE_ACTION_PSTATE_STOP 1 -typedef struct ipcmsg_start_suspend +typedef struct ipcmsg_start_stop { ipcmsg_base_t msg_cb; uint8_t action; PMCR_OWNER pmcr_owner; -} ipcmsg_start_suspend_t; +} ipcmsg_start_stop_t; typedef struct ipcmsg_clip_update @@ -269,9 +269,9 @@ typedef union quad_state0 uint64_t quad1_pstate : 8; // Pstate of Quad 1; 0xFF indicates EQ is off uint64_t quad2_pstate : 8; // Pstate of Quad 2; 0xFF indicates EQ is off uint64_t quad3_pstate : 8; // Pstate of Quad 3; 0xFF indicates EQ is off + uint64_t core_poweron_state : 16; // bit vector: 0:core0, 1:core1, ..., 15:core15 uint64_t ivrm_state : 4; // ivrm state: bit vector 0:quad0, 1:quad1, 2:quad2, 3;quad3 uint64_t ivrm_state_rsvd : 4; - uint64_t core_poweron_state : 16; // bit vector: 0:core0, 1:core1, ..., 15:core15 uint64_t external_vrm_setpoint : 8; // set point in mV } fields; } quad_state0_t; @@ -288,12 +288,11 @@ typedef union quad_state1 { uint64_t quad4_pstate : 8; // Pstate of Quad 4; 0xFF indicates EQ is off uint64_t quad5_pstate : 8; // Pstate of Quad 5; 0xFF indicates EQ is off - uint64_t requested_active_quad : 6; // Pstate of Quad 5; 0xFF indicates EQ is off - uint64_t quad_pstate_rsvd : 10; + uint64_t reserved : 16; uint64_t ivrm_state : 2; // ivrm state: bit vector 0:quad4, 1:quad5 uint64_t ivrm_state_rsvd : 6; uint64_t core_poweron_state : 8; // bit vector: 0:core16, 1:core17, ..., 7:core23 - uint64_t core_poweron_state_rsvd : 8; + uint64_t requested_active_quad : 8; uint64_t external_vrm_setpoint : 8; // set point in mV } fields; } quad_state1_t; diff --git a/src/occ_405/amec/amec_data.c b/src/occ_405/amec/amec_data.c index 05d60b9..816c59e 100755 --- a/src/occ_405/amec/amec_data.c +++ b/src/occ_405/amec/amec_data.c @@ -95,7 +95,7 @@ errlHndl_t AMEC_data_write_fcurr(const OCC_MODE i_mode) /*------------------------------------------------------------------------*/ /* Local Variables */ /*------------------------------------------------------------------------*/ - errlHndl_t l_err = NULL; + errlHndl_t l_err = NULL; /*------------------------------------------------------------------------*/ /* Code */ @@ -125,12 +125,10 @@ errlHndl_t AMEC_data_write_fcurr(const OCC_MODE i_mode) if(!l_err) { - // set the clip bounds wide open (if not in active state) - // if not already in active mode, send IPC command to PGPE to set - // pStates clips wide open (pmin - pmax) + // set the clip bounds open (if not in active state) if(!IS_OCC_STATE_ACTIVE()) { - l_err = pgpe_widen_clip_ranges(); + pgpe_widen_clip_ranges(CURRENT_STATE()); } } diff --git a/src/occ_405/amec/amec_freq.c b/src/occ_405/amec/amec_freq.c index 5dadfa7..916b319 100755 --- a/src/occ_405/amec/amec_freq.c +++ b/src/occ_405/amec/amec_freq.c @@ -593,7 +593,7 @@ void amec_slv_freq_smh(void) uint8_t core_num = 0; // core ID uint8_t core_idx = 0; // loop through cores within each quad Pstate pmax = 0; // select the maximum pstate (minimum frequency) - // within each quad, initialize to 0 + // within each quad, initialize to 0 (max frequency) /*------------------------------------------------------------------------*/ /* Code */ @@ -606,6 +606,7 @@ void amec_slv_freq_smh(void) { core_num = (quad*NUM_CORES_PER_QUAD) + core_idx; // loop through all cores + // The higher the pstate number, the lower the frequency if(pmax < proc_freq2pstate(g_amec->proc[0].core[core_num].f_request)) { pmax = proc_freq2pstate(g_amec->proc[0].core[core_num].f_request); diff --git a/src/occ_405/amec/amec_slave_smh.c b/src/occ_405/amec/amec_slave_smh.c index bf33cc4..2f28289 100755 --- a/src/occ_405/amec/amec_slave_smh.c +++ b/src/occ_405/amec/amec_slave_smh.c @@ -62,6 +62,8 @@ // Externs //************************************************************************* extern dcom_slv_inbox_t G_dcom_slv_inbox_rx; +extern opal_proc_voting_reason_t G_amec_opal_proc_throt_reason; + //************************************************************************* // Macros //************************************************************************* @@ -345,6 +347,14 @@ void amec_slv_common_tasks_post(void) // If not configured, this call will return immediately. amec_tb_record(AMEC_TB_250US); } + // if an OPAL system & just transitioned to CHAR or OBS state, set proc mnfg override + else if ( (IS_OCC_STATE_CHARACTERIZATION() || IS_OCC_STATE_OBSERVATION()) && + (MANUFACTURING_OVERRIDE != G_amec_opal_proc_throt_reason) && + (G_sysConfigData.system_type.kvm == true) ) + { + G_amec_opal_proc_throt_reason = MANUFACTURING_OVERRIDE; + ssx_semaphore_post(&G_dcomThreadWakeupSem); + } } // Function Specification diff --git a/src/occ_405/main.c b/src/occ_405/main.c index f34bba6..3012a01 100755 --- a/src/occ_405/main.c +++ b/src/occ_405/main.c @@ -1157,16 +1157,16 @@ void hmon_routine() commitErrl(&l_err); } - //if we are in observation or active state, then monitor the processor temperature - //for timeout conditions - if (IS_OCC_STATE_OBSERVATION() || IS_OCC_STATE_ACTIVE()) + //if we are in observation, characterization, or activate state, then monitor the processor + //temperature for timeout conditions and the processor VRHOT signal. + if (IS_OCC_STATE_OBSERVATION() || IS_OCC_STATE_ACTIVE() || IS_OCC_STATE_CHARACTERIZATION()) { amec_health_check_proc_timeout(); } - //if we are in observation 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()) && + //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)) { // For Cumulus systems only, check for centaur timeout and overtemp errors diff --git a/src/occ_405/occ_service_codes.h b/src/occ_405/occ_service_codes.h index a98ae03..c55194f 100644 --- a/src/occ_405/occ_service_codes.h +++ b/src/occ_405/occ_service_codes.h @@ -172,10 +172,6 @@ enum occExtReasonCode ERC_APSS_ADC_OUT_OF_RANGE_FAILURE = 0x0026, ERC_APSS_ADC_DUPLICATED_FAILURE = 0x0027, - ERC_STATE_FROM_OBS_TO_STB_FAILURE = 0x0028, - ERC_STATE_FROM_STB_TO_OBS_FAILURE = 0x0029, - ERC_STATE_HEARTBEAT_CFG_FAILURE = 0x0080, - ERC_AMEC_PCAPS_MISMATCH_FAILURE = 0x002A, ERC_AMEC_UNDER_PCAP_FAILURE = 0x002B, @@ -236,12 +232,15 @@ enum occExtReasonCode ERC_PGPE_BEACON_TIMEOUT = 0x00B0, ERC_PGPE_NOT_IDLE = 0x00B1, ERC_PGPE_UNSUCCESSFULL = 0x00B2, + ERC_PGPE_CLIP_UNSUCCESSFULL = 0x00B3, ERC_PGPE_PMCR_UNSUCCESSFULL = 0x00B4, ERC_PGPE_START_FAILURE = 0x00B5, ERC_PGPE_SUSPEND_FAILURE = 0x00B6, ERC_PGPE_CLIP_FAILURE = 0x00B7, ERC_PGPE_PPMR_OPPB_SIZE_MISMATCH = 0x00B8, + ERC_PGPE_ACTIVE_TO_OBSERVATION_TIMEOUT = 0x00B9, + ERC_PGPE_TASK_TIMEOUT = 0x00BA, ERC_WOF_QUAD_COUNT_FAILURE = 0x00C0, @@ -250,6 +249,16 @@ enum occExtReasonCode ERC_SMGR_NO_VALID_MODE_TRANSITION_CALL = 0x00E0, ERC_SMGR_NO_VALID_STATE_TRANSITION_CALL = 0x00E1, + + ERC_STATE_FROM_ALL_TO_STB_FAILURE = 0x0123, + ERC_STATE_FROM_ACT_TO_CHR_FAILURE = 0x0124, + ERC_STATE_FROM_CHR_TO_ACT_FAILURE = 0x0125, + ERC_STATE_FROM_CHR_TO_OBS_FAILURE = 0x0126, + ERC_STATE_FROM_OBS_TO_CHR_FAILURE = 0x0127, + ERC_STATE_FROM_STB_TO_CHR_FAILURE = 0x0128, + ERC_STATE_FROM_STB_TO_OBS_FAILURE = 0x0129, + + ERC_STATE_HEARTBEAT_CFG_FAILURE = 0x0180, }; // Error log Module Ids diff --git a/src/occ_405/pgpe/pgpe_interface.c b/src/occ_405/pgpe/pgpe_interface.c index bbdf801..b459b44 100644 --- a/src/occ_405/pgpe/pgpe_interface.c +++ b/src/occ_405/pgpe/pgpe_interface.c @@ -35,6 +35,7 @@ #include "proc_pstate.h" #include "proc_data_control.h" #include "occ_sys_config.h" +#include "ssx.h" extern opal_static_table_t G_opal_static_table; @@ -56,7 +57,7 @@ GpeRequest G_wof_vfrt_req; // The the GPE parameter fields for PGPE IPC calls. GPE_BUFFER(ipcmsg_clip_update_t* G_clip_update_parms_ptr); GPE_BUFFER(ipcmsg_set_pmcr_t* G_pmcr_set_parms_ptr); -GPE_BUFFER(ipcmsg_start_suspend_t G_start_suspend_parms); +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); @@ -69,7 +70,7 @@ GPE_BUFFER(ipcmsg_wof_vfrt_t G_wof_vfrt_parms); // // End Function Specification -errlHndl_t init_pgpe_ipcs(void) +void init_pgpe_ipcs(void) { errlHndl_t err = NULL; // Error handler @@ -108,18 +109,19 @@ errlHndl_t init_pgpe_ipcs(void) { REQUEST_RESET(err); } + else + { + // Initialization used in the task_core_data_control for PGPE success + // checks made before the first clip/pstate IPC message to be ever sent + // from either of the two double buffers. + G_core_data_control_occwrite_ptr->clips.msg_cb.rc = PGPE_RC_SUCCESS; + G_core_data_control_occwrite_ptr->pstates.msg_cb.rc = PGPE_RC_SUCCESS; + + G_core_data_control_gpewrite_ptr->clips.msg_cb.rc = PGPE_RC_SUCCESS; + G_core_data_control_gpewrite_ptr->pstates.msg_cb.rc = PGPE_RC_SUCCESS; + } - // Initialization used in the task_core_data_control for PGPE success - // checks made before the first clip/pstate IPC message to be ever sent - // from either of the two double buffers. - G_core_data_control_occwrite_ptr->clips.msg_cb.rc = PGPE_RC_SUCCESS; - G_core_data_control_occwrite_ptr->pstates.msg_cb.rc = PGPE_RC_SUCCESS; - - G_core_data_control_gpewrite_ptr->clips.msg_cb.rc = PGPE_RC_SUCCESS; - G_core_data_control_gpewrite_ptr->pstates.msg_cb.rc = PGPE_RC_SUCCESS; - - - return(err); + return; } @@ -411,65 +413,227 @@ errlHndl_t pgpe_init_wof_vfrt(void) // Function Specification // -// Name: pgpe_widen_clip_ranges +// Name: pgpe_widen_clip_blocking // -// Description: Wide open PGPE clip ranges. Since this IPC call -// is non-blocking, this routine has to assure call -// completion before checking the pgpe return value. +// Description: a blocking version of pgpe_widen_clip_ranges +// this call waits until the clip IPC task completes, +// and verifies this was a successful completion. // // End Function Specification -errlHndl_t pgpe_widen_clip_ranges(void) +#define CLIP_UPDATE_TIMEOUT 5 //maximum waiting time (usec) for clip update IPC task +int pgpe_widen_clip_blocking(OCC_STATE state) { + errlHndl_t err; + uint8_t wait_time = 0; + int rc = 0; // Return code: 0 means success, otherwise an error. - errlHndl_t err = NULL; // Error handler - uint8_t i; // Loop variable + do + { + // verify that the clip update IPC task is not currently running + if( !async_request_is_idle(&G_clip_update_req.request) ) + { + // an earlier clip update IPC call has not completed, trace and log an error + TRAC_ERR("pgpe_blocking_widen_clip: clip update IPC task is not Idle"); + + /* + * @errortype + * @moduleid PGPE_WIDEN_CLIP_BLOCKING_MOD + * @reasoncode PGPE_FAILURE + * @userdata4 ERC_PGPE_NOT_IDLE + * @devdesc pgpe clip update not idle + */ + err = createErrl( + PGPE_WIDEN_CLIP_BLOCKING_MOD, //ModId + PGPE_FAILURE, //Reasoncode + ERC_PGPE_NOT_IDLE, //Extended reason code + ERRL_SEV_PREDICTIVE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + 0, //Userdata1 + 0 //Userdata2 + ); + + rc = PGPE_FAILURE; + break; + } + else + { + // the function call to widen the clips + rc = pgpe_widen_clip_ranges(state); + + // clip update task failed + if(rc) + { + break; + } + } + + + // Wait until the clip_update IPC task completes + while( !async_request_is_idle(&G_clip_update_req.request) ) + { + if(wait_time > CLIP_UPDATE_TIMEOUT) + { + TRAC_ERR("pgpe_blocking_widen_clip: clip update IPC task timeout!"); + + /* + * @errortype + * @moduleid PGPE_WIDEN_CLIP_BLOCKING_MOD + * @reasoncode GPE_REQUEST_TASK_TIMEOUT + * @userdata4 OCC_NO_EXTENDED_RC + * @devdesc pgpe clip update timeout + */ + err = createErrl( + PGPE_WIDEN_CLIP_BLOCKING_MOD, //ModId + GPE_REQUEST_TASK_TIMEOUT, //Reasoncode + OCC_NO_EXTENDED_RC, //Extended reason code + ERRL_SEV_PREDICTIVE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + 0, //Userdata1 + 0 //Userdata2 + ); + + rc = GPE_REQUEST_TASK_TIMEOUT; + break; + } + + // sleep for 1 microsecond (allows context switching) + ssx_sleep(SSX_MICROSECONDS(1)); + + wait_time++; + } + + // clip update timed out + if(err) + { + break; + } + + // IPC task completed. check for errors + if ( G_clip_update_parms_ptr->msg_cb.rc != PGPE_RC_SUCCESS ) + { + // clip update IPC call has not completed, trace and log an error + TRAC_ERR("pgpe_blocking_widen_clip: clip update IPC task " + "returned an error [0x%08X]", + G_clip_update_parms_ptr->msg_cb.rc); + + /* + * @errortype + * @moduleid PGPE_WIDEN_CLIP_BLOCKING_MOD + * @reasoncode GPE_REQUEST_RC_FAILURE + * @userdata1 PGPE clip update's rc + * @userdata4 OCC_NO_EXTENDED_RC + * @devdesc pgpe clip update returned a failure code + */ + err = createErrl( + PGPE_WIDEN_CLIP_BLOCKING_MOD, //ModId + GPE_REQUEST_RC_FAILURE, //Reasoncode + OCC_NO_EXTENDED_RC, //Extended reason code + ERRL_SEV_PREDICTIVE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + G_clip_update_parms_ptr->msg_cb.rc, //Userdata1 + 0 //Userdata2 + ); + + rc = GPE_REQUEST_RC_FAILURE; + } + } while (0); - // Set clip bounds wide open - for(i=0; i<MAX_QUADS; i++) + if(err) { - // minimum pstate - G_clip_update_parms_ptr->ps_val_clip_min[i] = pmin_rail(); + REQUEST_RESET(err); + } + + return(rc); +} + - // maximum pstate: - G_clip_update_parms_ptr->ps_val_clip_max[i] = proc_freq2pstate(G_proc_fmax_mhz); +// Function Specification +// +// Name: pgpe_widen_clip_ranges +// +// Description: Widens PGPE clip ranges between minimum pstate, +// and maximum pstate allowed in the specified +// "state" parameter. Since this IPC call is +// non-blocking, the caller has to assure that +// IPC clip update task is idle, wait for IPC task +// completion, then check the pgpe return value. +// +// End Function Specification + +int pgpe_widen_clip_ranges(OCC_STATE state) +{ + + errlHndl_t err = NULL; // Error handler + int rc = 0; // return code + uint8_t quad; // Loop variable + + Pstate pmin = pmin_rail(); + Pstate pmax; + + bool valid_state = false; + + // when transitioning to observation state, + // set max clip to legacy turbo pstate clip + if(state == OCC_STATE_OBSERVATION) + { + pmax = proc_freq2pstate(G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO]); + valid_state = true; + } + // when transitioning to active or characterization state, + // wide open the clips. If WOF is enabled set it to ultra + // -turbo pstate, else, set it to turbo pstate. + else if (state == OCC_STATE_ACTIVE || state == OCC_STATE_CHARACTERIZATION) + { + pmax = proc_freq2pstate(G_proc_fmax_mhz); + valid_state = true; } - // Check that no previous clip update calls are still in progress - if(async_request_is_idle(&G_clip_update_req.request)) + if(valid_state) { + // Set clip bounds + for(quad=0; quad<MAX_QUADS; quad++) + { + // minimum pstate, independent of state + G_clip_update_parms_ptr->ps_val_clip_min[quad] = pmin; + + // max pstate (legacy turbo / ultra-turbo) + G_clip_update_parms_ptr->ps_val_clip_max[quad] = pmax; + } + // will check for this IPC completion at transition to active state - err = pgpe_clip_update(); + rc = pgpe_clip_update(); } else { - // an earlier clip update IPC call has not completed, trace and log an error - TRAC_ERR("pgpe_widen_clip_ranges: clip update IPC task is not Idle"); - - // log an error - MAIN_TRAC_ERR("pgpe_widen_clip_ranges: clip update IPC is not Idle"); - + TRAC_ERR("pgpe_widen_clip_ranges: should never be called in state %d", state); /* * @errortype * @moduleid PGPE_WIDEN_CLIP_RANGES_MOD * @reasoncode PGPE_FAILURE - * @userdata1 0 - * @userdata4 ERC_PGPE_NOT_IDLE - * @devdesc pgpe clip update not idle + * @userdata1 state + * @userdata4 ERC_PGPE_CLIP_FAILURE + * @devdesc pgpe clip update requested in an invalid state */ err = createErrl( - PGPE_WIDEN_CLIP_RANGES_MOD, //ModId - PGPE_FAILURE, //Reasoncode - OCC_NO_EXTENDED_RC, //Extended reason code - ERRL_SEV_PREDICTIVE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - 0, //Userdata1 - 0 //Userdata2 + PGPE_WIDEN_CLIP_RANGES_MOD, //ModId + PGPE_FAILURE, //Reasoncode + ERC_PGPE_CLIP_FAILURE, //Extended reason code + ERRL_SEV_PREDICTIVE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + state, //Userdata1 + 0 //Userdata2 ); + + rc = PGPE_FAILURE; + REQUEST_RESET(err); } - return(err); + return(rc); } // Function Specification @@ -482,10 +646,10 @@ errlHndl_t pgpe_widen_clip_ranges(void) // // End Function Specification -errlHndl_t pgpe_clip_update(void) +int pgpe_clip_update(void) { - int rc; // gpe schedule return code - errlHndl_t err = NULL; // Error handler + int rc = 0; // return code + errlHndl_t err = NULL; // Error handler do { @@ -515,6 +679,15 @@ errlHndl_t pgpe_clip_update(void) 0 //Userdata2 ); + // Callout firmware + addCalloutToErrl(err, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + + commitErrl(&err); + + rc = PGPE_FAILURE; break; } @@ -554,11 +727,12 @@ errlHndl_t pgpe_clip_update(void) 0 // userdata2 ); + rc = GPE_REQUEST_SCHEDULE_FAILURE; REQUEST_RESET(err); //This will add a firmware callout for us } }while(0); - return err; + return rc; } @@ -617,15 +791,16 @@ void pgpe_start_suspend_callback(void) { // Pstates are now enabled (enable Active State transition). G_proc_pstate_status = PSTATES_ENABLED; + + // upon successful pstates START, assign G_proc_pmcr_owner (OCC/CHAR/HOST) + G_proc_pmcr_owner = G_start_suspend_parms.pmcr_owner; } // this was a command to disable pstates - else if(G_start_suspend_parms.action == PGPE_ACTION_PSTATE_SUSPEND) + else if(G_start_suspend_parms.action == PGPE_ACTION_PSTATE_STOP) { // Pstates are now disabled (disaable Active State transition). G_proc_pstate_status = PSTATES_DISABLED; } - - G_proc_pmcr_owner = G_start_suspend_parms.pmcr_owner; } } while(0); @@ -645,25 +820,13 @@ void pgpe_start_suspend_callback(void) // // End Function Specification -errlHndl_t pgpe_start_suspend(uint8_t action) +int pgpe_start_suspend(uint8_t action, PMCR_OWNER owner) { - PMCR_OWNER owner; // PMCR owner - int rc; // gpe schedule return codes + int rc; // return code errlHndl_t err = NULL; // Error handler - // For now, we set PMCR ownership based on whether the system - // is OPAL system or not. - if(G_sysConfigData.system_type.kvm) - { - owner = PMCR_OWNER_HOST; - } - else - { - owner = PMCR_OWNER_OCC; - } - // set the IPC parameters - G_start_suspend_parms.action = action; + G_start_suspend_parms.action = action; G_start_suspend_parms.pmcr_owner = owner; // @TODO: remove this precompile directive check when PGPE code is integrated. @@ -700,6 +863,7 @@ errlHndl_t pgpe_start_suspend(uint8_t action) 0 // userdata2 ); + rc = GPE_REQUEST_SCHEDULE_FAILURE; REQUEST_RESET(err); //This will add a firmware callout for us } // successfully scheduled, set the G_proc_pstate_status to indicate transition @@ -712,7 +876,7 @@ errlHndl_t pgpe_start_suspend(uint8_t action) pgpe_start_suspend_callback(); #endif - return err; + return rc; } @@ -727,9 +891,9 @@ errlHndl_t pgpe_start_suspend(uint8_t action) // // End Function Specification -errlHndl_t pgpe_pmcr_set(void) +int pgpe_pmcr_set(void) { - int rc; // gpe schedule return codes + int rc; // return code errlHndl_t err = NULL; // Error handler do @@ -760,6 +924,15 @@ errlHndl_t pgpe_pmcr_set(void) 0 //Userdata2 ); + // Callout firmware + addCalloutToErrl(err, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + + commitErrl(&err); + + rc = PGPE_FAILURE; break; } @@ -778,10 +951,7 @@ errlHndl_t pgpe_pmcr_set(void) //Error in scheduling pgpe clip update task TRAC_ERR("pgpe_pmcr_set: Failed to schedule PMCR setup pgpe task rc=%x", rc); - } - if(rc != 0) - { /* @ * @errortype * @moduleid PGPE_PMCR_SET_MOD @@ -790,7 +960,7 @@ errlHndl_t pgpe_pmcr_set(void) * @userdata2 0 * @userdata4 OCC_NO_EXTENDED_RC * @devdesc OCC Failed to schedule a GPE job for clip update - */ + */ err = createErrl( PGPE_PMCR_SET_MOD, // modId GPE_REQUEST_SCHEDULE_FAILURE, // reasoncode @@ -802,11 +972,12 @@ errlHndl_t pgpe_pmcr_set(void) 0 // userdata2 ); + rc = GPE_REQUEST_SCHEDULE_FAILURE; REQUEST_RESET(err); //This will add a firmware callout for us } } while(0); - return err; + return rc; } diff --git a/src/occ_405/pgpe/pgpe_interface.h b/src/occ_405/pgpe/pgpe_interface.h index a777f28..539c422 100644 --- a/src/occ_405/pgpe/pgpe_interface.h +++ b/src/occ_405/pgpe/pgpe_interface.h @@ -27,8 +27,10 @@ #define _PGPE_INTERFACE_H_ #include "errl.h" +#include "state.h" +#include "pstate_pgpe_occ_api.h" -errlHndl_t init_pgpe_ipcs(void); +void init_pgpe_ipcs(void); errlHndl_t pgpe_init_clips(void); errlHndl_t pgpe_init_pmcr(void); @@ -36,10 +38,13 @@ errlHndl_t pgpe_init_start_suspend(void); errlHndl_t pgpe_init_wof_control(void); errlHndl_t pgpe_init_wof_vfrt(void); -errlHndl_t pgpe_widen_clip_ranges(void); -errlHndl_t pgpe_clip_update(void); -errlHndl_t pgpe_pmcr_set(void); -errlHndl_t pgpe_start_suspend(uint8_t action); +int pgpe_widen_clip_ranges(OCC_STATE state); +int pgpe_widen_clip_blocking(OCC_STATE state); +int pgpe_clip_update(void); + +int pgpe_pmcr_set(void); + +int pgpe_start_suspend(uint8_t action, PMCR_OWNER owner); void pgpe_start_suspend_callback(void); #endif /* #ifndef _PGPE_INTERFACE_H_ */ diff --git a/src/occ_405/pgpe/pgpe_service_codes.h b/src/occ_405/pgpe/pgpe_service_codes.h index 2e66952..30d6f1d 100644 --- a/src/occ_405/pgpe/pgpe_service_codes.h +++ b/src/occ_405/pgpe/pgpe_service_codes.h @@ -39,7 +39,8 @@ enum pgpeModuleId PGPE_START_SUSPEND_MOD = PGPE_COMP_ID | 0x06, PGPE_PMCR_SET_MOD = PGPE_COMP_ID | 0x07, PGPE_WIDEN_CLIP_RANGES_MOD = PGPE_COMP_ID | 0x08, - PGPE_START_SUSPEND_CALLBACK_MOD = PGPE_COMP_ID | 0x09, + PGPE_WIDEN_CLIP_BLOCKING_MOD = PGPE_COMP_ID | 0x09, + PGPE_START_SUSPEND_CALLBACK_MOD = PGPE_COMP_ID | 0x0A, }; diff --git a/src/occ_405/proc/proc_data_control.c b/src/occ_405/proc/proc_data_control.c index f10ce43..0e902a8 100755 --- a/src/occ_405/proc/proc_data_control.c +++ b/src/occ_405/proc/proc_data_control.c @@ -39,6 +39,7 @@ #include "p9_pstates_common.h" #include "pgpe_interface.h" #include "rtls_service_codes.h" +#include "proc_pstate.h" // The the GPE parameter fields for PGPE IPC calls. extern GPE_BUFFER(ipcmsg_clip_update_t* G_clip_update_parms_ptr); @@ -47,6 +48,13 @@ extern GPE_BUFFER(ipcmsg_set_pmcr_t* G_pmcr_set_parms_ptr); extern GpeRequest G_clip_update_req; extern GpeRequest G_pmcr_set_req; +extern bool G_state_transition_occuring; // A state transition is currently going on? + +// 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; + // create gpe request for GPE job. The initialization will be done one time // during gpe request create. GpeRequest G_core_data_control_req; @@ -70,112 +78,165 @@ GPE_BUFFER(PstatesClips* G_core_data_control_gpewrite_ptr) = { &G_quads_data_con // End Function Specification void task_core_data_control( task_t * i_task ) { - errlHndl_t err = NULL; //Error handler - PstatesClips* l_temp = NULL; + errlHndl_t err = NULL; //Error handler + PstatesClips* l_temp = NULL; + static bool L_trace_logged = false; // trace logging to avoid unnecessarily repeatig logs + ///////////////////////////////////////////////////////////////// - // perform Pstate/clip control if previous IPC call completed successfully - // if not idle, ignore cycle - // if an error was returned, log an error, and request reset - if(G_sysConfigData.system_type.kvm) // OPAL system + // Once a state transition process starts, task data control + // stops updating the PMCR/CLIPS updates, this way, the state + // transition protocol can set the clips without colliding + // with the task_core_data_control IPC tasks. + if(G_state_transition_occuring) { - // confirm that the clip update IPC from last cycle - // has successfully completed on PGPE (with no errors) - if( async_request_is_idle(&G_clip_update_req.request) && //clip_update/widen_clip_ranges completed - (G_clip_update_parms_ptr->msg_cb.rc == PGPE_RC_SUCCESS) ) // with no errors + if(L_trace_logged == false) { - - //The previous OPAL PGPE request succeeded: - - //1) swap gpewrite ptr with the occwrite ptr (double buffering). - l_temp = G_core_data_control_occwrite_ptr; - G_core_data_control_occwrite_ptr = G_core_data_control_gpewrite_ptr; - G_core_data_control_gpewrite_ptr = l_temp; - - //2) Set clip values from gpewrite's quad clips data-structure - G_clip_update_parms_ptr = &G_core_data_control_gpewrite_ptr->clips; - - //call PGPE IPC function to update the clips - pgpe_clip_update(); + TRAC_INFO("task_core_data_control: Pstate Control stopped because a state transition started."); + L_trace_logged = true; } - else if(G_clip_update_parms_ptr->msg_cb.rc != PGPE_RC_SUCCESS) + + // 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) { - // an earlier clip update IPC call has not completed, trace and log an error - TRAC_ERR("task_core_data_control: clip update IPC task returned an error, %d", - G_clip_update_parms_ptr->msg_cb.rc); - - /* - * @errortype - * @moduleid RTLS_TASK_CORE_DATA_CONTROL_MOD - * @reasoncode PGPE_FAILURE - * @userdata1 rc - * @userdata2 clip update task idle? - * @userdata4 ERC_PGPE_CLIP_UNSUCCESSFULL - * @devdesc pgpe clip update returned an error - */ - err = createErrl( - RTLS_TASK_CORE_DATA_CONTROL_MOD, //ModId - PGPE_FAILURE, //Reasoncode - ERC_PGPE_CLIP_UNSUCCESSFULL, //Extended reason code - ERRL_SEV_PREDICTIVE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - G_clip_update_parms_ptr->msg_cb.rc, //Userdata1 - async_request_is_idle(&G_clip_update_req.request) //Userdata2 - ); + // 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/widen_clip_ranges completed + (G_clip_update_parms_ptr->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 < MAX_QUADS; quad++) + { + if(G_clip_update_parms_ptr->ps_val_clip_max[quad] < pclip) + { + // minimum pclip value corresponds to pstate of maximum frequency + pclip = G_clip_update_parms_ptr->ps_val_clip_max[quad]; + } + } + // pclip of highest quad frequency corresponds to a frequency higher than legacy turbo + if(pclip < proc_freq2pstate(G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO])) + { + pgpe_widen_clip_ranges(OCC_STATE_OBSERVATION); + } + + //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; + } } } else { - // NON OPAL System, OCC owns PMCR: - if( async_request_is_idle(&G_pmcr_set_req.request) && // PMCR IPC from last TICK completed - (G_pmcr_set_parms_ptr->msg_cb.rc == PGPE_RC_SUCCESS) ) // with no errors - { - //The previous Non-OPAL PGPE request succeeded: - - //1) swap gpewrite ptr with the occwrite ptr (double buffering). - l_temp = G_core_data_control_occwrite_ptr; - G_core_data_control_occwrite_ptr = G_core_data_control_gpewrite_ptr; - G_core_data_control_gpewrite_ptr = l_temp; + L_trace_logged = false; - //2) Set Pstate values from gpewrite's quad pstates data-structure - G_pmcr_set_parms_ptr = &G_core_data_control_gpewrite_ptr->pstates; - - //call PGPE IPC function to update Pstates - pgpe_pmcr_set(); + // perform Pstate/clip control if previous IPC call completed successfully + // if not idle, ignore cycle + // if an error was returned, log an error, and request reset + if(G_sysConfigData.system_type.kvm) // OPAL system + { + // confirm that the clip update IPC from last cycle + // has successfully completed on PGPE (with no errors) + if( async_request_is_idle(&G_clip_update_req.request) && //clip_update/widen_clip_ranges completed + (G_clip_update_parms_ptr->msg_cb.rc == PGPE_RC_SUCCESS) ) // with no errors + { + //The previous OPAL PGPE request succeeded: + + //1) swap gpewrite ptr with the occwrite ptr (double buffering). + l_temp = G_core_data_control_occwrite_ptr; + G_core_data_control_occwrite_ptr = G_core_data_control_gpewrite_ptr; + G_core_data_control_gpewrite_ptr = l_temp; + + //2) Set clip values from gpewrite's quad clips data-structure + G_clip_update_parms_ptr = &G_core_data_control_gpewrite_ptr->clips; + + //call PGPE IPC function to update the clips + pgpe_clip_update(); + } + else if(G_clip_update_parms_ptr->msg_cb.rc != PGPE_RC_SUCCESS) + { + // an earlier clip update IPC call has not completed, trace and log an error + TRAC_ERR("task_core_data_control: clip update IPC task returned an error, %d", + G_clip_update_parms_ptr->msg_cb.rc); + + /* + * @errortype + * @moduleid RTLS_TASK_CORE_DATA_CONTROL_MOD + * @reasoncode PGPE_FAILURE + * @userdata1 rc + * @userdata2 clip update task idle? + * @userdata4 ERC_PGPE_CLIP_UNSUCCESSFULL + * @devdesc pgpe clip update returned an error + */ + err = createErrl( + RTLS_TASK_CORE_DATA_CONTROL_MOD, //ModId + PGPE_FAILURE, //Reasoncode + ERC_PGPE_CLIP_UNSUCCESSFULL, //Extended reason code + ERRL_SEV_PREDICTIVE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + G_clip_update_parms_ptr->msg_cb.rc, //Userdata1 + async_request_is_idle(&G_clip_update_req.request) //Userdata2 + ); + } } - else if(G_pmcr_set_parms_ptr->msg_cb.rc != PGPE_RC_SUCCESS) + else { - // an earlier clip update IPC call has not completed, trace and log an error - TRAC_ERR("task_core_data_control: pstate update IPC task returned an error, %d", - G_pmcr_set_parms_ptr->msg_cb.rc); - - /* - * @errortype - * @moduleid RTLS_TASK_CORE_DATA_CONTROL_MOD - * @reasoncode PGPE_FAILURE - * @userdata1 rc - * @userdata2 pmcr set task idle? - * @userdata4 ERC_PGPE_PMCR_UNSUCCESSFULL - * @devdesc pgpe PMCR set returned an error - */ - err = createErrl( - RTLS_TASK_CORE_DATA_CONTROL_MOD, //ModId - PGPE_FAILURE, //Reasoncode - ERC_PGPE_PMCR_UNSUCCESSFULL, //Extended reason code - ERRL_SEV_PREDICTIVE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - G_pmcr_set_parms_ptr->msg_cb.rc, //Userdata1 - async_request_is_idle(&G_pmcr_set_req.request) //Userdata2 - ); + // NON OPAL System, OCC owns PMCR: + if( async_request_is_idle(&G_pmcr_set_req.request) && // PMCR IPC from last TICK completed + (G_pmcr_set_parms_ptr->msg_cb.rc == PGPE_RC_SUCCESS) ) // with no errors + { + //The previous Non-OPAL PGPE request succeeded: + + //1) swap gpewrite ptr with the occwrite ptr (double buffering). + l_temp = G_core_data_control_occwrite_ptr; + G_core_data_control_occwrite_ptr = G_core_data_control_gpewrite_ptr; + G_core_data_control_gpewrite_ptr = l_temp; + + //2) Set Pstate values from gpewrite's quad pstates data-structure + G_pmcr_set_parms_ptr = &G_core_data_control_gpewrite_ptr->pstates; + + //call PGPE IPC function to update Pstates + pgpe_pmcr_set(); + } + else if(G_pmcr_set_parms_ptr->msg_cb.rc != PGPE_RC_SUCCESS) + { + // an earlier clip update IPC call has not completed, trace and log an error + TRAC_ERR("task_core_data_control: pstate update IPC task returned an error, %d", + G_pmcr_set_parms_ptr->msg_cb.rc); + + /* + * @errortype + * @moduleid RTLS_TASK_CORE_DATA_CONTROL_MOD + * @reasoncode PGPE_FAILURE + * @userdata1 rc + * @userdata2 pmcr set task idle? + * @userdata4 ERC_PGPE_PMCR_UNSUCCESSFULL + * @devdesc pgpe PMCR set returned an error + */ + err = createErrl( + RTLS_TASK_CORE_DATA_CONTROL_MOD, //ModId + PGPE_FAILURE, //Reasoncode + ERC_PGPE_PMCR_UNSUCCESSFULL, //Extended reason code + ERRL_SEV_PREDICTIVE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + G_pmcr_set_parms_ptr->msg_cb.rc, //Userdata1 + async_request_is_idle(&G_pmcr_set_req.request) //Userdata2 + ); + } } - } - if(err) - { - // commit error log - REQUEST_RESET(err); + if(err) + { + // commit error log + REQUEST_RESET(err); + } } return; diff --git a/src/occ_405/state.c b/src/occ_405/state.c index 81b5f9c..341dba7 100755 --- a/src/occ_405/state.c +++ b/src/occ_405/state.c @@ -45,20 +45,15 @@ 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 GpeRequest G_clip_update_req; extern GPE_BUFFER(ipcmsg_clip_update_t* G_clip_update_parms_ptr); +// OCC is ready to transition to observation state? +extern bool G_active_to_observation_ready; -// Maximum allowed value approx. 16.3 ms -#define PCBS_HEARBEAT_TIME_US 16320 - -errlHndl_t SMGR_standby_to_observation(); -errlHndl_t SMGR_standby_to_active(); -errlHndl_t SMGR_observation_to_standby(); -errlHndl_t SMGR_observation_to_active(); -errlHndl_t SMGR_active_to_observation(); -errlHndl_t SMGR_active_to_standby(); -errlHndl_t SMGR_all_to_safe(); +extern PMCR_OWNER G_proc_pmcr_owner; // State that OCC is currently in OCC_STATE G_occ_internal_state = OCC_STATE_STANDBY; @@ -89,22 +84,28 @@ const smgr_state_trans_t G_smgr_state_trans[] = * those catch-all transition functions. */ /* Current State New State Transition Function */ - {OCC_STATE_STANDBY, OCC_STATE_OBSERVATION, &SMGR_standby_to_observation}, - {OCC_STATE_STANDBY, OCC_STATE_ACTIVE, &SMGR_standby_to_active}, - {OCC_STATE_OBSERVATION, OCC_STATE_STANDBY, &SMGR_observation_to_standby}, - {OCC_STATE_OBSERVATION, OCC_STATE_ACTIVE, &SMGR_observation_to_active}, - {OCC_STATE_ACTIVE, OCC_STATE_OBSERVATION, &SMGR_active_to_observation}, - {OCC_STATE_ACTIVE, OCC_STATE_STANDBY, &SMGR_active_to_standby}, + {OCC_STATE_STANDBY, OCC_STATE_OBSERVATION, &SMGR_standby_to_observation}, + {OCC_STATE_STANDBY, OCC_STATE_CHARACTERIZATION, &SMGR_standby_to_characterization}, + {OCC_STATE_STANDBY, OCC_STATE_ACTIVE, &SMGR_standby_to_active}, + {OCC_STATE_OBSERVATION, OCC_STATE_CHARACTERIZATION, &SMGR_observation_to_characterization}, + {OCC_STATE_OBSERVATION, OCC_STATE_ACTIVE, &SMGR_observation_to_active}, + {OCC_STATE_CHARACTERIZATION, OCC_STATE_OBSERVATION, &SMGR_characterization_to_observation}, + {OCC_STATE_CHARACTERIZATION, OCC_STATE_ACTIVE, &SMGR_characterization_to_active}, + {OCC_STATE_ACTIVE, OCC_STATE_OBSERVATION, &SMGR_active_to_observation}, + {OCC_STATE_ACTIVE, OCC_STATE_CHARACTERIZATION, &SMGR_active_to_characterization}, /* ----- DEFAULT STATE TRANSITIONS ----- */ /* These are default state transitions for when it doesn't matter what * state we were in before the transition. */ /* Current State New State Transition Function */ + {OCC_STATE_ALL, OCC_STATE_STANDBY, &SMGR_all_to_standby}, {OCC_STATE_ALL, OCC_STATE_SAFE, &SMGR_all_to_safe}, }; + const uint8_t G_smgr_state_trans_count = sizeof(G_smgr_state_trans)/sizeof(smgr_state_trans_t); + uint32_t G_smgr_validate_data_active_mask = SMGR_VALIDATE_DATA_ACTIVE_MASK_HARDCODES; uint32_t G_smgr_validate_data_observation_mask = SMGR_VALIDATE_DATA_OBSERVATION_MASK_HARDCODES; @@ -164,21 +165,20 @@ errlHndl_t SMGR_standby_to_observation() * @userdata4 ERC_STATE_FROM_STB_TO_OBS_FAILURE * @devdesc Failed changing from standby to observation */ - l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId - INTERNAL_FAILURE, //reasoncode - ERC_STATE_FROM_STB_TO_OBS_FAILURE,//Extended reason code - ERRL_SEV_UNRECOVERABLE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - 0, //userdata1 - 0); //userdata2 + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + INTERNAL_FAILURE, //reasoncode + ERC_STATE_FROM_STB_TO_OBS_FAILURE,//Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + 0, //userdata1 + 0); //userdata2 // Callout firmware addCalloutToErrl(l_errlHndl, ERRL_CALLOUT_TYPE_COMPONENT_ID, ERRL_COMPONENT_ID_FIRMWARE, ERRL_CALLOUT_PRIORITY_HIGH); - } return l_errlHndl; } @@ -186,27 +186,98 @@ errlHndl_t SMGR_standby_to_observation() // Function Specification // -// Name: +// Name: SMGR_standby_to_characterization // -// Description: +// Description: switch from standby state to characterization state // // End Function Specification -errlHndl_t SMGR_observation_to_standby() +errlHndl_t SMGR_standby_to_characterization() { - errlHndl_t l_errlHndl = NULL; + errlHndl_t l_errlHndl = NULL; + int rc = 0; + static bool l_error_logged = FALSE; // To prevent trace and error log happened over and over - TRAC_IMP("SMGR: Observation to Standby Transition Started"); + do + { - // Set the RTL Flags to indicate which tasks can run - // - Clear ACTIVE b/c not in ACTIVE State - // - Clear OBSERVATION b/c not in OBSERVATION State - rtl_clr_run_mask_deferred(RTL_FLAG_ACTIVE | RTL_FLAG_OBS ); - rtl_set_run_mask_deferred(RTL_FLAG_STANDBY); + if( SMGR_MASK_ACTIVE_READY == + (SMGR_validate_get_valid_states() & SMGR_MASK_ACTIVE_READY)) + { + l_error_logged = FALSE; + TRAC_IMP("SMGR: Standby to Characterization State Transition Started"); - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_STANDBY; + // wide open pstate clips + rc = pgpe_widen_clip_blocking(OCC_STATE_CHARACTERIZATION); - TRAC_IMP("SMGR: Observation to Standby Transition Completed"); + if(rc) + { + TRAC_ERR("SMGR: failed to widen pstate clips."); + break; + } + else // successfully wide opened clips; enable pstates, then start transition + { + + // update OPAL static table in main memory + if(G_sysConfigData.system_type.kvm) + { + // upon succesful enablement of Pstate protocol on + // PGPE update OPAL table with pstate information. + proc_pstate_kvm_setup(); + } + + // 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 on PGPE."); + break; + } + else // Clips wide opened 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"); + } + } + } + } while (0); + + if(l_errlHndl && (false == l_error_logged)) + { + l_error_logged = TRUE; + TRAC_ERR("SMGR: Standby to Characterization Transition Failed"); + /* @ + * @errortype + * @moduleid MAIN_STATE_TRANSITION_MID + * @reasoncode INTERNAL_FAILURE + * @userdata1 none + * @userdata4 ERC_STATE_FROM_STB_TO_CHR_FAILURE + * @devdesc Failed changing from standby to characterization + */ + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + INTERNAL_FAILURE, //reasoncode + ERC_STATE_FROM_STB_TO_CHR_FAILURE, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + 0, //userdata1 + 0); //userdata2 + + // Callout firmware + addCalloutToErrl(l_errlHndl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + } return l_errlHndl; } @@ -214,170 +285,507 @@ errlHndl_t SMGR_observation_to_standby() // Function Specification // -// Name: SMGR_observation_to_active +// Name: SMGR_all_to_standby // -// Description: Transition from Observation state to Active state +// Description: Switch from any state to standby state // // End Function Specification -errlHndl_t SMGR_observation_to_active() + +#define WAIT_PGPE_TASK_TIMEOUT 200 // maximum time to wait for a PGPE task before timeout +errlHndl_t SMGR_all_to_standby() { - errlHndl_t l_errlHndl = NULL; - static bool l_error_logged = FALSE; // To prevent trace and error log happened over and over - int l_extRc = OCC_NO_EXTENDED_RC; - int l_rc = 0; + errlHndl_t l_errlHndl = NULL; + static bool l_error_logged = FALSE; // To prevent trace and error logging over and over + uint8_t wait_time = 0; + int rc; - // confirm that the clip update IPC call to widen clip ranges - // has successfully completed on PGPE (with no errors) - if( !async_request_is_idle(&G_clip_update_req.request) ) //widen_clip_ranges didn't complete + TRAC_IMP("SMGR: Transition from State (%d) to Standby Started", + CURRENT_STATE()); + + do { - // an earlier clip update IPC call has not completed, trace and log an error - TRAC_ERR("SMGR: clip update IPC task is not Idle"); - /* + // if Psates in transition (a pgpe_start_suspend IPC call still running), + // wait until it is settled up to WAIT_PGPE_TASK_TIMEOUT usec + while(G_proc_pstate_status == PSTATES_IN_TRANSITION && + wait_time < WAIT_PGPE_TASK_TIMEOUT) + { + // 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 pgpe_start_suspend() IPC completion + if(wait_time >= WAIT_PGPE_TASK_TIMEOUT) + { + TRAC_ERR("SMGR: Timeout waiting for Pstates start/suspend IPC task"); + + /* @ * @errortype - * @moduleid MAIN_SMGR_MID - * @reasoncode PGPE_FAILURE - * @userdata4 ERC_PGPE_NOT_IDLE - * @devdesc pgpe clip update not idle + * @moduleid MAIN_STATE_TRANSITION_MID + * @reasoncode GPE_REQUEST_TASK_TIMEOUT + * @userdata1 wait_time + * @userdata4 OCC_NO_EXTENDED_RC + * @devdesc timeout waiting for pstates start/suspend task */ - l_errlHndl = createErrl( - MAIN_SMGR_MID, //ModId - PGPE_FAILURE, //Reasoncode - ERC_PGPE_NOT_IDLE, //Extended reason code - ERRL_SEV_PREDICTIVE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - 0, //Userdata1 - 0 //Userdata2 - ); + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + GPE_REQUEST_TASK_TIMEOUT, //reasoncode + OCC_NO_EXTENDED_RC, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + wait_time, //userdata1 + 0); //userdata2 + + // Callout firmware + addCalloutToErrl(l_errlHndl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + break; + } + + // Stop Pstates if enabled + if(G_proc_pstate_status == PSTATES_ENABLED) + { + rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_STOP, G_proc_pmcr_owner); + if(rc) + { + TRAC_ERR("SMGR: Failed to stop the pstate protocol on PGPE."); + break; + } + } + + // Pstates Disabled, ready to safely transition to standby + + // Set the RTL Flags to indicate which tasks can run + // - Clear ACTIVE b/c not in ACTIVE State + // - Clear OBSERVATION b/c not in CHARACTERIZATION State + rtl_clr_run_mask_deferred(RTL_FLAG_ACTIVE | RTL_FLAG_OBS ); + rtl_set_run_mask_deferred(RTL_FLAG_STANDBY); + + // Set the actual STATE now that we have finished everything else + CURRENT_STATE() = OCC_STATE_STANDBY; + + TRAC_IMP("SMGR: Transition to Standby Completed"); + + } while (0); + + if(l_errlHndl) + { + l_error_logged = TRUE; + TRAC_ERR("SMGR: Transition to Standby Failed"); + + /* @ + * @errortype + * @moduleid MAIN_STATE_TRANSITION_MID + * @reasoncode INTERNAL_FAILURE + * @userdata1 starting state + * @userdata4 ERC_STATE_FROM_ALL_TO_STB_FAILURE + * @devdesc Failed changing from observation to characterization + */ + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + INTERNAL_FAILURE, //reasoncode + ERC_STATE_FROM_ALL_TO_STB_FAILURE, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + CURRENT_STATE(), //userdata1 + 0); //userdata2 // Callout firmware addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_COMPONENT_ID, - ERRL_COMPONENT_ID_FIRMWARE, - ERRL_CALLOUT_PRIORITY_HIGH); + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); } - else if ( G_clip_update_parms_ptr->msg_cb.rc != PGPE_RC_SUCCESS ) // IPC task completed with errors + + return l_errlHndl; +} + +// Function Specification +// +// Name: SMGR_characterization_to_observation +// +// Description: Switch from characterization to observation state +// +// End Function Specification +errlHndl_t SMGR_characterization_to_observation() +{ + errlHndl_t l_errlHndl = NULL; + int rc = 0; + static bool l_error_logged = FALSE; // To prevent trace and error logging over and over + + TRAC_IMP("SMGR: Characterization to Observation Transition Started"); + + do { - // an earlier clip update IPC call has not completed, trace and log an error - TRAC_ERR("SMGR: clip update IPC task returned an error [0x%08X]", - G_clip_update_parms_ptr->msg_cb.rc); + // widen clips to legacy turbo + rc = pgpe_widen_clip_blocking(OCC_STATE_OBSERVATION); - /* - * @errortype - * @moduleid MAIN_SMGR_MID - * @reasoncode PGPE_FAILURE - * @userdata1 PGPE clip update's rc - * @userdata4 ERC_PGPE_CLIP_FAILURE - * @devdesc pgpe clip update not idle - */ - l_errlHndl = createErrl( - MAIN_SMGR_MID, //ModId - PGPE_FAILURE, //Reasoncode - ERC_PGPE_CLIP_FAILURE, //Extended reason code - ERRL_SEV_PREDICTIVE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - G_clip_update_parms_ptr->msg_cb.rc, //Userdata1 - 0 //Userdata2 - ); + if(rc) + { + TRAC_ERR("SMGR: failed to tighten pstate clips."); + break; + } + else // clips set to legacy turbo; stop pstate protocol + { + rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_STOP, G_proc_pmcr_owner); + if(rc) + { + TRAC_ERR("SMGR: Failed to stop the pstate protocol on PGPE."); + 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); + + if(rc) + { + l_error_logged = TRUE; + TRAC_ERR("SMGR: Characterization to Observation Transition Failed"); + + /* @ + * @errortype + * @moduleid MAIN_STATE_TRANSITION_MID + * @reasoncode INTERNAL_FAILURE + * @userdata1 none + * @userdata4 ERC_STATE_FROM_CHR_TO_OBS_FAILURE + * @devdesc Failed changing from observation to characterization + */ + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + INTERNAL_FAILURE, //reasoncode + ERC_STATE_FROM_CHR_TO_OBS_FAILURE, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + 0, //userdata1 + 0); //userdata2 // Callout firmware addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_COMPONENT_ID, - ERRL_COMPONENT_ID_FIRMWARE, - ERRL_CALLOUT_PRIORITY_HIGH); + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); } - else // Clips wide opened with no errors, enable Pstates on PGPE - { + return l_errlHndl; +} - // Pstates are enabled via an IPC call to PGPE, which will - // set the G_proc_pstate_status flag - l_errlHndl = pgpe_start_suspend(PGPE_ACTION_PSTATE_START); +// Function Specification +// +// Name: SMGR_observation_to_characterization +// +// Description: Switch from Observation to Characterization state +// +// End Function Specification +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 + + TRAC_IMP("SMGR: Observation to Characterization Transition Started"); + + // no change in RTL flags, just turn-on pstate protocol, and wide open clips + + do + { + // 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."); + break; + } + // wide open pstate clips + rc = pgpe_widen_clip_blocking(OCC_STATE_CHARACTERIZATION); - if(l_errlHndl) + if(rc) { - TRAC_ERR("SMGR: Failed to switch to Active state because of a " - "failure to start the pstate protocol on PGPE."); + TRAC_ERR("SMGR: failed to widen pstate clips."); + break; } - else + else // successfully wide opened clips; enable pstates, then start transition { - // Pstates enabled, update OPAL static table in main memory + // update OPAL static table in main memory if(G_sysConfigData.system_type.kvm) { // upon succesful enablement of Pstate protocol on // PGPE update OPAL table with pstate information. proc_pstate_kvm_setup(); } + + // 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 on PGPE."); + break; + } + else // Clips wide opened successfully and pstates enabled; complete transition + { + // Set the actual STATE now that we have finished everything else + CURRENT_STATE() = OCC_STATE_CHARACTERIZATION; + + TRAC_IMP("SMGR: Observation to Characterization Transition Completed"); + } } + } while (0); + + if(rc && (false == l_error_logged)) + { + l_error_logged = TRUE; + TRAC_ERR("SMGR: Observation to Characterization Transition Failed"); + /* @ + * @errortype + * @moduleid MAIN_STATE_TRANSITION_MID + * @reasoncode INTERNAL_FAILURE + * @userdata1 none + * @userdata4 ERC_STATE_FROM_OBS_TO_CHR_FAILURE + * @devdesc Failed changing from observation to characterization + */ + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + INTERNAL_FAILURE, //reasoncode + ERC_STATE_FROM_OBS_TO_CHR_FAILURE, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + 0, //userdata1 + 0); //userdata2 + + // Callout firmware + addCalloutToErrl(l_errlHndl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); } - // NOTE that this is really unnecessary if you follow the TMGT OCC - // Interface Spec, which tells you that you need to check for the "Active - // Ready" bit in the poll response before you go to active state. - // But since we have scenerios where TMGT isn't the one putting us in - // active state (we are going there automatically) we needed to add this. + return l_errlHndl; +} + - // If we have all data we need to go to active state, but don't have pstates - // enabled yet...then we will do the aforementioned wait - if(((DATA_get_present_cnfgdata() & SMGR_VALIDATE_DATA_ACTIVE_MASK) == - SMGR_VALIDATE_DATA_ACTIVE_MASK)) + +// Function Specification +// +// Name: SMGR_observation_to_active +// +// Description: Transition from Observation state to Active state +// +// End Function Specification +errlHndl_t SMGR_observation_to_active() +{ + errlHndl_t l_errlHndl = NULL; + static bool l_error_logged = FALSE; // To prevent trace and error log happened over and over + int l_extRc = OCC_NO_EXTENDED_RC; + int l_rc = 0; + do { - SsxTimebase start = ssx_timebase_get(); - while( ! proc_is_hwpstate_enabled() ) + // NOTE that this is really unnecessary if you follow the TMGT OCC + // Interface Spec, which tells you that you need to check for the "Active + // Ready" bit in the poll response before you go to active state. + // But since we have scenerios where TMGT isn't the one putting us in + // active state (we are going there automatically) we needed to add this. + + // If we have all data we need to go to active state, but don't have pstates + // enabled yet...then we will do the aforementioned wait + if(SMGR_MASK_ACTIVE_READY == + (SMGR_validate_get_valid_states() & SMGR_MASK_ACTIVE_READY)) { - SsxInterval timeout = SSX_SECONDS(5); - if ((ssx_timebase_get() - start) > timeout) + l_rc = pgpe_widen_clip_blocking(OCC_STATE_ACTIVE); + + if(l_rc) { - l_rc = 1; - if(FALSE == l_error_logged) + TRAC_ERR("SMGR: Failed to switch to Active state because of a " + "failure to widen clip pstates"); + break; + } + + else // Clips wide opened with no errors, enable Pstates on PGPE + { + + // 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) { - TRAC_ERR("SMGR: Timeout waiting for Pstates to be enabled, " - "pmc_mode[%08x], chips_present[%02x], Cores Present [%08x]", - in32(PMC_MODE_REG), - G_sysConfigData.is_occ_present, - (uint32_t) ((in64(OCB_CCSR)) >> 32)); + l_rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_HOST); + } + else + { + l_rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_OCC); + } + if(l_rc) + { + TRAC_ERR("SMGR: Failed to switch to Active state because of a " + "failure to start the pstate protocol on PGPE."); + break; } - l_extRc = ERC_GENERIC_TIMEOUT; - break; } - } - if(proc_is_hwpstate_enabled() && G_sysConfigData.system_type.kvm) + + // Wait for pstates enablement completition. + SsxTimebase start = ssx_timebase_get(); + while( ! proc_is_hwpstate_enabled() ) + { + SsxInterval timeout = SSX_SECONDS(5); + if ((ssx_timebase_get() - start) > timeout) + { + l_rc = 1; + if(FALSE == l_error_logged) + { + TRAC_ERR("SMGR: Timeout waiting for Pstates to be enabled, " + "pmc_mode[%08x], chips_present[%02x], Cores Present [%08x]", + in32(PMC_MODE_REG), + G_sysConfigData.is_occ_present, + (uint32_t) ((in64(OCB_CCSR)) >> 32)); + } + l_extRc = ERC_GENERIC_TIMEOUT; + break; + } + } + + // if pstates are now enabled, all conditions are already met + // to transition to active state. + if(proc_is_hwpstate_enabled() ) + { + l_error_logged = FALSE; + TRAC_IMP("SMGR: Observation to Active Transition Started"); + + // 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 + if(G_sysConfigData.system_type.kvm) + { + TRAC_IMP("SMGR: Pstates are enabled, continuing with state trans"); + + // upon succesful enablement of Pstate protocol on + // PGPE update OPAL table with pstate information. + 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"); + } + else + { + TRAC_ERR("SMGR: Observation to Active Transition Failed, because pstates are not enabled"); + } + + if(l_rc && FALSE == l_error_logged) + { + l_error_logged = TRUE; + /* @ + * @errortype + * @moduleid MAIN_STATE_TRANSITION_MID + * @reasoncode INTERNAL_FAILURE + * @userdata1 SMGR_MASK_ACTIVE_READY + * @userdata2 valid states + * @userdata4 ERC_STATE_FROM_OBS_TO_STB_FAILURE + * @devdesc Failed changing from observation to standby + */ + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + INTERNAL_FAILURE, //reasoncode + l_extRc, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + SMGR_MASK_ACTIVE_READY, //userdata1 + SMGR_validate_get_valid_states());//userdata2 + + // Callout firmware + addCalloutToErrl(l_errlHndl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + } + } // Active Ready + else { - TRAC_IMP("SMGR: Pstates are enabled, continuing with state trans"); + TRAC_ERR("SMGR: Observation to Active Transition Failed, " + "OCC is not Active Ready cnfgdata=0x%08x, reqd=0x%08x", + DATA_get_present_cnfgdata(), + SMGR_VALIDATE_DATA_ACTIVE_MASK); } - } + } while (0); - // Check if all conditions are met to transition to active state. If - // they aren't, then log an error and fail to change state. - if( (SMGR_MASK_ACTIVE_READY == - (SMGR_validate_get_valid_states() & SMGR_MASK_ACTIVE_READY)) - && proc_is_hwpstate_enabled() ) - { - l_error_logged = FALSE; - TRAC_IMP("SMGR: Observation to Active Transition Started"); + return l_errlHndl; +} - // 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); +// Function Specification +// +// Name: SMGR_characterization_to_active +// +// Description: Transition from Characterization state to Active state +// +// 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 - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_ACTIVE; - TRAC_IMP("SMGR: Observation to Active Transition Completed"); - } - else if(l_rc) + do { - TRAC_ERR("SMGR: Observation to Active Transition Failed, cnfgdata=0x%08x, reqd=0x%08x", - DATA_get_present_cnfgdata(), - SMGR_VALIDATE_DATA_ACTIVE_MASK); - } + // 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: Failed to change PMCR ownership on PGPE."); + break; + } + + // Have all data we need to go to active state + if(((DATA_get_present_cnfgdata() & SMGR_VALIDATE_DATA_ACTIVE_MASK) == + SMGR_VALIDATE_DATA_ACTIVE_MASK) && + // and Psate protocol is enabled + proc_is_hwpstate_enabled() && G_sysConfigData.system_type.kvm) + { + TRAC_IMP("SMGR: Pstates are enabled, continuing with state trans"); + } + + // Check if all conditions are met to transition to active state. If + // they aren't, then log an error and fail to change state. + if( (SMGR_MASK_ACTIVE_READY == + (SMGR_validate_get_valid_states() & SMGR_MASK_ACTIVE_READY)) + && proc_is_hwpstate_enabled() ) + { + l_error_logged = FALSE; + TRAC_IMP("SMGR: Characterization to Active Transition Started"); + + // 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"); + } + } while (0); - if(l_rc && FALSE == l_error_logged) + if(rc && (false == l_error_logged)) { l_error_logged = TRUE; /* @ @@ -386,29 +794,28 @@ errlHndl_t SMGR_observation_to_active() * @reasoncode INTERNAL_FAILURE * @userdata1 SMGR_MASK_ACTIVE_READY * @userdata2 valid states - * @userdata4 ERC_STATE_FROM_OBS_TO_STB_FAILURE - * @devdesc Failed changing from observation to standby + * @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 - l_extRc, //Extended reason code - ERRL_SEV_UNRECOVERABLE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - SMGR_MASK_ACTIVE_READY, //userdata1 - SMGR_validate_get_valid_states());//userdata2 + 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 + SMGR_MASK_ACTIVE_READY, //userdata1 + SMGR_validate_get_valid_states()); //userdata2 // Callout firmware addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_COMPONENT_ID, - ERRL_COMPONENT_ID_FIRMWARE, - ERRL_CALLOUT_PRIORITY_HIGH); - + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); } + return l_errlHndl; } - // Function Specification // // Name: SMGR_active_to_observation @@ -416,22 +823,151 @@ errlHndl_t SMGR_observation_to_active() // Description: // // End Function Specification + errlHndl_t SMGR_active_to_observation() { - errlHndl_t l_errlHndl = NULL; + int rc = 0; + errlHndl_t l_errlHndl = NULL; + uint8_t wait_time = 0; TRAC_IMP("SMGR: Active to Observation Transition Started"); - // 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); + do + { + // 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; + } - // Set the actual STATE now that we have finished everything else - CURRENT_STATE() = OCC_STATE_OBSERVATION; + // Sleep enables context switching. + ssx_sleep(SSX_MICROSECONDS(10)); + wait_time += 10; + } - TRAC_IMP("SMGR: Active to Observation Transition Completed"); + // check for timeout while waiting for pgpe_start_suspend() IPC completion + if(wait_time > WAIT_PGPE_TASK_TIMEOUT) + { + TRAC_ERR("SMGR: Timeout waiting for G_active_to_observation_ready flag."); + + /* @ + * @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 + */ + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + PGPE_FAILURE, //reasoncode + ERC_PGPE_ACTIVE_TO_OBSERVATION_TIMEOUT, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + wait_time, //userdata1 + 0); //userdata2 + + // Callout firmware + addCalloutToErrl(l_errlHndl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + + rc = PGPE_FAILURE; + break; + } + + wait_time = 0; + + // wait until clip update task is done + while(!async_request_is_idle(&G_clip_update_req.request)) + { + if(wait_time > WAIT_PGPE_TASK_TIMEOUT) + { + break; + } + + // 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 pgpe_start_suspend() IPC completion + if(wait_time > WAIT_PGPE_TASK_TIMEOUT) + { + TRAC_ERR("SMGR: Timeout waiting for clip update IPC task"); + + /* @ + * @errortype + * @moduleid MAIN_STATE_TRANSITION_MID + * @reasoncode PGPE_FAILURE + * @userdata1 wait_time + * @userdata4 ERC_PGPE_TASK_TIMEOUT + * @devdesc timeout waiting for pstates start/suspend task + */ + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + PGPE_FAILURE, //reasoncode + ERC_PGPE_TASK_TIMEOUT, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + wait_time, //userdata1 + 0); //userdata2 + + // Callout firmware + addCalloutToErrl(l_errlHndl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + + rc = PGPE_FAILURE; + break; + } + + rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_STOP, G_proc_pmcr_owner); + if(rc) + { + TRAC_ERR("SMGR: failed to stop the pstate protocol on PGPE."); + break; + } + else // Pstates Disabled and clips wide opened successfully, 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; + } + + } while (0); + + if(rc) + { + TRAC_ERR("SMGR: Failed to switch to Observation state"); + } + else + { + // Pstates disabled, update OPAL static table in main memory + if(G_sysConfigData.system_type.kvm) + { + // upon succesful enablement of Pstate protocol on + // PGPE update OPAL table with pstate information. + proc_pstate_kvm_setup(); + } + + TRAC_IMP("SMGR: Active to Observation Transition Completed"); + } return l_errlHndl; } @@ -439,31 +975,88 @@ errlHndl_t SMGR_active_to_observation() // Function Specification // -// Name: SMGR_active_to_standby +// Name: SMGR_active_to_characterization // -// Description: +// Description: Switch from Active to characterization state // // End Function Specification -errlHndl_t SMGR_active_to_standby() +errlHndl_t SMGR_active_to_characterization() { - errlHndl_t l_errlHndl = NULL; + int rc = 0; + errlHndl_t l_errlHndl = NULL; - TRAC_IMP("SMGR: Active to Standby Transition Started"); + TRAC_IMP("SMGR: Active to Characterization Transition Started"); - // Transtion through both functions on this multi-state transtion - l_errlHndl = SMGR_active_to_observation(); - if(NULL == l_errlHndl) + do { - l_errlHndl = SMGR_observation_to_standby(); - } + // open wide pstate clips + rc = pgpe_widen_clip_blocking(OCC_STATE_CHARACTERIZATION); - if(l_errlHndl) + if(rc) + { + TRAC_ERR("SMGR: failed to widen pstate clips."); + break; + } + else // clips widened successfully, keep pstates enabled, but change ownership + { + rc = pgpe_start_suspend(PGPE_ACTION_PSTATE_START, PMCR_OWNER_CHAR); + + if(rc) + { + TRAC_ERR("SMGR: failed to change PMCR ownership."); + break; + } + else // Pstates Disabled and clips wide opened successfully, perform state transition + { + // 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; + } + } + } while (0); + + if(rc) { - TRAC_ERR("SMGR: Active to Standby Transition Failed"); + TRAC_ERR("SMGR: Failed to switch to Characterization state"); + /* @ + * @errortype + * @moduleid MAIN_STATE_TRANSITION_MID + * @reasoncode INTERNAL_FAILURE + * @userdata1 rc + * @userdata4 ERC_STATE_FROM_ACT_TO_CHR_FAILURE + * @devdesc Failed changing from standby to observation + */ + l_errlHndl = createErrl(MAIN_STATE_TRANSITION_MID, //modId + INTERNAL_FAILURE, //reasoncode + ERC_STATE_FROM_ACT_TO_CHR_FAILURE,//Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + rc, //userdata1 + 0); //userdata2 + + // Callout firmware + addCalloutToErrl(l_errlHndl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); } else { - TRAC_IMP("SMGR: Active to Standby Transition Completed"); + // Pstates disabled, update OPAL static table in main memory + if(G_sysConfigData.system_type.kvm) + { + // upon succesful enablement of Pstate protocol on + // PGPE update OPAL table with pstate information. + proc_pstate_kvm_setup(); + } + + TRAC_IMP("SMGR: Active to Characterization Transition Completed"); } return l_errlHndl; diff --git a/src/occ_405/state.h b/src/occ_405/state.h index 9752b9f..17ae7b6 100755 --- a/src/occ_405/state.h +++ b/src/occ_405/state.h @@ -31,6 +31,9 @@ #include "errl.h" #include "mode.h" +// Maximum allowed value approx. 16.3 ms +#define PCBS_HEARBEAT_TIME_US 16320 + extern uint32_t G_smgr_validate_data_active_mask; extern uint32_t G_smgr_validate_data_observation_mask; @@ -52,6 +55,7 @@ typedef enum OCC_STATE_OBSERVATION = 0x02, OCC_STATE_ACTIVE = 0x03, OCC_STATE_SAFE = 0x04, + OCC_STATE_CHARACTERIZATION = 0x05, // Make sure this is after the last valid state OCC_STATE_COUNT, @@ -63,8 +67,9 @@ typedef enum } OCC_STATE; // These are the only states that TMGT/HTMGT can send -#define OCC_STATE_IS_VALID(state) ((state == OCC_STATE_NOCHANGE) || \ - (state == OCC_STATE_OBSERVATION) || \ +#define OCC_STATE_IS_VALID(state) ((state == OCC_STATE_NOCHANGE) || \ + (state == OCC_STATE_OBSERVATION) || \ + (state == OCC_STATE_CHARACTERIZATION) || \ (state == OCC_STATE_ACTIVE)) /** @@ -144,6 +149,9 @@ typedef enum // Returns true if OCC State is observation #define IS_OCC_STATE_OBSERVATION() ( (OCC_STATE_OBSERVATION == G_occ_internal_state)? 1 : 0 ) +// Returns true if OCC State is charaterization +#define IS_OCC_STATE_CHARACTERIZATION() ( (OCC_STATE_CHARACTERIZATION == G_occ_internal_state)? 1 : 0 ) + /** * @struct smgr_state_trans_t * @brief Used by the "Set State" command to call the correct transition @@ -162,6 +170,24 @@ extern OCC_STATE G_occ_internal_req_state; extern OCC_STATE G_occ_master_state; extern OCC_STATE G_occ_external_req_state; +// State Transition Function Calls +errlHndl_t SMGR_standby_to_observation(); +errlHndl_t SMGR_standby_to_characterization(); +errlHndl_t SMGR_standby_to_active(); + +errlHndl_t SMGR_observation_to_characterization(); +errlHndl_t SMGR_observation_to_active(); + +errlHndl_t SMGR_characterization_to_observation(); +errlHndl_t SMGR_characterization_to_active(); + +errlHndl_t SMGR_active_to_observation(); +errlHndl_t SMGR_active_to_characterization(); + +errlHndl_t SMGR_all_to_standby(); + +errlHndl_t SMGR_all_to_safe(); + // Used by macro above to clear flag indicating to not halt OCC when a reset // is requested. inline void reset_disable_halt(void); @@ -182,5 +208,5 @@ errlHndl_t SMGR_set_state(OCC_STATE i_state); // parms we currently know. uint8_t SMGR_validate_get_valid_states(void); -#endif +#endif // _state_h diff --git a/src/occ_405/thread/chom.c b/src/occ_405/thread/chom.c index 979d44d..5e2d6e8 100755 --- a/src/occ_405/thread/chom.c +++ b/src/occ_405/thread/chom.c @@ -402,8 +402,10 @@ void chom_main() chom_data_init(); } - // only update chom sensors on an active OCC - if (IS_OCC_STATE_ACTIVE()) + // only update chom sensors on active, observing, or characterizing OCCs + if (IS_OCC_STATE_ACTIVE() || + IS_OCC_STATE_OBSERVATION() || + IS_OCC_STATE_CHARACTERIZATION()) { chom_update_sensors(); } |