summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/pstate_pgpe_occ_api.h53
-rwxr-xr-xsrc/occ_405/amec/amec_data.c8
-rwxr-xr-xsrc/occ_405/amec/amec_freq.c3
-rwxr-xr-xsrc/occ_405/amec/amec_slave_smh.c10
-rwxr-xr-xsrc/occ_405/main.c12
-rw-r--r--src/occ_405/occ_service_codes.h17
-rw-r--r--src/occ_405/pgpe/pgpe_interface.c325
-rw-r--r--src/occ_405/pgpe/pgpe_interface.h15
-rw-r--r--src/occ_405/pgpe/pgpe_service_codes.h3
-rwxr-xr-xsrc/occ_405/proc/proc_data_control.c243
-rwxr-xr-xsrc/occ_405/state.c971
-rwxr-xr-xsrc/occ_405/state.h32
-rwxr-xr-xsrc/occ_405/thread/chom.c6
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();
}
OpenPOWER on IntegriCloud