summaryrefslogtreecommitdiffstats
path: root/src/occ_405/wof/wof.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/occ_405/wof/wof.c')
-rw-r--r--src/occ_405/wof/wof.c216
1 files changed, 97 insertions, 119 deletions
diff --git a/src/occ_405/wof/wof.c b/src/occ_405/wof/wof.c
index 9e5e990..ff72d5f 100644
--- a/src/occ_405/wof/wof.c
+++ b/src/occ_405/wof/wof.c
@@ -47,6 +47,7 @@ extern GpeRequest G_wof_vfrt_req;
extern GpeRequest G_wof_control_req;
extern uint32_t G_nest_frequency_mhz;
extern pstateStatus G_proc_pstate_status;
+extern uint8_t G_occ_interrupt_type;
//******************************************************************************
// Globals
//******************************************************************************
@@ -126,7 +127,7 @@ void call_wof_main( void )
{
// Variable to ensure we do not keep trying to send vfrt GpeRequest
// more than 1 extra time.
- static bool L_vfrt_last_chance = false;
+ static uint8_t L_vfrt_last_chance = MAX_VFRT_CHANCES;
// Variable to ensure we do not keep trying to send the wof control
static bool L_wof_control_last_chance = false;
@@ -218,9 +219,10 @@ void call_wof_main( void )
case INITIAL_VFRT_SENT_WAITING:
// Check if request is still processing.
// Init state updated in wof_vfrt_callback
- if( !async_request_is_idle(&G_wof_vfrt_req.request) )
+ if( (!async_request_is_idle(&G_wof_vfrt_req.request)) ||
+ (g_wof->vfrt_state != STANDBY) )
{
- if( L_vfrt_last_chance )
+ if( L_vfrt_last_chance == 0 )
{
INTR_TRAC_ERR("WOF Disabled!"
" Init VFRT request timeout");
@@ -228,15 +230,17 @@ void call_wof_main( void )
}
else
{
- INTR_TRAC_INFO("one more chance sending initial VFRT");
- L_vfrt_last_chance = true;
+ INTR_TRAC_INFO("initial VFRT NOT idle."
+ " %d more chance(s)",
+ L_vfrt_last_chance );
+ L_vfrt_last_chance--;
}
}
break;
case INITIAL_VFRT_SUCCESS:
// We made it this far. Reset Last chance
- L_vfrt_last_chance = false;
+ L_vfrt_last_chance = MAX_VFRT_CHANCES;
// Send wof control on gpe request
// If enable_success returns true, init state was set
@@ -294,17 +298,19 @@ void call_wof_main( void )
!g_wof->wof_disabled )
{
// Normal execution of wof algorithm
- if( !async_request_is_idle(&G_wof_vfrt_req.request) )
+ if( (!async_request_is_idle(&G_wof_vfrt_req.request)) ||
+ (g_wof->vfrt_state != STANDBY) )
{
- if( L_vfrt_last_chance )
+ if( L_vfrt_last_chance == 0 )
{
INTR_TRAC_ERR("WOF Disabled! VFRT req timeout");
set_clear_wof_disabled(SET,WOF_RC_VFRT_REQ_TIMEOUT);
}
else
{
- INTR_TRAC_INFO("One more chance for vfrt request");
- L_vfrt_last_chance = true;
+ INTR_TRAC_INFO("VFRT NOT idle. %d more chance(s)",
+ L_vfrt_last_chance);
+ L_vfrt_last_chance--;
}
}
else
@@ -312,7 +318,7 @@ void call_wof_main( void )
// Request is idle. Run wof algorithm
wof_main();
- L_vfrt_last_chance = false;
+ L_vfrt_last_chance = MAX_VFRT_CHANCES;
// Finally make sure we are in the fully enabled state
if( g_wof->wof_init_state == PGPE_WOF_ENABLED_NO_PREV_DATA )
{
@@ -379,14 +385,6 @@ void wof_main( void )
// Send the new vfrt to the PGPE
send_vfrt_to_pgpe( g_wof->next_vfrt_main_mem_addr );
- if(async_request_is_idle(&G_wof_vfrt_req.request))
- {
- g_wof->gpe_req_rc = pgpe_request_schedule(&G_wof_vfrt_req);
- }
- else
- {
- INTR_TRAC_ERR("VFRT REQUEST at end of wof_main() timed out");
- }
}
/**
@@ -478,16 +476,17 @@ uint32_t calc_vfrt_mainstore_addr( void )
/**
- * copy_vfrt_to_sram
+ * copy_vfrt_to_sram_callback
*
- * Description: Call back function to copy VFRT into SRAM ping/pong buffer
- * This call will also tell the PGPE that a new VFRT is available
+ * Description: Call back function to BCE request to copy VFRT into SRAM
+ * ping/pong buffer. This call will also tell the PGPE
+ * that a new VFRT is available
*
* Param[in]: i_parms - pointer to a struct that will hold data necessary to
* the calculation.
* -Pointer to vfrt table temp buffer
*/
-void copy_vfrt_to_sram( void )
+void copy_vfrt_to_sram_callback( void )
{
/*
*
@@ -520,6 +519,13 @@ void copy_vfrt_to_sram( void )
// Set the parameters for the GpeRequest
G_wof_vfrt_parms.homer_vfrt_ptr = (HomerVFRTLayout_t*)l_buffer_address;
G_wof_vfrt_parms.active_quads = g_wof->req_active_quad_update;
+
+ if( g_wof->vfrt_state != STANDBY )
+ {
+ // Set vfrt state to let OCC know it needs to schedule the IPC command
+ g_wof->vfrt_state = NEED_TO_SCHEDULE;
+ }
+
}
/**
@@ -532,6 +538,10 @@ void copy_vfrt_to_sram( void )
*/
void wof_vfrt_callback( void )
{
+ // Update the VFRT state to indicate a new IPC message can be
+ // scheduled regardless of the RC of the previous one.
+ g_wof->vfrt_state = STANDBY;
+
// Confirm the WOF VFRT PGPE request has completed with no errors
if( G_wof_vfrt_parms.msg_cb.rc == PGPE_WOF_RC_VFRT_QUAD_MISMATCH )
{
@@ -567,7 +577,7 @@ void wof_vfrt_callback( void )
* send_vfrt_to_pgpe
*
* Description: Function to copy new VFRT from Mainstore to local SRAM buffer
- * and calls copy_vfrt_to_sram callback function to send new VFRT
+ * and calls copy_vfrt_to_sram_callback function to send new VFRT
* to the PGPE
* Note: If desired VFRT is the same as previous, skip.
*
@@ -576,8 +586,6 @@ void wof_vfrt_callback( void )
void send_vfrt_to_pgpe( uint32_t i_vfrt_main_mem_addr )
{
int l_ssxrc = SSX_OK;
- uint32_t l_reasonCode = 0;
- uint32_t l_extReasonCode = 0;
do
{
@@ -611,44 +619,30 @@ void send_vfrt_to_pgpe( uint32_t i_vfrt_main_mem_addr )
(uint32_t) &G_vfrt_temp_buff, // SRAM start address
MIN_BCE_REQ_SIZE, // size of copy
SSX_WAIT_FOREVER, // no timeout
- (AsyncRequestCallback)copy_vfrt_to_sram,
+ (AsyncRequestCallback)copy_vfrt_to_sram_callback,
NULL,
ASYNC_CALLBACK_IMMEDIATE );
if(l_ssxrc != SSX_OK)
{
INTR_TRAC_ERR("send_vfrt_to_pgpe: BCDE request create failure rc=[%08X]", -l_ssxrc);
- /*
- * @errortype
- * @moduleid SEND_VFRT_TO_PGPE
- * @reasoncode SSX_GENERIC_FAILURE
- * @userdata1 RC for BCE block-copy engine
- * @userdata2 Internal function checkpoint
- * @userdata4 ERC_BCE_REQUEST_CREATE_FAILURE
- * @devdesc Failed to create BCDE request
- */
- l_reasonCode = SSX_GENERIC_FAILURE;
- l_extReasonCode = ERC_BCE_REQUEST_CREATE_FAILURE;
break;
}
- // Do the actual copy
- l_ssxrc = bce_request_schedule( &G_vfrt_req );
-
- if(l_ssxrc != SSX_OK)
+ // Make sure we are in correct vfrt state
+ if( g_wof->vfrt_state == STANDBY )
{
- INTR_TRAC_ERR("send_vfrt_to_pgpe: BCE request schedule failure rc=[%08X]", -l_ssxrc);
- /*
- * @errortype
- * @moduleid SEND_VFRT_TO_PGPE
- * @reasoncode SSX_GENERIC_FAILURE
- * @userdata1 RC for BCE block-copy engine
- * @userdata4 ERC_BCE_REQUEST_SCHEDULE_FAILURE
- * @devdesc Failed to read PPMR data by using BCDE
- */
- l_reasonCode = SSX_GENERIC_FAILURE;
- l_extReasonCode = ERC_BCE_REQUEST_SCHEDULE_FAILURE;
- break;
+ // Set the VFRT state to ensure asynchronous order of operations
+ g_wof->vfrt_state = SEND_INIT;
+
+ // Do the actual copy
+ l_ssxrc = bce_request_schedule( &G_vfrt_req );
+
+ if(l_ssxrc != SSX_OK)
+ {
+ INTR_TRAC_ERR("send_vfrt_to_pgpe: BCE request schedule failure rc=[%08X]", -l_ssxrc);
+ break;
+ }
}
}
}while( 0 );
@@ -656,23 +650,8 @@ void send_vfrt_to_pgpe( uint32_t i_vfrt_main_mem_addr )
// Check for errors and log, if any
if( l_ssxrc != SSX_OK )
{
- errlHndl_t l_errl = createErrl(SEND_VFRT_TO_PGPE, //modId
- l_reasonCode, //reasoncode
- l_extReasonCode, //Extended reason code
- ERRL_SEV_UNRECOVERABLE, //Severity
- NULL, //Trace Buf
- 0, //Trace Size
- -l_ssxrc, //userdata1
- 0); //userdata2
-
- // Callout firmware
- addCalloutToErrl(l_errl,
- ERRL_CALLOUT_TYPE_COMPONENT_ID,
- ERRL_COMPONENT_ID_FIRMWARE,
- ERRL_CALLOUT_PRIORITY_HIGH);
-
- // Commit error log
- commitErrl(&l_errl);
+ // Formally disable WOF
+ set_clear_wof_disabled( SET, WOF_RC_IPC_FAILURE );
return;
}
@@ -1284,6 +1263,9 @@ void set_clear_wof_disabled( uint8_t i_action,
{
if( i_action == SET )
{
+ // Set the vfrt state back to standby
+ g_wof->vfrt_state = STANDBY;
+
// Set the bit
g_wof->wof_disabled |= i_bit_mask;
@@ -1444,7 +1426,7 @@ void set_clear_wof_disabled( uint8_t i_action,
i_bit_mask );
// Reset if on OpenPower
- if( (G_sysConfigData.system_type.kvm) )
+ if( G_occ_interrupt_type != FSP_SUPPORTED_OCC )
{
if(i_bit_mask & ~(IGNORE_WOF_RESET) )
{
@@ -1673,6 +1655,49 @@ void wof_control_callback( void )
}
}
+
+/**
+ * schedule_vfrt_request
+ *
+ * Description: Called from amec_slv_common_tasks_post every 500us. Checks
+ * to see if a new VFRT table is ready to be sent to the PGPE
+ * and if so, sends it and sets the vfrt state
+ */
+void schedule_vfrt_request( void )
+{
+ if( (g_wof->vfrt_state == NEED_TO_SCHEDULE ) &&
+ (async_request_is_idle(&G_wof_vfrt_req.request)) )
+ {
+ g_wof->gpe_req_rc = pgpe_request_schedule(&G_wof_vfrt_req);
+
+ // Check to make sure IPC request was scheduled correctly
+ if( g_wof->gpe_req_rc != 0 )
+ {
+ // If we were attempting to send the initial VFRT request,
+ // reset the state machine so we can start the process
+ // over
+ if( g_wof->wof_init_state == INITIAL_VFRT_SENT_WAITING )
+ {
+ g_wof->wof_init_state = WOF_DISABLED;
+ }
+
+ INTR_TRAC_ERR("schedule_vfrt_request: Error sending VFRT! gperc=%d"
+ g_wof->gpe_req_rc );
+
+ // Formally disable wof
+ set_clear_wof_disabled( SET, WOF_RC_IPC_FAILURE );
+
+ // Reset the global return code after logging the error
+ g_wof->gpe_req_rc = 0;
+ }
+
+ // Update vfrt state
+ g_wof->vfrt_state = SCHEDULED;
+ }
+}
+
+
+
/**
* send_initial_vfrt_to_pgpe
*
@@ -1692,53 +1717,6 @@ void send_initial_vfrt_to_pgpe( void )
// Send the final vfrt to shared OCC-PGPE SRAM.
send_vfrt_to_pgpe( g_wof->next_vfrt_main_mem_addr );
- if(async_request_is_idle(&G_wof_vfrt_req.request))
- {
- g_wof->gpe_req_rc = pgpe_request_schedule(&G_wof_vfrt_req);
- }
- else
- {
- INTR_TRAC_INFO("Intial vfrt request was NOT idle");
- }
-
- // Check to make sure IPC request was scheduled correctly
- if( g_wof->gpe_req_rc != 0 )
- {
- INTR_TRAC_ERR("send_initial_vfrt: Error sending initial VFRT! gperc=%d",
- g_wof->gpe_req_rc);
- //Error in scheduling wof_vfrt task
- /* @
- * @errortype
- * @moduleid SEND_INIT_VFRT
- * @reasoncode GPE_REQUEST_SCHEDULE_FAILURE
- * @userdata1 rc - gpe_request_schedule return code
- * @userdata2 0
- * @userdata4 OCC_NO_EXTENDED_RC
- * @devdesc OCC Failed to schedule a GPE job for wof vfrt
- */
- errlHndl_t l_errl = createErrl(
- SEND_INIT_VFRT, // modId
- GPE_REQUEST_SCHEDULE_FAILURE, // reasoncode
- OCC_NO_EXTENDED_RC, // Extended reason code
- ERRL_SEV_UNRECOVERABLE, // Severity
- NULL, // Trace Buf
- DEFAULT_TRACE_SIZE, // Trace Size
- g_wof->gpe_req_rc, // userdata1
- 0 // userdata2
- );
-
- // Callout firmware
- addCalloutToErrl(l_errl,
- ERRL_CALLOUT_TYPE_COMPONENT_ID,
- ERRL_COMPONENT_ID_FIRMWARE,
- ERRL_CALLOUT_PRIORITY_HIGH);
-
- // Commit error log
- commitErrl(&l_errl);
-
- // Reset the global return code after logging the error
- g_wof->gpe_req_rc = 0;
- }
// Update Init state
if(g_wof->wof_init_state < INITIAL_VFRT_SENT_WAITING)
OpenPOWER on IntegriCloud