summaryrefslogtreecommitdiffstats
path: root/src/occ_405/sensor
diff options
context:
space:
mode:
Diffstat (limited to 'src/occ_405/sensor')
-rwxr-xr-xsrc/occ_405/sensor/sensor.h21
-rwxr-xr-xsrc/occ_405/sensor/sensor_inband_cmd.c557
-rw-r--r--src/occ_405/sensor/sensor_inband_cmd.h112
-rw-r--r--src/occ_405/sensor/sensor_main_memory.h1
-rwxr-xr-xsrc/occ_405/sensor/sensor_service_codes.h6
5 files changed, 690 insertions, 7 deletions
diff --git a/src/occ_405/sensor/sensor.h b/src/occ_405/sensor/sensor.h
index c28b0cd..3b301d9 100755
--- a/src/occ_405/sensor/sensor.h
+++ b/src/occ_405/sensor/sensor.h
@@ -75,6 +75,12 @@ typedef enum
AMEC_SENSOR_TYPE_PERF = 0x0200,
AMEC_SENSOR_TYPE_ALL = 0xffff,
}AMEC_SENSOR_TYPE;
+// Changes to sensor type bits would require changes to select sensor groups command
+// Define the sensor types allowed to be selected via select sensor groups command
+#define VALID_SET_SENSOR_GROUPS_MASK (AMEC_SENSOR_TYPE_GENERIC | AMEC_SENSOR_TYPE_CURRENT | \
+ AMEC_SENSOR_TYPE_VOLTAGE | AMEC_SENSOR_TYPE_TEMP | AMEC_SENSOR_TYPE_UTIL | \
+ AMEC_SENSOR_TYPE_TIME | AMEC_SENSOR_TYPE_FREQ | AMEC_SENSOR_TYPE_POWER | \
+ AMEC_SENSOR_TYPE_PERF)
// AMEC_SENSOR_LOC_INVALID can not be used to identify sensor location.
// A bit vector mask is used to specify sensor locations that AMESTER is
@@ -113,13 +119,16 @@ typedef enum
// AMEC_SENSOR_CLEAR_ALL_MINMAX clears all min/max values in the sensor.
typedef enum
{
- AMEC_SENSOR_CLEAR_SAMPLE_MINMAX = 0x0001,
- AMEC_SENSOR_CLEAR_CSM_SAMPLE_MINMAX = 0x0002,
- AMEC_SENSOR_CLEAR_PROFILER_SAMPLE_MINMAX = 0x0004,
- AMEC_SENSOR_CLEAR_JOB_S_SAMPLE_MINMAX = 0x0008,
- AMEC_SENSOR_CLEAR_ALL_MINMAX = 0xffff,
+ AMEC_SENSOR_CLEAR_SAMPLE_MINMAX = 0x01,
+ AMEC_SENSOR_CLEAR_CSM_SAMPLE_MINMAX = 0x10,
+ AMEC_SENSOR_CLEAR_PROFILER_SAMPLE_MINMAX = 0x20,
+ AMEC_SENSOR_CLEAR_JOB_S_SAMPLE_MINMAX = 0x40,
+ AMEC_SENSOR_CLEAR_ALL_MINMAX = 0xff,
} AMEC_SENSOR_CLEAR_TYPE;
-
+// The bits for types must match the defined owners in the clear sensor data command
+// Define the owners allowed to be cleared via clear sensor data command
+#define VALID_CLEAR_SENSOR_OWNER_MASK (AMEC_SENSOR_CLEAR_CSM_SAMPLE_MINMAX | \
+ AMEC_SENSOR_CLEAR_PROFILER_SAMPLE_MINMAX | AMEC_SENSOR_CLEAR_JOB_S_SAMPLE_MINMAX)
/*****************************************************************************/
// Forward declaration as used in vectorSensor
struct sensor;
diff --git a/src/occ_405/sensor/sensor_inband_cmd.c b/src/occ_405/sensor/sensor_inband_cmd.c
new file mode 100755
index 0000000..15a8967
--- /dev/null
+++ b/src/occ_405/sensor/sensor_inband_cmd.c
@@ -0,0 +1,557 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_405/sensor/sensor_inband_cmd.c $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2017 */
+/* [+] 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
+//******************************************************************************
+#include <cmdh_fsp_cmds.h>
+#include <sensor_inband_cmd.h>
+#include <homer.h>
+#include <occ_service_codes.h>
+#include <sensor_service_codes.h>
+#include <trac.h>
+#include <occhw_async.h>
+#include <common.h>
+
+
+//******************************************************************************
+// Block Copy Engine (BCE) Defines/Globals
+//******************************************************************************
+
+// Buffer in SRAM to copy larger commands cmd/rsp buffer from/to main memory using the BCE
+DMA_BUFFER(inband_max_cmd_t G_inband_cmd_max_data_bce_buff) = {{0}};
+
+// Buffer in SRAM to copy smaller commands cmd/rsp buffer from/to main memory using the BCE
+DMA_BUFFER(inband_min_cmd_t G_inband_cmd_min_data_bce_buff) = {{0}};
+
+// BCE request structure. Used by BCE functions to schedule copy request.
+BceRequest G_inband_cmd_bce_req;
+
+/**
+ * Specifies whether the BCE request was scheduled. If false, the request
+ * finished or has never been scheduled/initialized.
+ */
+bool G_inband_cmd_req_scheduled = false;
+
+// Number of tics passed waiting for BCE callback
+uint8_t G_bce_callback_wait = 0;
+
+volatile uint8_t G_inband_occ_cmd_state = INBAND_OCC_CMD_NONE;
+volatile uint8_t G_inband_occ_bce_saved_state = INBAND_OCC_CMD_NONE;
+
+//******************************************************************************
+// Functions
+//******************************************************************************
+
+
+/**
+ * Logs an error caused by the Block Copy Engine. Does nothing if a BCE error
+ * has already been logged.
+ *
+ * Note that the required error log comment containing tags like 'userdata4' and
+ * 'devdesc' must be located by the call to this function. It is not located
+ * inside this function because the value of those tags varies.
+ *
+ * @param i_modId Module ID
+ * @param i_extReasonCode Extended reason code
+ * @param i_userData1 Userdata1 value
+ * @param i_userData2 Userdata2 value
+ */
+void inband_cmd_log_bce_error(uint16_t i_modId, uint16_t i_extReasonCode,
+ uint32_t i_userData1, uint32_t i_userData2)
+{
+ static bool L_error_logged = false;
+ if (!L_error_logged)
+ {
+ // Create and commit error
+ errlHndl_t l_errl = createErrl(i_modId, // Module ID
+ INBAND_CMD_ERROR, // Reason code
+ i_extReasonCode, // Extended reason code
+ ERRL_SEV_INFORMATIONAL, // Severity
+ NULL, // Trace Buffers
+ DEFAULT_TRACE_SIZE, // Trace Size
+ i_userData1, // Userdata1
+ i_userData2); // Userdata2
+ commitErrl(&l_errl);
+ L_error_logged = true;
+ }
+}
+
+
+/**
+ * Returns whether the global BCE request struct is idle and ready for re-use.
+ * Returns true immediately if the request was not scheduled. If the request
+ * was scheduled, checks to see if it has finished.
+ *
+ * @param i_caller_mod_id Module ID of calling function in case an error occurs
+ * @return True if BCE request is idle, false otherwise
+ */
+bool inband_cmd_is_bce_req_idle(uint16_t i_caller_mod_id)
+{
+ // Number of times we've waited for current request to finish
+ static uint8_t L_wait_count = 0;
+
+ // If the request was not previously scheduled, then it is idle. This also
+ // handles the case where the request has not been initialized yet.
+ if (!G_inband_cmd_req_scheduled)
+ {
+ return true;
+ }
+
+ // Request was scheduled; check if it finished and is now idle
+ if (async_request_is_idle(&G_inband_cmd_bce_req.request))
+ {
+ // Request is now idle and ready for re-use
+ G_inband_cmd_req_scheduled = false;
+
+ // If we were waiting for request to finish, trace and clear wait count
+ if (L_wait_count > 0)
+ {
+ TRAC_INFO("inband_cmd_is_bce_req_idle: "
+ "Request finished after waiting %u times: caller=0x%04X",
+ L_wait_count, i_caller_mod_id);
+ L_wait_count = 0;
+ }
+ return true;
+ }
+
+ // Request was scheduled but has not finished. Increment wait count unless
+ // we are already at the max (to avoid overflow).
+ if (L_wait_count < UINT8_MAX)
+ {
+ ++L_wait_count;
+ }
+
+ // If this is the first time we've waited for this request, trace it
+ if (L_wait_count == 1)
+ {
+ TRAC_INFO("inband_cmd_is_bce_req_idle: "
+ "Waiting for request to finish: caller=0x%04X",
+ i_caller_mod_id);
+ }
+
+ // If this is the second time we've waited for this request, log BCE error
+ if (L_wait_count == 2)
+ {
+ /* @
+ * @errortype
+ * @moduleid INBAND_CMD_IS_BCE_REQ_IDLE_MOD
+ * @reasoncode INBAND_CMD_ERROR
+ * @userdata1 Caller module ID
+ * @userdata2 0
+ * @userdata4 ERC_GENERIC_TIMEOUT
+ * @devdesc BCE request not finished after waiting twice
+ */
+ inband_cmd_log_bce_error(INBAND_CMD_IS_BCE_REQ_IDLE_MOD, ERC_GENERIC_TIMEOUT,
+ i_caller_mod_id, 0);
+ }
+
+ // Return false since request is not idle
+ return false;
+}
+
+/**
+ * inband_cmd_bce_callback
+ *
+ * Description: Callback function for G_inband_cmd_bce_req BCE request
+ * NO TRACING OR CALLING FUNCTIONS THAT TRACE ALLOWED
+ */
+void inband_cmd_bce_callback( void )
+{
+ static bool L_processed_at_least_one_cmd = FALSE;
+ static uint8_t L_last_seq_num_processed = 0;
+ uint8_t seq_num = 0;
+ uint8_t cmd_flags = 0;
+
+ // Decide what to do next for processing an in-band command for the BCE that finished
+ switch (G_inband_occ_cmd_state)
+ {
+ case INBAND_OCC_CMD_CHECK_FOR_CMD:
+ // check for command uses min bce data buffer
+ // If we processed at least one cmd it is not a new command if same seq number
+ cmd_flags = G_inband_cmd_min_data_bce_buff.header.flags;
+ seq_num = G_inband_cmd_min_data_bce_buff.header.seq;
+ if( ( (!L_processed_at_least_one_cmd) ||
+ (L_processed_at_least_one_cmd && (seq_num != L_last_seq_num_processed)) ) &&
+ ( (cmd_flags & IN_BAND_CMD_READY_MASK) == IN_BAND_CMD_READY_MASK) )
+ {
+ // There is a command to process
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_START;
+ // now that we have a cmd save seq num so we don't keep processing the same cmd
+ L_processed_at_least_one_cmd = TRUE;
+ L_last_seq_num_processed = seq_num;
+ }
+ else
+ {
+ // No command
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_NONE;
+ }
+ break;
+
+ case INBAND_OCC_CMD_RSP_READY:
+ // response is ready send interrupt
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_RSP_INT;
+ break;
+
+ default:
+ // Invalid state. Can't trace here set state to invalid to trace later
+ G_inband_occ_bce_saved_state = G_inband_occ_cmd_state;
+ G_inband_occ_cmd_state = INBAND_OCC_INVALID_BCE_CALLBACK;
+ break;
+ }
+}
+
+/**
+ * Copies the specified number of bytes either to main mem or down from main mem
+ * for handling an inband command using the Block Copy Engine (BCE).
+ *
+ * @param i_main_mem_addr Main memory address for copy. Must be 128-byte aligned
+ * @param i_sram_addr SRAM address for copy. Must be 128-byte aligned
+ * @param i_byte_count Number of bytes to copy. Must be multiple of 128.
+ * Must be <= INBAND_OCC_CMD_BCE_BUF_SIZE. 0 bytes is not valid
+ * @param i_to_main_mem TRUE indicates copy is sram to main memory
+ * FALSE indicates copy is main memory to sram
+ * @param i_caller_mod_id Module ID of the calling function in case an error occurs
+ * @return True if BCE request was successfully scheduled, false otherwise
+ */
+bool inband_cmd_bce_copy(uint32_t i_main_mem_addr, uint32_t i_sram_addr,
+ size_t i_byte_count, bool i_to_main_mem, uint16_t i_caller_mod_id)
+{
+ int l_rc = 0;
+
+ // Verify address and byte count are valid
+ static bool L_traced_param_error = false;
+ if (((i_main_mem_addr % 128) != 0) || ((i_sram_addr % 128) != 0) ||
+ ((i_byte_count % 128) != 0) || (i_byte_count > INBAND_CMD_MAX_BCE_BUF_SIZE) ||
+ (i_byte_count == 0) )
+ {
+ if (!L_traced_param_error)
+ {
+ TRAC_ERR("inband_cmd_bce_copy: Input parameter error: "
+ "address=0x%08X SRAM=0x%08X length=%u caller=0x%04X",
+ i_main_mem_addr, i_sram_addr, i_byte_count, i_caller_mod_id);
+ L_traced_param_error = true;
+ }
+ return false;
+ }
+
+ // Check if a copy request was previously scheduled and is not yet finished
+ static bool L_traced_sched_error = false;
+ if (!inband_cmd_is_bce_req_idle(i_caller_mod_id))
+ {
+ if (!L_traced_sched_error)
+ {
+ TRAC_ERR("inband_cmd_bce_copy: Previous request not finished: caller=0x%04X",
+ i_caller_mod_id);
+ L_traced_sched_error = true;
+ }
+ return false;
+ }
+
+ // Create BCE request based on if copy is up or down from main memory
+ if (i_to_main_mem)
+ {
+ l_rc = bce_request_create(&G_inband_cmd_bce_req, // Block copy request
+ &G_pba_bcue_queue, // SRAM up to mainstore
+ i_main_mem_addr, // Mainstore address
+ i_sram_addr, // SRAM start address
+ i_byte_count, // Size of copy
+ SSX_WAIT_FOREVER, // No timeout
+ (AsyncRequestCallback) inband_cmd_bce_callback,
+ NULL, // No call back args
+ ASYNC_CALLBACK_IMMEDIATE);
+ }
+ else
+ {
+ l_rc = bce_request_create(&G_inband_cmd_bce_req, // Block copy request
+ &G_pba_bcde_queue, // mainstore down to SRAM
+ i_main_mem_addr, // Mainstore address
+ i_sram_addr, // SRAM start address
+ i_byte_count, // Size of copy
+ SSX_WAIT_FOREVER, // No timeout
+ (AsyncRequestCallback) inband_cmd_bce_callback,
+ NULL, // No call back args
+ ASYNC_CALLBACK_IMMEDIATE);
+ }
+
+ if (l_rc != SSX_OK) // fail to create BCE request?
+ {
+ TRAC_ERR("inband_cmd_bce_copy: Request create failure: rc=0x%08X caller=0x%04X",
+ -l_rc, i_caller_mod_id);
+ /* @
+ * @errortype
+ * @moduleid INBAND_CMD_BCE_COPY_MOD
+ * @reasoncode INBAND_CMD_ERROR
+ * @userdata1 Return code from bce_request_create()
+ * @userdata2 Caller module ID
+ * @userdata4 ERC_BCE_REQUEST_CREATE_FAILURE
+ * @devdesc Failed to create BCE request
+ */
+ inband_cmd_log_bce_error(INBAND_CMD_BCE_COPY_MOD, ERC_BCE_REQUEST_CREATE_FAILURE,
+ -l_rc, i_caller_mod_id);
+ return false;
+ }
+
+ // Schedule BCE request
+ l_rc = bce_request_schedule(&G_inband_cmd_bce_req);
+ if (l_rc != SSX_OK)
+ {
+ TRAC_ERR("inband_cmd_bce_copy: Request schedule failure: rc=0x%08X caller=0x%04X",
+ -l_rc, i_caller_mod_id);
+ /* @
+ * @errortype
+ * @moduleid INBAND_CMD_BCE_COPY_MOD
+ * @reasoncode INBAND_CMD_ERROR
+ * @userdata1 Return code from bce_request_schedule()
+ * @userdata2 Caller module ID
+ * @userdata4 ERC_BCE_REQUEST_SCHEDULE_FAILURE
+ * @devdesc Failed to schedule BCE request
+ */
+ inband_cmd_log_bce_error(INBAND_CMD_BCE_COPY_MOD, ERC_BCE_REQUEST_SCHEDULE_FAILURE,
+ -l_rc, i_caller_mod_id);
+ return false;
+ }
+
+ // Successfully scheduled request. Copy is not blocking, so need to check
+ // whether it finished later. Set flag indicating request is scheduled.
+ G_inband_cmd_req_scheduled = true;
+ return true;
+}
+
+
+// Function Specification
+//
+// Name: inband_command_check
+//
+// Description: Check for command from the inband interface
+//
+// End Function Specification
+void inband_command_check(void)
+{
+ // Only check for a new command if not currently processing an inband command
+ if (G_inband_occ_cmd_state == INBAND_OCC_CMD_NONE)
+ {
+ // Create and Schedule BCE to read minimum bytes of OCC inband command buffer in HOMER
+ memset((void*)&G_inband_cmd_min_data_bce_buff, 0x00, sizeof(inband_min_cmd_t));
+ bool i_to_main_mem = FALSE; // this request is main mem down to SRAM
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_CHECK_FOR_CMD;
+ G_bce_callback_wait = 0;
+ if (inband_cmd_bce_copy(INBAND_OCC_CMD_ADDRESS_HOMER, (uint32_t)&G_inband_cmd_min_data_bce_buff,
+ INBAND_CMD_MIN_BCE_BUF_SIZE, i_to_main_mem, INBAND_CMD_CHECK_MOD))
+ {
+ // Copy succeeded. The BCE callback will handle next
+ }
+ else
+ {
+ // copy failed try again next time
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_NONE;
+ }
+ }
+}
+
+// Function Specification
+//
+// Name: inband_command_handler
+//
+// Description: Command handler for inband commands this should only be called if
+// it is already known that there is an in-band command in process
+// This is checked to be called on every tick
+//
+// End Function Specification
+void inband_command_handler(void)
+{
+ uint8_t l_reason_code = ERRL_RC_INTERNAL_FAIL;
+ uint16_t l_cmd_data_len = 0;
+ uint8_t l_seq_num = 0;
+ uint8_t l_cmd_type = 0xFF;
+ uint16_t l_rsp_data_length = 0;
+ uint16_t l_bce_copy_size = 0;
+ uint8_t l_bce_padding = 0;
+ bool l_to_main_mem = TRUE; // BCE requests from here are going SRAM to main memory
+ bool l_bce_scheduled = FALSE;
+
+ // Decide what to do next for processing an in-band command
+ if(G_inband_occ_cmd_state == INBAND_OCC_CMD_START)
+ {
+ // We use the max buffer for response
+ memset((void*)&G_inband_cmd_max_data_bce_buff, 0x00, INBAND_CMD_MAX_BCE_BUF_SIZE);
+
+ // When we check for command we used the minimum bce buffer
+ l_seq_num = G_inband_cmd_min_data_bce_buff.header.seq;
+ l_cmd_type = G_inband_cmd_min_data_bce_buff.header.cmd_type;
+ l_cmd_data_len = CONVERT_UINT8_ARRAY_UINT16(G_inband_cmd_min_data_bce_buff.header.data_length[0],
+ G_inband_cmd_min_data_bce_buff.header.data_length[1]);
+
+ // if data is more than min we will need to do another BCE to read the rest of the cmd
+ if(l_cmd_data_len > INBAND_MIN_DATA_LENGTH)
+ {
+ // invalid command, currently no cmd supported is larger than min requiring 2nd BCE
+ l_reason_code = ERRL_RC_INVALID_CMD_LEN;
+ }
+ else
+ {
+ // Have the full command, process it based on command type.
+ // cmd data is in min data BCE buffer the rsp data will go in the max data BCE buffer
+ uint8_t* l_cmd_data_ptr = (uint8_t*) &G_inband_cmd_min_data_bce_buff.data;
+ uint8_t* l_rsp_data_ptr = (uint8_t*) &G_inband_cmd_max_data_bce_buff.data;
+
+ switch(l_cmd_type)
+ {
+ case CMDH_CLEAR_SENSOR_DATA:
+ l_reason_code = cmdh_clear_sensor_data(l_cmd_data_len,
+ l_cmd_data_ptr,
+ INBAND_MAX_DATA_LENGTH,
+ &l_rsp_data_length,
+ l_rsp_data_ptr);
+ break;
+
+ case CMDH_SET_PCAP_INBAND:
+ l_reason_code = cmdh_set_pcap_inband(l_cmd_data_len,
+ l_cmd_data_ptr,
+ INBAND_MAX_DATA_LENGTH,
+ &l_rsp_data_length,
+ l_rsp_data_ptr);
+ break;
+
+ case CMDH_WRITE_PSR:
+ l_reason_code = cmdh_write_psr(l_cmd_data_len,
+ l_cmd_data_ptr,
+ INBAND_MAX_DATA_LENGTH,
+ &l_rsp_data_length,
+ l_rsp_data_ptr);
+ break;
+
+ case CMDH_SELECT_SENSOR_GROUPS:
+ l_reason_code = cmdh_select_sensor_groups(l_cmd_data_len,
+ l_cmd_data_ptr,
+ INBAND_MAX_DATA_LENGTH,
+ &l_rsp_data_length,
+ l_rsp_data_ptr);
+ break;
+
+ default:
+ l_reason_code = ERRL_RC_INVALID_CMD;
+ break;
+ } // end switch
+ } // end cmd process
+
+ // fill in response header in G_inband_cmd_max_data_bce_buff
+ G_inband_cmd_max_data_bce_buff.header.flags = IN_BAND_RSP_READY_MASK;
+ G_inband_cmd_max_data_bce_buff.header.seq = l_seq_num;
+ G_inband_cmd_max_data_bce_buff.header.cmd_type = l_cmd_type;
+ G_inband_cmd_max_data_bce_buff.header.reserved_rc = l_reason_code;
+ G_inband_cmd_max_data_bce_buff.header.data_length[0] = ((uint8_t *)&l_rsp_data_length)[0];
+ G_inband_cmd_max_data_bce_buff.header.data_length[1] = ((uint8_t *)&l_rsp_data_length)[1];
+
+ // Copy the response from SRAM to main memory
+ // Determine BCE copy size, must be factor of 128
+ l_bce_copy_size = sizeof(inband_occ_cmd_header_t) + l_rsp_data_length;
+ l_bce_padding = l_bce_copy_size % 128;
+ if(l_bce_padding)
+ {
+ l_bce_copy_size += (128 - l_bce_padding);
+ }
+
+ G_bce_callback_wait = 0;
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_RSP_READY;
+ l_bce_scheduled = inband_cmd_bce_copy(INBAND_OCC_RSP_ADDRESS_HOMER,
+ (uint32_t)&G_inband_cmd_max_data_bce_buff,
+ l_bce_copy_size,
+ l_to_main_mem,
+ INBAND_CMD_HANDLER_MOD);
+ if (!l_bce_scheduled)
+ {
+ // failed to copy response
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_NONE;
+ }
+ else
+ {
+ TRAC_INFO("inband_command_handler: Command 0x%02X with "
+ "seq_num 0x%02X finished with RC 0x%02X",
+ l_cmd_type, l_seq_num, l_reason_code);
+ }
+
+ } // INBAND_OCC_CMD_START
+
+ else if(G_inband_occ_cmd_state == INBAND_OCC_CMD_RSP_INT)
+ {
+ // Send interrupt to indciate response is ready in main mem
+ notify_host(INTR_REASON_OPAL_SHARED_MEM_CHANGE);
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_NONE;
+ }
+
+ else if( (G_inband_occ_cmd_state == INBAND_OCC_CMD_CHECK_FOR_CMD) ||
+ (G_inband_occ_cmd_state == INBAND_OCC_CMD_RSP_READY) )
+ {
+ // Waiting for BCE to finish, these states are handled by BCE callback
+ // if the callback is never called (BCE failure) for a max wait log error
+ G_bce_callback_wait++;
+ if(G_bce_callback_wait == MAX_TICS_INBAND_BCE_CALLBACK_WAIT)
+ {
+ TRAC_ERR("inband_command_handler: Timeout waiting for BCE callback cmd state 0x%02X",
+ G_inband_occ_cmd_state);
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_NONE;
+ /* @
+ * @errortype
+ * @moduleid INBAND_CMD_HANDLER_MOD
+ * @reasoncode INBAND_CMD_ERROR
+ * @userdata1 Inband command state
+ * @userdata2 Caller module ID
+ * @userdata4 ERC_BCE_REQ_CALLBACK_TIMEOUT
+ * @devdesc Timeout waiting for BCE callback
+ */
+ inband_cmd_log_bce_error(INBAND_CMD_HANDLER_MOD, ERC_BCE_REQ_CALLBACK_TIMEOUT,
+ G_inband_occ_cmd_state, INBAND_CMD_HANDLER_MOD);
+ }
+ }
+
+ else if(G_inband_occ_cmd_state == INBAND_OCC_INVALID_BCE_CALLBACK)
+ {
+ // BCE callback was called with invalid state, trace now and set state to none
+ static bool L_traced_bce_bad_state = FALSE;
+ if (!L_traced_bce_bad_state)
+ {
+ TRAC_ERR("inband_command_handler: inband_cmd_bce_callback detected invalid state %u",
+ G_inband_occ_bce_saved_state);
+ L_traced_bce_bad_state = TRUE;
+ }
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_NONE;
+ G_inband_occ_bce_saved_state = INBAND_OCC_CMD_NONE;
+ }
+
+ else
+ {
+ // Invalid state
+ static bool L_traced_bad_state = FALSE;
+ if (!L_traced_bad_state)
+ {
+ TRAC_ERR("inband_command_handler: Called with invalid state %u",
+ G_inband_occ_cmd_state);
+ L_traced_bad_state = TRUE;
+ }
+ G_inband_occ_cmd_state = INBAND_OCC_CMD_NONE;
+ }
+}
diff --git a/src/occ_405/sensor/sensor_inband_cmd.h b/src/occ_405/sensor/sensor_inband_cmd.h
new file mode 100644
index 0000000..4e39f84
--- /dev/null
+++ b/src/occ_405/sensor/sensor_inband_cmd.h
@@ -0,0 +1,112 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_405/sensor/sensor_inband_cmd.h $ */
+/* */
+/* OpenPOWER OnChipController Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017,2017 */
+/* [+] 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 _SENSOR_INBAND_CMD_H
+#define _SENSOR_INBAND_CMD_H
+
+/**
+ * @file sensor_inband_cmd.h
+ *
+ * This file declares the functions and global variables for supporting the inband
+ * command protocol defined in the OCC Firmware Interface spec
+ *
+ */
+
+//******************************************************************************
+// Defines/Structs/Globals
+//******************************************************************************
+
+// States of inband OCC command processing
+typedef enum
+{
+ INBAND_OCC_CMD_NONE = 0x00, // No inband command in process
+ INBAND_OCC_CMD_CHECK_FOR_CMD = 0x01, // Check for cmd when BCE read finishes
+ INBAND_OCC_CMD_START = 0x02, // Start processing the command
+ INBAND_OCC_CMD_RSP_READY = 0x03, // Response ready
+ INBAND_OCC_CMD_RSP_INT = 0x04, // Send Response Interrupt
+ INBAND_OCC_INVALID_BCE_CALLBACK = 0x05, // BCE callback called with invalid OCC cmd state
+} INBAND_OCC_CMD_STATE;
+
+// Current state of inband OCC command processing
+extern volatile uint8_t G_inband_occ_cmd_state;
+// Last state saved for error handling
+extern volatile uint8_t G_inband_occ_bce_saved_state;
+
+#define MAX_TICS_INBAND_BCE_CALLBACK_WAIT 0x03
+#define IN_BAND_CMD_READY_MASK 0x80
+#define IN_BAND_RSP_IN_PROGRESS_MASK 0x02
+#define IN_BAND_RSP_READY_MASK 0x01
+
+typedef struct __attribute__ ((packed))
+{
+ uint8_t flags;
+ uint8_t seq;
+ uint8_t cmd_type;
+ uint8_t reserved_rc; // as a command reserved, as a response RC
+ uint8_t data_length[2];
+} inband_occ_cmd_header_t;
+
+// Data Size is Block Copy Engine dependent, 128 min to 4kB max
+#define INBAND_CMD_MIN_BCE_BUF_SIZE 128
+#define INBAND_CMD_MAX_BCE_BUF_SIZE 4096
+#define INBAND_MAX_DATA_LENGTH INBAND_CMD_MAX_BCE_BUF_SIZE - sizeof(inband_occ_cmd_header_t)
+#define INBAND_MIN_DATA_LENGTH INBAND_CMD_MIN_BCE_BUF_SIZE - sizeof(inband_occ_cmd_header_t)
+
+typedef struct __attribute__ ((packed))
+{
+ inband_occ_cmd_header_t header;
+ // Data bytes
+ uint8_t data[INBAND_MIN_DATA_LENGTH];
+}inband_min_cmd_t;
+
+typedef struct __attribute__ ((packed))
+{
+ inband_occ_cmd_header_t header;
+ // Data bytes
+ uint8_t data[INBAND_MAX_DATA_LENGTH];
+}inband_max_cmd_t;
+
+//******************************************************************************
+// Function Prototypes
+//******************************************************************************
+
+/**
+ * Check for a command from the inband command/response interface
+ *
+ * There are inband commands to select sensors to write to main memory and
+ * clear sensors min/max by user
+ *
+ * This function is called from amec_slv_common_tasks_post()
+ */
+void inband_command_check(void);
+
+/**
+ * Handle a command from the inband command/response interface
+ *
+ * This function is called from amec_slv_substate_6_x
+ */
+void inband_command_handler(void);
+
+#endif // _SENSOR_INBAND_CMD_H
diff --git a/src/occ_405/sensor/sensor_main_memory.h b/src/occ_405/sensor/sensor_main_memory.h
index f9cd29f..f989e13 100644
--- a/src/occ_405/sensor/sensor_main_memory.h
+++ b/src/occ_405/sensor/sensor_main_memory.h
@@ -302,5 +302,4 @@ void main_mem_sensors_update(void);
*/
void main_mem_sensors_set_enabled(AMEC_SENSOR_TYPE i_sensor_type, bool i_enabled);
-
#endif // _SENSOR_MAIN_MEMORY_H
diff --git a/src/occ_405/sensor/sensor_service_codes.h b/src/occ_405/sensor/sensor_service_codes.h
index 397a2d5..f511edf 100755
--- a/src/occ_405/sensor/sensor_service_codes.h
+++ b/src/occ_405/sensor/sensor_service_codes.h
@@ -44,6 +44,12 @@ enum occSensorModuleId
MM_SENSORS_WRITE_NAMES_MOD = SNSR_COMP_ID | 0x16,
MM_SENSORS_WRITE_READINGS_MOD = SNSR_COMP_ID | 0x17,
MM_SENSORS_VALIDATE_READINGS_MOD = SNSR_COMP_ID | 0x18,
+
+ // Inband commands
+ INBAND_CMD_IS_BCE_REQ_IDLE_MOD = SNSR_COMP_ID | 0x20,
+ INBAND_CMD_BCE_COPY_MOD = SNSR_COMP_ID | 0x21,
+ INBAND_CMD_HANDLER_MOD = SNSR_COMP_ID | 0x22,
+ INBAND_CMD_CHECK_MOD = SNSR_COMP_ID | 0x23,
};
#endif /* #ifndef _SENSOR_SERVICE_CODES_H_ */
OpenPOWER on IntegriCloud