summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWael El-Essawy <welessa@us.ibm.com>2016-09-16 10:18:30 -0500
committerWael El-Essawy <welessa@us.ibm.com>2016-09-23 16:04:11 -0400
commitd137bd848a05d5afd8a9ee5c9803f421ebd0a922 (patch)
tree75fa87939a9f7028921504e9b6a27cbd138af930
parenta1788a7353ef2072534b77f79396c04ade749314 (diff)
downloadtalos-occ-d137bd848a05d5afd8a9ee5c9803f421ebd0a922.tar.gz
talos-occ-d137bd848a05d5afd8a9ee5c9803f421ebd0a922.zip
Enable FW Timing Sensors
Enable scheduling of the GPE NOP task to do GPE timings and verify all sensors being updated in amec_update_fw_sensors() are being populated correctly. Change-Id: I623dd7518be9a8736e601c7d2fa748097a4d773a RTC: 141299 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29849 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Wael El-Essawy <welessa@us.ibm.com>
-rwxr-xr-xsrc/gpe_export.h7
-rw-r--r--src/ipc_func_ids.h2
-rw-r--r--src/occ_405/amec/amec_init.c42
-rw-r--r--src/occ_405/amec/amec_sensors_fw.c68
-rwxr-xr-xsrc/occ_405/dimm/dimm.c6
-rw-r--r--src/occ_gpe0/gpe_util.c30
-rw-r--r--src/occ_gpe0/ipc_func_tables.c4
-rw-r--r--src/occ_gpe1/gpe1_main.c1
-rw-r--r--src/occ_gpe1/ipc_func_tables.c3
-rw-r--r--src/occ_gpe1/nop.c61
-rw-r--r--src/occ_gpe1/topfiles.mk2
11 files changed, 158 insertions, 68 deletions
diff --git a/src/gpe_export.h b/src/gpe_export.h
index 7f4496d..9c53f77 100755
--- a/src/gpe_export.h
+++ b/src/gpe_export.h
@@ -44,11 +44,16 @@ typedef struct {
// Arguments for doing a SCOM from GPE0
typedef struct ipc_scom_op
{
+ GpeErrorStruct error; // Error of SCOM operation
uint32_t addr; // Register address
uint64_t data; // Data for read/write
uint32_t size; // Size of data buffer
uint8_t read; // Read (1) or write (0)
- GpeErrorStruct error; // Error of SCOM operation
} ipc_scom_op_t;
+typedef struct nop
+{
+ GpeErrorStruct error; // Error of operation
+} nop_t;
+
#endif //_GPE_EXPORT_H
diff --git a/src/ipc_func_ids.h b/src/ipc_func_ids.h
index f640674..b5d446f 100644
--- a/src/ipc_func_ids.h
+++ b/src/ipc_func_ids.h
@@ -57,6 +57,7 @@ IPC_FUNCIDS_TABLE_START
IPC_FUNC_ID(IPC_ST_APSS_COMPLETE_PWR_MEAS_READ_FUNCID)
IPC_FUNC_ID(IPC_ST_GET_CORE_DATA_FUNCID)
IPC_FUNC_ID(IPC_ST_SCOM_OPERATION)
+ IPC_FUNC_ID(IPC_ST_GPE0_NOP)
IPC_FUNCIDS_ST_END(OCCHW_INST_ID_GPE0)
//Functions that are only supported by GPE1 should be defined here
@@ -64,6 +65,7 @@ IPC_FUNCIDS_TABLE_START
IPC_FUNCIDS_ST_START(OCCHW_INST_ID_GPE1)
IPC_FUNC_ID(IPC_ST_DIMM_SM_FUNCID)
IPC_FUNC_ID(IPC_ST_DIMM_CONTROL_FUNCID)
+ IPC_FUNC_ID(IPC_ST_GPE1_NOP)
IPC_FUNCIDS_ST_END(OCCHW_INST_ID_GPE1)
//Functions that are only supported by GPE2 should be defined here
diff --git a/src/occ_405/amec/amec_init.c b/src/occ_405/amec/amec_init.c
index 4179e70..e0fdd84 100644
--- a/src/occ_405/amec/amec_init.c
+++ b/src/occ_405/amec/amec_init.c
@@ -357,41 +357,37 @@ void amec_init_gamec_struct(void)
// End Function Specification
void amec_slave_init()
{
-// @TODO - TEMP: not ready yet
-/*
errlHndl_t l_err = NULL; // Error handler
int rc = 0; // Return code
int rc2 = 0; // Return code
-*/
// Set the GPE Request Pointers to NULL in case the create fails.
G_fw_timing.gpe0_timing_request = NULL;
G_fw_timing.gpe1_timing_request = NULL;
-// @TODO - TEMP: not ready yet
-#if 0
-
// Initializes the GPE routine that will be used to measure the worst case
// timings for GPE0
- rc = pore_flex_create( &G_gpe_nop_request[0], //gpe_req for the task
- &G_pore_gpe0_queue, //queue
- (void *) GPE_pore_nop, //entry point
- (uint32_t) NULL, //parm for the task
- SSX_WAIT_FOREVER, //no timeout
- (AsyncRequestCallback) amec_slv_update_gpe_sensors, //callback
- (void *) GPE_ENGINE_0, //callback argument
- ASYNC_CALLBACK_IMMEDIATE ); //options
+ rc = gpe_request_create(&G_gpe_nop_request[0], //gpe_req for the task
+ &G_async_gpe_queue0, //queue
+ IPC_ST_GPE0_NOP, //Function ID
+ NULL, //parm for the task
+ SSX_WAIT_FOREVER, //no timeout
+ (AsyncRequestCallback)
+ amec_slv_update_gpe_sensors, //callback
+ (void *) GPE_ENGINE_0, //callback argument
+ ASYNC_CALLBACK_IMMEDIATE ); //options
// Initializes the GPE routine that will be used to measure the worst case
// timings for GPE1
- rc2 = pore_flex_create( &G_gpe_nop_request[1], //gpe_req for the task
- &G_pore_gpe1_queue, //queue
- (void *)GPE_pore_nop, //entry point
- (uint32_t) NULL, //parm for the task
- SSX_WAIT_FOREVER, //no timeout
- (AsyncRequestCallback) amec_slv_update_gpe_sensors, //callback
- (void *) GPE_ENGINE_1, //callback argument
- ASYNC_CALLBACK_IMMEDIATE ); //options
+ rc2 = gpe_request_create( &G_gpe_nop_request[1], //gpe_req for the task
+ &G_async_gpe_queue1, //queue
+ IPC_ST_GPE1_NOP, //Function ID
+ NULL, //parm for the task
+ SSX_WAIT_FOREVER, //no timeout
+ (AsyncRequestCallback)
+ amec_slv_update_gpe_sensors, //callback
+ (void *) GPE_ENGINE_1, //callback argument
+ ASYNC_CALLBACK_IMMEDIATE ); //options
// If we couldn't create the poreFlex objects, there must be a major problem
// so we will log an error and halt OCC.
@@ -432,8 +428,6 @@ void amec_slave_init()
G_fw_timing.gpe1_timing_request = &G_gpe_nop_request[1];
}
-#endif // #if 0 - @TODO - TEMP - Not ready yet
-
// Initialize Vector Sensors for AMEC use
amec_init_vector_sensors();
diff --git a/src/occ_405/amec/amec_sensors_fw.c b/src/occ_405/amec/amec_sensors_fw.c
index 8447f2c..07b3f5d 100644
--- a/src/occ_405/amec/amec_sensors_fw.c
+++ b/src/occ_405/amec/amec_sensors_fw.c
@@ -42,6 +42,8 @@
#include "sensor_enum.h"
#include "amec_service_codes.h"
#include <amec_sensors_fw.h>
+#include "gpe_register_addresses.h"
+#include "gpe_firmware_registers.h"
/******************************************************************************/
/* Globals */
@@ -124,13 +126,14 @@ void amec_update_fw_sensors(void)
// Kick off GPE programs to track WorstCase time in GPE
// and update the sensors.
// ------------------------------------------------------
- if( (NULL != G_fw_timing.gpe0_timing_request)
- && (NULL != G_fw_timing.gpe1_timing_request) )
+ if( (NULL != G_fw_timing.gpe0_timing_request) &&
+ (NULL != G_fw_timing.gpe1_timing_request) )
{
//Check if both GPE engines were able to complete the last GPE job on
//the queue within 1 tick.
l_gpe0_idle = async_request_is_idle(&G_fw_timing.gpe0_timing_request->request);
l_gpe1_idle = async_request_is_idle(&G_fw_timing.gpe1_timing_request->request);
+
if(l_gpe0_idle && l_gpe1_idle)
{
//reset the consecutive trace count
@@ -138,8 +141,8 @@ void amec_update_fw_sensors(void)
//Both GPE engines finished on time. Now check if they were
//successful too.
- if( async_request_completed(&(G_fw_timing.gpe0_timing_request->request))
- && async_request_completed(&(G_fw_timing.gpe1_timing_request->request)) )
+ if( async_request_completed(&(G_fw_timing.gpe0_timing_request->request)) &&
+ async_request_completed(&(G_fw_timing.gpe1_timing_request->request)) )
{
// GPEtickdur0 = duration of last tick's PORE-GPE0 duration
sensor_update( AMECSENSOR_PTR(GPEtickdur0), G_fw_timing.gpe_dur[0]);
@@ -162,15 +165,13 @@ void amec_update_fw_sensors(void)
// Update Time used to measure GPE duration.
G_fw_timing.rtl_start_gpe = G_fw_timing.rtl_start;
-// @TODO - TEMP - Old PORE SCHEDULE, needs to be replaced with GPE schedule code.
-/*
// Schedule the GPE Routines that will run and update the worst
// case timings (via callback) after they complete. These GPE
// routines are the last GPE routines added to the queue
// during the RTL tick.
- rc = pore_flex_schedule(G_fw_timing.gpe0_timing_request);
- rc2 = pore_flex_schedule(G_fw_timing.gpe1_timing_request);
-*/
+ rc = gpe_request_schedule(G_fw_timing.gpe0_timing_request);
+ rc2 = gpe_request_schedule(G_fw_timing.gpe1_timing_request);
+
if(rc || rc2)
{
/* @
@@ -199,45 +200,38 @@ void amec_update_fw_sensors(void)
}
else if(L_consec_trace_count < MAX_CONSEC_TRACE)
{
-// @TODO: TEMP - PORE GPE Codes, needs to reflect PPE architecture.
-/*
- uint64_t l_dbg0;
- uint64_t l_dbg1;
- uint64_t l_status;
+ gpe_gpenxiramdbg_t xsr_sprg0;
+ gpe_gpenxiramedr_t ir_edr;
+ gpe_gpenxidbgpro_t iar_xsr;
// Reset will eventually be requested due to not having power measurement
// data after X ticks, but add some additional FFDC to the trace that
// will tell us what GPE job is currently executing.
if(!l_gpe0_idle)
{
- l_dbg1 = in64(PORE_GPE0_DBG1);
- l_dbg0 = in64(PORE_GPE0_DBG0);
- l_status = in64(PORE_GPE0_STATUS);
- TRAC_ERR("GPE0 programs did not complete within one tick. DBG0[0x%08x%08x] DBG1[0x%08x%08x]",
- (uint32_t)(l_dbg0 >> 32),
- (uint32_t)(l_dbg0 & 0x00000000ffffffffull),
- (uint32_t)(l_dbg1 >> 32),
- (uint32_t)(l_dbg1 & 0x00000000ffffffffull));
- TRAC_ERR("Additional GPE0 debug data: STATUS[0x%08x%08x]",
- (uint32_t)(l_status >> 32),
- (uint32_t)(l_status & 0x00000000ffffffffull));
+ xsr_sprg0.value = in64(GPE_GPE0XIRAMDBG);
+ ir_edr.value = in64(GPE_GPE0XIRAMEDR);
+ iar_xsr.value = in64(GPE_GPE0XIDBGPRO);
+ TRAC_ERR("GPE0 programs did not complete within one tick. "
+ "XSR[0x%08x] IAR[0x%08x] IR[0x%08x] EDR[0x%08x]",
+ iar_xsr.fields.xsr, iar_xsr.fields.iar,
+ ir_edr.fields.ir, ir_edr.fields.edr);
+ TRAC_ERR("Additional GPE0 debug data: RAM_XSR[0x%08x] RAM_SPRG0[0x%08x]",
+ xsr_sprg0.fields.xsr, xsr_sprg0.fields.sprg0);
}
if(!l_gpe1_idle)
{
- l_dbg1 = in64(PORE_GPE1_DBG1);
- l_dbg0 = in64(PORE_GPE1_DBG0);
- l_status = in64(PORE_GPE1_STATUS);
- TRAC_ERR("GPE1 programs did not complete within one tick. DBG0[0x%08x%08x] DBG1[0x%08x%08x]",
- (uint32_t)(l_dbg0 >> 32),
- (uint32_t)(l_dbg0 & 0x00000000ffffffffull),
- (uint32_t)(l_dbg1 >> 32),
- (uint32_t)(l_dbg1 & 0x00000000ffffffffull));
- TRAC_ERR("Additional GPE1 debug data: STATUS[0x%08x%08x]",
- (uint32_t)(l_status >> 32),
- (uint32_t)(l_status & 0x00000000ffffffffull));
+ xsr_sprg0.value = in64(GPE_GPE1XIRAMDBG);
+ ir_edr.value = in64(GPE_GPE1XIRAMEDR);
+ iar_xsr.value = in64(GPE_GPE1XIDBGPRO);
+ TRAC_ERR("GPE1 programs did not complete within one tick. "
+ "XSR[0x%08x] IAR[0x%08x] IR[0x%08x] EDR[0x%08x]",
+ iar_xsr.fields.xsr, iar_xsr.fields.iar,
+ ir_edr.fields.ir, ir_edr.fields.edr);
+ TRAC_ERR("Additional GPE1 debug data: RAM_XSR[0x%08x] RAM_SPRG0[0x%08x]",
+ xsr_sprg0.fields.xsr, xsr_sprg0.fields.sprg0);
}
L_consec_trace_count++;
-*/
}
}
}
diff --git a/src/occ_405/dimm/dimm.c b/src/occ_405/dimm/dimm.c
index 62250da..676f127 100755
--- a/src/occ_405/dimm/dimm.c
+++ b/src/occ_405/dimm/dimm.c
@@ -142,10 +142,10 @@ void memory_nimbus_init()
// Initializes GPE request for DIMM temperature reading IPC Task,
DIMM_DBG("memory_nimbus_init: Creating request GPE1 DIMM data IPC task");
rc_dimm_sm = gpe_request_create(
- &G_dimm_sm_request,
+ &G_dimm_sm_request, // gpe_req for the task
&G_async_gpe_queue1, // queue
- IPC_ST_DIMM_SM_FUNCID, // entry_point
- &G_dimm_sm_args, // entry_point arg
+ IPC_ST_DIMM_SM_FUNCID, // Function ID
+ &G_dimm_sm_args, // parm for the task
SSX_WAIT_FOREVER, // no timeout
NULL, // callback
NULL, // callback arg
diff --git a/src/occ_gpe0/gpe_util.c b/src/occ_gpe0/gpe_util.c
index d8f7e6d..72a0288 100644
--- a/src/occ_gpe0/gpe_util.c
+++ b/src/occ_gpe0/gpe_util.c
@@ -216,3 +216,33 @@ void ipc_scom_operation(ipc_msg_t* cmd, void* arg)
pk_halt();
}
}
+
+/*
+ * Function Specification:
+ *
+ * Name: gpe0_nop
+ *
+ * Description: a function that does nothing. Called to measure IPC timing
+ *
+ * Inputs: none
+ *
+ * return: none
+ *
+ * End Function Specification
+ */
+
+void gpe0_nop(ipc_msg_t* cmd, void* arg)
+{
+ int rc;
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
+ nop_t *args = (nop_t*)async_cmd->cmd_data;
+
+ // send back a response, IPC success even if ffdc/rc are non zeros
+ rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
+ if(rc)
+ {
+ PK_TRACE("gpe0_nop: Failed to send response back. Halting GPE0", rc);
+ gpe_set_ffdc(&(args->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
+ pk_halt();
+ }
+}
diff --git a/src/occ_gpe0/ipc_func_tables.c b/src/occ_gpe0/ipc_func_tables.c
index afb399b..7b4c8a1 100644
--- a/src/occ_gpe0/ipc_func_tables.c
+++ b/src/occ_gpe0/ipc_func_tables.c
@@ -36,6 +36,8 @@ void gpe_get_core_data(ipc_msg_t* cmd, void* arg);
void ipc_scom_operation(ipc_msg_t* cmd, void* arg);
+void gpe0_nop(ipc_msg_t* cmd, void* arg);
+
extern ipc_msgq_t G_gpe0_test_msgq0;
// Function table for multi target (common) functions
@@ -66,7 +68,7 @@ IPC_HANDLER(apss_continue_pwr_meas_read, 0) // 4 - IPC_ST_APSS_CONTINUE_PWR_MEA
IPC_HANDLER(apss_complete_pwr_meas_read, 0) // 5 - IPC_ST_APSS_COMPLETE_PWR_MEAS_READ_FUNCID
IPC_HANDLER(gpe_get_core_data, 0) // 6 - IPC_ST_GET_CORE_DATA_FUNCID
IPC_HANDLER(ipc_scom_operation, 0) // 7 - IPC_ST_SCOM_OPERATION
-IPC_HANDLER_DEFAULT // 8
+IPC_HANDLER(gpe0_nop, 0) // 8 - IPC_ST_GPE0_NOP
IPC_HANDLER_DEFAULT // 9
IPC_HANDLER_DEFAULT // 10
IPC_HANDLER_DEFAULT // 11
diff --git a/src/occ_gpe1/gpe1_main.c b/src/occ_gpe1/gpe1_main.c
index 88f3be8..a7a3ff5 100644
--- a/src/occ_gpe1/gpe1_main.c
+++ b/src/occ_gpe1/gpe1_main.c
@@ -69,3 +69,4 @@ int main(int argc, char **argv)
return 0;
}
+
diff --git a/src/occ_gpe1/ipc_func_tables.c b/src/occ_gpe1/ipc_func_tables.c
index ab352c6..d575ae3 100644
--- a/src/occ_gpe1/ipc_func_tables.c
+++ b/src/occ_gpe1/ipc_func_tables.c
@@ -26,6 +26,7 @@
#include "gpe1_dimm.h"
void gpe_dimm_control(ipc_msg_t* cmd, void* arg);
+void gpe1_nop(ipc_msg_t* cmd, void* arg);
// Function table for multi target (common) functions
IPC_MT_FUNC_TABLE_START
@@ -43,7 +44,7 @@ IPC_MT_FUNC_TABLE_END
IPC_ST_FUNC_TABLE_START
IPC_HANDLER(gpe_dimm_sm, 0) // 0 - IPC_ST_DIMM_SM_FUNCID
IPC_HANDLER(gpe_dimm_control, 0) // 1 - IPC_ST_DIMM_CONTROL_FUNCID
-IPC_HANDLER_DEFAULT // 2
+IPC_HANDLER(gpe1_nop, 0) // 2 - IPC_ST_GPE1_NOP
IPC_HANDLER_DEFAULT // 3
IPC_HANDLER_DEFAULT // 4
IPC_HANDLER_DEFAULT // 5
diff --git a/src/occ_gpe1/nop.c b/src/occ_gpe1/nop.c
new file mode 100644
index 0000000..5a99c64
--- /dev/null
+++ b/src/occ_gpe1/nop.c
@@ -0,0 +1,61 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_gpe1/nop.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* 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 */
+/* */
+/* 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. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include "pk.h"
+#include "ppe42_scom.h"
+#include "gpe_export.h"
+#include "ipc_api.h"
+#include "ipc_async_cmd.h"
+#include "gpe_util.h"
+
+/*
+ * Function Specification:
+ *
+ * Name: gpe1_nop
+ *
+ * Description: a function that does nothing. Called to measure IPC timing
+ *
+ * Inputs: none
+ *
+ * return: none
+ *
+ * End Function Specification
+ */
+
+void gpe1_nop(ipc_msg_t* cmd, void* arg)
+{
+ int rc;
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
+ nop_t *args = (nop_t*)async_cmd->cmd_data;
+
+ // send back a response, IPC success even if ffdc/rc are non zeros
+ rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
+ if(rc)
+ {
+ PK_TRACE("gpe1_nop: Failed to send response back. Halting GPE1", rc);
+ gpe_set_ffdc(&(args->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc);
+ pk_halt();
+ }
+}
diff --git a/src/occ_gpe1/topfiles.mk b/src/occ_gpe1/topfiles.mk
index 4499c81..75a8fbc 100644
--- a/src/occ_gpe1/topfiles.mk
+++ b/src/occ_gpe1/topfiles.mk
@@ -23,7 +23,7 @@
#
# IBM_PROLOG_END_TAG
-TOP-C-SOURCES = gpe1_main.c gpe1_dimm_read.c gpe1_dimm_reset.c \
+TOP-C-SOURCES = gpe1_main.c gpe1_dimm_read.c gpe1_dimm_reset.c nop.c \
pk_app_irq_table.c ipc_func_tables.c gpe1_dimm_control.c
TOP-S-SOURCES =
OpenPOWER on IntegriCloud