summaryrefslogtreecommitdiffstats
path: root/src/occ_405/trac
diff options
context:
space:
mode:
authorWilliam Bryan <wilbryan@us.ibm.com>2015-08-03 12:38:58 -0500
committerWilliam A. Bryan <wilbryan@us.ibm.com>2015-08-03 15:32:27 -0500
commit420e6d248cc6d2b3c39bc3970e3bb6747b3bddc3 (patch)
treec9f6691eddba39193e39aa769367e1267fb9fc86 /src/occ_405/trac
parentadade8c8ef30ed519322674c762d95663009c5d4 (diff)
downloadtalos-occ-420e6d248cc6d2b3c39bc3970e3bb6747b3bddc3.tar.gz
talos-occ-420e6d248cc6d2b3c39bc3970e3bb6747b3bddc3.zip
new ssx and lib files
Change-Id: I2328b1e86d59e3788910687d762fb70ec680058f Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/19503 Reviewed-by: William A. Bryan <wilbryan@us.ibm.com> Tested-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/occ_405/trac')
-rwxr-xr-xsrc/occ_405/trac/trac.h285
-rwxr-xr-xsrc/occ_405/trac/trac_interface.c1135
-rwxr-xr-xsrc/occ_405/trac/trac_interface.h310
-rwxr-xr-xsrc/occ_405/trac/trac_service_codes.h73
4 files changed, 1803 insertions, 0 deletions
diff --git a/src/occ_405/trac/trac.h b/src/occ_405/trac/trac.h
new file mode 100755
index 0000000..87f669b
--- /dev/null
+++ b/src/occ_405/trac/trac.h
@@ -0,0 +1,285 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ/trac/trac.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 _trac_h
+#define _trac_h
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include <trac_interface.h>
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+#ifndef NO_TRAC_STRINGS
+
+#define ERR_MRK "ERR: "
+#define INFO_MRK "INF: "
+#define IMP_MRK "IMP: "
+#define DBG_MRK "DBG: "
+
+//NOTE: TRAC_ERR must be used for tracing error related information only
+// TRAC_IMP must be used for tracing important OCC state/status that
+// changes once or twice OCC lifetime. It must NOT be used
+// for tracing anything that seems important to particular
+// developer. This trace buffer must not wrap so use it with
+// caution.
+// TRAC_INFO must be used for anything that does not fall under
+// TRAC_ERR or TRAC_IMP. Any debug or informational traces.
+// TRAC_DBG must be used for debug purpose only. This traces will be
+// turned OFF with product code.
+#ifdef TRAC_TO_SIMICS
+#define TRAC_ERR(frmt,args...) \
+ printf(ERR_MRK "%s: "frmt "\n",__FUNCTION__,##args)
+#define TRAC_INFO(frmt,args...) \
+ printf(INFO_MRK "%s: "frmt "\n",__FUNCTION__,##args)
+#define TRAC_IMP(frmt,args...) \
+ printf(IMP_MRK "%s: "frmt "\n",__FUNCTION__,##args)
+
+#define DBG_PRINT(fmt,args...) \
+ printf(DBG_MRK "%s: "fmt "\n",__FUNCTION__,##args)
+
+extern void dumpHexString(const void *i_data, const unsigned int len, const char *string);
+#define DEBUG_HEXDUMP(data, len, string) \
+ dumpHexString(data, len, string)
+
+#else //TRAC_TO_SIMICS
+
+#define TRAC_ERR(frmt,args...) \
+ TRACE(g_trac_err,ERR_MRK frmt,##args)
+#define TRAC_INFO(frmt,args...) \
+ TRACE(g_trac_inf,INFO_MRK frmt,##args)
+#define TRAC_IMP(frmt,args...) \
+ TRACE(g_trac_imp,IMP_MRK frmt,##args)
+#define DBG_PRINT(fmt,args...) \
+ TRACE(g_trac_inf,DBG_MRK fmt,##args)
+#define DEBUG_HEXDUMP(data, len, string) \
+ TRACEBIN(g_trac_inf, string, data,len)
+
+#endif //TRAC_TO_SIMICS
+
+
+#ifdef MAIN_DEBUG
+ #define MAIN_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define MAIN_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define MAIN_DBG(frmt,args...)
+ #define MAIN_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef RTLS_DEBUG
+ #define RTLS_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define RTLS_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define RTLS_DBG(frmt,args...)
+ #define RTLS_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef PROC_DEBUG
+ #define PROC_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define PROC_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define PROC_DBG(frmt,args...)
+ #define PROC_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef CENT_DEBUG
+ #define CENT_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define CENT_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define CENT_DBG(frmt,args...)
+ #define CENT_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef THRD_DEBUG
+ #define THRD_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define THRD_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define THRD_DBG(frmt,args...)
+ #define THRD_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef AMEC_DEBUG
+ #define AMEC_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define AMEC_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define AMEC_DBG(frmt,args...)
+ #define AMEC_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef APLT_DEBUG
+ #define APLT_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define APLT_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define APLT_DBG(frmt,args...)
+ #define APLT_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef DCOM_DEBUG
+ #define DCOM_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define DCOM_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define DCOM_DBG(frmt,args...)
+ #define DCOM_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef ERRL_DEBUG
+ #define ERRL_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define ERRL_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define ERRL_DBG(frmt,args...)
+ #define ERRL_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef APSS_DEBUG
+ #define APSS_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define APSS_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define APSS_DBG(frmt,args...)
+ #define APSS_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef DPSS_DEBUG
+ #define DPSS_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define DPSS_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define DPSS_DBG(frmt,args...)
+ #define DPSS_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef CMDH_DEBUG
+ #define CMDH_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define CMDH_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define CMDH_DBG(frmt,args...)
+ #define CMDH_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef SNSR_DEBUG
+ #define SNSR_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define SNSR_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define SNSR_DBG(frmt,args...)
+ #define SNSR_DBG_HEXDUMP(data, len, string)
+#endif
+
+#ifdef TMER_DEBUG
+ #define TMER_DBG(frmt,args...) \
+ DBG_PRINT(frmt,##args)
+ #define TMER_DBG_HEXDUMP(data, len, string) \
+ DEBUG_HEXDUMP(data, len, string)
+#else
+ #define TMER_DBG(frmt,args...)
+ #define TMER_DBG_HEXDUMP(data, len, string)
+#endif
+
+#else // NO_TRAC_STRINGS
+
+#define TRAC_ERR(frmt,args...)
+#define TRAC_INFO(frmt,args...)
+#define TRAC_IMP(frmt,args...)
+
+#define MAIN_DBG(frmt,args...)
+#define RTLS_DBG(frmt,args...)
+#define PROC_DBG(frmt,args...)
+#define THRD_DBG(frmt,args...)
+#define AMEC_DBG(frmt,args...)
+#define APLT_DBG(frmt,args...)
+#define DCOM_DBG(frmt,args...)
+#define ERRL_DBG(frmt,args...)
+#define CENT_DBG(frmt,args...)
+#define CMDH_DBG(frmt,args...)
+#define APSS_DBG(frmt,args...)
+#define DPSS_DBG(frmt,args...)
+#define SNSR_DBG(frmt,args...)
+#define TMER_DBG(frmt,args...)
+
+#define MAIN_DBG_HEXDUMP(frmt,args...)
+#define RTLS_DBG_HEXDUMP(frmt,args...)
+#define PROC_DBG_HEXDUMP(frmt,args...)
+#define THRD_DBG_HEXDUMP(frmt,args...)
+#define AMEC_DBG_HEXDUMP(frmt,args...)
+#define APLT_DBG_HEXDUMP(frmt,args...)
+#define DCOM_DBG_HEXDUMP(frmt,args...)
+#define ERRL_DBG_HEXDUMP(frmt,args...)
+#define CENT_DBG_HEXDUMP(frmt,args...)
+#define CMDH_DBG_HEXDUMP(frmt,args...)
+#define APSS_DBG_HEXDUMP(frmt,args...)
+#define DPSS_DBG_HEXDUMP(frmt,args...)
+#define SNSR_DBG_HEXDUMP(frmt,args...)
+#define TMER_DBG_HEXDUMP(frmt,args...)
+
+#endif
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+#endif // _trac_h
diff --git a/src/occ_405/trac/trac_interface.c b/src/occ_405/trac/trac_interface.c
new file mode 100755
index 0000000..56a7cfb
--- /dev/null
+++ b/src/occ_405/trac/trac_interface.c
@@ -0,0 +1,1135 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_405/trac/trac_interface.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 */
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include "ssx.h"
+
+#include <trac_interface.h>
+#include <trac_service_codes.h>
+#include <occ_common.h>
+#include <comp_ids.h>
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+#define TRAC_END_BUFFER "&"
+
+#define TRAC_INTF_MUTEX_TIMEOUT SSX_SECONDS(5)
+
+#define TRACE_BUF_VERSION 0x01; /*!< Trace buffer version */
+#define TRACE_FIELDTRACE 0x4654; /*!< Field Trace - "FT" */
+#define TRACE_FIELDBIN 0x4644 /*!< Binary Field Trace - "FD" */
+
+#define TRAC_TIME_REAL 0 // upper 32 = seconds, lower 32 = microseconds
+#define TRAC_TIME_50MHZ 1
+#define TRAC_TIME_200MHZ 2
+#define TRAC_TIME_167MHZ 3 // 166666667Hz
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+
+/// Instantiate the buffers for the traces.
+///
+/// It may be beneficial to add the attribute:
+/// __attribute__ ((section (".noncacheable")))
+/// when debugging on real HW, in case the OCC hangs and we can't access
+/// the cache to get coherent data.
+uint8_t g_trac_inf_buffer[TRACE_BUFFER_SIZE];
+uint8_t g_trac_err_buffer[TRACE_BUFFER_SIZE];
+uint8_t g_trac_imp_buffer[TRACE_BUFFER_SIZE];
+
+// Need to modify the addTraceToErrl() function in errl.c when new trace buffer is added/removed
+tracDesc_t g_trac_inf = (tracDesc_t) &g_trac_inf_buffer;
+tracDesc_t g_trac_err = (tracDesc_t) &g_trac_err_buffer;
+tracDesc_t g_trac_imp = (tracDesc_t) &g_trac_imp_buffer;
+
+const trace_descriptor_array_t g_des_array[] =
+{
+ {&g_trac_inf,"INF"},
+ {&g_trac_err,"ERR"},
+ {&g_trac_imp,"IMP"}
+};
+
+SsxSemaphore g_trac_mutex;
+
+static bool circular_full_flag = FALSE;
+circular_buf_header_t g_isr_circular_header;
+circular_entire_data_t g_isr_circular_buf[CIRCULAR_BUFFER_SIZE];
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+/*
+ * Initialize all header values of a trace buffer
+ *
+ * This function will initialize all of the values in the trace buffer
+ * header so that it is ready for tracing.
+ *
+ * param o_buf Pointer to trace buffer which will be initialized.
+ * param i_comp Component who is getting buffer initialized.
+ *
+ * return Non-zero return code on error.
+ */
+UINT trac_init_values_buffer(tracDesc_t *o_buf,const CHAR *i_comp);
+
+
+/*
+ * Raw buffer write function
+ *
+ * This function assumes i_td has been initialized and it also assume
+ * the critical region of the input trace descriptor has been locked.
+ *
+ * param io_td Initialized trace descriptor pointer to buffer to trace to.
+ * param i_ptr Pointer to data to write to trace buffer
+ * param i_size Size of i_ptr
+ *
+ * return Non-zero return code on error.
+ */
+UINT trac_write_data(tracDesc_t io_td,
+ const void *i_ptr,
+ const ULONG i_size);
+
+/*
+ * Write data to circular buffer
+ *
+ * param i_ptr
+ *
+ * return Non-zero return code on error.
+ */
+uint16_t trac_write_data_to_circular(circular_entire_data_t *i_ptr);
+
+
+ /**
+ * Get data from circular buffer
+ *
+ * param o_ptr
+ *
+ * return Non-zero return code on error.
+ */
+uint16_t get_trac_entry_data_from_circular(circular_entire_data_t *o_ptr);
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+// Function Specification
+//
+// Name: TRAC_init_buffers
+//
+// Description:
+//
+// End Function Specification
+UINT TRAC_init_buffers()
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ INT l_rc = 0;
+ UINT l_num_des = 0;
+ UINT i=0;
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+
+ // Initialize trace mutex
+ l_rc = ssx_semaphore_create(&g_trac_mutex, 1, 1);
+
+ if(SSX_OK != l_rc)
+ {
+ // Badness, don't continue
+ FIELD("TRAC_init_buffers: Failed to create mutex");
+ }
+ else
+ {
+ // Initialize trace buffers
+ l_num_des = sizeof(g_des_array) / sizeof(trace_descriptor_array_t);
+
+ for(i=0;i<l_num_des;i++)
+ {
+ // Initialize the buffer
+ l_rc = trac_init_values_buffer(g_des_array[i].entry,
+ g_des_array[i].comp);
+ if(l_rc)
+ {
+ FIELD1("TRAC_init_buffers: Failed to initialize buffer: ",
+ (unsigned char)i);
+ break;
+ }
+ }
+ }
+
+ // Initialize isr circular buffer it to all 0's
+ g_isr_circular_header.head = 0;
+ g_isr_circular_header.tail = 0;
+ g_isr_circular_header.entryCount = 0;
+
+ memset(g_isr_circular_buf, 0 , CIRCULAR_BUFFER_SIZE * sizeof(circular_entire_data_t));
+
+ return(l_rc);
+}
+
+// Function Specification
+//
+// Name: trac_init_values_buffer
+//
+// Description:
+//
+// End Function Specification
+UINT trac_init_values_buffer(tracDesc_t *o_buf,const CHAR *i_comp)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ UINT16 l_rc = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ // Initialize it to all 0's
+ memset(*o_buf,0,(size_t)TRACE_BUFFER_SIZE);
+
+ (*o_buf)->ver = TRACE_BUF_VERSION;
+ (*o_buf)->hdr_len = sizeof(trace_buf_head_t);
+ (*o_buf)->time_flg = TRAC_TIME_REAL;
+ (*o_buf)->endian_flg = 'B'; // Big Endian
+ memcpy((*o_buf)->comp,i_comp,(size_t)COMP_NAME_SIZE);
+ (*o_buf)->size = TRACE_BUFFER_SIZE;
+ (*o_buf)->times_wrap = 0;
+ (*o_buf)->next_free = sizeof(trace_buf_head_t);
+
+ return(l_rc);
+}
+
+// Function Specification
+//
+// Name: trace_adal_write_all
+//
+// Description: In order to leverage the tracepp, need to add this function. It will call
+// trac_write_int finally
+//
+// End Function Specification
+UINT trace_adal_write_all(tracDesc_t io_td,const trace_hash_val i_hash,
+ const char *i_fmt,const ULONG i_line, const ULONG i_type,...)
+{
+ UINT rc = 0, i = 0;
+ UINT l_num_args = 0;
+ ULONG l_i_param[TRACE_MAX_ARGS] = {0};
+
+ // Calculate the number of optional parameters by looking at the i_fmt.
+ // i_fmt will store something like "%d,%f,%u"
+ if(i_fmt != NULL)
+ {
+ l_num_args = 1;
+ for(i=0;i_fmt[i] != 0;i++)
+ {
+ if( i_fmt[i] == ',')
+ {
+ l_num_args++;
+ }
+ }
+ }
+
+
+ // Get the optional parameters
+ va_list l_argptr; //will hold optional parameters
+ va_start(l_argptr,i_type);
+
+ // Check the number of optional parameters
+ if(TRACE_MAX_ARGS < l_num_args)
+ {
+ l_num_args = TRACE_MAX_ARGS;
+ }
+
+ for (i=0;i<l_num_args;i++)
+ {
+ l_i_param[i] = va_arg(l_argptr,ULONG);
+ }
+
+ va_end(l_argptr);
+
+
+
+ rc = trac_write_int(io_td,
+ i_hash, i_line,
+ l_num_args,
+ l_i_param[0],
+ l_i_param[1],
+ l_i_param[2],
+ l_i_param[3],
+ l_i_param[4] );
+ return rc;
+}
+
+
+// Function Specification
+//
+// Name: trac_write_int
+//
+// Description:
+//
+// End Function Specification
+UINT trac_write_int(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const UINT i_num_args,
+ const ULONG i_1,const ULONG i_2,const ULONG i_3,
+ const ULONG i_4,const ULONG i_5
+ )
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ UINT l_rc = 0;
+ ULONG l_entry_size = 0;
+ trace_entire_entry_t l_entry;
+ SsxMachineContext l_ctx = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ if(io_td != NULL)
+ {
+
+ // Calculate total space needed
+ l_entry_size = sizeof(trace_entry_stamp_t);
+ l_entry_size += sizeof(trace_entry_head_t);
+
+ // We always add the size of the entry at the end of the trace entry
+ // so the parsing tool can easily walk the trace buffer stack so we
+ // need to add that on to total size
+ l_entry_size += sizeof(ULONG);
+
+ // Now add on size for actual number of arguments we're tracing
+ l_entry_size += (i_num_args * sizeof(ULONG));
+
+ // Word align the entry
+ l_entry_size = (l_entry_size + 3) & ~3;
+
+ // Fill in the entry structure
+ //l_entry.stamp.tid = (ULONG)tx_thread_identify(); // What is response to this in AME code?
+ l_entry.stamp.tid = (__ssx_kernel_context_thread() ? 1 : 0); //context thread or ISR
+
+ // Capture the time. Note the time stamp is split into tbh (upper) and
+ // tbl (lower), both of which are 32 bits each. The ssx_timebase_get
+ // call returns a uint64_t
+
+ uint64_t l_time = ssx_timebase_get();
+ l_entry.stamp.tbh = l_time / SSX_TIMEBASE_FREQUENCY_HZ; // seconds
+ l_entry.stamp.tbl = ((l_time % SSX_TIMEBASE_FREQUENCY_HZ)*1000000000) // nanoseconds
+ /SSX_TIMEBASE_FREQUENCY_HZ;
+
+ // Length is equal to size of data
+ l_entry.head.length = (i_num_args * sizeof(ULONG));
+ l_entry.head.tag = TRACE_FIELDTRACE;
+ l_entry.head.hash = i_hash;
+ l_entry.head.line = i_line;
+
+ switch (i_num_args)
+ {
+ case 5: l_entry.args[4] = i_5; // Intentional Fall Through
+ case 4: l_entry.args[3] = i_4; // Intentional Fall Through
+ case 3: l_entry.args[2] = i_3; // Intentional Fall Through
+ case 2: l_entry.args[1] = i_2; // Intentional Fall Through
+ case 1: l_entry.args[0] = i_1; // Intentional Fall Through
+ default: ;
+ }
+
+ // Now put total size at end of buffer
+ l_entry.args[i_num_args] = l_entry_size;
+
+ // Disable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+
+ // Check if context thread or ISR get semaphore or not
+ // If ISR did not get semaphore, will add trace log into circular buffer.
+ // Context thread will check circular buffer, and add log back into trace buffer.
+ // Prevent ISR did not get semaphore, and lost trace log.
+ l_rc = ssx_semaphore_pend(&g_trac_mutex,
+ __ssx_kernel_context_thread()? \
+ TRAC_INTF_MUTEX_TIMEOUT : SSX_NO_WAIT);
+
+ if(l_rc == SSX_OK)
+ {
+ // Either this is thread context and mutex was locked within
+ // timeout or this is interrupt context and mutex was immediately
+ // available, regardless, mutex is now locked.
+ l_rc = SUCCESS;
+
+ // Update the entry count
+ io_td->te_count++;
+
+ l_rc = trac_write_data(io_td, (void *)&l_entry, l_entry_size);
+
+ if(l_rc != SUCCESS)
+ {
+ // Badness - Not much we can do on trace failure. Can't log error
+ // because of recursion concerns. Luckily a trace error is not critical.
+ FIELD("trac_write_int: Failed in call to trac_write_data()");
+ }
+
+ // Always try to release even if error above
+ ssx_semaphore_post(&g_trac_mutex);
+ }
+ else if(!__ssx_kernel_context_thread())
+ {
+ // Tracing in interrupt context and mutex was locked, SSX
+ // returned -SSX_SEMAPHORE_PEND_NO_WAIT
+
+ // Failed to get semaphore in ISR
+ // Create trace in ISR circular buffer
+ circular_entire_data_t l_cir_data_in;
+ l_cir_data_in.len = l_entry_size;
+ memcpy(&l_cir_data_in.comp, io_td->comp, (size_t)COMP_NAME_SIZE);
+ l_cir_data_in.entry = l_entry;
+
+ if(g_isr_circular_header.entryCount >= CIRCULAR_BUFFER_SIZE)
+ {
+ FIELD("trac_write_int: Circular Buffer size insufficient!\n");
+ circular_full_flag = TRUE;
+ l_rc = TRAC_CIRCULAR_BUFF_FULL;
+ // Always try to release even if error above
+ ssx_semaphore_post(&g_trac_mutex);
+ return(l_rc);
+ }
+
+ // Save to Circular Buffer
+ l_rc = trac_write_data_to_circular(&l_cir_data_in);
+ g_isr_circular_header.head = (++g_isr_circular_header.head) % CIRCULAR_BUFFER_SIZE;
+ g_isr_circular_header.entryCount++;
+
+ if(l_rc != SUCCESS)
+ {
+ // Badness - Not much we can do on trace failure. Can't log error
+ // because of recursion concerns. Luckily a trace error is not critical.
+ FIELD("trac_write_int: Failed in call to trac_write_data_to_circular()");
+ }
+ }
+ else
+ {
+ // Failed to get mutex in thread
+ FIELD("trac_write_int: Failed to get mutex");
+ }
+
+ // Re-enable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_exit(&l_ctx);
+
+
+ //2nd. Check caller from thread?
+ if(__ssx_kernel_context_thread() && (g_isr_circular_header.entryCount > 0))
+ {
+ if(circular_full_flag)
+ {
+ // If ISR circular buffer is full, create a trace in IMP
+ // Use existed trace structure to create new trace
+
+ // re-calculate size of the new trace entry
+ l_entry_size = l_entry_size + ((1 - i_num_args)*4);
+
+ // fill trace field
+ l_entry.head.hash = trace_adal_hash("IMP: ISR Circular Buffer is full, %d entries lost", -1);
+ l_entry.head.line = __LINE__;
+
+ // one argument for this trace
+ l_entry.head.length = sizeof(ULONG);
+ l_entry.args[0] = circular_full_flag;
+ l_entry.args[1] = l_entry_size;
+
+ // Disable non-critical interrupts in thread context
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+
+ //Write to IMP trace buffer
+ l_rc = ssx_semaphore_pend(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
+ if(l_rc == SSX_OK)
+ {
+ tracDesc_t imp_td = TRAC_get_td("IMP");
+ // Update the entry count
+ imp_td->te_count++;
+
+ l_rc = trac_write_data(imp_td, (void *)&l_entry, l_entry_size);
+ if(l_rc != SUCCESS)
+ {
+ // Badness - Not much we can do on trace failure. Can't log error
+ // because of recursion concerns. Luckily a trace error is not critical.
+ FIELD("trac_write_int: Failed in call to trac_write_data()");
+ }
+ ssx_semaphore_post(&g_trac_mutex);
+ }
+ else
+ {
+ // Failed to get mutex in thread
+ FIELD("trac_write_int: Failed to get mutex");
+ }
+
+ // Re-enable non-critical interrupts
+ ssx_critical_section_exit(&l_ctx);
+
+ // Reset full flag
+ circular_full_flag = FALSE;
+ l_rc = TRAC_CIRCULAR_BUFF_FULL;
+ }
+
+ circular_entire_data_t l_cir_data_out;
+
+ do
+ {
+ // Thread context here, disable non-critical
+ // interrupts while unloading circular buffer
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+
+ // Get tail position
+ g_isr_circular_header.tail = g_isr_circular_header.tail % CIRCULAR_BUFFER_SIZE;
+ //Copy One trace entity from circular buffer
+ get_trac_entry_data_from_circular(&l_cir_data_out);
+
+ //Write to trace buffer
+ l_rc = ssx_semaphore_pend(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
+ if(l_rc == SSX_OK)
+ {
+ tracDesc_t i_td = TRAC_get_td((const char *)l_cir_data_out.comp);
+
+ // Update the entry count
+ i_td->te_count++;
+
+ l_rc = trac_write_data(i_td,
+ (const void *)&l_cir_data_out.entry,
+ (const ULONG)l_cir_data_out.len);
+
+ if(l_rc == SUCCESS)
+ {
+ if(g_isr_circular_header.tail == g_isr_circular_header.head )
+ g_isr_circular_header.entryCount = 0;
+ else
+ {
+ g_isr_circular_header.tail++;
+ g_isr_circular_header.entryCount--;
+ }
+ }
+ else
+ {
+ // Badness - Not much we can do on trace failure. Can't log error
+ // because of recursion concerns. Luckily a trace error is not critical.
+ FIELD("trac_write_int: Failed in call to trac_write_data()");
+ }
+
+ ssx_semaphore_post(&g_trac_mutex);
+ }
+ else
+ {
+ // Failed to get mutex in thread
+ FIELD("trac_write_int: Failed to get mutex");
+ }
+ // Re-enable non-critical interrupts
+ ssx_critical_section_exit(&l_ctx);
+ }
+ while(g_isr_circular_header.entryCount > 0);
+ }
+ }
+ else
+ {
+ l_rc = TRAC_INVALID_PARM;
+ FIELD("trac_write_int: User passed invalid parameter");
+ }
+
+ return(l_rc);
+}
+
+
+// Function Specification
+//
+// Name: trac_write_bin
+//
+// Description:
+//
+// End Function Specification
+UINT trac_write_bin(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const void *i_ptr,
+ const ULONG i_size)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ UINT l_rc = 0;
+ ULONG l_entry_size = 0;
+ trace_bin_entry_t l_entry;
+ SsxMachineContext l_ctx = 0;
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ if((io_td == NULL) || (i_ptr == NULL) || (i_size == 0))
+ {
+ l_rc = TRAC_INVALID_PARM;
+ }
+ else
+ {
+ // Calculate total space needed
+ l_entry_size = sizeof(trace_entry_stamp_t);
+ l_entry_size += sizeof(trace_entry_head_t);
+
+ // We always add the size of the entry at the end of the trace entry
+ // so the parsing tool can easily walk the trace buffer stack so we
+ // need to add that on to total size
+ l_entry_size += sizeof(ULONG);
+
+ // Now add on size for actual size of the binary data
+ l_entry_size += i_size;
+
+ // Word align the entry
+ l_entry_size = (l_entry_size + 3) & ~3;
+
+ // Fill in the entry structure
+ //l_entry.stamp.tid = (ULONG)tx_thread_identify(); // What is response to this in AME code?
+ l_entry.stamp.tid = 0; // What is response to this in AME code?
+
+ // Length is equal to size of data
+ l_entry.head.length = i_size;
+ l_entry.head.tag = TRACE_FIELDBIN;
+ l_entry.head.hash = i_hash;
+ l_entry.head.line = i_line;
+
+ // We now have total size and need to reserve a part of the trace
+ // buffer for this
+
+ // CRITICAL REGION START
+ // Disable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+
+ l_rc = ssx_semaphore_pend(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
+
+ if(l_rc != SSX_OK)
+ {
+ // Badness
+ FIELD("trac_write_bin: Failed to get mutex");
+ }
+ else
+ {
+ // Capture the time. Note the time stamp is split into tbh (upper) and
+ // tbl (lower), both of which are 32 bits each. The ssx_timebase_get
+ // call returns a uint64_t
+
+ uint64_t l_time = ssx_timebase_get();
+ l_entry.stamp.tbh = l_time / SSX_TIMEBASE_FREQUENCY_HZ; // seconds
+ l_entry.stamp.tbl = ((l_time % SSX_TIMEBASE_FREQUENCY_HZ)*1000000000) // nanoseconds
+ /SSX_TIMEBASE_FREQUENCY_HZ;
+
+ // Increment trace counter
+ io_td->te_count++;;
+
+ // First write the header
+ l_rc = trac_write_data(io_td,
+ (void *)&l_entry,
+ sizeof(l_entry));
+ do
+ {
+ if(l_rc != SUCCESS)
+ {
+ // Badness - Not much we can do on trace failure. Can't log error
+ // because of recursion concerns. Luckily a trace error is not critical.
+ FIELD("trac_write_bin: Failed in call to trac_write_data - 1()");
+ break;
+ }
+
+ // Now write the actual binary data
+ l_rc = trac_write_data(io_td,
+ i_ptr,
+ i_size);
+ if(l_rc != SUCCESS)
+ {
+ // Badness - Not much we can do on trace failure. Can't log error
+ // because of recursion concerns. Luckily a trace error is not critical.
+ FIELD("trac_write_bin: Failed in call to trac_write_data - 2()");
+ break;
+ }
+
+ // Now write the size at the end
+ l_rc = trac_write_data(io_td,
+ (void *)&l_entry_size,
+ sizeof(l_entry_size));
+ if(l_rc != SUCCESS)
+ {
+ // Badness - Not much we can do on trace failure. Can't log error
+ // because of recursion concerns. Luckily a trace error is not critical.
+ FIELD("trac_write_bin: Failed in call to trac_write_data - 3()");
+ break;
+ }
+ }
+ while(FALSE);
+
+ ssx_semaphore_post(&g_trac_mutex);
+ // Re-enable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_exit(&l_ctx);
+ }
+ // CRITICAL REGION END
+ }
+
+ return(l_rc);
+}
+
+// Function Specification
+//
+// Name: trac_write_data
+//
+// Description:
+//
+// End Function Specification
+UINT trac_write_data(tracDesc_t io_td,
+ const void *i_ptr,
+ const ULONG i_size)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ UINT l_rc = 0;
+ ULONG l_total_size = i_size;
+ void *l_buf_ptr = NULL;
+ ULONG l_offset = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ do
+ {
+
+ if(i_size > TRACE_BUFFER_SIZE)
+ {
+ FIELD("trac_write_data: Input size too large!");
+ l_rc = TRAC_DATA_SIZE_TOO_LARGE;
+ break;
+ }
+
+ if((io_td->next_free + l_total_size) > TRACE_BUFFER_SIZE)
+ {
+ // copy what we can to end
+ l_buf_ptr = (char *)io_td + io_td->next_free;
+ l_buf_ptr = (void *) ( ((ULONG) l_buf_ptr + 3) & ~3);
+ l_offset = TRACE_BUFFER_SIZE-io_td->next_free;
+ memcpy(l_buf_ptr,i_ptr,(size_t)l_offset);
+
+ l_total_size -= l_offset;
+
+ // Now adjust the main header of buffer
+ io_td->times_wrap++;
+ io_td->next_free = io_td->hdr_len;
+ }
+
+ l_buf_ptr = (char *)io_td + io_td->next_free;
+
+ // Word align the write - total size includes this alignment
+ l_buf_ptr = (void *) ( ((ULONG) l_buf_ptr + 3) & ~3);
+
+ memcpy(l_buf_ptr,(char *)i_ptr + l_offset,l_total_size);
+
+ // Make sure size is correct for word alignment
+ // Note that this works with binary trace because only the binary data
+ // has the potential to be un-word aligned. If two parts of the binary
+ // trace had this problem then this code would not work.
+ l_total_size = (l_total_size + 3) & ~3;
+ io_td->next_free += l_total_size;
+
+ }while(FALSE);
+
+ return(l_rc);
+
+}
+
+// Function Specification
+//
+// Name: TRAC_get_td
+//
+// Description:
+//
+// End Function Specification
+tracDesc_t TRAC_get_td(const char *i_comp)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ UINT l_num_des = 0;
+ UINT i=0;
+ tracDesc_t l_td = NULL;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ l_num_des = sizeof(g_des_array) / sizeof(trace_descriptor_array_t);
+
+ for(i=0;i<l_num_des;i++)
+ {
+ if(memcmp(i_comp,(*(g_des_array[i].entry))->comp,(size_t)COMP_NAME_SIZE) == 0)
+ {
+ // Found the component
+ l_td = *g_des_array[i].entry;
+ break;
+ }
+ }
+
+ return(l_td);
+}
+
+// Function Specification
+//
+// Name: TRAC_get_buffer
+//
+// Description:
+//
+// End Function Specification
+UINT TRAC_get_buffer(const tracDesc_t i_td_ptr,
+ void *o_data)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ UINT l_rc = 0;
+ SsxMachineContext l_ctx = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ if((i_td_ptr) && (o_data != NULL))
+ {
+ // Disable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+
+ // Get the lock
+ l_rc = ssx_semaphore_pend(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
+ if(l_rc != SSX_OK)
+ {
+ // Badness
+ FIELD("TRAC_get_buffer: Failed to get mutex");
+ }
+ else
+ {
+ l_rc = SUCCESS;
+
+ // Copy it's buffer into temp one
+ memcpy(o_data,i_td_ptr,(size_t)TRACE_BUFFER_SIZE);
+
+ // Always try to release even if error above
+ ssx_semaphore_post(&g_trac_mutex);
+
+ // Re-enable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_exit(&l_ctx);
+ }
+ }
+ else
+ {
+ FIELD("TRAC_get_buffer: Invalid parameter passed by caller");
+ l_rc = TRAC_INVALID_PARM;
+ }
+
+ return(l_rc);
+}
+
+// Function Specification
+//
+// Name: TRAC_get_buffer_partial
+//
+// Description:
+//
+// End Function Specification
+UINT TRAC_get_buffer_partial(const tracDesc_t i_td_ptr,
+ void *io_data,
+ UINT *io_size)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ UINT l_rc = 0;
+ char *l_full_buf = NULL;
+ tracDesc_t l_head = NULL;
+ UINT l_part_size = 0;
+ bool l_lock_get = FALSE;
+ SsxMachineContext l_ctx = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ do
+ {
+ if((i_td_ptr == NULL) || (io_data == NULL) || (io_size == NULL))
+ {
+ FIELD("TRAC_get_buffer_partial: Invalid parameter passed by caller");
+ l_rc = TRAC_INVALID_PARM;
+ if(io_size != NULL)
+ {
+ *io_size = 0;
+ }
+ break;
+ }
+
+ // We can't even fit in first part of buffer
+ // Make sure data size is larger than header length
+ // Otherwise, we will be accessing beyond memory
+ if(*io_size < sizeof(trace_buf_head_t))
+ {
+ // Need to at least have enough space for the header
+ FIELD("TRAC_get_buffer_partial: *io_size too small");
+ l_rc = TRAC_DATA_SIZE_LESS_THAN_HEADER_SIZE;
+ *io_size = 0;
+ break;
+ }
+
+ // CRITICAL REGION START
+ // Disable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+
+ // Get the lock
+ l_rc = ssx_semaphore_pend(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
+ if(l_rc != SSX_OK)
+ {
+ // Badness
+ FIELD("TRAC_get_buffer_partial: Failed to get mutex");
+ }
+ else
+ {
+ // Now that we have full buffer, adjust it to be requested size
+ memset(io_data,0,(size_t)*io_size);
+
+ l_lock_get = TRUE;
+ l_full_buf = (char*)i_td_ptr;
+ if(*io_size >= TRACE_BUFFER_SIZE)
+ {
+ // It fits
+ *io_size = TRACE_BUFFER_SIZE;
+ memcpy(io_data,l_full_buf,(size_t)*io_size);
+ break;
+ }
+
+ // copy the header of the trace buffer to io_data
+ l_head = (tracDesc_t)l_full_buf;
+ memcpy(io_data,l_full_buf,(size_t)(l_head->hdr_len));
+
+ // Reuse the l_head to point to the io_data and fill in the data
+ l_head = (tracDesc_t)io_data;
+
+ if((l_head->next_free == l_head->hdr_len) && (l_head->times_wrap == 0))
+ {
+ // No data in buffer so just return what we have
+ *io_size = 0;
+ break;
+ }
+
+ if(l_head->next_free > *io_size)
+ {
+ l_part_size = *io_size - l_head->hdr_len;
+
+ memcpy((UCHAR *)io_data+l_head->hdr_len,
+ l_full_buf+l_head->next_free-l_part_size,
+ (size_t)l_part_size);
+
+ // We don't need to update *io_size, all data copied.
+ l_head->size = *io_size;
+
+ // Set pointer at beginning because this will be a
+ // "just wrapped" buffer.
+ l_head->next_free = l_head->hdr_len;
+
+ // Buffer is now wrapped because we copied max data into it.
+ if(!l_head->times_wrap)
+ {
+ l_head->times_wrap = 1;
+ }
+ }
+ else
+ {
+ // First part of buffer fits fine
+ memcpy((UCHAR *)io_data+l_head->hdr_len,
+ l_full_buf+l_head->hdr_len,
+ (size_t)(l_head->next_free - l_head->hdr_len));
+
+
+ // If it's wrapped then pick up some more data
+ if(l_head->times_wrap)
+ {
+ // Figure out how much room we have left
+ l_part_size = *io_size - l_head->next_free;
+
+ memcpy((UCHAR *)io_data+l_head->next_free,
+ l_full_buf+TRACE_BUFFER_SIZE-l_part_size,
+ (size_t)l_part_size);
+
+ // We don't need to update *io_size, all data copied.
+ l_head->size = *io_size;
+ }
+ else
+ {
+ // Update copied length which is what we have in trace buffer
+ l_head->size = l_head->next_free;
+ *io_size = l_head->next_free;
+ }
+ }
+ }
+ // CRITICAL REGION END
+ }
+ while(FALSE);
+
+ // Always try to release even if error above
+ if(l_lock_get)
+ {
+ ssx_semaphore_post(&g_trac_mutex);
+ // Re-enable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_exit(&l_ctx);
+ }
+
+ return(l_rc);
+}
+
+// Function Specification
+//
+// Name: TRAC_reset_buf
+//
+// Description:
+//
+// End Function Specification
+UINT TRAC_reset_buf()
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ UINT l_rc = 0;
+ UINT l_num_des = 0;
+ UINT i=0;
+ SsxMachineContext l_ctx = 0;
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ // Disable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+
+ // Get mutex so no one traces
+ l_rc = ssx_semaphore_pend(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
+ if(l_rc != SSX_OK)
+ {
+ // Badness
+ FIELD("TRAC_reset_buf: Failure trying to get mutex");
+ }
+ else
+ {
+ l_num_des = sizeof(g_des_array) / sizeof(trace_descriptor_array_t);
+
+ for(i=0;i<l_num_des;i++)
+ {
+ // Initialize the buffer
+ l_rc = trac_init_values_buffer(g_des_array[i].entry,
+ g_des_array[i].comp);
+ if(l_rc)
+ {
+ FIELD("TRAC_reset_buf: Failure in call to trac_init_values_buffer()");
+ break;
+ }
+ }
+ }
+
+ // Always try to release even if fail above
+ ssx_semaphore_post(&g_trac_mutex);
+
+ // Re-enable non-critical interrupts if thread context
+ if (__ssx_kernel_context_thread())
+ ssx_critical_section_exit(&l_ctx);
+
+ return(l_rc);
+}
+
+
+// Function Specification
+//
+// Name: trac_write_data_to_circular
+//
+// Description:
+//
+// End Function Specification
+uint16_t trac_write_data_to_circular(circular_entire_data_t *i_ptr)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ uint16_t l_rc = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ memcpy((void *)&g_isr_circular_buf[g_isr_circular_header.head],
+ (void *)i_ptr,
+ sizeof(circular_entire_data_t));
+
+ return(l_rc);
+}
+
+// Function Specification
+//
+// Name: get_trac_entry_data_from_circular
+//
+// Description:
+//
+// End Function Specification
+uint16_t get_trac_entry_data_from_circular(circular_entire_data_t *o_ptr)
+{
+ /*------------------------------------------------------------------------*/
+ /* Local Variables */
+ /*------------------------------------------------------------------------*/
+ uint16_t l_rc = 0;
+
+ /*------------------------------------------------------------------------*/
+ /* Code */
+ /*------------------------------------------------------------------------*/
+
+ memcpy((void *)o_ptr,
+ (void *)&g_isr_circular_buf[g_isr_circular_header.tail],
+ sizeof(circular_entire_data_t));
+
+ return(l_rc);
+}
diff --git a/src/occ_405/trac/trac_interface.h b/src/occ_405/trac/trac_interface.h
new file mode 100755
index 0000000..d448a0e
--- /dev/null
+++ b/src/occ_405/trac/trac_interface.h
@@ -0,0 +1,310 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ/trac/trac_interface.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 _TRAC_INTERFACE_H
+#define _TRAC_INTERFACE_H
+
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include <occ_common.h>
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+/* Used to trace 0 - 5 arguments or a binary buffer when using a hash value. */
+
+#define TRACE(i_td,i_string,args...) \
+ trace_adal_write_all(i_td,trace_adal_hash(i_string,-1),__LINE__,0,##args)
+
+#define TRACEBIN(i_td,i_string,i_ptr,i_size) \
+ trac_write_bin(i_td,trace_adal_hash(i_string,0),__LINE__,i_ptr,i_size)
+
+#ifndef NO_TRAC_STRINGS
+
+#define FIELD(a) \
+ printf("%s",a)
+
+#define FIELD1(a,b) \
+ printf("%s%lx",a,(unsigned long)b)
+
+#else // NO_TRAC_STRINGS
+
+#define FIELD(a)
+
+#define FIELD1(a,b)
+
+#endif // NO_TRAC_STRINGS
+
+#define SUCCESS 0
+
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+#define TRACE_MAX_ARGS 5 /* Maximum number of args to trace */
+
+typedef uint32_t trace_hash_val;
+
+// NOTE! Increment this when new components are added!
+#define TRAC_NUM_TRACE_COMPONENTS 1
+
+
+#define TRACE_BUFFER_SIZE 8192
+
+#define CIRCULAR_BUFFER_SIZE 4
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+/*
+ * Structure is put at beginning of all trace buffers
+ */
+typedef struct trace_buf_head {
+ UCHAR ver; /* version of this struct (1) */
+ UCHAR hdr_len; /* size of this struct in bytes */
+ UCHAR time_flg; /* meaning of timestamp entry field */
+ UCHAR endian_flg; /* flag for big ('B') or little ('L') endian */
+ CHAR comp[16]; /* the buffer name as specified in init call */
+ UINT32 size; /* size of buffer, including this struct */
+ UINT32 times_wrap; /* how often the buffer wrapped */
+ UINT32 next_free; /* offset of the byte behind the latest entry */
+ UINT32 te_count; /* Updated each time a trace is done */
+ UINT32 extracted; /* Not currently used */
+}trace_buf_head_t;
+
+/*
+ * Timestamp and thread id for each trace entry.
+ */
+typedef struct trace_entry_stamp {
+ UINT32 tbh; /* timestamp upper part */
+ UINT32 tbl; /* timestamp lower part */
+ UINT32 tid; /* process/thread id */
+}trace_entry_stamp_t;
+
+/*
+ * Structure is used by adal app. layer to fill in trace info.
+ */
+typedef struct trace_entry_head {
+ UINT16 length; /* size of trace entry */
+ UINT16 tag; /* type of entry: xTRACE xDUMP, (un)packed */
+ UINT32 hash; /* a value for the (format) string */
+ UINT32 line; /* source file line number of trace call */
+}trace_entry_head_t;
+
+/*
+ * Parameter traces can be all contained in one write.
+ */
+typedef struct trace_entire_entry {
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+ UINT32 args[TRACE_MAX_ARGS + 1];
+} trace_entire_entry_t;
+
+
+/*
+ * Binary first writes header and time stamp.
+ */
+typedef struct trace_bin_entry {
+ trace_entry_stamp_t stamp;
+ trace_entry_head_t head;
+} trace_bin_entry_t;
+
+/*
+ * Used as input to traces to get to correct buffer.
+ */
+typedef trace_buf_head_t * tracDesc_t;
+
+/*
+ * Structure is used to hold array of all trace descriptors
+ */
+typedef struct trace_descriptor_array
+{
+ tracDesc_t *entry; /* Pointer to trace descriptor */
+ CHAR *comp; /* Pointer to component name */
+}trace_descriptor_array_t;
+
+typedef struct circular_buf_head
+{
+ UINT32 head; // pointer to head
+ UINT32 tail; // pointer to tail
+ UINT32 entryCount; // nums of entry
+} circular_buf_header_t;
+
+
+typedef struct circular_entire_data {
+ UINT32 len;
+ CHAR comp[4];
+ trace_entire_entry_t entry;
+} circular_entire_data_t;
+
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+// All TPMF component trace descriptors.
+extern tracDesc_t g_trac_inf;
+extern tracDesc_t g_trac_err;
+extern tracDesc_t g_trac_imp;
+
+extern const trace_descriptor_array_t g_des_array[];
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+/*
+ * Allocate and initialize all trace buffers in memory.
+ *
+ * This function will allocate memory for each of the pre-defined trace
+ * buffers, initialize the buffers with starting data, and set up the
+ * trace descriptors which each component will use to trace.
+ *
+ * This function must be called first before any components try to trace!
+ *
+ * return Non-zero return code on error.
+ */
+UINT TRAC_init_buffers(void);
+
+/*
+ * Retrieve full trace buffer for component i_comp
+ *
+ * This function assumes memory has already been allocated for
+ * the full trace buffer in o_data.
+ *
+ * param i_td_ptr Trace descriptor of buffer to retrieve.
+ * param o_data Pre-allocated pointer to where data will be stored.
+ *
+ * return Non-zero return code on error
+ */
+UINT TRAC_get_buffer(const tracDesc_t i_td_ptr,
+ void *o_data);
+
+/*
+ * Retrieve partial trace buffer for component i_comp
+ *
+ * This function assumes memory has already been allocated for
+ * the trace buffer (size io_size). This function will copy
+ * in up to io_size in bytes to the buffer and set io_size
+ * to the exact size that is copied in.
+ *
+ * param i_td_ptr Trace descriptor of buffer to retrieve.
+ * param o_data Pre-allocated pointer to where data will be stored.
+ * param io_size Size of trace data to retrieve (input)
+ * Actual size of trace data stored (output)
+ *
+ * return Non-zero return code on error
+ */
+UINT TRAC_get_buffer_partial(const tracDesc_t i_td_ptr,
+ void *o_data,
+ UINT *io_size);
+
+/*
+ * Retrieve trace descriptor for input component name
+ *
+ * param i_comp Component name to retrieve trace descriptor for.
+ *
+ * return Valid trace descriptor on success, NULL on failure.
+ */
+tracDesc_t TRAC_get_td(const char *i_comp);
+
+/*
+ * Reset all trace buffers
+ *
+ * return Non-zero return code on error
+ */
+UINT TRAC_reset_buf(void);
+
+
+/*
+ * Trace input integers to trace buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * param io_td Initialized trace descriptor pointer to buffer to trace to.
+ * param i_hash Hash value to be recorded for this trace.
+ * param i_fmt Output format
+ * param i_line Line number trace is occurring on.
+ * param i_type trace type. field or debug.
+ * param ... params that are limited to a size of 4 bytes, i.e. int, uint32_t, nnn*
+ *
+ * return Non-zero return code on error.
+ */
+UINT trace_adal_write_all(tracDesc_t io_td,const trace_hash_val i_hash,
+ const char *i_fmt,const ULONG i_line, const ULONG i_type,...);
+
+
+/*
+ * Trace input integers to trace buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * param io_td Initialized trace descriptor pointer to buffer to trace to.
+ * param i_hash Hash value to be recorded for this trace.
+ * param i_line Line number trace is occurring on.
+ * param i_num_args Number of arguments to trace.
+ * param i_1 Input Parameter 1
+ * param i_2 Input Parameter 2
+ * param i_3 Input Parameter 3
+ * param i_4 Input Parameter 4
+ * param i_5 Input Parameter 5
+ *
+ * return Non-zero return code on error.
+ */
+UINT trac_write_int(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const UINT i_num_args,
+ const ULONG i_1,const ULONG i_2,const ULONG i_3,
+ const ULONG i_4,const ULONG i_5
+ );
+
+
+/*
+ * Trace binary data to buffer.
+ *
+ * This function assumes i_td has been initialized.
+ *
+ * param io_td Initialized trace descriptor pointer to buffer to trace to.
+ * param i_hash Hash value to be recorded for this trace.
+ * param i_line Line number trace is occurring on.
+ * param i_ptr Pointer to binary data to trace.
+ * param i_size Size of data to copy from i_ptr.
+ *
+ * return Non-zero return code on error.
+ */
+UINT trac_write_bin(tracDesc_t io_td,const trace_hash_val i_hash,
+ const ULONG i_line,
+ const void *i_ptr,
+ const ULONG i_size);
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+#endif //_TRAC_INTERFACE_H
diff --git a/src/occ_405/trac/trac_service_codes.h b/src/occ_405/trac/trac_service_codes.h
new file mode 100755
index 0000000..f7a278a
--- /dev/null
+++ b/src/occ_405/trac/trac_service_codes.h
@@ -0,0 +1,73 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/occ_405/trac/trac_service_codes.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 _TRAC_SERVICE_CODES_H_
+#define _TRAC_SERVICE_CODES_H_
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include <comp_ids.h>
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+enum tracReasonCodes
+{
+ TRAC_ERROR_BLOCK_ALLOCATE = TRAC_COMP_ID | 0x00,
+ TRAC_ERROR_COMP_NOT_FOUND = TRAC_COMP_ID | 0x01,
+ TRAC_MEM_ALLOC_FAIL = TRAC_COMP_ID | 0x02,
+ TRAC_MEM_BUFF_TOO_SMALL = TRAC_COMP_ID | 0x03,
+ TRAC_INVALID_PARM = TRAC_COMP_ID | 0x04,
+ TRAC_DATA_SIZE_TOO_LARGE = TRAC_COMP_ID | 0x05,
+ TRAC_DATA_SIZE_LESS_THAN_HEADER_SIZE = TRAC_COMP_ID | 0x06,
+ TRAC_CIRCULAR_BUFF_FULL = TRAC_COMP_ID | 0x07,
+};
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+#endif /* #ifndef _TRAC_SERVICE_CODES_H_ */
OpenPOWER on IntegriCloud