summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/apss_structs.h45
-rw-r--r--src/ipc_func_ids.h4
-rwxr-xr-xsrc/occ_405/main.c251
-rwxr-xr-xsrc/occ_405/pss/apss.c16
-rw-r--r--src/occ_405/pss/apss.h8
-rwxr-xr-xsrc/occ_gpe0/apss_composite.pS155
-rw-r--r--src/occ_gpe0/apss_init.c333
-rwxr-xr-xsrc/occ_gpe0/apss_init.pS226
-rw-r--r--src/occ_gpe0/apss_read.c9
-rw-r--r--src/occ_gpe0/apss_util.c96
-rw-r--r--src/occ_gpe0/apss_util.h11
-rwxr-xr-xsrc/occ_gpe0/gpe_export.h2
-rwxr-xr-xsrc/occ_gpe0/gpe_macros.h153
-rw-r--r--src/occ_gpe0/ipc_func_tables.c12
-rw-r--r--src/occ_gpe0/topfiles.mk2
-rw-r--r--src/occ_gpe0/wait_spi.c104
16 files changed, 701 insertions, 726 deletions
diff --git a/src/apss_structs.h b/src/apss_structs.h
index a43ec3b..953e475 100644
--- a/src/apss_structs.h
+++ b/src/apss_structs.h
@@ -23,15 +23,35 @@
/* */
/* IBM_PROLOG_END_TAG */
+/* This header file is used by both occ_405 and occ_gpe0. */
+/* Contains common structures and globals. */
+
#ifndef _APSS_STRUCTS_H
#define _APSS_STRUCTS_H
#include <gpe_export.h>
+
+// List of supported APSS Modes set in occ_gpe0/apss_init.c
+#define APSS_MODE_COMPOSITE 0
+#define APSS_MODE_AUTO2 1
+
+
+// List of possible apss Return Codes
+#define APSS_RC_SUCCESS 0x0
+#define APSS_RC_SPI_TIMEOUT 0x1
+#define APSS_RC_SCOM_GET_FAILED 0x2
+#define APSS_RC_SCOM_PUT_FAILED 0x3
+#define APSS_RC_INVALID_REG 0x4
+#define APSS_RC_IPC_SEND_FAILED 0x5
+#define APSS_RC_INVALID_APSS_MODE 0x6
+
+
+
/* This data structure holds the common args data structures between the */
/* 405 and the GPE0, used in IPC communications. */
/* We started by adding these common apss data structures to test the */
-/* code the way it worked before using the PORE GPE assembly. We will */
+/* code the way it worked before using the GPE assembly. We will */
/* probably have to add the apssPwrMeasStruct_t to include GPIO, */
/* measurements, and to maintain a single data structure for all GPE0's */
/* ASPSS routine (or may be consolidate the three routines in a single */
@@ -48,36 +68,37 @@ struct apssGpioConfigStruct
} __attribute__ ((__packed__));
typedef struct apssGpioConfigStruct apssGpioConfigStruct_t;
-struct apssCompositeConfigStruct
+struct apssModeConfigStruct
{
- uint8_t numAdcChannelsToRead;
- uint8_t numGpioPortsToRead;
+ uint8_t mode;
+ uint8_t numAdcChannelsToRead;
+ uint8_t numGpioPortsToRead;
} __attribute__ ((__packed__));
-typedef struct apssCompositeConfigStruct apssCompositeConfigStruct_t;
+typedef struct apssModeConfigStruct apssModeConfigStruct_t;
typedef struct {
- PoreGpeErrorStruct error;
+ GpeErrorStruct error;
apssGpioConfigStruct_t config0; // G_gpio_config[0] (input to APSS)
apssGpioConfigStruct_t config1; // G_gpio_config[1] (input to APSS)
} initGpioArgs_t;
typedef struct {
- PoreGpeErrorStruct error;
- apssCompositeConfigStruct_t config; // G_apss_composite_config (input to APSS)
-} setCompositeModeArgs_t;
+ GpeErrorStruct error;
+ apssModeConfigStruct_t config; // G_apss_composite_config (input to APSS)
+} setApssModeArgs_t;
typedef struct
{
- PoreGpeErrorStruct error;
+ GpeErrorStruct error;
} apss_start_args_t;
typedef struct {
- PoreGpeErrorStruct error;
+ GpeErrorStruct error;
uint64_t meas_data[4]; // G_apss_pwr_meas (1st block of data) (output from APSS)
} apss_continue_args_t;
typedef struct {
- PoreGpeErrorStruct error;
+ GpeErrorStruct error;
uint64_t meas_data[4]; // G_apss_pwr_meas (2nd block of data) (output from APSS)
} apss_complete_args_t;
diff --git a/src/ipc_func_ids.h b/src/ipc_func_ids.h
index a2eb58c..e253e39 100644
--- a/src/ipc_func_ids.h
+++ b/src/ipc_func_ids.h
@@ -55,6 +55,8 @@ IPC_FUNCIDS_TABLE_START
//These function ID's can only be sent to GPE0
IPC_FUNCIDS_ST_START(OCCHW_INST_ID_GPE0)
IPC_FUNC_ID(IPC_ST_TEST_FUNC0)
+ IPC_FUNC_ID(IPC_ST_APSS_INIT_GPIO_FUNCID)
+ IPC_FUNC_ID(IPC_ST_APSS_INIT_MODE_FUNCID)
IPC_FUNC_ID(IPC_ST_APSS_START_PWR_MEAS_READ_FUNCID)
IPC_FUNC_ID(IPC_ST_APSS_CONTINUE_PWR_MEAS_READ_FUNCID)
IPC_FUNC_ID(IPC_ST_APSS_COMPLETE_PWR_MEAS_READ_FUNCID)
@@ -73,7 +75,7 @@ IPC_FUNCIDS_TABLE_START
//Functions that are only supported by GPE3 should be defined here
//These function ID's can only be sent to GPE3
IPC_FUNCIDS_ST_START(OCCHW_INST_ID_GPE3)
- IPC_FUNCIDS_ST_END(OCCHW_INST_ID_GPE3)
+ IPC_FUNCIDS_ST_END(OCCHW_INST_ID_GPE3)
//Functions that are only supported by PPC should be defined here
//These function ID's can only be sent to the PPC
diff --git a/src/occ_405/main.c b/src/occ_405/main.c
index d795eef..b4246ba 100755
--- a/src/occ_405/main.c
+++ b/src/occ_405/main.c
@@ -56,6 +56,7 @@
#include <thrm_thread.h>
#include "scom.h"
//#include <fir_data_collect.h>
+#include <pss_service_codes.h>
extern void __ssx_boot;
extern uint32_t G_occ_phantom_critical_count;
@@ -63,7 +64,7 @@ extern uint32_t G_occ_phantom_noncritical_count;
extern uint8_t G_occ_interrupt_type;
// Remove the next LOC when dcom_initialize_roles() is un-commented
-uint8_t G_occ_role = OCC_MASTER; // TEMP
+uint8_t G_occ_role = OCC_MASTER; // TEMP
// TEMP Remove next 6 LOC when apssInitApplet.c is added
extern GpeRequest G_meas_start_request;
@@ -362,8 +363,8 @@ void gpe_reset(uint32_t instance_id)
* Name: occ_ipc_setup
*
* Description: Initialzes IPC (Inter Process Communication) that is used
- * to communicate with GPEs.
- * This will also start GPE0 and GPE1.
+ * to communicate with GPEs.
+ * This will also start GPE0 and GPE1.
* NOTE: SGPE and PGPE are started prior to the OCC 405 during the IPL.
*
* End Function Specification
@@ -547,58 +548,206 @@ void hmon_routine()
void master_occ_init()
{
- OCC_APLT_STATUS_CODES l_status = OCC_APLT_SUCCESS;
- errlHndl_t l_errl = NULL;
+ errlHndl_t l_err = NULL;
+ GpeRequest l_request; //Used once here to initialize apss.
+ // TODO: Move the APSS initialization code back to an applet once applets are running on P9.
// Initialize APSS
- // Start TEMP code until apssInitApplet.c is compiled and running applets is supported
- TRAC_INFO("apss_initialize: Creating request G_meas_start_request.");
- //Create the request for measure start. Scheduling will happen in apss.c
- gpe_request_create(&G_meas_start_request,
- &G_async_gpe_queue0, // queue
- IPC_ST_APSS_START_PWR_MEAS_READ_FUNCID, // entry_point
- (uint32_t)&G_gpe_start_pwr_meas_read_args, // entry_point arg
- SSX_WAIT_FOREVER, // no timeout
- NULL, // callback
- NULL, // callback arg
- ASYNC_CALLBACK_IMMEDIATE); // options
-
- TRAC_INFO("apss_initialize: Creating request G_meas_cont_request.");
- //Create the request for measure continue. Scheduling will happen in apss.c
- gpe_request_create(&G_meas_cont_request,
- &G_async_gpe_queue0, // request
- IPC_ST_APSS_CONTINUE_PWR_MEAS_READ_FUNCID, // entry_point
- (uint32_t)&G_gpe_continue_pwr_meas_read_args, // entry_point arg
- SSX_WAIT_FOREVER, // no timeout
- NULL, // callback
- NULL, // callback arg
- ASYNC_CALLBACK_IMMEDIATE); // options
-
- TRAC_INFO("apss_initialize: Creating request G_meas_complete_request.");
- //Create the request for measure complete. Scheduling will happen in apss.c
- gpe_request_create(&G_meas_complete_request,
- &G_async_gpe_queue0, // queue
- IPC_ST_APSS_COMPLETE_PWR_MEAS_READ_FUNCID, // entry_point
- (uint32_t)&G_gpe_complete_pwr_meas_read_args, // entry_point arg
- SSX_WAIT_FOREVER, // no timeout
- (AsyncRequestCallback)reformat_meas_data, // callback,
- (void*)NULL, // callback arg
- ASYNC_CALLBACK_IMMEDIATE); // options
-
- // END TEMP code. Un-comment runApplet() when TEMP code is removed
-/* runApplet(OCC_APLT_APSS_INIT, // Applet enum Name
- NULL, // Applet arguments
- TRUE, // Blocking call?
- NULL, // Applet finished semaphore
- &l_errl, // Error log handle
- &l_status); // Error status
-*/
- if( (NULL != l_errl) || (l_status != OCC_APLT_SUCCESS))
+ // Setup the GPIO init structure to pass to the PPE program
+ G_gpe_apss_initialize_gpio_args.error.error = 0;
+ G_gpe_apss_initialize_gpio_args.error.ffdc = 0;
+ G_gpe_apss_initialize_gpio_args.config0.direction
+ = G_gpio_config[0].direction;
+ G_gpe_apss_initialize_gpio_args.config0.drive
+ = G_gpio_config[0].drive;
+ G_gpe_apss_initialize_gpio_args.config0.interrupt
+ = G_gpio_config[0].interrupt;
+ G_gpe_apss_initialize_gpio_args.config1.direction
+ = G_gpio_config[1].direction;
+ G_gpe_apss_initialize_gpio_args.config1.drive
+ = G_gpio_config[1].drive;
+ G_gpe_apss_initialize_gpio_args.config1.interrupt
+ = G_gpio_config[1].interrupt;
+
+ // Create/schedule IPC_ST_APSS_INIT_GPIO_FUNCID and wait for it to complete (BLOCKING)
+ TRAC_INFO("master_occ_init: Creating request for GPE_apss_initialize_gpio");
+ gpe_request_create(&l_request, // request
+ &G_async_gpe_queue0, // queue
+ IPC_ST_APSS_INIT_GPIO_FUNCID, // Function ID
+ (uint8_t)&G_gpe_apss_initialize_gpio_args, // GPE argument_ptr
+ SSX_SECONDS(5), // timeout
+ NULL, // callback
+ NULL, // callback arg
+ ASYNC_REQUEST_BLOCKING); // options
+
+ // Schedule the request to be executed
+ TRAC_INFO("master_occ_init: Scheduling request for IPC_ST_APSS_INIT_GPIO_FUNCID");
+ gpe_request_schedule(&l_request);
+
+ // Check for a timeout only; will create the error below.
+ if(ASYNC_REQUEST_STATE_TIMED_OUT == l_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
+ // it to the front of the queue.
+ // Let's log an error, and include the FFDC data if it was
+ // generated.
+ TRAC_ERR("master_occ_init: Timeout communicating with PPE for APSS Init.");
+ }
+
+
+ TRAC_INFO("master_occ_init: GPE_apss_initialize_gpio completed w/rc=0x%08x\n",
+ l_request.request.completion_state);
+
+
+ //TODO: The ipc command will return "SUCCESS" even if an internal PPE failure
+ // occurs. Make sure that checking for rc as seen below, is good enough.
+
+ // Only continue if initializaton completed without any errors.
+ if ((ASYNC_REQUEST_STATE_COMPLETE == l_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
+ G_gpe_apss_set_mode_args.error.error = 0;
+ G_gpe_apss_set_mode_args.error.ffdc = 0;
+ G_gpe_apss_set_mode_args.config.mode
+ = G_apss_mode_config.mode; //Mode used is set in apss.c
+ G_gpe_apss_set_mode_args.config.numAdcChannelsToRead
+ = G_apss_mode_config.numAdcChannelsToRead;
+ G_gpe_apss_set_mode_args.config.numGpioPortsToRead
+ = G_apss_mode_config.numGpioPortsToRead;
+
+ // Create/schedule GPE_apss_set_mode and wait for it to complete (BLOCKING)
+ TRAC_INFO("master_occ_init: Creating request for GPE_apss_set_mode");
+ gpe_request_create(&l_request, // request
+ &G_async_gpe_queue0, // queue
+ IPC_ST_APSS_INIT_MODE_FUNCID, // Function ID
+ (uint8_t)&G_gpe_apss_set_mode_args, // GPE argument_ptr
+ SSX_SECONDS(5), // timeout
+ NULL, // callback
+ NULL, // callback arg
+ ASYNC_REQUEST_BLOCKING); // options
+ //Schedule set_mode
+ gpe_request_schedule(&l_request);
+
+ // Check for a timeout, will create the error log later
+ if(ASYNC_REQUEST_STATE_TIMED_OUT == l_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
+ // it to the front of the queue.
+ // Let's log an error, and include the FFDC data if it was
+ // generated.
+ TRAC_ERR("master_occ_init: Timeout communicating with PPE for APSS Init");
+ }
+
+ TRAC_INFO("master_occ_init: GPE_apss_set_mode completed w/rc=0x%08x",
+ l_request.request.completion_state);
+
+ //Continue only if mode set was successful.
+ if ((ASYNC_REQUEST_STATE_COMPLETE == l_request.request.completion_state) &&
+ (G_gpe_apss_set_mode_args.error.rc == ERRL_RC_SUCCESS))
+ {
+ TRAC_INFO("master_occ_init: Creating request G_meas_start_request.");
+ //Create the request for measure start. Scheduling will happen in apss.c
+ gpe_request_create(&G_meas_start_request,
+ &G_async_gpe_queue0, // queue
+ IPC_ST_APSS_START_PWR_MEAS_READ_FUNCID, // entry_point
+ (uint8_t)&G_gpe_start_pwr_meas_read_args,// entry_point arg
+ SSX_WAIT_FOREVER, // no timeout
+ NULL, // callback
+ NULL, // callback arg
+ ASYNC_CALLBACK_IMMEDIATE); // options
+
+ TRAC_INFO("master_occ_init: Creating request G_meas_cont_request.");
+ //Create the request for measure continue. Scheduling will happen in apss.c
+ gpe_request_create(&G_meas_cont_request,
+ &G_async_gpe_queue0, // request
+ IPC_ST_APSS_CONTINUE_PWR_MEAS_READ_FUNCID, // entry_point
+ (uint8_t)&G_gpe_continue_pwr_meas_read_args, // entry_point arg
+ SSX_WAIT_FOREVER, // no timeout
+ NULL, // callback
+ NULL, // callback arg
+ ASYNC_CALLBACK_IMMEDIATE); // options
+
+ TRAC_INFO("master_occ_init: Creating request G_meas_complete_request.");
+ //Create the request for measure complete. Scheduling will happen in apss.c
+ gpe_request_create(&G_meas_complete_request,
+ &G_async_gpe_queue0, // queue
+ IPC_ST_APSS_COMPLETE_PWR_MEAS_READ_FUNCID, // entry_point
+ (uint8_t)&G_gpe_complete_pwr_meas_read_args, // entry_point arg
+ SSX_WAIT_FOREVER, // no timeout
+ (AsyncRequestCallback)reformat_meas_data, // callback,
+ (void*)NULL, // callback arg
+ ASYNC_CALLBACK_IMMEDIATE); // options
+
+ }
+ else
+ {
+ /*
+ * @errortype
+ * @moduleid PSS_MID_APSS_INIT
+ * @reasoncode INTERNAL_FAILURE
+ * @userdata1 GPE returned rc code
+ * @userdata2 GPE returned abort code
+ * @userdata4 ERC_PSS_COMPOSITE_MODE_FAIL
+ * @devdesc Failure from GPE for setting composite mode on
+ * APSS
+ */
+ l_err = createErrl(PSS_MID_APSS_INIT, // i_modId,
+ INTERNAL_FAILURE, // i_reasonCode,
+ ERC_PSS_COMPOSITE_MODE_FAIL, // extended reason code
+ 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
+ addUsrDtlsToErrl(l_err,
+ (uint8_t*)&G_gpe_apss_set_mode_args,
+ sizeof(G_gpe_apss_set_mode_args),
+ ERRL_STRUCT_VERSION_1,
+ ERRL_USR_DTL_TRACE_DATA);
+
+ // Returning an error log will cause us to go to safe
+ // state so we can report error to FSP
+ }
+ }
+ else
{
- TRAC_ERR("APSS init applet returned error: l_status: 0x%x", l_status);
+ /*
+ * @errortype
+ * @moduleid PSS_MID_APSS_INIT
+ * @reasoncode INTERNAL_FAILURE
+ * @userdata1 GPE returned rc code
+ * @userdata2 GPE returned abort code
+ * @userdata4 ERC_PSS_GPIO_INIT_FAIL
+ * @devdesc Failure from GPE for gpio initialization on APSS
+ */
+ l_err = createErrl(PSS_MID_APSS_INIT, // i_modId,
+ INTERNAL_FAILURE, // i_reasonCode,
+ ERC_PSS_GPIO_INIT_FAIL, // extended reason code
+ 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
+ addUsrDtlsToErrl(l_err,
+ (uint8_t*)&G_gpe_apss_initialize_gpio_args,
+ sizeof(G_gpe_apss_initialize_gpio_args),
+ ERRL_STRUCT_VERSION_1,
+ ERRL_USR_DTL_TRACE_DATA);
+
+ // Returning an error log will cause us to go to safe
+ // state so we can report error to FSP
+ }
+
+ if( (NULL != l_err))
+ {
+ TRAC_ERR("APSS init applet returned error");
// commit & delete. CommitErrl handles NULL error log handle
- REQUEST_RESET(l_errl);
+ // TEMP -- NO ERRL / RESET YET
+ //REQUEST_RESET(l_err);
}
// Reinitialize the PBAX Queues
@@ -1137,7 +1286,7 @@ int main(int argc, char **argv)
// The offset from the start of the HOMER is 0x00100000, we will need to
// create a temporary mapping to this section of the HOMER with ppc405_mmu_map
// (at address 0x00000000) read the value, convert it, and then unmap.
-
+
// Don't do a version check before reading the nest freq, it's present in
// all HOMER versions.
uint32_t l_tb_freq_hz = 0;
diff --git a/src/occ_405/pss/apss.c b/src/occ_405/pss/apss.c
index 77a111f..fa08af8 100755
--- a/src/occ_405/pss/apss.c
+++ b/src/occ_405/pss/apss.c
@@ -44,14 +44,14 @@
// Configure both GPIOs (directoin/drive/interrupts): All Input, All 1's, No Interrupts
const apssGpioConfigStruct_t G_gpio_config[2] = { {0x00, 0xFF, 0x00}, {0x00, 0xFF, 0x00} };
-// Configure streaming of: 16 ADCs, 2 GPIOs
-const apssCompositeConfigStruct_t G_apss_composite_config = { 16, 2 };
+// Configure streaming of: APSS Mode, 16 ADCs, 2 GPIOs
+const apssModeConfigStruct_t G_apss_mode_config = { APSS_MODE_AUTO2, 16, 2 };
// Power Measurements (read from APSS every RealTime loop)
apssPwrMeasStruct_t G_apss_pwr_meas = { {0} };
GPE_BUFFER(initGpioArgs_t G_gpe_apss_initialize_gpio_args);
-GPE_BUFFER(setCompositeModeArgs_t G_gpe_apss_set_composite_mode_args);
+GPE_BUFFER(setApssModeArgs_t G_gpe_apss_set_mode_args);
uint64_t G_gpe_apss_time_start;
uint64_t G_gpe_apss_time_end;
@@ -637,14 +637,14 @@ void reformat_meas_data()
// Copy measurements into correct struction locations (based on composite config)
uint16_t l_index = 0;
- memcpy(G_apss_pwr_meas.adc, &l_buffer[l_index], (G_apss_composite_config.numAdcChannelsToRead * 2));
- l_index += (G_apss_composite_config.numAdcChannelsToRead * 2);
- memcpy(G_apss_pwr_meas.gpio, &l_buffer[l_index], (G_apss_composite_config.numGpioPortsToRead * 2));
+ memcpy(G_apss_pwr_meas.adc, &l_buffer[l_index], (G_apss_mode_config.numAdcChannelsToRead * 2));
+ l_index += (G_apss_mode_config.numAdcChannelsToRead * 2);
+ memcpy(G_apss_pwr_meas.gpio, &l_buffer[l_index], (G_apss_mode_config.numGpioPortsToRead * 2));
// TOD is always located at same offset
memcpy(&G_apss_pwr_meas.tod, &l_buffer[l_continue_meas_length+l_complete_meas_length-8], 8);
- APSS_DBG("...into structure: (%d ADC, %d GPIO)\n", G_apss_composite_config.numAdcChannelsToRead,
- G_apss_composite_config.numGpioPortsToRead);
+ APSS_DBG("...into structure: (%d ADC, %d GPIO)\n", G_apss_mode_config.numAdcChannelsToRead,
+ G_apss_mode_config.numGpioPortsToRead);
APSS_DBG_HEXDUMP(&G_apss_pwr_meas, sizeof(G_apss_pwr_meas), "G_apss_pwr_meas");
}
diff --git a/src/occ_405/pss/apss.h b/src/occ_405/pss/apss.h
index 482919e..a332bea 100644
--- a/src/occ_405/pss/apss.h
+++ b/src/occ_405/pss/apss.h
@@ -67,11 +67,11 @@ struct apssPwrMeasStruct
} __attribute__ ((__packed__));
typedef struct apssPwrMeasStruct apssPwrMeasStruct_t;
-// @TODO - Does G_gpio_config and G_apss_composite_config need to be used outside of APSS? If not I will remove from .h
+// @TODO - Does G_gpio_config and G_apss_mode_config need to be used outside of APSS? If not I will remove from .h
// G_gpio_config: configuration for APSS GPIO pins (default all input, all 1's, not int)
extern const apssGpioConfigStruct_t G_gpio_config[NUM_OF_APSS_GPIO_PORTS];
-// G_apss_composite_config: system parms needed to select correct composite command options
-extern const apssCompositeConfigStruct_t G_apss_composite_config;
+// G_apss_mode_config: system parms needed to select correct mode command options
+extern const apssModeConfigStruct_t G_apss_mode_config;
// G_apss_pwr_meas: power, temp and GPIO readings that OCC gathers from APSS every tick
extern apssPwrMeasStruct_t G_apss_pwr_meas;
@@ -80,7 +80,7 @@ extern apssPwrMeasStruct_t G_apss_pwr_meas;
extern volatile bool G_ApssPwrMeasCompleted;
extern initGpioArgs_t G_gpe_apss_initialize_gpio_args;
-extern setCompositeModeArgs_t G_gpe_apss_set_composite_mode_args;
+extern setApssModeArgs_t G_gpe_apss_set_mode_args;
extern uint64_t G_gpe_apss_time_start;
extern uint64_t G_gpe_apss_time_end;
diff --git a/src/occ_gpe0/apss_composite.pS b/src/occ_gpe0/apss_composite.pS
deleted file mode 100755
index 9e03c08..0000000
--- a/src/occ_gpe0/apss_composite.pS
+++ /dev/null
@@ -1,155 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/occ/gpe/apss_composite.pS $
-#
-# OpenPOWER OnChipController Project
-#
-# Contributors Listed Below - COPYRIGHT 2011,2014
-# [+] Google Inc.
-# [+] 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
-
-//////////////////////////////////////////////////////////////////////
-// Includes
-//////////////////////////////////////////////////////////////////////
-.nolist
-#include "pgp.h"
-#include "pgas.h"
-.list
-
-//////////////////////////////////////////////////////////////////////
-// Define Address Space
-//////////////////////////////////////////////////////////////////////
-.oci
-
-//////////////////////////////////////////////////////////////////////
-// Define Symbols
-//////////////////////////////////////////////////////////////////////
-
-#include <pss_constants.h>
-
-#define GPE_PROG_ID 0x0003
-
-//////////////////////////////////////////////////////////////////////
-// Define Structures
-//////////////////////////////////////////////////////////////////////
-
-// Declare the offsets of the struct that will be passed to the
-// GPE program via the ETR register
-//
-// struct G_gpe_apss_read_altitude_args =
-// {
-.struct 0
-ERROR_RC:
- .struct ERROR_RC + 8
-ERROR_FFDC:
- .struct ERROR_FFDC + 8
-CONFIG:
-// };
-
-
-//////////////////////////////////////////////////////////////////////
-// Begin Program
-//////////////////////////////////////////////////////////////////////
-
-.text
-
-#include <gpe_macros.h>
-#include <pss_macros.h>
-
-//--------------------------------------------------------------------
-// PORE-GPE Routine Specification:
-//
-// Name: GPE_apss_set_composite_mode
-//
-// Description: Set APSS into composite mode so OCC can read ADC, Temp & GPIO data
-//
-// Inputs: G_gpe_apss_set_composite_mode_args
-// struct {
-// PoreGpeErrorStruct error;
-// apssCompositeConfigStruct_t config; // G_apss_composite_config (input to APSS)
-// } G_gpe_apss_set_composite_mode_args;
-// struct {
-// uint64_t rc; // This should be read as 63:32=addr, 31:0=rc
-// uint64_t ffdc; // Whatever GPE program puts in for FFDC data
-// } PoreGpeErrorStruct;
-// struct {
-// uint8_t numAdcChannelsToRead;
-// uint8_t numGpioPortsToRead;
-// } apssCompositeConfigStruct
-//
-// Outputs: None (except FFDC on failure)
-//
-// End PORE-GPE Routine Specification
-//--------------------------------------------------------------------
-.global GPE_apss_set_composite_mode
-GPE_apss_set_composite_mode:
-
- // Copy passed Structure Pointer into A1
- mr A1, ETR
-
- // Wait for SPI operations to be complete (10usec timeout)
- _wait_for_spi_ops_complete 10, error_timeout
-
- // Setup control regs
- // frame size=16, out_count1=16, in_delay1=never, in_count2=16
- _putscom SPIPSS_P2S_CTRL_REG0, 0x4100000000000000
- // bridge_enable, clock_divider=7, 1 frame
- _putscom SPIPSS_P2S_CTRL_REG1, 0x8090000000000000
- // inter_frame_delay=25 (2.5usec)
- _putscom SPIPSS_P2S_CTRL_REG2, 0x0019000000000000
-
- // APSS command to set composite data streaming mode (APSS cmd 0x8xxx, reserved bits are 1)
- li D0, 0x8C00000000000000
- // last ADC channel address (0 = 1 ADC, etc)
- ldandi D1, CONFIG, A1, 0x1F00000000000000
- srdi D1, D1, 56
- subs D1, D1, 1
- sldi D1, D1, 54
- or D0, D0, D1
- // number of GPIO ports to return (0 = 0 GPIOs, etc...)
- ldandi D1, CONFIG, A1, 0x0003000000000000
- or D0, D0, D1
- // use auto2 mode (more reliable than composite mode)
- _putscom SPIPSS_P2S_WDATA_REG, 0x3FC0000000000000
-
- // Start SPI transaction
- _putscom SPIPSS_P2S_COMMAND_REG, 0x8000000000000000
-
- // Wait 20usec for apss becoming ready to send out the frame of composite mode
- waits (20 * MICROSECONDS)
-
- halt
-
-
-error_statusreg:
- // An error/reserved bit was set when reading p2s status register...
- // D0: P2S_STATUS_REG
- _saveffdc GPE_PROG_ID, 0x0002
- halt
-
-
-error_timeout:
- // p2s_ongoing bit was never cleared after several retries...
- // D0: P2S_STATUS_REG
- _saveffdc GPE_PROG_ID, 0x0001
- halt
-
-//////////////////////////////////////////////////////////////////////
-// End of Program
-//////////////////////////////////////////////////////////////////////
diff --git a/src/occ_gpe0/apss_init.c b/src/occ_gpe0/apss_init.c
new file mode 100644
index 0000000..ca58404
--- /dev/null
+++ b/src/occ_gpe0/apss_init.c
@@ -0,0 +1,333 @@
+#include "pk.h"
+#include "ppe42_scom.h"
+#include "ipc_api.h"
+#include "ipc_async_cmd.h"
+#include "pss_constants.h"
+#include <apss_structs.h> //H file common with occ_405
+#include "apss_util.h"
+
+/*
+ * Function Specification
+ *
+ * Name: apss_start_spi_command
+ *
+ * Description: Writes the P2S_COMMAND register to trigger the execution
+ * of a command loaded into the P2S_WDATA_REG
+ *
+ * End Function Specification
+ */
+uint32_t apss_start_spi_command(initGpioArgs_t * args, uint8_t i_noWait)
+{
+ uint32_t rc = 0;
+ uint64_t regValue = 0x8000000000000000;
+
+ // Start SPI transaction
+ rc = putscom_abs(SPIPSS_P2S_COMMAND_REG, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_start_spi_command: SPIPSS_P2S_COMMAND_REG putscom failed. rc = 0x%08x",
+ rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_COMMAND_REG, rc, 0x8000000000000000);
+ }
+ else
+ {
+
+ pk_sleep(PK_MICROSECONDS(5));
+
+ if (!i_noWait)
+ {
+ rc = wait_spi_completion(args, SPIPSS_P2S_STATUS_REG, 10);
+ if (rc)
+ {
+ PK_TRACE("apss_start_spi_command: Timed out waiting for ops to complete. rc = 0x%08x",
+ rc);
+ //FFDC set in wait_spi_completion
+ }
+ }
+ }
+
+ return rc;
+}
+
+/*
+ * Function Specification
+ *
+ * Name: apss_init_gpio
+ *
+ * Description: Initialize the APSS GPIO ports
+ *
+ * End Function Specification
+ */
+void apss_init_gpio(ipc_msg_t* cmd, void* arg)
+{
+ //Note: arg was set to 0 in ipc func table (ipc_func_tables.c), so don't use it
+
+ uint32_t rc;
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
+ initGpioArgs_t *args = (initGpioArgs_t*)async_cmd->cmd_data;
+ uint64_t regValue = 0;
+
+ do
+ {
+ // Wait for SPI operations to be complete (up to 10usec timeout)
+ rc = wait_spi_completion(args, SPIPSS_P2S_STATUS_REG, 10);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: Timed out waiting for ops to complete. rc = 0x%08x", rc);
+ //FFDC set in wait_spi_completion
+ break;
+ }
+
+ ////////////////////////////
+ // Setup the control regs
+ // frame_size=16, out_count=16, in_delay1=never, in_count2=16
+ regValue = 0x410FC00004000000;
+ rc = putscom_abs(SPIPSS_P2S_CTRL_REG0, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPIPSS_P2S_CTRL_REG0 putscom failed. rc = 0x%08x", rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG0, rc, regValue);
+ break;
+ }
+ // bridge_enable, clock_divider=7, 2 frames
+ regValue = 0x8090400000000000;
+ rc = putscom_abs(SPIPSS_P2S_CTRL_REG1, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPIPSS_P2S_CTRL_REG1 putscom failed. rc = 0x%08x", rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG1, rc, regValue);
+ break;
+ }
+ // inter_frame_delay=50 (5usec)
+ regValue = 0x0019000000000000;
+ rc = putscom_abs(SPIPSS_P2S_CTRL_REG2, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPIPSS_P2S_CTRL_REG2 putscom failed. rc = 0x%08x", rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG2, rc, regValue);
+ break;
+ }
+
+ uint64_t port = 0;
+ //Loop through the 2 ports setup
+ for (port=0; port <= 1; port++)
+ {
+ //////////////////////
+ // Direction (APSS cmd 0x4xxx); Configure GPIO mode (input or output)
+ regValue = args->config0.direction;
+ regValue = regValue << 48;
+ regValue |= 0x4000000000000000;
+ regValue |= (port << 56);
+
+ rc = putscom_abs(SPIPSS_P2S_WDATA_REG, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPIPSS_P2S_WDATA_REG putscom failed. value:0x%X. rc = 0x%08x",
+ regValue, rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_WDATA_REG, rc, regValue);
+ break;
+ }
+
+ // Start SPI transaction
+ rc = apss_start_spi_command(args,0);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPI command start failed. rc = 0x%08x", rc);
+ //FFDC already added
+ break;
+ }
+
+ //---------------
+ // Drive (APSS cmd 0x5xxx)
+ regValue = args->config0.drive;
+ regValue = regValue << 48;
+ regValue |= 0x5000000000000000;
+ regValue |= (port << 56);
+
+ rc = putscom_abs(SPIPSS_P2S_WDATA_REG, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPIPSS_P2S_WDATA_REG putscom failed. value:0x%X. rc = 0x%08x",
+ regValue, rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_WDATA_REG, rc, regValue);
+ break;
+ }
+ // Start SPI transaction
+ rc = apss_start_spi_command(args, 0);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPI command start failed. rc = 0x%08x", rc);
+ //FFDC already added.
+ break;
+ }
+
+ //--------------------
+ // Interrupt (APSS cmd 0x6xxx)
+ regValue = args->config0.interrupt;
+ regValue = regValue << 48;
+ regValue |= 0x6000000000000000;
+ regValue |= (port << 56);
+
+ rc = putscom_abs(SPIPSS_P2S_WDATA_REG, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPIPSS_P2S_WDATA_REG putscom failed. value:0x%X. rc = 0x%08x",
+ regValue, rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_WDATA_REG, rc, regValue);
+ break;
+ }
+
+ // Start SPI transaction
+ if (port == 0)
+ {
+ rc = apss_start_spi_command(args, 0);
+ }else
+ {
+ //No need to wait since it's the last command.
+ rc = apss_start_spi_command(args, 1);
+ }
+
+ if (rc)
+ {
+ PK_TRACE("apss_init_gpio: SPI command start failed. rc = 0x%08x", rc);
+ //FFDC already set
+ break;
+ }
+ }//End of port while loop.
+ }while(0);
+
+ // send back a successful response. OCC will check rc and ffdc
+ rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS);
+
+ if(rc)
+ {
+ PK_TRACE("apss_init_gpio: Failed to send response back. Halting GPE0", rc);
+ apss_set_ffdc(&(args->error), 0x00, rc, regValue);
+ pk_halt();
+ }
+}
+
+/*
+ * Function Specification
+ *
+ * Name: apss_init_mode
+ *
+ * Description: Initialize the APSS mode
+ *
+ * End Function Specification
+ */
+void apss_init_mode(ipc_msg_t* cmd, void* arg)
+{
+ //Note: arg was set to 0 in ipc func table (ipc_func_tables.c), so don't use it
+
+ uint32_t rc = APSS_RC_SUCCESS;
+ uint32_t ipc_rc = IPC_RC_SUCCESS;
+ ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd;
+ setApssModeArgs_t *args = (setApssModeArgs_t*)async_cmd->cmd_data;
+ uint64_t regValue = 0;
+
+ do
+ {
+ // Wait for SPI operations to be complete (up to 10usec timeout)
+ rc = wait_spi_completion(args, SPIPSS_P2S_STATUS_REG, 10);
+ if (rc)
+ {
+ PK_TRACE("apss_init_mode: Timed out waiting for ops to complete. rc = 0x%08x", rc);
+ //FFDC set in wait_spi_completion
+ break;
+ }
+
+ ////////////////////////////
+ // Setup the control regs
+ // frame_size=16, out_count1=16, in_delay1=never, in_count2=16
+ regValue = 0x4100000000000000;
+ rc = putscom_abs(SPIPSS_P2S_CTRL_REG0, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_mode: SPIPSS_P2S_CTRL_REG0 putscom failed. rc = 0x%08x", rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG0, rc, regValue);
+ break;
+ }
+
+ // bridge_enable, clock_divider=7, 1 frames
+ regValue = 0x8090000000000000;
+ rc = putscom_abs(SPIPSS_P2S_CTRL_REG1, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_mode: SPIPSS_P2S_CTRL_REG1 putscom failed. rc = 0x%08x", rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG1, rc, regValue);
+ break;
+ }
+ // inter_frame_delay=25 (2.5usec)
+ regValue = 0x0019000000000000;
+ rc = putscom_abs(SPIPSS_P2S_CTRL_REG2, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_mode: SPIPSS_P2S_CTRL_REG2 putscom failed. rc = 0x%08x", rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_CTRL_REG2, rc, regValue);
+ break;
+ }
+
+ //Check for requested APSS mode.
+ if (args->config.mode == APSS_MODE_COMPOSITE)
+ {
+ // APSS command to set composite data streaming mode (APSS cmd 0x8xxx, reserved bits are 1)
+ // binary: 100011aaaa0000gg000000000000000000000000000000000000000000000000
+ regValue = args->config.numAdcChannelsToRead - 1; //aaaa => Address of last ADC channel (countOfADCChannels - 1)
+ regValue = regValue << 6; //Make space for GPIO port count
+ regValue |= (args->config.numGpioPortsToRead) & 0x03; //gg => Num of GPIO ports
+ regValue = (regValue << 51) | 0x8C00000000000000; //Add Command at D15-D12
+ }
+ else if (args->config.mode == APSS_MODE_AUTO2)
+ {
+ // Set Auto2 mode
+ regValue = 0x3FC0000000000000;
+ }
+ else
+ {
+ //Invalid mode.
+ PK_TRACE("apss_init_mode: Given invalid APSS Mode. Mode:0x%X", args->config.mode);
+ rc = APSS_RC_INVALID_APSS_MODE;
+ apss_set_ffdc(&(args->error), 0x00, rc, args->config.mode);
+ ipc_rc = IPC_RC_CMD_FAILED;
+ break;
+ }
+
+ rc = putscom_abs(SPIPSS_P2S_WDATA_REG, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_mode: SPIPSS_P2S_WDATA_REG putscom to set MODE failed. value:0x%X. rc = 0x%08x",
+ regValue, rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_WDATA_REG, rc, regValue);
+ break;
+ }
+
+ regValue = 0x8000000000000000;
+ // Start SPI transaction
+ rc = putscom_abs(SPIPSS_P2S_COMMAND_REG, &regValue);
+ if (rc)
+ {
+ PK_TRACE("apss_init_mode: SPIPSS_P2S_COMMAND_REG putscom failed. rc = 0x%08x",
+ rc);
+ apss_set_ffdc(&(args->error), SPIPSS_P2S_COMMAND_REG, rc, 0x8000000000000000);
+ }
+
+ //Wait 20usec for apss becoming ready to send out the frame of composite mode
+ pk_sleep(PK_MICROSECONDS(20));;
+
+ }while(0);
+
+ // send back a response
+ PK_TRACE("apss_init_mode: Sending APSS response ReturnCode:0x%X. APSSrc:0x%X (0 = Success)",
+ ipc_rc, rc);
+ rc = ipc_send_rsp(cmd, ipc_rc);
+
+ //If we fail to send ipc response, then this error takes prescedence over any other error.
+ //TODO: See if there's another space to write the error out to.
+ if(rc)
+ {
+ PK_TRACE("apss_init_mode: Failed to send response back to mode initialization. Halting GPE0", ipc_rc);
+ apss_set_ffdc(&(args->error), 0x00, ipc_rc, regValue);
+ pk_halt();
+ }
+}
diff --git a/src/occ_gpe0/apss_init.pS b/src/occ_gpe0/apss_init.pS
deleted file mode 100755
index 23dfdd7..0000000
--- a/src/occ_gpe0/apss_init.pS
+++ /dev/null
@@ -1,226 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/occ/gpe/apss_init.pS $
-#
-# OpenPOWER OnChipController Project
-#
-# Contributors Listed Below - COPYRIGHT 2011,2014
-# [+] Google Inc.
-# [+] 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
-
-//////////////////////////////////////////////////////////////////////
-// Includes
-//////////////////////////////////////////////////////////////////////
-.nolist
-#include "pgp.h"
-#include "pgas.h"
-.list
-
-//////////////////////////////////////////////////////////////////////
-// Define Address Space
-//////////////////////////////////////////////////////////////////////
-.oci
-
-//////////////////////////////////////////////////////////////////////
-// Define Symbols
-//////////////////////////////////////////////////////////////////////
-
-#include <pss_constants.h>
-
-#define GPE_PROG_ID 0x0001
-
-//////////////////////////////////////////////////////////////////////
-// Define Structures
-//////////////////////////////////////////////////////////////////////
-
-// Declare the offsets of the struct that will be passed to the
-// GPE program via the ETR register
-//
-// struct G_gpe_apss_initialize_gpio_args =
-// {
-.struct 0
-ERROR_RC:
- .struct ERROR_RC + 8
-ERROR_FFDC:
- .struct ERROR_FFDC + 8
-CONFIG:
-// };
-
-//////////////////////////////////////////////////////////////////////
-// Begin Program
-//////////////////////////////////////////////////////////////////////
-
-.text
-
-#include <gpe_macros.h>
-#include <pss_macros.h>
-
-//--------------------------------------------------------------------
-// Name: _perform_spi_transaction (MACRO)
-//
-// Description: Start SPI transaction, wait for 5usec, and then
-// wait for operation to complete.
-//
-// Inputs: None
-//
-// Outputs: None (on error, D0 will contain status register)
-//
-// Modifies: CTR, D0, D1
-//--------------------------------------------------------------------
-.macro _perform_spi_transaction
-
-// Start SPI transaction
-_putscom SPIPSS_P2S_COMMAND_REG, 0x8000000000000000
-
-// wait 5usec
-waits (5 * MICROSECONDS)
-
-_wait_for_spi_ops_complete 10, error_timeout
-
-.endm
-
-
-//--------------------------------------------------------------------
-// PORE-GPE Routine Specification:
-//
-// Name: GPE_apss_initialize_gpio
-//
-// Description: Initialize APSS GPIO pins for Input/Output, Interrupt
-// Drive H/L
-//
-// Inputs: G_gpe_apss_initialize_gpio_args - Error and G_gpio_config
-// struct {
-// PoreGpeErrorStruct error;
-// apssGpioConfigStruct gpio_config0 // G_gpio_config[0] (input to APSS)
-// apssGpioConfigStruct gpio_config1 // G_gpio_config[1] (input to APSS)
-// } G_gpe_apss_initialize_gpio_args
-// struct {
-// uint64_t rc; // This should be read as 63:32=addr, 31:0=rc
-// uint64_t ffdc; // Whatever GPE program puts in for FFDC data
-// } PoreGpeErrorStruct;
-// struct apssGpioConfigStruct
-// {
-// uint8_t direction;
-// uint8_t drive;
-// uint8_t interrupt;
-// }
-//
-// Outputs: None (except FFDC on failure)
-//
-// End PORE-GPE Routine Specification
-//--------------------------------------------------------------------
-.global GPE_apss_initialize_gpio
-GPE_apss_initialize_gpio:
-
- // Copy passed Structure Pointer into A1
- mr A1, ETR
- halt
-
- // TODO Clean this up, unreachable code left over below, hook for future
- // function
-
- // Wait for SPI operations to be complete (up to 10usec timeout)
- _wait_for_spi_ops_complete 10, error_timeout
-
- // Setup control regs
- // frame_size=16, out_count=16, in_delay1=never, in_count2=16
- _putscom SPIPSS_P2S_CTRL_REG0, 0x410FC00004000000
- // bridge_enable, clock_divider=7, 2 frames
- _putscom SPIPSS_P2S_CTRL_REG1, 0x8090400000000000
- // inter_frame_delay=50 (5usec)
- _putscom SPIPSS_P2S_CTRL_REG2, 0x0019000000000000
-
- // Build apss commands based on gpio_config arguments
- // Arguments are each 1 byte long and contain default
- // value to be used to init each item (Direction/Drive/Interrupt)
-
- //// Port 0
-
- // Port 0 - Direction (APSS cmd 0x40xx)
- ldandi D0, CONFIG, A1, 0xFF00000000000000
- srdi D0, D0, 8
- ori D0, D0, 0x4000000000000000
- _putscom_d0 SPIPSS_P2S_WDATA_REG
-
- _perform_spi_transaction
-
- // Port 0 - Drive (APSS cmd 0x50xx)
- ldandi D0, CONFIG, A1, 0x00FF000000000000
- ori D0, D0, 0x5000000000000000
- _putscom_d0 SPIPSS_P2S_WDATA_REG
-
- _perform_spi_transaction
-
- // Port 0 - Interrupt (APSS cmd 0x60xx)
- ldandi D0, CONFIG, A1, 0x0000FF0000000000
- ori D0, D0, 0x0060000000000000
- sldi D0, D0, 8
- _putscom_d0 SPIPSS_P2S_WDATA_REG
-
- _perform_spi_transaction
-
- //// Port 1
-
- // Port 1 - Direction (APSS cmd 0x41xx)
- ldandi D0, CONFIG, A1, 0x000000FF00000000
- ori D0, D0, 0x0000410000000000
- sldi D0, D0, 16
- _putscom_d0 SPIPSS_P2S_WDATA_REG
-
- _perform_spi_transaction
-
- // Port 1 - Drive (APSS cmd 0x51xx)
- ldandi D0, CONFIG, A1, 0x00000000FF000000
- ori D0, D0, 0x0000005100000000
- sldi D0, D0, 24
- _putscom_d0 SPIPSS_P2S_WDATA_REG
-
- _perform_spi_transaction
-
- // Port 1 - Interrups (APSS cmd 0x61xx)
- ldandi D0, CONFIG, A1, 0x0000000000FF0000
- ori D0, D0, 0x0000000061000000
- sldi D0, D0, 32
- _putscom_d0 SPIPSS_P2S_WDATA_REG
-
- // Start SPI transaction (dont need to wait for p2s_ongoing bit since last cmd)
- _putscom SPIPSS_P2S_COMMAND_REG, 0x8000000000000000
-
- // wait 5usec
- waits (5 * MICROSECONDS)
-
- halt
-
-
-error_statusreg:
- // An error/reserved bit was set when reading p2s status register...
- // D0: P2S_STATUS_REG
- _saveffdc GPE_PROG_ID, 0x0002
- halt
-
-
-error_timeout:
- // p2s_ongoing bit was never cleared after several retries...
- // D0: P2S_STATUS_REG
- _saveffdc GPE_PROG_ID, 0x0001
- halt
-
-//////////////////////////////////////////////////////////////////////
-// End of Program
-//////////////////////////////////////////////////////////////////////
diff --git a/src/occ_gpe0/apss_read.c b/src/occ_gpe0/apss_read.c
index 04d6e72..87863c6 100644
--- a/src/occ_gpe0/apss_read.c
+++ b/src/occ_gpe0/apss_read.c
@@ -30,8 +30,7 @@
#include "ipc_async_cmd.h"
#include "pss_constants.h"
#include <apss_structs.h>
-
-extern int wait_spi_completion(int reg, int timeout); //wait_spi.c
+#include "apss_util.h"
void apss_start_pwr_meas_read(ipc_msg_t* cmd, void* arg)
{
@@ -56,7 +55,7 @@ void apss_start_pwr_meas_read(ipc_msg_t* cmd, void* arg)
// wait for ADC completion, or timeout after 5 micro seconds.
// scom register SPIPSS_ADC_STATUS_REG's bit 0 (HWCTRL_ONGOING)
// indicates when completion occurs.
- rc = wait_spi_completion(SPIPSS_ADC_STATUS_REG, 5);
+ rc = wait_spi_completion(args, SPIPSS_ADC_STATUS_REG, 5);
if(rc) // Timeout Reached, and SPI transaction didn't complete, copy over rc
{
PK_TRACE("gpe0:apss_start_pwr_meas_read:wait_spi_completion failed with rc = 0x%08x", rc);
@@ -161,7 +160,7 @@ void apss_continue_pwr_meas_read(ipc_msg_t* cmd, void* arg)
// wait for ADC completion, or timeout after 100 micro seconds.
// scom register SPIPSS_ADC_STATUS_REG's bit 0 (HWCTRL_ONGOING)
// indicates when completion occurs.
- rc = wait_spi_completion(SPIPSS_ADC_STATUS_REG, 100);
+ rc = wait_spi_completion(args, SPIPSS_ADC_STATUS_REG, 100);
if(rc) // Timeout Reached, and SPI transaction didn't complete, copy returned status into rc
// REVIEW: Should we also copy something into the ffdc as well?
{
@@ -234,7 +233,7 @@ void apss_complete_pwr_meas_read(ipc_msg_t* cmd, void* arg)
// wait for ADC completion, or timeout after 100 micro seconds.
// scom register SPIPSS_ADC_STATUS_REG's bit 0 (HWCTRL_ONGOING)
// indicates when completion occurs.
- rc = wait_spi_completion(SPIPSS_ADC_STATUS_REG, 100);
+ rc = wait_spi_completion(args, SPIPSS_ADC_STATUS_REG, 100);
if(rc) // Timeout Reached, and SPI transaction didn't complete, copy returned status into rc
// REVIEW: Should we also copy something into the ffdc as well? whether in wait_spi_completion or here?
{
diff --git a/src/occ_gpe0/apss_util.c b/src/occ_gpe0/apss_util.c
new file mode 100644
index 0000000..4fa586a
--- /dev/null
+++ b/src/occ_gpe0/apss_util.c
@@ -0,0 +1,96 @@
+
+#include "pk.h"
+#include "ppe42_scom.h"
+#include "pss_constants.h"
+#include "apss_util.h"
+#define SPIPSS_P2S_ONGOING_MASK 0x8000000000000000
+
+/*
+ * Function Specification
+ *
+ * Name: apss_set_ffdc
+ *
+ * Description: Fills up the error struct with the given data.
+ *
+ * End Function Specification
+ */
+void apss_set_ffdc(GpeErrorStruct *o_error, uint32_t i_addr, uint32_t i_rc, uint64_t i_ffdc)
+{
+
+ o_error->addr = i_addr;
+ //Return codes defined in apss_struct.h
+ o_error->rc = i_rc;
+ o_error->ffdc = i_ffdc;
+
+}
+
+//--------------------------------------------------------------------
+// Name: wait_spi
+//
+// Description: Read the specified register (SPIPSS_P2S_STATUS_REG
+// or SPIPSS_ADC_STATUS_REG), and check if it's p2s_ongoing
+// bit is 0 (operations done). If not, wait
+// up to the timeout usec (~1usec per retry).
+// If still not clear, continue looping,
+// If error/reserved bits are set, a return code will be sent back
+//
+// Inputs: timeout - # usec to wait for ongoing bit to clear
+// Register: SPIPSS_P2S_STATUS_REG or SPIPSS_ADC_STATUS_REG
+//
+// return: 0 -> Success: spi transaction completed within timeout limit
+// not 0 -> timeout: spi transaction did not complete within timeout
+// bits 0:7 are masked, and returned back for potential analysis
+// of the reason that the transaction timed out
+//--------------------------------------------------------------------
+
+int wait_spi_completion(initGpioArgs_t *args, uint32_t reg, uint8_t timeout)
+{
+ int i;
+ int rc;
+ uint64_t status;
+
+ if((reg != SPIPSS_P2S_STATUS_REG) && (reg != SPIPSS_ADC_STATUS_REG))
+ {
+ PK_TRACE("gpe0:wait_spi_completion failed: Invalid Register 0x%08x", reg);
+ rc = APSS_RC_INVALID_REG;
+ apss_set_ffdc((&(args->error)),reg,rc, 0x00);
+ }
+ else
+ {
+ // Keep polling the P2S_ONGOING bits for timeout
+ for (i = 0; i< timeout; i++)
+ {
+ rc = getscom_abs(reg, &status);
+ if(rc)
+ {
+ PK_TRACE("gpe0:wait_spi_completion failed with rc = 0x%08x", rc);
+ apss_set_ffdc(&(args->error),reg,APSS_RC_SCOM_GET_FAILED, rc);
+ rc = APSS_RC_SCOM_GET_FAILED;
+ break;
+ }
+
+
+ // bit zero is the P2s_ONGOING / HWCTRL_ONGOING
+ // set to 1: means operation is in progress (ONGOING)
+ // set to 0: means operation is complete, therefore exit for loop.
+ if((status & SPIPSS_P2S_ONGOING_MASK) == 0)
+ {
+ rc = 0;
+ break;
+ }
+
+ // sleep for 1 microsecond before retry
+ pk_sleep(PK_MICROSECONDS(1));
+ }
+ }
+
+ //Timed out waiting on P2S_ONGOING bit.
+ if (i >= timeout)
+ {
+ PK_TRACE("gpe0:wait_spi_completion Timed out waiting for p2s_ongoing to clear.");
+ apss_set_ffdc(&(args->error),reg,APSS_RC_SPI_TIMEOUT, rc);
+ rc = APSS_RC_SPI_TIMEOUT;
+ }
+
+ return rc;
+}
diff --git a/src/occ_gpe0/apss_util.h b/src/occ_gpe0/apss_util.h
new file mode 100644
index 0000000..a3a2f26
--- /dev/null
+++ b/src/occ_gpe0/apss_util.h
@@ -0,0 +1,11 @@
+
+#ifndef _APSS_UTIL_H
+#define _APSS_UTIL_H
+
+#include <apss_structs.h>
+
+void apss_set_ffdc(GpeErrorStruct *o_error, uint32_t i_addr, uint32_t i_rc, uint64_t i_ffdc);
+
+int wait_spi_completion(initGpioArgs_t *args, uint32_t reg, uint8_t timeout);
+
+#endif //_APSS_UTIL_H
diff --git a/src/occ_gpe0/gpe_export.h b/src/occ_gpe0/gpe_export.h
index 6922638..84184e7 100755
--- a/src/occ_gpe0/gpe_export.h
+++ b/src/occ_gpe0/gpe_export.h
@@ -36,6 +36,6 @@ typedef struct {
uint64_t error;
};
uint64_t ffdc;
-} PoreGpeErrorStruct; // Same for every GPE program
+} GpeErrorStruct; // Same for every GPE program
#endif //_GPE_EXPORT_H
diff --git a/src/occ_gpe0/gpe_macros.h b/src/occ_gpe0/gpe_macros.h
deleted file mode 100755
index b5f605c..0000000
--- a/src/occ_gpe0/gpe_macros.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/occ_405/gpe/gpe_macros.h $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2015 */
-/* [+] 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 */
-
-#ifndef _GPE_MACROS_H
-#define _GPE_MACROS_H
-
-//--------------------------------------------------------------------
-// Macro Specification:
-//
-// Name: _saveffdc
-//
-// Description: Save FFDC into error structure
-//
-// struct {
-// uint64_t rc; // This should be read as 63:32=addr, 31:0=rc
-// uint64_t ffdc; // Whatever GPE program puts in for FFDC data
-// } PoreGpeErrorStruct;
-//
-// - Copy D0 into PoreGpeErrorStruct->ffdc
-// - Copy \gpe_id into PoreGpeErrorStruct->rc[63:32]
-// - Copy \rc into PoreGpeErrorStruct->rc[31:0]
-//
-// Inputs: \gpe_id - Unique GPE program number to identify what prog failed
-// \rc - Unique GPE error code that will indicate failure
-// ETR - Assumed to be set to base address of
-// passed argument structure
-//
-// End Macro Specification
-//--------------------------------------------------------------------
-.macro _saveffdc, gpe_id, rc
-
- // Make sure passed Structure Pointer is loaded into A1
- mr A1, ETR
-
- // Save address to send back (upper word of D1)
- srdi D1, D1, 32
- // TODO: Simcs does not support SPRG0 yet, so use 24 bit CTR for now
- //mr SPRG0, D1
- mr CTR, D1
-
- // Check if rc was already saved...
- ld D1, 0, A1
- andi D1, D1, 0xFFFFFFFF00000000
- branz D1, 1f
-
- // Save D0 into FFDC of error structure
- std D0, 8, A1
- ld D0, 8, A1
-
- // Save address to send back... (truncated to 24 bits)
- mr D0, CTR
- // Save GPE progam ID
- li D1, \gpe_id
- sldi D1, D1, 16
- // and return code
- ori D1, D1, \rc
- sldi D1, D1, 32
- // combine GPE program/RC with address
- or D0, D0, D1
-
- // Save data into error structure
- std D0, 0, A1
- ld D0, 8, A1
- ld D0, 0, A1
-
-1:
-.endm
-
-
-//--------------------------------------------------------------------
-// Macro Specification:
-//
-// Name: _getscom
-//
-// Description: Get a SCOM based on passed in Address, put it in D0
-//
-// Inputs: SCOM Address
-//
-// Outputs: D0 - Result of SCOM
-//
-// End Macro Specification
-//--------------------------------------------------------------------
-.macro _getscom, address
-
- lpcs P0, \address
- ld D0, \address, P0
-.endm
-
-//--------------------------------------------------------------------
-// Macro Specification:
-//
-// Name: _putscom
-//
-// Description: Store data into SCOM based on passed in Address
-//
-// Inputs: SCOM Address, Data
-//
-// Outputs: None
-//
-// End Macro Specification
-//--------------------------------------------------------------------
-.macro _putscom, address, data
- lpcs P0, \address
- li D0, \data
- std D0, \address, P0
-.endm
-
-//--------------------------------------------------------------------
-// Macro Specification:
-//
-// Name: _putscom_d0
-//
-// Description: Store D0 into SCOM based on passed in Address
-//
-// Inputs: SCOM Address
-//
-// Outputs: None
-//
-// End Macro Specification
-//--------------------------------------------------------------------
-.macro _putscom_d0, address
- lpcs P0, \address
- std D0, \address, P0
-.endm
-
-#define TOD_VALUE_REG 0x00040020
-
-// Constant for use in wait statments: waits (5 * MICROSECONDS)
-#define MICROSECONDS 600
-
-#endif //_GPE_MACROS_H
diff --git a/src/occ_gpe0/ipc_func_tables.c b/src/occ_gpe0/ipc_func_tables.c
index 82ff16e..c1ea1e7 100644
--- a/src/occ_gpe0/ipc_func_tables.c
+++ b/src/occ_gpe0/ipc_func_tables.c
@@ -25,6 +25,8 @@
#include "ipc_api.h"
#include "ipc_ping.h"
+void apss_init_gpio(ipc_msg_t* cmd, void* arg);
+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);
@@ -52,11 +54,11 @@ IPC_MT_FUNC_TABLE_END
// Function table for single target (processor-specific) functions
IPC_ST_FUNC_TABLE_START
IPC_MSGQ_HANDLER(&G_gpe0_test_msgq0) // 0 - IPC_ST_TEST_FUNC0
-IPC_HANDLER(apss_start_pwr_meas_read, 0) // 1 - IPC_ST_APSS_START_PWR_MEAS_READ_FUNCID
-IPC_HANDLER(apss_continue_pwr_meas_read, 0) // 2 - IPC_ST_APSS_CONTINUE_PWR_MEAS_READ_FUNCID
-IPC_HANDLER(apss_complete_pwr_meas_read, 0) // 3 - IPC_ST_APSS_COMPLETE_PWR_MEAS_READ_FUNCID
-IPC_HANDLER_DEFAULT // 4
-IPC_HANDLER_DEFAULT // 5
+IPC_HANDLER(apss_init_gpio, 0) // 1 - IPC_ST_APSS_INIT_GPIO_FUNCID
+IPC_HANDLER(apss_init_mode, 0) // 2 - IPC_ST_APSS_INIT_MODE_FUNCID
+IPC_HANDLER(apss_start_pwr_meas_read, 0) // 3 - IPC_ST_APSS_START_PWR_MEAS_READ_FUNCID
+IPC_HANDLER(apss_continue_pwr_meas_read, 0) // 4 - IPC_ST_APSS_CONTINUE_PWR_MEAS_READ_FUNCID
+IPC_HANDLER(apss_complete_pwr_meas_read, 0) // 5 - IPC_ST_APSS_COMPLETE_PWR_MEAS_READ_FUNCID
IPC_HANDLER_DEFAULT // 6
IPC_HANDLER_DEFAULT // 7
IPC_HANDLER_DEFAULT // 8
diff --git a/src/occ_gpe0/topfiles.mk b/src/occ_gpe0/topfiles.mk
index e1c81b3..ae62fae 100644
--- a/src/occ_gpe0/topfiles.mk
+++ b/src/occ_gpe0/topfiles.mk
@@ -22,7 +22,7 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
-TOP-C-SOURCES = gpe0_main.c pk_app_irq_table.c ipc_func_tables.c apss_read.c wait_spi.c
+TOP-C-SOURCES = gpe0_main.c pk_app_irq_table.c ipc_func_tables.c apss_read.c apss_util.c apss_init.c
TOP-S-SOURCES =
TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-S-SOURCES:.S=.o)
diff --git a/src/occ_gpe0/wait_spi.c b/src/occ_gpe0/wait_spi.c
deleted file mode 100644
index 1bff747..0000000
--- a/src/occ_gpe0/wait_spi.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/occ_405/wait_spi.c $ */
-/* */
-/* OpenPOWER OnChipController Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2015 */
-/* [+] 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 */
-
-
-// This file contains a single function that deals with polling the
-// xxxxx_ONGOING status bit in two spi scom registers to confirm completion
-// of SPI transactions.
-//
-// In the near future, this function may be combined with additional spi
-// utilities and in that case the filename will definitely change.
-
-
-
-#include "pk.h"
-#include "ppe42_scom.h"
-#include "pss_constants.h"
-
-//--------------------------------------------------------------------
-// Name: wait_spi
-//
-// Description: Read the specified register (SPIPSS_P2S_STATUS_REG
-// or SPIPSS_ADC_STATUS_REG), and and check if it p2s_ongoing
-// bit is 0 (operations done). If not, wait
-// up to the timeout usec (~1usec per retry).
-// If still not clear, continue looping,
-// If error/reserved bits are set, a return code will be sent back
-//
-// Inputs: timeout - # usec to wait for ongoing bit to clear
-// Register: SPIPSS_P2S_STATUS_REG or SPIPSS_ADC_STATUS_REG
-//
-// return: 0 -> Success: spi transaction completed within timeout limit
-// not 0 -> timeout: spi transaction did not complete within timeout
-// bits 0:7 are masked, and returned back for potential analysis
-// of the reason that the transaction timed out
-//--------------------------------------------------------------------
-
-int wait_spi_completion(int reg, int timeout)
-{
- int i;
- int rc;
- uint64_t status;
-
- if(reg != SPIPSS_P2S_STATUS_REG && // Only these SPI status registers tested
- reg != SPIPSS_ADC_STATUS_REG) // for xxxx_ONGOING bits for now.
- {
- PK_TRACE("gpe0:wait_spi_completion failed: Invalid Register 0x%08x", reg);
- pk_halt();
- }
-
- for (i = 0; i< timeout; i++) // Keep polling the xxxx_ONGOING bits for timeout
- {
- rc = getscom_abs(reg, &status);
- if(rc)
- {
- PK_TRACE("gpe0:wait_spi_completion failed with rc = 0x%08x", rc);
- pk_halt();
- }
-
-
- // bit zero is the P2s_ONGOING / HWCTRL_ONGOING
- // set to 1: means operation is in progress (ONGOING)
- // reset to 0: means operation is complete
- if(status & 0x8000000000000000)
- break;
- pk_sleep(PK_MICROSECONDS(1)); // sleep for 1 microsecond before retry
- }
-
- if (i < timeout) // success: transaction completed before timeout limit
- {
- // REVIEW: It is true that the operation completed, but should we
- // check whether a reserved or error bit was set? ...
- // If this is possible, then we should set the ffdc to indicate that
- return 0;
- }
- else //timeout:
- // P2s_ONGOING / HWCTRL_ONGOING bit is on, other status info too
- // return 32 MSB only, (only 8 are used now,
- // while the 56 LSB are reserved in P9
- {
- return (status >> 32);
- }
-}
OpenPOWER on IntegriCloud