summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2017-11-10 06:01:29 -0600
committerMartha Broyles <mbroyles@us.ibm.com>2017-12-18 11:42:27 -0500
commit0bf193d8d4f98934d4f539b1950e8b46c03a2716 (patch)
treeb429746ff2533b2fc95178cfc7342457c0b46ed0
parentfce2d94a9bc94e9468bce173b11fd0b96ef36c1f (diff)
downloadtalos-occ-0bf193d8d4f98934d4f539b1950e8b46c03a2716.tar.gz
talos-occ-0bf193d8d4f98934d4f539b1950e8b46c03a2716.zip
APSS Reset Support
Change-Id: I23dd10a7bc78841ecd4382e8ac8667afbb7c2ddd RTC: 163601 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/49871 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com>
-rw-r--r--src/common/apss_structs.h4
-rw-r--r--src/common/ipc_func_ids.h1
-rwxr-xr-xsrc/occ_405/amec/amec_master_smh.c7
-rwxr-xr-xsrc/occ_405/amec/amec_sensors_power.c4
-rwxr-xr-xsrc/occ_405/dcom/dcom.h4
-rw-r--r--src/occ_405/dcom/dcomMasterTx.c5
-rw-r--r--src/occ_405/occ_service_codes.h1
-rwxr-xr-xsrc/occ_405/pss/apss.c426
-rw-r--r--src/occ_405/pss/apss.h14
-rwxr-xr-xsrc/occ_405/pss/pss_service_codes.h1
-rwxr-xr-xsrc/occ_405/rtls/rtls.h1
-rwxr-xr-xsrc/occ_405/rtls/rtls_tables.c10
-rw-r--r--src/occ_gpe0/apss_init.c89
-rw-r--r--src/occ_gpe0/ipc_func_tables.c3
-rw-r--r--src/occ_gpe1/gpe_gpu_init.c2
15 files changed, 533 insertions, 39 deletions
diff --git a/src/common/apss_structs.h b/src/common/apss_structs.h
index af64fe0..99242fa 100644
--- a/src/common/apss_structs.h
+++ b/src/common/apss_structs.h
@@ -91,4 +91,8 @@ typedef struct {
uint64_t meas_data[4]; // G_apss_pwr_meas (2nd block of data) (output from APSS)
} apss_complete_args_t;
+typedef struct {
+ GpeErrorStruct error;
+} apss_reset_args_t;
+
#endif //_APSS_STRUCTS_H
diff --git a/src/common/ipc_func_ids.h b/src/common/ipc_func_ids.h
index cdd80fb..4684937 100644
--- a/src/common/ipc_func_ids.h
+++ b/src/common/ipc_func_ids.h
@@ -61,6 +61,7 @@ IPC_FUNCIDS_TABLE_START
IPC_FUNC_ID(IPC_ST_GET_NEST_DTS_FUNCID)
IPC_FUNC_ID(IPC_ST_FIR_COLLECTION)
IPC_FUNC_ID(IPC_ST_GET_TOD_FUNCID)
+ IPC_FUNC_ID(IPC_ST_APSS_RESET_FUNCID)
IPC_FUNCIDS_ST_END(OCCHW_INST_ID_GPE0)
//Functions that are only supported by GPE1 should be defined here
diff --git a/src/occ_405/amec/amec_master_smh.c b/src/occ_405/amec/amec_master_smh.c
index ab2a3af..74559c6 100755
--- a/src/occ_405/amec/amec_master_smh.c
+++ b/src/occ_405/amec/amec_master_smh.c
@@ -899,8 +899,11 @@ void amec_mst_common_tasks_post(void)
//Call OCC pcaps mismatch function
amec_mst_check_pcaps_match();
- //Call check under power cap function
- amec_mst_check_under_pcap();
+ if(0 == G_dcom_slv_inbox_doorbell_rx.apss_recovery_in_progress)
+ {
+ //Call check under power cap function
+ amec_mst_check_under_pcap();
+ }
}
}
diff --git a/src/occ_405/amec/amec_sensors_power.c b/src/occ_405/amec/amec_sensors_power.c
index b168c02..77e727b 100755
--- a/src/occ_405/amec/amec_sensors_power.c
+++ b/src/occ_405/amec/amec_sensors_power.c
@@ -198,7 +198,9 @@ void amec_update_apss_sensors(void)
{
// Need to check to make sure APSS data has been received
// via slave inbox first
- if (G_slv_inbox_received && (G_pwr_reading_type == PWR_READING_TYPE_APSS))
+ if (G_slv_inbox_received &&
+ (G_pwr_reading_type == PWR_READING_TYPE_APSS) &&
+ (0 == G_dcom_slv_inbox_doorbell_rx.apss_recovery_in_progress))
{
uint8_t l_proc = G_pbax_id.chip_id;
uint32_t temp32 = 0;
diff --git a/src/occ_405/dcom/dcom.h b/src/occ_405/dcom/dcom.h
index 109b4ef..3bbfcda 100755
--- a/src/occ_405/dcom/dcom.h
+++ b/src/occ_405/dcom/dcom.h
@@ -273,8 +273,10 @@ typedef struct
uint16_t adc[MAX_APSS_ADC_CHANNELS]; // 32 bytes
// Time of Day Clock from the last APSS reading
uint64_t tod; // 8 bytes
+ // Apss reset in progress
+ uint8_t apss_recovery_in_progress; // 1 byte
// Reserved
- uint8_t _reserved_1[51]; // 51 bytes
+ uint8_t _reserved_1[50]; // 50 bytes
// Counter in case we want to determine sequence errors
uint8_t magic_counter; // 1 byte
// Magic Number for denoting the end of the packet
diff --git a/src/occ_405/dcom/dcomMasterTx.c b/src/occ_405/dcom/dcomMasterTx.c
index a65dc31..7ba80e3 100644
--- a/src/occ_405/dcom/dcomMasterTx.c
+++ b/src/occ_405/dcom/dcomMasterTx.c
@@ -183,6 +183,7 @@ uint32_t dcom_build_slv_inbox(void)
G_dcom_slv_inbox_doorbell_tx.gpio[0] = G_apss_pwr_meas.gpio[0];
G_dcom_slv_inbox_doorbell_tx.gpio[1] = G_apss_pwr_meas.gpio[1];
G_dcom_slv_inbox_doorbell_tx.tod = G_apss_pwr_meas.tod;
+ G_dcom_slv_inbox_doorbell_tx.apss_recovery_in_progress = G_apss_recovery_requested;
G_dcom_slv_inbox_doorbell_tx.magic_counter++;
G_dcom_slv_inbox_doorbell_tx.magic2 = PBAX_MAGIC_NUMBER_32B;
@@ -245,7 +246,9 @@ void task_dcom_tx_slv_inbox( task_t *i_self)
{
// If we are in standby or no APSS present, we need to fake out
// the APSS data since we aren't talking to APSS.
- if( (OCC_STATE_STANDBY == CURRENT_STATE()) || (G_pwr_reading_type != PWR_READING_TYPE_APSS) )
+ if( (OCC_STATE_STANDBY == CURRENT_STATE()) ||
+ (G_pwr_reading_type != PWR_READING_TYPE_APSS) ||
+ G_apss_recovery_requested )
{
G_ApssPwrMeasCompleted = TRUE;
}
diff --git a/src/occ_405/occ_service_codes.h b/src/occ_405/occ_service_codes.h
index 6eb66a4..f357c88 100644
--- a/src/occ_405/occ_service_codes.h
+++ b/src/occ_405/occ_service_codes.h
@@ -199,6 +199,7 @@ enum occExtReasonCode
ERC_APSS_ADC_OUT_OF_RANGE_FAILURE = 0x0026,
ERC_APSS_ADC_DUPLICATED_FAILURE = 0x0027,
ERC_APSS_NO_VALID_DATA = 0x0028,
+ ERC_APSS_RESET_FAILURE = 0x0029,
ERC_AMEC_PCAPS_MISMATCH_FAILURE = 0x002A,
ERC_AMEC_UNDER_PCAP_FAILURE = 0x002B,
diff --git a/src/occ_405/pss/apss.c b/src/occ_405/pss/apss.c
index 6e50313..6c68a74 100755
--- a/src/occ_405/pss/apss.c
+++ b/src/occ_405/pss/apss.c
@@ -59,18 +59,23 @@ uint64_t G_gpe_apss_time_start;
uint64_t G_gpe_apss_time_end;
// Flag for requesting APSS recovery when OCC detects all zeroes or data out of sync
-bool G_apss_recovery_requested = FALSE;
+volatile bool G_apss_recovery_requested = FALSE;
bool G_apss_data_traced = FALSE;
GPE_BUFFER(apss_start_args_t G_gpe_start_pwr_meas_read_args);
GPE_BUFFER(apss_continue_args_t G_gpe_continue_pwr_meas_read_args);
GPE_BUFFER(apss_complete_args_t G_gpe_complete_pwr_meas_read_args);
+GPE_BUFFER(apss_reset_args_t G_gpe_apss_reset_args);
GpeRequest G_meas_start_request;
GpeRequest G_meas_cont_request;
GpeRequest G_meas_complete_request;
+GpeRequest G_init_gpio_request;
+GpeRequest G_init_mode_request;
+GpeRequest G_apss_reset_request;
// Up / down counter for redundant apss failures
uint32_t G_backup_fail_count = 0;
+uint32_t G_apss_reset_count = 0;
#ifdef DEBUG_APSS_SEQ
uint32_t G_sequence_start = 0;
@@ -144,9 +149,11 @@ void dumpHexString(const void *i_data, const unsigned int len, const char *strin
// End Function Specification
void do_apss_recovery(void)
{
+ errlHndl_t l_err = NULL;
+
if (!G_apss_data_traced)
{
- INTR_TRAC_ERR("detected invalid power data[%08x%08x]",
+ INTR_TRAC_ERR("detected invalid power data[%08x%08x]. Requesting APSS reset.",
(uint32_t)(G_gpe_continue_pwr_meas_read_args.meas_data[0] >> 32),
(uint32_t)(G_gpe_continue_pwr_meas_read_args.meas_data[0] & 0x00000000ffffffffull));
G_apss_data_traced = TRUE;
@@ -160,6 +167,12 @@ void do_apss_recovery(void)
{
// Increment the up/down counter
G_backup_fail_count++;
+
+ rtl_stop_task(TASK_ID_APSS_START);
+ rtl_stop_task(TASK_ID_APSS_CONT);
+ rtl_stop_task(TASK_ID_APSS_DONE);
+
+ rtl_start_task(TASK_ID_APSS_RESET);
}
else
{
@@ -179,14 +192,14 @@ void do_apss_recovery(void)
* @userdata4 OCC_NO_EXTENDED_RC
* @devdesc Redundant APSS failure. Power Management Redundancy Lost.
*/
- errlHndl_t l_err = createErrl(PSS_MID_DO_APSS_RECOVERY,
- REDUNDANT_APSS_GPE_FAILURE,
- OCC_NO_EXTENDED_RC,
- ERRL_SEV_PREDICTIVE,
- NULL,
- DEFAULT_TRACE_SIZE,
- 0,
- 0);
+ l_err = createErrl(PSS_MID_DO_APSS_RECOVERY,
+ REDUNDANT_APSS_GPE_FAILURE,
+ OCC_NO_EXTENDED_RC,
+ ERRL_SEV_PREDICTIVE,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ 0,
+ 0);
// APSS callout
addCalloutToErrl(l_err,
@@ -212,6 +225,45 @@ void do_apss_recovery(void)
commitErrl(&l_err);
}
}
+ else
+ {
+ rtl_stop_task(TASK_ID_APSS_START);
+ rtl_stop_task(TASK_ID_APSS_CONT);
+ rtl_stop_task(TASK_ID_APSS_DONE);
+
+ if(G_apss_reset_count < APSS_MAX_NUM_RESET_RETRIES)
+ {
+ ++G_apss_reset_count;
+ rtl_start_task(TASK_ID_APSS_RESET);
+ }
+ else
+ {
+ /*
+ * @errortype
+ * @moduleid PSS_MID_DO_APSS_RECOVERY
+ * @reasoncode APSS_HARD_FAILURE
+ * @userdata1 0
+ * @userdata2 0
+ * @userdata4 ERC_APSS_RESET_FAILURE
+ * @devdesc apss reset failed 3 times
+ */
+ l_err = createErrl(PSS_MID_DO_APSS_RECOVERY,
+ APSS_HARD_FAILURE,
+ ERC_APSS_RESET_FAILURE,
+ ERRL_SEV_UNRECOVERABLE,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ 0,
+ 0);
+
+ addCalloutToErrl(l_err,
+ ERRL_CALLOUT_TYPE_HUID,
+ G_sysConfigData.apss_huid,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+
+ REQUEST_RESET(l_err);
+ }
+ }
}
// Note: The complete request must be global, since it must stick around until after the
@@ -412,7 +464,7 @@ void task_apss_continue_pwr_meas(struct task *i_self)
break;
}
- //Don't run anything if apss recovery is in progress
+ // Don't run anything if apps recovery has been requested
if(G_apss_recovery_requested)
{
break;
@@ -551,6 +603,12 @@ void task_apss_continue_pwr_meas(struct task *i_self)
// End Function Specification
#define APSS_ADC_SEQ_MASK 0xf000f000f000f000ull
#define APSS_ADC_SEQ_CHECK 0x0000100020003000ull
+
+#ifdef DEBUG_APSS_RESET
+// Make var in cacheless section
+GPE_BUFFER(volatile int g_force_apss_reset) = 0;
+#endif
+
void reformat_meas_data()
{
// NO TRACING ALLOWED IN CRITICAL INTERRUPT (any IPC callback functions)
@@ -566,7 +624,11 @@ void reformat_meas_data()
}
// Check that the first 4 sequence nibbles are 0, 1, 2, 3 in the ADC data
- if (((G_gpe_continue_pwr_meas_read_args.meas_data[0] & APSS_ADC_SEQ_MASK) != APSS_ADC_SEQ_CHECK) ||
+ if(
+#ifdef DEBUG_APSS_RESET
+ g_force_apss_reset ||
+#endif
+ ((G_gpe_continue_pwr_meas_read_args.meas_data[0] & APSS_ADC_SEQ_MASK) != APSS_ADC_SEQ_CHECK) ||
!(G_gpe_continue_pwr_meas_read_args.meas_data[0] & ~APSS_ADC_SEQ_MASK))
{
// Recovery will begin on the next tick
@@ -574,6 +636,9 @@ void reformat_meas_data()
// Indicate that collection completed but is invalid so tx_slv_inbox will stop waiting for valid data
G_ApssPwrMeasDoneInvalid = TRUE;
G_apss_recovery_requested = TRUE;
+#ifdef DEBUG_APSS_RESET
+ g_force_apss_reset = 0;
+#endif
break;
}
else
@@ -649,12 +714,11 @@ void task_apss_complete_pwr_meas(struct task *i_self)
}
if(G_apss_recovery_requested)
{
- // Allow apss measurement to proceed on next tick
- G_apss_recovery_requested = FALSE;
+ // Just in case it's possible to get here after G_apss_recovery_requested is true,
+ // but before apss reset starts
break;
}
-
if (L_scheduled)
{
if ((ASYNC_REQUEST_STATE_COMPLETE != G_meas_complete_request.request.completion_state) ||
@@ -831,7 +895,6 @@ bool apss_gpio_get(uint8_t i_pin_number, uint8_t *o_pin_value)
errlHndl_t initialize_apss(void)
{
errlHndl_t l_err = NULL;
- GpeRequest l_request; //Used once here to initialize apss.
uint8_t l_retryCount = 0;
// Initialize APSS
@@ -855,7 +918,7 @@ errlHndl_t initialize_apss(void)
// Create/schedule IPC_ST_APSS_INIT_GPIO_FUNCID and wait for it to complete (BLOCKING)
TRAC_INFO("initialize_apss: Creating request for GPE_apss_initialize_gpio");
- gpe_request_create(&l_request, // request
+ gpe_request_create(&G_init_gpio_request, // request
&G_async_gpe_queue0, // queue
IPC_ST_APSS_INIT_GPIO_FUNCID, // Function ID
&G_gpe_apss_initialize_gpio_args, // GPE argument_ptr
@@ -866,10 +929,10 @@ errlHndl_t initialize_apss(void)
// Schedule the request to be executed
TRAC_INFO("initialize_apss: Scheduling request for IPC_ST_APSS_INIT_GPIO_FUNCID");
- gpe_request_schedule(&l_request);
+ gpe_request_schedule(&G_init_gpio_request);
// Check for a timeout only; will create the error below.
- if(ASYNC_REQUEST_STATE_TIMED_OUT == l_request.request.completion_state)
+ if(ASYNC_REQUEST_STATE_TIMED_OUT == G_init_gpio_request.request.completion_state)
{
// For whatever reason, we hit a timeout. It could be either
// that the HW did not work, or the request didn't ever make
@@ -881,10 +944,10 @@ errlHndl_t initialize_apss(void)
TRAC_INFO("initialize_apss: GPE_apss_initialize_gpio completed w/rc=0x%08x",
- l_request.request.completion_state);
+ G_init_gpio_request.request.completion_state);
// Only continue if initializaton completed without any errors.
- if ((ASYNC_REQUEST_STATE_COMPLETE == l_request.request.completion_state) &&
+ if ((ASYNC_REQUEST_STATE_COMPLETE == G_init_gpio_request.request.completion_state) &&
(G_gpe_apss_initialize_gpio_args.error.rc == ERRL_RC_SUCCESS))
{
// Setup the mode structure to pass to the GPE program
@@ -899,7 +962,7 @@ errlHndl_t initialize_apss(void)
// Create/schedule GPE_apss_set_mode and wait for it to complete (BLOCKING)
TRAC_INFO("initialize_apss: Creating request for GPE_apss_set_mode");
- gpe_request_create(&l_request, // request
+ gpe_request_create(&G_init_mode_request, // request
&G_async_gpe_queue0, // queue
IPC_ST_APSS_INIT_MODE_FUNCID, // Function ID
&G_gpe_apss_set_mode_args, // GPE argument_ptr
@@ -908,10 +971,10 @@ errlHndl_t initialize_apss(void)
NULL, // callback arg
ASYNC_REQUEST_BLOCKING); // options
//Schedule set_mode
- gpe_request_schedule(&l_request);
+ gpe_request_schedule(&G_init_mode_request);
// Check for a timeout, will create the error log later
- if(ASYNC_REQUEST_STATE_TIMED_OUT == l_request.request.completion_state)
+ if(ASYNC_REQUEST_STATE_TIMED_OUT == G_init_mode_request.request.completion_state)
{
// For whatever reason, we hit a timeout. It could be either
// that the HW did not work, or the request didn't ever make
@@ -922,10 +985,10 @@ errlHndl_t initialize_apss(void)
}
TRAC_INFO("initialize_apss: GPE_apss_set_mode completed w/rc=0x%08x",
- l_request.request.completion_state);
+ G_init_mode_request.request.completion_state);
//Continue only if mode set was successful.
- if ((ASYNC_REQUEST_STATE_COMPLETE != l_request.request.completion_state) ||
+ if ((ASYNC_REQUEST_STATE_COMPLETE != G_init_mode_request.request.completion_state) ||
(G_gpe_apss_set_mode_args.error.rc != ERRL_RC_SUCCESS))
{
/*
@@ -944,8 +1007,8 @@ errlHndl_t initialize_apss(void)
ERRL_SEV_UNRECOVERABLE, // i_severity
NULL, // i_trace,
0x0000, // i_traceSz,
- l_request.request.completion_state, // i_userData1,
- l_request.request.abort_state); // i_userData2
+ G_init_mode_request.request.completion_state, // i_userData1,
+ G_init_mode_request.request.abort_state); // i_userData2
addUsrDtlsToErrl(l_err,
(uint8_t*)&G_gpe_apss_set_mode_args,
sizeof(G_gpe_apss_set_mode_args),
@@ -973,8 +1036,8 @@ errlHndl_t initialize_apss(void)
ERRL_SEV_UNRECOVERABLE, // i_severity
NULL, // tracDesc_t i_trace,
0x0000, // i_traceSz,
- l_request.request.completion_state, // i_userData1,
- l_request.request.abort_state); // i_userData2
+ G_init_gpio_request.request.completion_state, // i_userData1,
+ G_init_gpio_request.request.abort_state); // i_userData2
addUsrDtlsToErrl(l_err,
(uint8_t*)&G_gpe_apss_initialize_gpio_args,
@@ -1021,6 +1084,36 @@ errlHndl_t initialize_apss(void)
NULL, // callback arg
ASYNC_CALLBACK_IMMEDIATE); // options
+ // Active state versions of initialization requests
+ TRAC_INFO("initialize_apss: Creating request G_init_gpio_request for active state.");
+ gpe_request_create(&G_init_gpio_request, // request
+ &G_async_gpe_queue0, // queue
+ IPC_ST_APSS_INIT_GPIO_FUNCID, // Function ID
+ &G_gpe_apss_initialize_gpio_args, // GPE argument_ptr
+ SSX_WAIT_FOREVER, // timeout
+ NULL, // callback
+ NULL, // callback arg
+ ASYNC_CALLBACK_IMMEDIATE); // options
+
+ TRAC_INFO("initialize_apss: Creating request G_init_mode_request for active state.");
+ gpe_request_create(&G_init_mode_request, // request
+ &G_async_gpe_queue0, // queue
+ IPC_ST_APSS_INIT_MODE_FUNCID, // Function ID
+ &G_gpe_apss_set_mode_args, // GPE argument_ptr
+ SSX_WAIT_FOREVER, // timeout
+ NULL, // callback
+ NULL, // callback arg
+ ASYNC_CALLBACK_IMMEDIATE); // options
+
+ TRAC_INFO("initialize_apss: Creating request G_reset_request.");
+ gpe_request_create(&G_apss_reset_request, // request
+ &G_async_gpe_queue0, // queue
+ IPC_ST_APSS_RESET_FUNCID, // Function ID
+ &G_gpe_apss_reset_args, // GPE argument_ptr
+ SSX_WAIT_FOREVER, // timeout
+ NULL, // callback
+ NULL, // callback arg
+ ASYNC_CALLBACK_IMMEDIATE); // options
// Successfully initialized APSS, no need to go through again. Let's leave.
break;
}
@@ -1042,3 +1135,276 @@ errlHndl_t initialize_apss(void)
return l_err;
}
+
+void task_apss_reset(task_t *i_self)
+{
+ int schedule_rc = 0;
+ static int L_apss_reset_state = APSS_RESET_STATE_START;
+
+ static bool L_scheduled_reset = FALSE;
+ static bool L_scheduled_init_gpio = FALSE;
+ static bool L_scheduled_init_mode = FALSE;
+
+ static bool L_reset_ffdc_collected = FALSE;
+ static bool L_init_gpio_ffdc_collected = FALSE;
+ static bool L_init_mode_ffdc_collected = FALSE;
+
+ APSS_DBG("Calling task_apss_reset. State %d",L_apss_reset_state);
+
+ do
+ {
+ if(L_scheduled_reset)
+ {
+ if (!async_request_is_idle(&G_apss_reset_request.request))
+ {
+ INTR_TRAC_INFO("E>task_apss_reset: gpe apss reset request "
+ "is not idle.");
+ break;
+ }
+
+ if((ASYNC_REQUEST_STATE_COMPLETE !=
+ G_apss_reset_request.request.completion_state) ||
+ (0 != G_gpe_apss_reset_args.error.error))
+ {
+ INTR_TRAC_ERR("task_apss_reset: reset request failed with "
+ "rc:0x%08x, ffdc:0x%08X%08X. "
+ "CompletionState:0x%X.",
+ G_gpe_apss_reset_args.error.rc,
+ (uint32_t) (G_gpe_apss_reset_args.error.ffdc >> 32),
+ (uint32_t) G_gpe_apss_reset_args.error.ffdc,
+ G_apss_reset_request.request.completion_state);
+ if(!L_reset_ffdc_collected)
+ {
+ errlHndl_t err = NULL;
+
+ /*
+ * @errortype
+ * @moduleid PSS_MID_APSS_RESET
+ * @reasoncode APSS_GPE_FAILURE
+ * @userdata1 GPE return code
+ * @userdata2 0
+ * @userdata4 ERC_APSS_RESET_FAILURE
+ * @devdesc Failed to reset apss
+ */
+ err = createErrl(PSS_MID_APSS_RESET, // moduleId
+ APSS_GPE_FAILURE, //reasonCode
+ ERC_APSS_RESET_FAILURE,
+ ERRL_SEV_INFORMATIONAL,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ G_gpe_apss_reset_args.error.rc,
+ 0);
+ addUsrDtlsToErrl(err,
+ (uint8_t*)&G_apss_reset_request.ffdc,
+ sizeof(G_apss_reset_request.ffdc),
+ ERRL_STRUCT_VERSION_1,
+ ERRL_USR_DTL_BINARY_DATA);
+ commitErrl(&err);
+
+ L_reset_ffdc_collected = TRUE;
+ }
+ }
+ }
+
+ if(L_scheduled_init_gpio)
+ {
+ if (!async_request_is_idle(&G_init_gpio_request.request))
+ {
+ INTR_TRAC_INFO("E>task_apss_reset: gpe apss init gpio request "
+ "is not idle.");
+ break;
+ }
+
+ if((ASYNC_REQUEST_STATE_COMPLETE !=
+ G_init_gpio_request.request.completion_state) ||
+ (0 != G_gpe_apss_initialize_gpio_args.error.error))
+ {
+ INTR_TRAC_ERR("task_apss_reset: reset request failed with "
+ "rc:0x%08x, ffdc:0x%08X%08X. "
+ "CompletionState:0x%X.",
+ G_gpe_apss_initialize_gpio_args.error.rc,
+ (uint32_t) (G_gpe_apss_initialize_gpio_args.error.ffdc >> 32),
+ (uint32_t) G_gpe_apss_initialize_gpio_args.error.ffdc,
+ G_init_gpio_request.request.completion_state);
+
+ if(!L_init_gpio_ffdc_collected)
+ {
+ errlHndl_t err = NULL;
+
+ /*
+ * @errortype
+ * @moduleid PSS_MID_APSS_RESET
+ * @reasoncode APSS_GPE_FAILURE
+ * @userdata1 GPE return code
+ * @userdata2 0
+ * @userdata4 ERC_PSS_GPIO_INIT_FAIL
+ * @devdesc Failed to reset apss
+ */
+ err = createErrl(PSS_MID_APSS_RESET, // moduleId
+ APSS_GPE_FAILURE, //reasonCode
+ ERC_PSS_GPIO_INIT_FAIL,
+ ERRL_SEV_INFORMATIONAL,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ G_gpe_apss_initialize_gpio_args.error.rc,
+ 0);
+ addUsrDtlsToErrl(err,
+ (uint8_t*)&G_init_gpio_request.ffdc,
+ sizeof(G_init_gpio_request.ffdc),
+ ERRL_STRUCT_VERSION_1,
+ ERRL_USR_DTL_BINARY_DATA);
+ commitErrl(&err);
+
+ L_init_gpio_ffdc_collected = TRUE;
+ }
+ }
+ }
+
+ if(L_scheduled_init_mode)
+ {
+ if (!async_request_is_idle(&G_init_mode_request.request))
+ {
+ INTR_TRAC_INFO("E>task_apss_reset: gpe apss init mode request "
+ "is not idle.");
+ break;
+ }
+
+ if((ASYNC_REQUEST_STATE_COMPLETE !=
+ G_init_mode_request.request.completion_state) ||
+ (0 != G_gpe_apss_set_mode_args.error.error))
+ {
+ INTR_TRAC_ERR("task_apss_reset: reset request failed with "
+ "rc:0x%08x, ffdc:0x%08X%08X. "
+ "CompletionState:0x%X.",
+ G_gpe_apss_set_mode_args.error.rc,
+ (uint32_t) (G_gpe_apss_set_mode_args.error.ffdc >> 32),
+ (uint32_t) G_gpe_apss_set_mode_args.error.ffdc,
+ G_init_mode_request.request.completion_state);
+
+ if(!L_init_mode_ffdc_collected)
+ {
+ errlHndl_t err = NULL;
+
+ /*
+ * @errortype
+ * @moduleid PSS_MID_APSS_RESET
+ * @reasoncode APSS_GPE_FAILURE
+ * @userdata1 GPE return code
+ * @userdata2 0
+ * @userdata4 ERC_PSS_COMPOSITE_MODE_FAIL
+ * @devdesc Failed to reset apss
+ */
+ err = createErrl(PSS_MID_APSS_RESET, // moduleId
+ APSS_GPE_FAILURE, //reasonCode
+ ERC_PSS_COMPOSITE_MODE_FAIL,
+ ERRL_SEV_INFORMATIONAL,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ G_gpe_apss_set_mode_args.error.rc,
+ 0);
+ addUsrDtlsToErrl(err,
+ (uint8_t*)&G_init_mode_request.ffdc,
+ sizeof(G_init_mode_request.ffdc),
+ ERRL_STRUCT_VERSION_1,
+ ERRL_USR_DTL_BINARY_DATA);
+ commitErrl(&err);
+
+ L_init_mode_ffdc_collected = TRUE;
+ }
+ }
+ }
+
+ switch (L_apss_reset_state)
+ {
+ case APSS_RESET_STATE_START:
+ case APSS_RESET_STATE_WAIT_1MS:
+ // TOGGLE apss reset GPIO pin
+ schedule_rc = gpe_request_schedule(&G_apss_reset_request);
+ L_scheduled_reset = TRUE;
+ break;
+
+ case APSS_RESET_STATE_WAIT_DONE:
+
+ G_gpe_apss_initialize_gpio_args.error.error = 0;
+ G_gpe_apss_initialize_gpio_args.error.ffdc = 0;
+
+ schedule_rc = gpe_request_schedule(&G_init_gpio_request);
+
+ L_scheduled_reset = FALSE;
+ L_scheduled_init_gpio = TRUE;
+ break;
+
+ case APSS_RESET_STATE_REINIT:
+
+ G_gpe_apss_set_mode_args.error.error = 0;
+ G_gpe_apss_set_mode_args.error.ffdc = 0;
+
+ schedule_rc = gpe_request_schedule(&G_init_mode_request);
+
+ L_scheduled_init_gpio = FALSE;
+ L_scheduled_init_mode = TRUE;
+ break;
+
+ case APSS_RESET_STATE_COMPLETE:
+ L_apss_reset_state = -1;
+ L_scheduled_init_mode = FALSE;
+
+ // Disable this task
+ rtl_stop_task(TASK_ID_APSS_RESET);
+
+ // Resuming your regulary scheduled programs.
+ rtl_start_task(TASK_ID_APSS_START);
+ rtl_start_task(TASK_ID_APSS_CONT);
+ rtl_start_task(TASK_ID_APSS_DONE);
+
+ G_apss_recovery_requested = FALSE;
+ G_apss_data_traced = FALSE;
+
+ break;
+
+ default:
+ break;
+ }
+
+ if(schedule_rc)
+ {
+ errlHndl_t err = NULL;
+
+ INTR_TRAC_ERR("task_apss_reset: schedule failed w/rc=0x%08X (%d us)", schedule_rc,
+ (int) ((ssx_timebase_get())/(SSX_TIMEBASE_FREQUENCY_HZ/1000000)));
+
+ /*
+ * @errortype
+ * @moduleid PSS_MID_APSS_RESET
+ * @reasoncode SSX_GENERIC_FAILURE
+ * @userdata1 GPE shedule returned rc code
+ * @userdata2 APSS reset state
+ * @userdata4 ERC_APSS_SCHEDULE_FAILURE
+ * @devdesc task_apss_start_pwr_meas schedule failed
+ */
+ err = createErrl(PSS_MID_APSS_RESET,
+ SSX_GENERIC_FAILURE,
+ ERC_APSS_SCHEDULE_FAILURE,
+ ERRL_SEV_PREDICTIVE,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ schedule_rc,
+ L_apss_reset_state);
+
+ // Request reset since this should never happen.
+ REQUEST_RESET(err);
+
+ L_scheduled_reset = FALSE;
+ L_scheduled_init_gpio = FALSE;
+ L_scheduled_init_mode = FALSE;
+ break;
+ }
+
+ ++L_apss_reset_state;
+
+ }
+ while(0);
+
+ APSS_DBG("task_apss_reset finished w/rc=0x%08X\n", rc);
+}
+
diff --git a/src/occ_405/pss/apss.h b/src/occ_405/pss/apss.h
index ba0b775..0bd45ac 100644
--- a/src/occ_405/pss/apss.h
+++ b/src/occ_405/pss/apss.h
@@ -43,11 +43,12 @@
void dumpHexString(const void *i_data, const unsigned int len, const char *string);
#endif
-#define APSS_DATA_FAIL_PMAX_RAIL 16 //Number of steps before we lower Pmax_rail to nominal. This should allow for 4ms/16ticks with no APSS data.
-#define APSS_DATA_FAIL_MAX 400 //Number of steps we reach before reseting OCC. This should allow for 100ms/400ticks with no APSS data.
+#define APSS_DATA_FAIL_PMAX_RAIL 100 //Number of steps before we lower Pmax_rail to nominal. This should allow for 50ms/100 ticks with no APSS data.
+#define APSS_DATA_FAIL_MAX 200 //Number of steps we reach before reseting OCC. This should allow for 100ms/200ticks with no APSS data.
#define APSS_DATA_FAILURE_STEP 1 //Number of steps to increment FAIL_COUNT due to a failed APSS data collection.
#define APSS_ERRORLOG_RESET_THRESHOLD 16 //When to allow apss tasks to log another error if count goes back to 0 again.
#define APSS_MAX_NUM_INIT_RETRIES 2
+#define APSS_MAX_NUM_RESET_RETRIES 3
extern uint16_t G_apss_fail_updown_count; //Used to keep count of number of APSS data collection fails.
//Decrement APSS_FAIL_COUNT to 0.
@@ -58,6 +59,13 @@ extern uint16_t G_apss_fail_updown_count; //Used to keep count of number of
(G_apss_fail_updown_count += APSS_DATA_FAILURE_STEP): \
(G_apss_fail_updown_count = APSS_DATA_FAIL_MAX);}
+// Apss reset task is run every other tic (1 ms)
+#define APSS_RESET_STATE_START 0
+#define APSS_RESET_STATE_WAIT_1MS 1
+#define APSS_RESET_STATE_WAIT_DONE 51 // Wait 50 ms
+#define APSS_RESET_STATE_REINIT 52
+#define APSS_RESET_STATE_COMPLETE 53
+
struct apssPwrMeasStruct
{
uint16_t adc[MAX_APSS_ADC_CHANNELS];
@@ -86,10 +94,12 @@ extern uint64_t G_gpe_apss_time_end;
void task_apss_start_pwr_meas(task_t *i_self);
void task_apss_continue_pwr_meas(task_t *i_self);
void task_apss_complete_pwr_meas(task_t *i_self);
+void task_apss_reset(task_t *i_self);
void apss_test_pwr_meas(); // used to test measurements
void reformat_meas_data();
bool apss_gpio_get(uint8_t i_pin_number, uint8_t *o_pin_value);
errlHndl_t initialize_apss(void);
+extern volatile bool G_apss_recovery_requested;
#endif //_APSS_H
diff --git a/src/occ_405/pss/pss_service_codes.h b/src/occ_405/pss/pss_service_codes.h
index 5a7fe85..eadf141 100755
--- a/src/occ_405/pss/pss_service_codes.h
+++ b/src/occ_405/pss/pss_service_codes.h
@@ -39,6 +39,7 @@ enum pssModuleId
PSS_MID_DPSS_RD_STATUS = PSS_COMP_ID | 0x06,
PSS_MID_DO_APSS_RECOVERY = PSS_COMP_ID | 0x07,
PSS_MID_AVSBUS_READ = PSS_COMP_ID | 0x08,
+ PSS_MID_APSS_RESET = PSS_COMP_ID | 0x09,
};
#endif /* #ifndef _PSS_SERVICE_CODES_H_ */
diff --git a/src/occ_405/rtls/rtls.h b/src/occ_405/rtls/rtls.h
index 973bab4..1d01b11 100755
--- a/src/occ_405/rtls/rtls.h
+++ b/src/occ_405/rtls/rtls.h
@@ -63,6 +63,7 @@ typedef enum {
TASK_ID_24X7, // 24x7 data collection task
TASK_ID_GPE_TIMINGS,
TASK_ID_GET_TOD, // Get time of day task
+ TASK_ID_APSS_RESET, // (HW) reset APSS
TASK_END // This must always be the last enum in this list,
// so that TASK_END always equals the last task ID + 1.
} task_id_t;
diff --git a/src/occ_405/rtls/rtls_tables.c b/src/occ_405/rtls/rtls_tables.c
index c23e1ea..9d1f18e 100755
--- a/src/occ_405/rtls/rtls_tables.c
+++ b/src/occ_405/rtls/rtls_tables.c
@@ -72,6 +72,7 @@
#define FLAGS_APSS_START_MEAS APSS_TASK_FLAGS
#define FLAGS_APSS_CONT_MEAS APSS_TASK_FLAGS
#define FLAGS_APSS_DONE_MEAS APSS_TASK_FLAGS
+#define FLAGS_APSS_RESET RTL_FLAG_MSTR | RTL_FLAG_OBS | RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY
#define FLAGS_DCOM_PARSE_OCC_FW_MSG RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_OBS | RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | RTL_FLAG_RUN | RTL_FLAG_STANDBY | RTL_FLAG_RST_REQ | RTL_FLAG_APSS_NOT_INITD
#define FLAGS_MISC_405_CHECKS RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_OBS | RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | RTL_FLAG_RUN | RTL_FLAG_STANDBY | RTL_FLAG_RST_REQ | RTL_FLAG_APSS_NOT_INITD
@@ -127,9 +128,11 @@ task_t G_task_table[TASK_END] = {
{ FLAGS_24X7, task_24x7, NULL }, // TASK_ID_24X7
{ FLAGS_GPE_TIMINGS, task_gpe_timings, NULL }, // TASK_ID_GPE_TIMINGS
{ FLAGS_GET_TOD, task_get_tod, NULL }, // TASK_ID_GET_TOD
+ { FLAGS_APSS_RESET, task_apss_reset, NULL }, // TASK_APSS_RESET
};
const uint8_t G_tick0_seq[] = {
+ TASK_ID_APSS_RESET,
TASK_ID_APSS_START,
TASK_ID_GET_TOD,
TASK_ID_CORE_DATA_LOW,
@@ -176,6 +179,7 @@ const uint8_t G_tick1_seq[] = {
TASK_END };
const uint8_t G_tick2_seq[] = {
+ TASK_ID_APSS_RESET,
TASK_ID_APSS_START,
TASK_ID_GET_TOD,
TASK_ID_CORE_DATA_LOW,
@@ -222,6 +226,7 @@ const uint8_t G_tick3_seq[] = {
TASK_END };
const uint8_t G_tick4_seq[] = {
+ TASK_ID_APSS_RESET,
TASK_ID_APSS_START,
TASK_ID_GET_TOD,
TASK_ID_CORE_DATA_LOW,
@@ -268,6 +273,7 @@ const uint8_t G_tick5_seq[] = {
TASK_END };
const uint8_t G_tick6_seq[] = {
+ TASK_ID_APSS_RESET,
TASK_ID_APSS_START,
TASK_ID_GET_TOD,
TASK_ID_CORE_DATA_LOW,
@@ -313,6 +319,7 @@ const uint8_t G_tick7_seq[] = {
TASK_END };
const uint8_t G_tick8_seq[] = {
+ TASK_ID_APSS_RESET,
TASK_ID_APSS_START,
TASK_ID_GET_TOD,
TASK_ID_CORE_DATA_LOW,
@@ -359,6 +366,7 @@ const uint8_t G_tick9_seq[] = {
TASK_END };
const uint8_t G_tick10_seq[] = {
+ TASK_ID_APSS_RESET,
TASK_ID_APSS_START,
TASK_ID_GET_TOD,
TASK_ID_CORE_DATA_LOW,
@@ -404,6 +412,7 @@ const uint8_t G_tick11_seq[] = {
TASK_END };
const uint8_t G_tick12_seq[] = {
+ TASK_ID_APSS_RESET,
TASK_ID_APSS_START,
TASK_ID_GET_TOD,
TASK_ID_CORE_DATA_LOW,
@@ -450,6 +459,7 @@ const uint8_t G_tick13_seq[] = {
TASK_END };
const uint8_t G_tick14_seq[] = {
+ TASK_ID_APSS_RESET,
TASK_ID_APSS_START,
TASK_ID_GET_TOD,
TASK_ID_CORE_DATA_LOW,
diff --git a/src/occ_gpe0/apss_init.c b/src/occ_gpe0/apss_init.c
index 702393a..efb3f8d 100644
--- a/src/occ_gpe0/apss_init.c
+++ b/src/occ_gpe0/apss_init.c
@@ -29,6 +29,11 @@
#include "pss_constants.h"
#include <apss_structs.h> //H file common with occ_405
#include "gpe_util.h"
+#include "p9_misc_scom_addresses.h"
+
+// PV_CP0_P_PRV_GPIO2
+#define APSS_RESET_GPIO (0x2000000000000000ull)
+
// Default to Auto-2 for now, should get set when the mode
// is initialized, and before any APSS data is gathered.
@@ -201,6 +206,45 @@ void apss_init_gpio(ipc_msg_t* cmd, void* arg)
break;
}
}//End of port while loop.
+ if (rc)
+ {
+ break;
+ }
+
+ // Enable GPIO that's used for APSS resets
+ //
+ // Set APSS_RESET_GPIO output high before enabling it's output
+
+ regValue = APSS_RESET_GPIO;
+ rc = putscom_abs(PU_GPIO_OUTPUT_OR, regValue);
+ if(rc)
+ {
+ PK_TRACE("apss_init: APSS_RESET_GPIO_OUTPUT low failed. rc:0x%08x",rc);
+ gpe_set_ffdc(&(args->error), 0, GPE_RC_SCOM_PUT_FAILED, rc);
+ break;
+ }
+
+ // Read output enable pins.
+ rc = getscom_abs(PU_GPIO_OUTPUT_EN, &regValue);
+ if(rc)
+ {
+ PK_TRACE("apss_init: Read APSS_RESET_GPIO_OUTPUT_EN failed. rc:0x%08x",rc);
+ gpe_set_ffdc(&(args->error), 0, GPE_RC_SCOM_GET_FAILED, rc);
+ break;
+ }
+
+ // Enable APSS_RESET_GPIO as output
+ regValue |= APSS_RESET_GPIO;
+
+ rc = putscom_abs(PU_GPIO_OUTPUT_EN, regValue);
+ if(rc)
+ {
+ PK_TRACE("apss_init: APSS_RESET_GPIO_OUTPUT_EN failed. rc:0x%08x",rc);
+ gpe_set_ffdc(&(args->error), 0, GPE_RC_SCOM_PUT_FAILED, rc);
+ break;
+ }
+
+
}while(0);
// send back a successful response. OCC will check rc and ffdc
@@ -353,3 +397,48 @@ void apss_init_mode(ipc_msg_t* cmd, void* arg)
PK_TRACE("apss_init_mode: completed successfully.");
}
}
+
+
+// ----------------------------------------------------
+// Toggle the output of the APSS RESET pin
+// ----------------------------------------------------
+void apss_toggle_hw_reset(ipc_msg_t* cmd, void* arg)
+{
+ static int g_apss_reset_state = ~(0);
+
+ int rc = 0;
+ uint32_t apss_reset_address;
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
+ initGpioArgs_t *args = (initGpioArgs_t*)async_cmd->cmd_data;
+
+ if(g_apss_reset_state) // not in reset
+ {
+ apss_reset_address = PU_GPIO_OUTPUT_CLR;
+ }
+ else
+ {
+ apss_reset_address = PU_GPIO_OUTPUT_OR;
+ }
+ g_apss_reset_state = ~g_apss_reset_state;
+ PK_TRACE("apss_toggle_apss_hw_reset: %d",(uint16_t)g_apss_reset_state);
+
+
+ // Set/clear GPIO2 output
+ rc = putscom_abs(apss_reset_address, APSS_RESET_GPIO);
+ if(rc)
+ {
+ PK_TRACE("apss_toggle_hw_reset: APSS_RESET_GPIO_OUTPUT toggle failed. rc:0x%08x",rc);
+ gpe_set_ffdc(&(args->error), 0, GPE_RC_SCOM_PUT_FAILED, rc);
+ }
+
+ // send back a successful response. OCC will check rc and ffdc
+ rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
+
+ if(rc)
+ {
+ PK_TRACE("apss_toggle_hw_reset: Failed to send response back. rc = 0x%08x. Halting GPE0",
+ rc);
+ gpe_set_ffdc(&(args->error), 0x00, rc, 0);
+ pk_halt();
+ }
+}
diff --git a/src/occ_gpe0/ipc_func_tables.c b/src/occ_gpe0/ipc_func_tables.c
index 14166df..110f9fa 100644
--- a/src/occ_gpe0/ipc_func_tables.c
+++ b/src/occ_gpe0/ipc_func_tables.c
@@ -32,6 +32,7 @@ void apss_init_mode(ipc_msg_t* cmd, void* arg);
void apss_start_pwr_meas_read(ipc_msg_t* cmd, void* arg);
void apss_continue_pwr_meas_read(ipc_msg_t* cmd, void* arg);
void apss_complete_pwr_meas_read(ipc_msg_t* cmd, void* arg);
+void apss_toggle_hw_reset(ipc_msg_t* cmd, void* arg);
void gpe_get_core_data(ipc_msg_t* cmd, void* arg);
void gpe_get_nest_dts(ipc_msg_t* cmd, void* arg);
void gpe_get_tod(ipc_msg_t* cmd, void* arg);
@@ -75,7 +76,7 @@ IPC_HANDLER(gpe0_nop, 0) // 8 - IPC_ST_GPE0_NOP
IPC_HANDLER(gpe_get_nest_dts, 0) // 9 - IPC_ST_GET_NEST_DTS_FUNCID
IPC_HANDLER(ipc_fir_collection, 0) // 10 - IPC_ST_FIR_COLLECTION
IPC_HANDLER(gpe_get_tod, 0) // 11 - IPC_ST_GET_TOD_FUNCID
-IPC_HANDLER_DEFAULT // 12
+IPC_HANDLER(apss_toggle_hw_reset, 0) // 12 - IPC_ST_APSS_RESET_FUNCID
IPC_HANDLER_DEFAULT // 13
IPC_HANDLER_DEFAULT // 14
IPC_HANDLER_DEFAULT // 15
diff --git a/src/occ_gpe1/gpe_gpu_init.c b/src/occ_gpe1/gpe_gpu_init.c
index a293905..d7dc29b 100644
--- a/src/occ_gpe1/gpe_gpu_init.c
+++ b/src/occ_gpe1/gpe_gpu_init.c
@@ -39,7 +39,7 @@ void gpe_gpu_init(ipc_msg_t* cmd, void* arg)
gpe_set_ffdc(&(args->error), 0, GPE_RC_GPU_INIT_FAILED, rc);
}
- // pin0 as output, pin1 as input, pin3 unchanged
+ // pin0 as output, pin1 as input, pin2 unchanged
data64 &= 0xBfffffffffffffffull;
data64 |= 0x8000000000000000ull;
OpenPOWER on IntegriCloud