Skip to content

Commit

Permalink
Timebase overflow issue in gpe0
Browse files Browse the repository at this point in the history
Change-Id: I555873ef13b5094f3499085f8aafb40ce4cc4320
CQ: SW403677
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48464
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Martha Broyles <mbroyles@us.ibm.com>
Reviewed-by: Christopher J. Cain <cjcain@us.ibm.com>
Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
  • Loading branch information
dgilbert999 authored and wilbryan committed Oct 19, 2017
1 parent 1522d76 commit 619a19c
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 7 deletions.
11 changes: 11 additions & 0 deletions src/occ_405/mem/memory_power_control.c
Expand Up @@ -35,6 +35,11 @@ GpeRequest G_mem_power_control_req;
// GPE arguments
GPE_BUFFER(mem_power_control_args_t G_mem_power_control_args);

/**
* GPE shared data area for gpe1 tracebuffer and size
*/
extern gpe_shared_data_t G_shared_gpe_data;


// Function Specification
//
Expand Down Expand Up @@ -261,6 +266,12 @@ int gpe_mem_power_control(uint8_t mem_pwr_ctl, uint8_t mca, uint8_t wait_idle_gp
0 //Userdata2
);

addUsrDtlsToErrl(err,
(uint8_t *) G_shared_gpe_data.gpe1_tb_ptr,
G_shared_gpe_data.gpe1_tb_sz,
ERRL_USR_DTL_STRUCT_VERSION_1,
ERRL_USR_DTL_TRACE_DATA);

commitErrl(&err);

L_busy_error_traced = true;
Expand Down
25 changes: 22 additions & 3 deletions src/occ_405/sensor/sensor_get_tod_task.c
Expand Up @@ -87,7 +87,8 @@
typedef enum
{
GET_TOD_ERRL_USR_DTLS_NONE, ///< No data to store
GET_TOD_ERRL_USR_DTLS_GPE_FFDC ///< ffdc value from GPE0 in G_get_tod_args
GET_TOD_ERRL_USR_DTLS_GPE_FFDC, ///< ffdc value from GPE0 in G_get_tod_args
GET_TOD_ERRL_USR_DTLS_GPE_TRACE, ///< get GPE0 trace buffer
} GET_TOD_ERRL_USR_DTLS_DATA;


Expand Down Expand Up @@ -129,6 +130,10 @@ uint8_t G_get_tod_error_count = 0;
*/
bool G_get_tod_enabled = true;

/**
* GPE shared data area for gpe0 tracebuffer and size
*/
extern gpe_shared_data_t G_shared_gpe_data;

//******************************************************************************
// Private Functions
Expand Down Expand Up @@ -222,6 +227,16 @@ void get_tod_log_error(uint16_t i_modId, uint8_t i_reasonCode,
ERRL_USR_DTL_BINARY_DATA);
}

if (i_usrDtlsData == GET_TOD_ERRL_USR_DTLS_GPE_TRACE)
{

addUsrDtlsToErrl(l_errl,
(uint8_t *) G_shared_gpe_data.gpe0_tb_ptr,
G_shared_gpe_data.gpe0_tb_sz,
ERRL_USR_DTL_STRUCT_VERSION_1,
ERRL_USR_DTL_TRACE_DATA);
}

// Add processor callout
addCalloutToErrl(l_errl,
ERRL_CALLOUT_TYPE_HUID,
Expand Down Expand Up @@ -283,8 +298,12 @@ bool get_tod_is_request_idle(void)
* @userdata4 ERC_GENERIC_TIMEOUT
* @devdesc GPE request not finished after waiting repeatedly
*/
get_tod_log_error(GET_TOD_IS_REQ_IDLE_MOD, GPE_REQUEST_TASK_NOT_IDLE,
ERC_GENERIC_TIMEOUT, 0, 0, GET_TOD_ERRL_USR_DTLS_NONE);
get_tod_log_error(GET_TOD_IS_REQ_IDLE_MOD,
GPE_REQUEST_TASK_NOT_IDLE,
ERC_GENERIC_TIMEOUT,
0,
0,
GET_TOD_ERRL_USR_DTLS_GPE_TRACE);
}

// Return false since request is not idle
Expand Down
63 changes: 63 additions & 0 deletions src/occ_gpe0/apss_read.c
Expand Up @@ -32,8 +32,16 @@
#include <apss_structs.h>
#include "gpe_util.h"

#define MAX_EXECUTION_TIMER (PK_INTERVAL_SCALE((uint32_t)PK_MICROSECONDS(250)))

extern uint8_t G_apss_mode;
extern gpe_shared_data_t * G_gpe_shared_data;


uint32_t g_max_apss_start __attribute__((section(".sbss.debug"))) = 0;
uint32_t g_max_apss_cont __attribute__((section(".sbss.debug"))) = 0;
uint32_t g_max_apss_comp __attribute__((section(".sbss.debug"))) = 0;

/*
* Function Specifications:
*
Expand All @@ -58,6 +66,9 @@ void apss_start_pwr_meas_read(ipc_msg_t* cmd, void* arg)
#ifdef DEBUG_APSS_SEQ
PK_TRACE("apss_start_pwr_meas_read: enter");
#endif
uint32_t end_time = 0;
uint32_t diff_time = 0;
uint32_t start_time = pk_timebase32_get();

int rc;
uint64_t regValue; // a pointer to hold the putscom_abs register value
Expand Down Expand Up @@ -172,6 +183,21 @@ void apss_start_pwr_meas_read(ipc_msg_t* cmd, void* arg)
#ifdef DEBUG_APSS_SEQ
PK_TRACE("apss_start_pwr_meas_read: calling ipc_send_rsp()");
#endif
end_time = pk_timebase32_get();

diff_time = end_time - start_time;

if(diff_time > g_max_apss_start)
{
g_max_apss_start = diff_time;

if(diff_time > MAX_EXECUTION_TIMER)
{
PK_TRACE("apss_start_pwr_meas_read took longer than expected. Delta OTBR: %x",
diff_time);
}
}


// send back a response, IPC success even if ffdc/rc are non zeros
rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
Expand Down Expand Up @@ -206,6 +232,10 @@ void apss_continue_pwr_meas_read(ipc_msg_t* cmd, void* arg)
// the ipc arguments are passed through the ipc_msg_t structure, has a pointer
// to the G_gpe_continue_pwr_meas_read_args

uint32_t end_time = 0;
uint32_t diff_time = 0;
uint32_t start_time = pk_timebase32_get();

uint64_t regValue = 0;
int rc;
ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
Expand Down Expand Up @@ -318,6 +348,21 @@ void apss_continue_pwr_meas_read(ipc_msg_t* cmd, void* arg)
PK_TRACE("apss_continue_pwr_meas_read: calling ipc_send_rsp()");
#endif

end_time = pk_timebase32_get();

diff_time = end_time - start_time;

if(diff_time > g_max_apss_cont)
{
g_max_apss_cont = diff_time;

if(diff_time > MAX_EXECUTION_TIMER)
{
PK_TRACE("apss_continue took longer than expected. Delta OTBR: %x",
diff_time);
}
}

// send back a response, IPC success (even if ffdc/rc are non zeros)
rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
if(rc)
Expand Down Expand Up @@ -354,6 +399,10 @@ void apss_complete_pwr_meas_read(ipc_msg_t* cmd, void* arg)
#ifdef DEBUG_APSS_SEQ
PK_TRACE("apss_complete_pwr_meas_read: enter");
#endif
uint32_t end_time = 0;
uint32_t diff_time = 0;
uint32_t start_time = pk_timebase32_get();


int rc;
ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
Expand Down Expand Up @@ -404,6 +453,20 @@ void apss_complete_pwr_meas_read(ipc_msg_t* cmd, void* arg)
#ifdef DEBUG_APSS_SEQ
PK_TRACE("apss_complete_pwr_meas_read: calling ipc_send_rsp()");
#endif
end_time = pk_timebase32_get();

diff_time = end_time - start_time;

if(diff_time > g_max_apss_comp)
{
g_max_apss_comp = diff_time;

if(diff_time > MAX_EXECUTION_TIMER)
{
PK_TRACE("apss_complete took longer than expected. Delta OTBR: %x",
diff_time);
}
}

// send back a response, IPC success (even if ffdc/rc are non zeros)
rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
Expand Down
9 changes: 6 additions & 3 deletions src/occ_gpe0/gpe_util.c
Expand Up @@ -163,11 +163,14 @@ void busy_wait(uint32_t i_microseconds)
uint32_t end_count = current_count +
PK_INTERVAL_SCALE((uint32_t)PK_MICROSECONDS(i_microseconds));

// Handle wrap case
// end_count rolled over, Need to wait for roll-over of timebase
if(current_count > end_count)
{
// let counter roll over
while(current_count > end_count)
// If there is a high priority interrupt (DEC), the timebase could
// increment more than once between readings and if end_count value is
// very small then the roll-over could be missed, so just look at upper
// bit instead of comparing against end_count.
while((0x80000000 & current_count) != 0)
{
current_count = pk_timebase32_get();
}
Expand Down
2 changes: 1 addition & 1 deletion src/occ_gpe0/link.cmd
Expand Up @@ -108,7 +108,7 @@ SECTIONS

_SDA_BASE_ = .;
.sdata . : { *(.sdata*) . = ALIGN(128); } > sram
.sbss . : { *(.sbss*) . = ALIGN(128); } > sram
.sbss . : { *(.sbss.debug) *(.sbss*) . = ALIGN(128); } > sram

// Other read-write data
// It's not clear why boot.S is generating empty .glink,.iplt
Expand Down

0 comments on commit 619a19c

Please sign in to comment.