summaryrefslogtreecommitdiffstats
path: root/src/occ/errl
diff options
context:
space:
mode:
Diffstat (limited to 'src/occ/errl')
-rwxr-xr-xsrc/occ/errl/errl.c984
-rwxr-xr-xsrc/occ/errl/errl.h404
-rwxr-xr-xsrc/occ/errl/test/Makefile55
-rwxr-xr-xsrc/occ/errl/test/app.mk99
-rwxr-xr-xsrc/occ/errl/test/errltest.c786
-rwxr-xr-xsrc/occ/errl/test/gpefiles.mk24
-rwxr-xr-xsrc/occ/errl/test/parser.c292
-rwxr-xr-xsrc/occ/errl/test/test.mk28
8 files changed, 2672 insertions, 0 deletions
diff --git a/src/occ/errl/errl.c b/src/occ/errl/errl.c
new file mode 100755
index 0000000..3f997b9
--- /dev/null
+++ b/src/occ/errl/errl.c
@@ -0,0 +1,984 @@
+/******************************************************************************
+// @file errl.h
+// @brief OCC Errl Component
+*/
+/******************************************************************************
+ *
+ * @page ChangeLogs Change Logs
+ * @section _errl_c errl.c
+ * @verbatim
+ *
+ * Flag Def/Fea Userid Date Description
+ * ------- ---------- -------- ---------- ----------------------------------
+ * tapiar 06/15/2011 Created errl methods
+ * abagepa 08/15/2011 Add: a couple of trace statements
+ * @01 tapiar 10/05/2011 Add: a couple of trace statements
+ * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+ * @pb00E pbavari 03/11/2012 Added correct include file
+ * @nh001 neilhsu 05/23/2012 Add missing error log tags
+ * @th022 thallet 10/04/2012 Add helper function to return slotId
+ * @nh004 864941 neilhsu 12/20/2012 Support get/delete errl & added trace info
+ * @at012 868019 alvinwan 01/25/2013 TRAC_get_buffer_partial() can result in TLB Miss Exception
+ * @th032 thallet 04/19/2013 Dcache_Flush so FSP can read from SRAM
+ * @th036 881677 thallet 05/06/2013 Support for new Poll Command
+ * @jh001 881996 joshych 05/07/2013 Support SRAM error log format
+ * @jh002 883921 joshych 06/17/2013 Read OCC error log from SRAM
+ * @gm006 SW224414 milesg 09/16/2013 Reset and FFDC improvements
+ * @gm016 909061 milesg 12/10/2013 Allow traces to use all available space
+ * @gm028 911670 milesg 02/27/2014 Immediate safe mode on checkstop
+ * @gm041 928150 milesg 06/02/2014 allow callouts to be added to info errors if mfg action flag is set
+ *
+ * @endverbatim
+ *
+ *///*************************************************************************/
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include "ssx.h"
+
+#include <errl.h>
+//@pb00Ec - changed from common.h to occ_common.h for ODE support
+#include <occ_common.h>
+#include <comp_ids.h>
+#include <trac.h>
+#include <state.h>
+#include <dcom.h>
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+uint32_t G_occErrSlotBits = 0x000000000;
+uint8_t G_occErrIdCounter= 0x00;
+
+uint8_t G_errslot1[MAX_ERRL_ENTRY_SZ] = {0};
+uint8_t G_errslot2[MAX_ERRL_ENTRY_SZ] = {0};
+uint8_t G_errslot3[MAX_ERRL_ENTRY_SZ] = {0};
+uint8_t G_errslot4[MAX_ERRL_ENTRY_SZ] = {0};
+uint8_t G_errslot5[MAX_ERRL_ENTRY_SZ] = {0};
+uint8_t G_errslot6[MAX_ERRL_ENTRY_SZ] = {0};
+uint8_t G_errslot7[MAX_ERRL_ENTRY_SZ] = {0};
+
+uint8_t G_infoslot[MAX_ERRL_ENTRY_SZ] = {0};
+
+uint8_t G_callslot[MAX_ERRL_CALL_HOME_SZ] = {0};
+
+errlHndl_t G_occErrSlots[ERRL_MAX_SLOTS] = {
+ (errlHndl_t) G_errslot1,
+ (errlHndl_t) G_errslot2,
+ (errlHndl_t) G_errslot3,
+ (errlHndl_t) G_errslot4,
+ (errlHndl_t) G_errslot5,
+ (errlHndl_t) G_errslot6,
+ (errlHndl_t) G_errslot7,
+ (errlHndl_t) G_infoslot,
+ (errlHndl_t) G_callslot
+ };
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+void hexDumpLog( errlHndl_t i_log );
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+// Function Specification
+//
+// Name: getErrSlotNumAndErrId
+//
+// Description: Get Error Slot Number and Error Id
+//
+// Flow: 06/06/11 FN=getErrSlotNumAndErrId
+//
+// End Function Specification
+uint8_t getErrSlotNumAndErrId(
+ ERRL_SEVERITY i_severity,
+ uint8_t *o_errlId,
+ uint64_t *o_timeStamp
+ )
+{
+ // Locals
+ uint8_t l_rc = ERRL_INVALID_SLOT;
+ uint32_t l_mask = ERRL_SLOT_MASK_DEFAULT;
+
+ switch ( i_severity )
+ {
+ case ERRL_SEV_INFORMATIONAL:
+ l_mask = ERRL_SLOT_MASK_INFORMATIONAL;
+ break;
+ case ERRL_SEV_PREDICTIVE:
+ l_mask = ERRL_SLOT_MASK_PREDICTIVE;
+ break;
+ case ERRL_SEV_UNRECOVERABLE:
+ l_mask = ERRL_SLOT_MASK_UNRECOVERABLE;
+ break;
+ case ERRL_SEV_CALLHOME_DATA:
+ l_mask = ERRL_SLOT_MASK_CALL_HOME_DATA;
+ break;
+ };
+
+
+ // we have a valid mask
+ if ( l_mask != ERRL_SLOT_MASK_DEFAULT )
+ {
+ // 1. Find an available slot
+ uint8_t l_slot = ERRL_INVALID_SLOT;
+ uint32_t l_slotBitWord = ~(G_occErrSlotBits | l_mask);
+ SsxMachineContext l_ctx;
+
+ // 2. use assembly cntlzw to get slot & (disable/enable interrupts)
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+ __asm__ __volatile__ ( "cntlzw %0, %1;" : "=r" (l_slot) : "r" (l_slotBitWord));
+ ssx_critical_section_exit(&l_ctx);
+
+ // slot is valid
+ if ( l_slot < ERRL_MAX_SLOTS )
+ {
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+ // 3. Get time stamp & save off timestamp
+ // Internal caller so assuming valid pointer
+ *o_timeStamp = ssx_timebase_get();
+ // save of counter and then increment it
+ // Note: Internal caller so assuming valid pointer
+ *o_errlId = ((++G_occErrIdCounter) == 0) ? ++G_occErrIdCounter : G_occErrIdCounter;
+
+ G_occErrSlotBits |= (ERRL_SLOT_SHIFT >> l_slot); // @nh004c
+ ssx_critical_section_exit(&l_ctx);
+
+ l_rc = l_slot;
+
+ }
+ }
+
+ // return slot
+ return l_rc;
+}
+
+// Function Specification
+//
+// Name: getErrSlotNumByErrId
+//
+// Description: Get Error Slot Num By Error Id
+//
+// End Function Specification
+uint8_t getErrSlotNumByErrId(const uint8_t i_errlId) // @nh004a
+{
+ uint8_t l_SlotNum = ERRL_INVALID_SLOT;
+ uint8_t i = 0;
+
+ // the errID should starting from 1 to 0xff
+ if (i_errlId != 0)
+ {
+ // search for all slot and try to get slot num
+ for (i = 0; i < ERRL_MAX_SLOTS; i ++)
+ {
+ if (i_errlId == G_occErrSlots[i]->iv_entryId)
+ {
+ // Found, return the array index as slot num
+ l_SlotNum = i;
+ break;
+ }
+ }
+ }
+
+ // return ERRL_INVALID_SLOT(0xff) if not found
+ return l_SlotNum;
+}
+
+
+// Function Specification
+//
+// Name: getErrSlotOCIAddr
+//
+// Description: Get Error Slot OCI address
+//
+// End Function Specification
+uint32_t getErrSlotOCIAddr(const uint8_t i_SlotNum) // @nh004a
+{
+ void *l_addr = 0;
+
+ if (i_SlotNum < ERRL_MAX_SLOTS)
+ {
+ l_addr = G_occErrSlots[i_SlotNum];
+ }
+
+ return (uint32_t)l_addr;
+}
+
+
+// Function Specification
+//
+// Name: getErrlOCIAddrByID
+//
+// Description: Get Error Slot OCI address
+//
+// End Function Specification
+uint32_t getErrlOCIAddrByID(const uint8_t i_id)
+{
+ // This function verifies the id is valid
+ uint8_t l_slot = getErrSlotNumByErrId(i_id);
+
+ // This function verifies that slot is valid
+ return getErrSlotOCIAddr(l_slot);
+}
+
+
+// Function Specification
+//
+// Name: getErrlLengthByID
+//
+// Description: Get Error Log Length
+//
+// End Function Specification
+uint16_t getErrlLengthByID(const uint8_t i_id)
+{
+ uint16_t l_length = 0;
+ uint8_t l_slot = getErrSlotNumByErrId(i_id);
+
+ /// check if error log is committed before returning length
+ /// because after it is committed, length shouldn't change.
+ if(l_slot < ERRL_MAX_SLOTS)
+ {
+ if (G_occErrSlots[l_slot]->iv_userDetails.iv_committed)
+ {
+ l_length = G_occErrSlots[l_slot]->iv_userDetails.iv_entrySize;
+ }
+ }
+
+ return l_length;
+}
+
+
+// Function Specification
+//
+// Name: getLastGetErrID
+//
+// Description: Get the oldest Error ID
+//
+// End Function Specification
+uint8_t getOldestErrlID() // @nh004a
+{
+ uint8_t l_entryId = 0;
+ uint8_t i = 0;
+ uint64_t l_timestamp = 0;
+
+ for (i = 0; i < ERRL_MAX_SLOTS; i++)
+ {
+ if (G_occErrSlots[i]->iv_userDetails.iv_committed)
+ {
+ // Get the oldest entry by searching the Mininum Err entry ID
+ if ((l_timestamp == 0) ||
+ (G_occErrSlots[i]->iv_userDetails.iv_timeStamp <= l_timestamp) )
+ {
+ l_timestamp = G_occErrSlots[i]->iv_userDetails.iv_timeStamp;
+ l_entryId = G_occErrSlots[i]->iv_entryId;
+ }
+ }
+ }
+
+ return l_entryId;
+}
+
+
+// Function Specification
+//
+// Name: createErrl
+//
+// Description: Create an Error Log
+//
+// Flow: 03/29/12 FN=createErrl
+//
+// End Function Specification
+errlHndl_t createErrl(
+ const uint16_t i_modId,
+ const uint8_t i_reasonCode,
+ const uint32_t i_extReasonCode, // @nh001a
+ const ERRL_SEVERITY i_sev,
+ const tracDesc_t i_trace,
+ const uint16_t i_traceSz,
+ const uint32_t i_userData1,
+ const uint32_t i_userData2
+ )
+{
+ // Locals
+ errlHndl_t l_rc = INVALID_ERR_HNDL;
+ uint64_t l_time = 0;
+ uint8_t l_id = 0;
+ uint8_t l_errSlot = getErrSlotNumAndErrId( i_sev, &l_id, &l_time);
+
+
+ if ( l_errSlot != ERRL_INVALID_SLOT )
+ {
+ TRAC_INFO("Creating error log in slot [%d]", l_errSlot);
+
+ // get slot pointer
+ l_rc = G_occErrSlots[ l_errSlot ];
+
+ // save off default size
+ l_rc->iv_userDetails.iv_entrySize = sizeof( ErrlEntry_t );
+
+ // add trace
+ addTraceToErrl( i_trace, i_traceSz, l_rc );
+
+ // save off entry Id
+ l_rc->iv_entryId = l_id;
+
+ //Save off version info
+ l_rc->iv_version = ERRL_STRUCT_VERSION_1;
+
+ // save off time
+ l_rc->iv_userDetails.iv_timeStamp = l_time;
+
+ // if its a call home error then set the sev to informational
+ l_rc->iv_severity = (i_sev == ERRL_SEV_CALLHOME_DATA ? (uint8_t)ERRL_SEV_INFORMATIONAL : i_sev);
+
+ l_rc->iv_userData4 = i_extReasonCode; // @nh001a
+
+ // save off user detail section version
+ l_rc->iv_userDetails.iv_version = ERRL_USR_DTL_STRUCT_VERSION_1;
+
+ // save off rest of input parameters
+ l_rc->iv_userDetails.iv_modId = i_modId;
+ l_rc->iv_reasonCode = i_reasonCode;
+ l_rc->iv_userDetails.iv_userData1 = i_userData1;
+ l_rc->iv_userDetails.iv_userData2 = i_userData2;
+
+ // set callout count to 0
+ l_rc->iv_numCallouts = 0;
+
+ // save off occ fields
+ //NOTE: Design does not exist for these fields
+ // TODO fix this when design is done!
+ l_rc->iv_userDetails.iv_fwLevel = 0;
+ l_rc->iv_userDetails.iv_occId = G_pob_id.chip_id;
+ l_rc->iv_userDetails.iv_occRole = G_occ_role;
+ l_rc->iv_userDetails.iv_operatingState = CURRENT_STATE();
+ }
+ else
+ {
+ // TODO: put a threshold on this trace
+ TRAC_INFO("Error Logs are FULL - Slot [%d]", l_errSlot); //@01a @nh004c
+ }
+
+ return l_rc;
+}
+
+
+// Function Specification
+//
+// Name: addTraceToErrl
+//
+// Description: Add trace to an error log
+//
+// Flow: 06/06/11 FN=addTraceToErrl
+//
+// End Function Specification
+void addTraceToErrl(
+ const tracDesc_t i_trace,
+ const uint16_t i_traceSz,
+ errlHndl_t io_err)
+{
+ UINT l_expectLen = 0, l_rtLen = 0, l_bytes_left; //gm016
+ void * l_traceAddr = io_err;
+ uint16_t l_actualSizeOfUsrDtls = 0;
+ pore_status_t l_gpe0_status;
+ static bool L_gpe_halt_traced = FALSE;
+
+
+ // check if GPE was frozen due to a checkstop
+ l_gpe0_status.value = in64(PORE_GPE0_STATUS);
+ if(l_gpe0_status.fields.freeze_action && !L_gpe_halt_traced)
+ {
+ L_gpe_halt_traced = TRUE;
+ TRAC_ERR("addTraceToErrl: OCC GPE halted due to checkstop. GPE0 status[0x%08x%08x]",
+ l_gpe0_status.words.high_order, l_gpe0_status.words.low_order);
+ }
+
+ // 1. Check if error log is not null
+ // 2. error log is not invalid
+ // 3. error log has not been commited
+ // 4. input trace is not zero
+ // 5. free space is enough
+ // 6. input trace descriptor is valid
+ if( (io_err != NULL) &&
+ (io_err != INVALID_ERR_HNDL) &&
+ (io_err->iv_userDetails.iv_committed == 0) &&
+ // @nh004d
+ (i_traceSz != 0) &&
+ ((io_err->iv_userDetails.iv_entrySize + sizeof(ErrlUserDetailsEntry_t)) < MAX_ERRL_ENTRY_SZ ) &&
+ ((i_trace==g_trac_inf)||(i_trace==g_trac_err)||(i_trace==g_trac_imp)||(i_trace==NULL)) ) // @at012a
+ {
+ //local copy of the usr details entry
+ ErrlUserDetailsEntry_t l_usrDtlsEntry;
+ uint16_t l_headerSz = sizeof( l_usrDtlsEntry );
+
+ //adjust user details entry size to available size (word align )
+ uint16_t l_availableSize = MAX_ERRL_ENTRY_SZ - (io_err->iv_userDetails.iv_entrySize + l_headerSz );
+ l_usrDtlsEntry.iv_size = ( i_traceSz < l_availableSize ) ? i_traceSz : l_availableSize; // @jh001c
+
+ //set type
+ l_usrDtlsEntry.iv_type = (uint8_t) ERRL_USR_DTL_TRACE_DATA;
+
+ //set version
+ l_usrDtlsEntry.iv_version = ERRL_TRACE_VERSION_1;
+
+ //copy the data into error the offset is the size of the current errorlog
+ void * l_p = io_err;
+
+ // @nh004a -- Start
+ // Caculate trace data address. Starting from errl address + sizeof(ErrlEntry_t + ErrlUserDetailsEntry_t).
+ l_traceAddr = l_p + io_err->iv_userDetails.iv_entrySize + l_headerSz;
+
+ // check if user request to add trace from a specific trace buffer
+ if (i_trace != NULL)
+ {
+ // Ensure requested length are larger than one trace info size.
+ if (l_usrDtlsEntry.iv_size >= sizeof (trace_buf_head_t))
+ {
+ l_rtLen = l_usrDtlsEntry.iv_size;
+ TRAC_get_buffer_partial(i_trace, l_traceAddr, &l_rtLen);
+
+ // Update data size
+ l_usrDtlsEntry.iv_size = l_rtLen;
+ }
+ else
+ {
+ TRAC_IMP("addTraceToErrl: Not enough buffer size for trace, Avail[%d], Req[%d]\n", l_availableSize, l_usrDtlsEntry.iv_size);
+
+ //Requested size is not able to fill in any trace info. Clear data length and give up.
+ l_usrDtlsEntry.iv_size = 0;
+ }
+ }
+ else
+ {
+ // User not specify which trace buffer to add.
+ // We have three kinds of trace buffer.(INF/IMP/ERR).Get partial of them to fill in user detail section of this ERR Log.
+ l_bytes_left = l_usrDtlsEntry.iv_size; //gm016
+ l_expectLen = l_bytes_left / NUM_OF_TRACE_TYPE;
+
+ // Ensure the size are able to fill in at least one trace info.
+ if (l_expectLen >= sizeof (trace_buf_head_t))
+ {
+ l_rtLen = l_expectLen;
+ TRAC_get_buffer_partial(TRAC_get_td("ERR"), l_traceAddr, &l_rtLen);
+ l_actualSizeOfUsrDtls += l_rtLen;
+ l_bytes_left -= l_rtLen; //gm016
+
+ l_rtLen = l_bytes_left / 2; //gm016
+ TRAC_get_buffer_partial(TRAC_get_td("IMP"), (l_traceAddr + l_actualSizeOfUsrDtls), &l_rtLen);
+ l_actualSizeOfUsrDtls += l_rtLen;
+ l_bytes_left -= l_rtLen; //gm016
+
+ l_rtLen = l_bytes_left; //gm016
+ TRAC_get_buffer_partial(TRAC_get_td("INF"), (l_traceAddr + l_actualSizeOfUsrDtls), &l_rtLen);
+ l_actualSizeOfUsrDtls += l_rtLen;
+
+ // Update data size
+ l_usrDtlsEntry.iv_size = l_actualSizeOfUsrDtls;
+ }
+ else
+ {
+ // Check to see if we are still able to fill in 1 or 2 traces into this Err log.
+ if (l_usrDtlsEntry.iv_size > sizeof (trace_buf_head_t))
+ {
+ l_rtLen = l_usrDtlsEntry.iv_size;
+
+ // Added only ERR trace info
+ TRAC_get_buffer_partial(TRAC_get_td("ERR"), l_traceAddr, &l_rtLen);
+
+ // Update data size
+ l_usrDtlsEntry.iv_size = l_rtLen;
+ }
+ else
+ {
+ TRAC_IMP("addTraceToErrl: Not enough buffer size for trace, Avail[%d], Req[%d]\n", l_availableSize, l_usrDtlsEntry.iv_size);
+
+ //We do not have enough size to fill in any trace info. Clear data length.
+ l_usrDtlsEntry.iv_size = 0;
+ }
+ }
+ }
+
+ if (l_usrDtlsEntry.iv_size)
+ {
+ // Finally, cacluate entire data length including usrDtl header.
+ l_actualSizeOfUsrDtls = l_usrDtlsEntry.iv_size + l_headerSz;
+
+ // save of user detail header for trace buf section we just added.
+ // Address is starting from "errl address + sizeof(ErrlEntry_t)."
+ //
+ // io_err |----------------------------------------|
+ // | ErrlEntry_t |
+ // | {iv_userDetails.iv_userDetailEntrySize,| <== we may have more usrdtl sections, need to add length
+ // | ... other elements ... }| of new usrdtl section(ErrlUserDetailsEntry_t + trace lens)
+ // |----------------------------------------|
+ // | ErrlUserDetailsEntry_t | <== copy usrdtl header to here (l_usrDtlsEntry)
+ // |----------------------------------------|
+ //trace buf | trace1(ex.INF) | <== trace already filled in at this moment.
+ // | trace2(ex.INF&IMP&ERR) |
+ // | ... |
+ //
+ l_p = memcpy( l_p+((io_err->iv_userDetails.iv_entrySize)),&l_usrDtlsEntry, l_headerSz );
+ }
+ // @nh004a -- End
+
+ //update usr data entry size
+ io_err->iv_userDetails.iv_userDetailEntrySize += l_actualSizeOfUsrDtls;
+
+ //update error log size
+ io_err->iv_userDetails.iv_entrySize += l_actualSizeOfUsrDtls;
+
+ }//end validation check
+}
+
+
+// Function Specification
+//
+// Name: reportErrorLog
+//
+// Description: report the log to tmgt
+//
+// Flow: FN=None
+//
+// End Function Specification
+void reportErrorLog( errlHndl_t i_err, uint16_t i_entrySize )
+{
+ // report the log to tmgt
+ // will need to give them the address and size to read
+
+ // TODO: Guts still not defined yet
+ TRAC_INFO("Reporting error @ %p with size %d",i_err, i_entrySize );
+ TRAC_INFO("ModID: 0x%08X, RC: 0x%08X, UserData1: 0x%08X, UserData2: 0x%08X",
+ i_err->iv_userDetails.iv_modId, i_err->iv_reasonCode,
+ i_err->iv_userDetails.iv_userData1, i_err->iv_userDetails.iv_userData2);
+
+ // TODO: remove this when tracing is enabled
+ hexDumpLog( i_err );
+}
+
+
+// Function Specification
+//
+// Name: commitErrl
+//
+// Description: Commit an Error Log
+//
+// Flow: 06/06/11 FN=commitErrl
+//
+// End Function Specification
+void commitErrl( errlHndl_t *io_err )
+{
+ pore_status_t l_gpe0_status;
+
+ if ( io_err != NULL )
+ {
+ // check if handle is valid and is NOT empty
+ if ((*io_err != NULL ) && ( *io_err != INVALID_ERR_HNDL ))
+ {
+ // check if GPE was frozen due to a checkstop
+ l_gpe0_status.value = in64(PORE_GPE0_STATUS);
+ if(l_gpe0_status.fields.freeze_action)
+ {
+ //Go to the reset state to minimize errors
+ reset_state_request(RESET_REQUESTED_DUE_TO_ERROR);
+
+ //clear out all other actions and set the safe mode req'd action
+ (*io_err)->iv_actions.word = ERRL_ACTIONS_SAFE_MODE_REQUIRED;
+
+ //set severity to informational
+ (*io_err)->iv_severity = ERRL_SEV_INFORMATIONAL;
+
+ //set callouts to 0
+ (*io_err)->iv_numCallouts = 0;
+ }
+
+ // if reset action bit is set force severity to unrecoverable and
+ // make sure there is at least one callout
+ if((*io_err)->iv_actions.reset_required) //@gm006
+ {
+ (*io_err)->iv_severity = ERRL_SEV_UNRECOVERABLE;
+ if(!(*io_err)->iv_numCallouts)
+ {
+ addCalloutToErrl(*io_err,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_FIRMWARE,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+ }
+ }
+
+ // mark the last callout by zeroing out the next one
+ if((*io_err)->iv_numCallouts < ERRL_MAX_CALLOUTS)
+ {
+ memset(&(*io_err)->iv_callouts[(*io_err)->iv_numCallouts], 0,
+ sizeof(ErrlCallout_t));
+ }
+
+ // number of callouts must be the max value as defined by the TMGT-OCC spec.
+ (*io_err)->iv_numCallouts = ERRL_MAX_CALLOUTS; // @jh002a
+
+ // save off committed
+ (*io_err)->iv_userDetails.iv_committed = 1;
+
+ // calculate checksum & save it off
+ uint32_t l_cnt = 2; // starting point is after checksum field
+ uint32_t l_sum = 0;
+ uint32_t l_size = (*io_err)->iv_userDetails.iv_entrySize;
+ uint8_t * l_p = (uint8_t *)*io_err;
+
+ for( ; l_cnt < l_size ; l_cnt++ )
+ {
+ l_sum += *(l_p+l_cnt);
+ }
+
+ (*io_err)->iv_checkSum = l_sum;
+
+ // Flush error log out to SRAM since the FSP will directly read it
+ dcache_flush( *io_err, MAX_ERRL_ENTRY_SZ ); // @th032
+
+ // report error to FSP
+ reportErrorLog( *io_err, l_size );
+ }
+
+ *io_err = (errlHndl_t) NULL;
+ }
+}
+
+
+// Function Specification
+//
+// Name: getErrlLogId
+//
+// Description: Get Log Id from an Error Log
+//
+// Flow: --/--/-- FN=
+//
+// End Function Specification
+uint8_t getErrlLogId( errlHndl_t io_err )
+{
+ uint8_t l_logId = ERRL_INVALID_SLOT;
+
+ // check if handle is valid and is NOT empty
+ if ((io_err != NULL ) && ( io_err != INVALID_ERR_HNDL ))
+ {
+ l_logId = (io_err)->iv_entryId;
+ }
+
+ return l_logId;
+}
+
+
+// Function Specification
+//
+// Name: deleteErrl
+//
+// Description: Delete an Error Log
+//
+// Flow: 06/06/11 FN=deleteErrl
+//
+// End Function Specification
+errlHndl_t deleteErrl( errlHndl_t *io_err) // @nh004c
+{
+ errlHndl_t l_err = INVALID_ERR_HNDL;
+
+ if (io_err != NULL)
+ {
+ // check if handle is valid and is NOT empty
+ if ((*io_err != NULL ) &&
+ (*io_err != INVALID_ERR_HNDL ))
+ {
+
+ // find the slot number by traversing the global array
+ uint32_t l_slot = 0;
+
+ for( ; l_slot < ERRL_MAX_SLOTS; l_slot++ )
+ {
+ if ( *io_err == G_occErrSlots[ l_slot ] )
+ {
+ TRAC_INFO("deleting error @%p at slot [%d]", *io_err, l_slot );
+
+ // clear out space in that slot
+ memset(*io_err, 0, (*io_err)->iv_userDetails.iv_entrySize );
+
+ // Disable interrupts
+ SsxMachineContext l_ctx;
+ ssx_critical_section_enter(SSX_NONCRITICAL, &l_ctx);
+
+ //clear the error log slot bit for reuse
+ G_occErrSlotBits &= ~(ERRL_SLOT_SHIFT >> l_slot);
+
+ // Enable interrupts
+ ssx_critical_section_exit(&l_ctx);
+
+ l_err = NULL;
+
+ // done doing the work
+ break;
+ }
+ }
+ } // end if valid error log handl
+
+ //set the handle to null
+ *io_err = (errlHndl_t) NULL;
+ }
+
+ return l_err;
+}
+
+
+// Function Specification
+//
+// Name: addCalloutToErrl
+//
+// Description: Add a callout to an Error Log
+//
+// Flow: 06/06/11 FN=addCalloutToErrl
+//
+// End Function Specification
+// @jh001c
+void addCalloutToErrl(
+ errlHndl_t io_err,
+ const ERRL_CALLOUT_TYPE i_type,
+ const uint64_t i_calloutValue,
+ const ERRL_CALLOUT_PRIORITY i_priority)
+{
+ // 1. check if handle is valid (not null or invalid)
+ // 2. not committed
+ // 3. severity is not informational (unless mfg action flag is set)
+ // 4. callouts still not full
+ if ( (io_err != NULL ) &&
+ (io_err != INVALID_ERR_HNDL) &&
+ (io_err->iv_userDetails.iv_committed == 0) &&
+ (io_err->iv_actions.mfg_error || io_err->iv_severity != ERRL_SEV_INFORMATIONAL) && //gm041
+ (io_err->iv_numCallouts < ERRL_MAX_CALLOUTS) )
+ {
+ //set callout type
+ io_err->iv_callouts[ io_err->iv_numCallouts ].iv_type = (uint8_t)i_type;
+
+ //set callout value
+ io_err->iv_callouts[ io_err->iv_numCallouts ].iv_calloutValue = i_calloutValue;
+
+ //set priority
+ io_err->iv_callouts[ io_err->iv_numCallouts].iv_priority = (uint8_t)i_priority;
+
+ //increment actual number of callout
+ io_err->iv_numCallouts++;
+ }
+}
+
+
+// Function Specification
+//
+// Name: addUsrDtlsToErrl
+//
+// Description: Add User Details to an Error Log
+//
+// Flow: 06/06/11 FN=addUsrDtlsToErrl
+//
+// End Function Specification
+void addUsrDtlsToErrl(
+ errlHndl_t io_err,
+ uint8_t *i_dataPtr,
+ const uint16_t i_size,
+ const uint8_t i_version,
+ const ERRL_USR_DETAIL_TYPE i_type)
+{
+ // Locals
+ uint16_t l_maxSize = (i_type == ERRL_USR_DTL_CALLHOME_DATA) ? MAX_ERRL_CALL_HOME_SZ : MAX_ERRL_ENTRY_SZ;
+
+ // 1. check if handle is valid
+ // 2. NOT empty
+ // 3. not committed
+ // 4. size being passed in is valid
+ // 5. data pointer is valid
+ // 6. and we have enough size
+ if ((io_err != NULL ) &&
+ (io_err != INVALID_ERR_HNDL ) &&
+ (io_err->iv_userDetails.iv_committed == 0) &&
+ (i_size != 0) &&
+ (i_dataPtr != NULL) &&
+ ((io_err->iv_userDetails.iv_entrySize) < l_maxSize))
+ {
+ //local copy of the usr details entry
+ ErrlUserDetailsEntry_t l_usrDtlsEntry;
+ uint16_t l_headerSz = sizeof( l_usrDtlsEntry );
+
+ //adjust user details entry size to available size (word align )
+ uint16_t l_availableSize = l_maxSize - (io_err->iv_userDetails.iv_entrySize + l_headerSz );
+ l_usrDtlsEntry.iv_size = ( i_size < l_availableSize ) ? i_size : l_availableSize; // @jh001c
+
+ //set type
+ l_usrDtlsEntry.iv_type = (uint8_t)i_type;
+
+ //set version
+ l_usrDtlsEntry.iv_version = i_version;
+
+ //set the data
+ uint16_t l_actualSizeOfUsrDtls = l_headerSz + l_usrDtlsEntry.iv_size;
+
+ //copy the data into error the offset is the size of the current errorlog
+ void * l_p = io_err;
+ l_p = memcpy( l_p+((io_err->iv_userDetails.iv_entrySize)),&l_usrDtlsEntry, l_headerSz );
+ memcpy( l_p+l_headerSz, i_dataPtr, l_usrDtlsEntry.iv_size);
+
+ //update usr data entry size
+ io_err->iv_userDetails.iv_userDetailEntrySize += l_actualSizeOfUsrDtls;
+
+ //update error log size
+ io_err->iv_userDetails.iv_entrySize += l_actualSizeOfUsrDtls;
+ }
+}
+
+
+// Function Specification
+//
+// Name: setErrlSevToInfo
+//
+// Description: Set Error Log Severity to Informational
+// NOTE: Any callouts in the current error log will be DROPPED!
+//
+// Flow: 06/06/11 FN=setErrlSevToInfo
+//
+// End Function Specification
+void setErrlSevToInfo( errlHndl_t io_err )
+{
+ // check if handle is valid
+ // NOT empty
+ // not committed
+ if ( (io_err != NULL )
+ && ( io_err != INVALID_ERR_HNDL )
+ && (io_err->iv_userDetails.iv_committed == 0) )
+ {
+ //set sev to informational
+ io_err->iv_severity = ERRL_SEV_INFORMATIONAL;
+
+ //clear any callouts
+ uint32_t l_sizeOfcallouts = sizeof(ErrlCallout_t)*(io_err->iv_numCallouts);
+ memset(io_err->iv_callouts, 0,l_sizeOfcallouts );
+
+ //clear number of callouts
+ io_err->iv_numCallouts = 0;
+ }
+}
+
+
+// Function Specification
+//
+// Name: setErrlActions
+//
+// Description: Set Actions to an Error Log
+//
+// Flow: 05/14/13 FN=setErrlActions
+//
+// End Function Specification
+// @jh001a
+void setErrlActions(errlHndl_t io_err, const uint8_t i_mask)
+{
+ // check if handle is valid
+ // NOT empty
+ // not committed
+ if ( (io_err != NULL )
+ && ( io_err != INVALID_ERR_HNDL )
+ && (io_err->iv_userDetails.iv_committed == 0) )
+ {
+ // set the appropriate action bits$
+ io_err->iv_actions.word |= i_mask;
+ }
+}
+
+
+// Function Specification
+//
+// Name: hexDumpLog
+//
+// Description: Hex Dump Log
+//
+// Flow: FN=None
+//
+// End Function Specification
+void hexDumpLog( errlHndl_t i_log )
+{
+#if 0
+ // Locals
+ uint32_t l_written = 0;
+ uint32_t l_counter = 0;
+ uint8_t * l_data = (uint8_t*) i_log;
+ uint32_t l_len = i_log->iv_userDetails.iv_entrySize;
+
+ while ( l_counter < l_len)
+ {
+ if (( i_log == NULL ) ||
+ ( i_log == INVALID_ERR_HNDL ))
+ {
+ // break out if log is invalid
+ // do nothing
+ break;
+ }
+
+ printf("| %08X ", (uint32_t) l_data + l_counter);
+
+ // Display 16 bytes in Hex with 2 spaces in between
+ l_written = 0;
+ uint8_t i = 0;
+ for ( i = 0; i < 16 && l_counter < l_len; i++ )
+ {
+ l_written += printf("%02X",l_data[l_counter++]);
+
+ if ( ! ( l_counter % 4 ) )
+ {
+ l_written += printf(" ");
+ }
+ }
+
+ // Pad with spaces
+ uint8_t l_space[64] = {0};
+ memset( l_space, 0x00, sizeof( l_space ));
+ memset( l_space, ' ', 43-l_written);
+ printf("%s", l_space );
+
+ // Display ASCII
+ l_written = 0;
+ uint8_t l_char;
+ for ( ; i > 0 ; i-- )
+ {
+ l_char = l_data[ l_counter-i ];
+
+ if ( isprint( l_char ) &&
+ ( l_char != '&' ) &&
+ ( l_char != '<' ) &&
+ ( l_char != '>' )
+ )
+ {
+ l_written += printf("%c",l_char );
+ }
+ else
+ {
+ l_written += printf("." );
+ }
+ }
+
+ // Pad with spaces
+ uint8_t l_space2[64] = {0};
+ memset( l_space2, 0x00, sizeof( l_space2 ));
+ memset( l_space2, ' ', 19-l_written);
+ printf("%s|\n", l_space2 );
+ }
+#endif
+}
diff --git a/src/occ/errl/errl.h b/src/occ/errl/errl.h
new file mode 100755
index 0000000..830b614
--- /dev/null
+++ b/src/occ/errl/errl.h
@@ -0,0 +1,404 @@
+/******************************************************************************
+// @file errl.h
+// @brief OCC Errl Component header file
+*/
+/******************************************************************************
+ *
+ * @page ChangeLogs Change Logs
+ * @section _errl_h errl.h
+ * @verbatim
+ *
+ * Flag Def/Fea Userid Date Description
+ * ------- ---------- -------- ---------- ----------------------------------
+ * tapiar 06/15/2011 Created errl methods
+ * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+ * @pb00E pbavari 03/11/2012 Added correct include file
+ * @nh001 neilhsu 05/23/2012 Add missing error log tags
+ * @th022 thallet 10/08/2012 Add method to get errl logId
+ * @nh004 864941 neilhsu 12/20/2012 Support get/delete errl & added trace info
+ * @th032 thallet 04/26/2013 Tuleta HW Bringup
+ * @th036 881677 thallet 05/06/2013 Support for new poll command
+ * @jh001 881996 joshych 05/07/2013 Support SRAM error log format
+ * @jh002 883921 joshych 06/17/2013 Read OCC error log from SRAM
+ * @fk002 905632 fmkassem 11/05/2013 Remove CriticalPathMonitor code
+ * @gm028 911670 milesg 02/27/2014 Immediate safe mode on checkstop
+ *
+ * @endverbatim
+ *
+ *///*************************************************************************/
+
+#ifndef _ERRL_H
+#define _ERRL_H
+
+/** \defgroup OCC Errl Component
+ *
+ */
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+//@pb00Ec - changed from common.h to occ_common.h for ODE support
+#include <occ_common.h>
+#include <trac_interface.h>
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+// Used as default for invalid slot number
+static const uint8_t ERRL_INVALID_SLOT = 0xFF;
+
+// Used for shifting slot bits
+static const uint32_t ERRL_SLOT_SHIFT = 0x80000000;
+
+// Used for defaulting handle to invalid
+static const uint32_t INVALID_ERR = 0xFFFFFFFF;
+
+/* Sizes constants */
+// Max size of non call home data logs (2048 bytes)
+#define MAX_ERRL_ENTRY_SZ 0x800
+
+// Max size of call home data log (3072 bytes)
+#define MAX_ERRL_CALL_HOME_SZ 0xC00
+
+// Max size of callouts
+#define ERRL_MAX_CALLOUTS 6
+
+// Max number of error logs
+#define ERRL_MAX_SLOTS 9
+
+// Used to default a old/bad error handle
+#define INVALID_ERR_HNDL (errlHndl_t)INVALID_ERR
+
+// USED to determine the number of all trace buffer types. Now have (INF/IMP/ERR)
+#define NUM_OF_TRACE_TYPE 3
+
+// These bits are used to acquire a slot number. When used with the global
+// slot bit mask, we are able to get 7 slots for predictive/unrecoverable errors,
+// 1 slot for informational logs, and 1 slot for call home data log
+/* Slot Masks */
+typedef enum
+{
+ ERRL_SLOT_MASK_DEFAULT = 0xFFFFFFFF,
+ ERRL_SLOT_MASK_INFORMATIONAL = 0xFEFFFFFF,
+ ERRL_SLOT_MASK_PREDICTIVE = 0x01FFFFFF,
+ ERRL_SLOT_MASK_UNRECOVERABLE = 0x01FFFFFF,
+ ERRL_SLOT_MASK_CALL_HOME_DATA = 0xFF7FFFFF,
+} ERRL_SLOT_MASK;
+
+// These are the possible severities that an error log can have.
+// Users must ONLY use these enum values for severity.
+/* Error Severity */
+typedef enum
+{
+ ERRL_SEV_INFORMATIONAL = 0x00,
+ ERRL_SEV_PREDICTIVE = 0x01,
+ ERRL_SEV_UNRECOVERABLE = 0x02,
+ ERRL_SEV_CALLHOME_DATA = 0x03,
+} ERRL_SEVERITY;
+
+// These are the possible actions that an error log can have.
+// Users must ONLY use these enum values for actions.
+/* Error Actions */
+// @jh001a
+typedef enum
+{
+ ERRL_ACTIONS_CONSOLIDATE_ERRORS = 0x01, //ignored by tmgt at this time
+ ERRL_ACTIONS_MANUFACTURING_ERROR = 0x08, //tmgt will set severity to predictive while in mfg mode
+ ERRL_ACTIONS_SAFE_MODE_REQUIRED = 0x40, //immediate permanent safe mode without any recovery (checkstop)
+ ERRL_ACTIONS_RESET_REQUIRED = 0x80, //permanent safe mode after 3 recovery attempts
+} ERRL_ACTIONS_MASK;
+
+// These are the possible callout priorities that a callout can have.
+// Users must ONLY use these enum values for callout priority
+/* Callout Priority */
+typedef enum
+{
+ ERRL_CALLOUT_PRIORITY_INVALID = 0x00,
+ ERRL_CALLOUT_PRIORITY_LOW = 0x01,
+ ERRL_CALLOUT_PRIORITY_MED = 0x02,
+ ERRL_CALLOUT_PRIORITY_HIGH = 0x03,
+} ERRL_CALLOUT_PRIORITY;
+
+// These are the user detail types that a user details can have.
+// Users must ONLY use these enum values for user detail type
+/* User Detail Type */
+typedef enum
+{
+ ERRL_USR_DTL_TRACE_DATA = 0x01,
+ ERRL_USR_DTL_CALLHOME_DATA = 0x02,
+ ERRL_USR_DTL_BINARY_DATA = 0x03,
+} ERRL_USR_DETAIL_TYPE;
+
+// These are the possible OCC States.
+/* OCC States */
+typedef enum
+{
+ ERRL_OCC_STATE_INVALID = 0xFF,
+} ERRL_OCC_STATE;
+
+//Versions
+/* Errl Structure Version */
+typedef enum
+{
+ ERRL_STRUCT_VERSION_1 = 0x01,
+} ERRL_STRUCT_VERSION;
+
+/* Errl User Details Version */
+typedef enum
+{
+ ERRL_USR_DTL_STRUCT_VERSION_1 = 0x01,
+} ERRL_USR_DTL_STRUCT_VERSION;
+
+
+/* Errl Trace Version */
+typedef enum
+{
+ ERRL_TRACE_VERSION_1 = 0x00,
+} ERRL_TRACE_VERSION;
+
+/* Type of Callout */
+// @jh001a
+typedef enum
+{
+ ERRL_CALLOUT_TYPE_HUID = 0x01,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID = 0x02,
+} ERRL_CALLOUT_TYPE;
+
+/* TMGT-OCC Component Ids */
+// @jh001a
+typedef enum
+{
+ ERRL_COMPONENT_ID_FIRMWARE = 0x01,
+ ERRL_COMPONENT_ID_OVER_TEMPERATURE = 0x04,
+ ERRL_COMPONENT_ID_OVERSUBSCRIPTION = 0x05,
+ ERRL_COMPONENT_ID_NONE = 0xFF,
+} ERRL_COMPONENT_ID;
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+/* Callout Structure */
+// @jh001c $
+// TMGT_OCC_INTERFACE_v1_2_1
+struct ErrlCallout
+{
+ // Type of callout. NOTE: Users must use ERRL_CALLOUT_TYPE enum
+ uint8_t iv_type;
+ // Callout Value
+ uint64_t iv_calloutValue;
+ // Callout Priority. NOTE: Users must use ERRL_CALLOUT_PRIORITY enum
+ uint8_t iv_priority;
+ // Reserved 1
+ uint16_t iv_reserved1;
+} __attribute__ ((__packed__));
+
+typedef struct ErrlCallout ErrlCallout_t;
+
+// The User Detail Entry Structure consists of the fields below followed
+// by the actual data the user is trying to collect.
+// NOTE: A data pointer field is NOT defined but rather inferred here. In the
+// error log contents, the user will see all the subsequent fields followed
+// by the actual data
+/* User Detail Entry Structure */
+struct ErrlUserDetailsEntry
+{
+ uint8_t iv_version; // User Details Entry Version
+ uint8_t iv_type; // User Details Entry Type
+ // Note: Users must use ERRL_USR_DETAIL_TYPE enum
+ uint16_t iv_size; // User Details Entry Size
+} __attribute__ ((__packed__));
+
+typedef struct ErrlUserDetailsEntry ErrlUserDetailsEntry_t;
+
+// The User Detail Structure consists of the fields below followed
+// by each individual User Details Entry structure & data
+// NOTE: A data pointer field is NOT defined but rather inferred here. In the
+// error log contents, the user will see all the subsequent fields followed
+// by each User Details Entry structure and its data
+/* User Detail Structure */
+struct ErrlUserDetails
+{
+ uint8_t iv_version; // User Details Version
+ uint8_t iv_reserved; // Reserved
+ uint16_t iv_modId; // Module Id
+ uint32_t iv_fwLevel; // Firmware Level
+ uint64_t iv_timeStamp; // Time Stamp
+ uint8_t iv_occId; // OCC ID
+ uint8_t iv_occRole; // OCC Role
+ uint8_t iv_operatingState; // OCC State
+ uint8_t iv_committed:1; // Log Committed?
+ uint8_t iv_reserved1:7;
+ uint32_t iv_userData1; // User Data Word 1
+ uint32_t iv_userData2; // User Data Word 2
+ uint32_t iv_userData3; // User Data Word 3
+ uint16_t iv_entrySize; // Log Size
+ uint16_t iv_userDetailEntrySize; // User Details Size
+} __attribute__ ((__packed__));
+
+typedef struct ErrlUserDetails ErrlUserDetails_t;
+
+/* Error Log Structure */
+// @jh001c
+// TMGT_OCC_INTERFACE_v1_2_1
+struct ErrlEntry
+{
+ // Log CheckSum
+ uint16_t iv_checkSum;
+ // Log Version
+ uint8_t iv_version;
+ // Log Entry ID
+ uint8_t iv_entryId;
+ // Log Reason Code
+ uint8_t iv_reasonCode;
+ // Log Severity - NOTE: Users must use ERRL_SEVERITY enum
+ uint8_t iv_severity;
+ // Actions to process the errors
+ union
+ {
+ struct
+ {
+ uint8_t reset_required : 1; // Error is critical and requires OCC reset
+ uint8_t safe_mode_required : 1; // immediate permanent safe mode (used for checkstops)
+ uint8_t reserved5 : 1;
+ uint8_t reserved4 : 1;
+ uint8_t mfg_error : 1; // Fan go to max,oversubscription,core above warning,Throttled.
+ uint8_t reserved2 : 1;
+ uint8_t reserved1 : 1;
+ uint8_t consolidate_error : 1; // Look for same SRC from all OCCs
+ };
+ uint8_t word;
+ } iv_actions;
+ // Reserved for extended reason code for uniquely identifying error if needed // @nh001c
+ uint32_t iv_userData4;
+ // Log Callout Number
+ uint8_t iv_numCallouts;
+ // Callouts
+ ErrlCallout_t iv_callouts[ERRL_MAX_CALLOUTS];
+ // User Details section for Log
+ ErrlUserDetails_t iv_userDetails;
+
+} __attribute__ ((__packed__));
+
+typedef struct ErrlEntry ErrlEntry_t;
+
+/* Error Log Handle */
+typedef ErrlEntry_t* errlHndl_t;
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+extern uint32_t G_occErrSlotBits;
+extern uint8_t G_occErrIdCounter;
+
+extern errlHndl_t G_occErrSlots[ERRL_MAX_SLOTS];
+
+// Globals used by testcases
+extern uint8_t G_errslot1[MAX_ERRL_ENTRY_SZ];
+extern uint8_t G_errslot2[MAX_ERRL_ENTRY_SZ];
+extern uint8_t G_errslot3[MAX_ERRL_ENTRY_SZ];
+extern uint8_t G_errslot4[MAX_ERRL_ENTRY_SZ];
+extern uint8_t G_errslot5[MAX_ERRL_ENTRY_SZ];
+extern uint8_t G_errslot6[MAX_ERRL_ENTRY_SZ];
+extern uint8_t G_errslot7[MAX_ERRL_ENTRY_SZ];
+extern uint8_t G_infoslot[MAX_ERRL_ENTRY_SZ];
+extern uint8_t G_callslot[MAX_ERRL_CALL_HOME_SZ];
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+/* Create an Error Log */
+errlHndl_t createErrl(
+ const uint16_t i_modId,
+ const uint8_t i_reasonCode,
+ const uint32_t i_extReasonCode, // @nh001a
+ const ERRL_SEVERITY i_sev,
+ const tracDesc_t i_trace,
+ const uint16_t i_traceSz,
+ const uint32_t i_userData1,
+ const uint32_t i_userData2
+ );
+
+
+/* Add Trace Data to Error Log */
+void addTraceToErrl(
+ const tracDesc_t i_trace,
+ const uint16_t i_traceSz,
+ errlHndl_t io_errl
+ );
+
+/* Commit the Error Log */
+void commitErrl( errlHndl_t * io_err );
+
+/* Delete the Error Log */
+errlHndl_t deleteErrl( errlHndl_t * io_err);
+
+/* Add Callout to Error Log */
+// @jh001c
+void addCalloutToErrl(
+ errlHndl_t io_err,
+ const ERRL_CALLOUT_TYPE i_type,
+ const uint64_t i_calloutValue,
+ const ERRL_CALLOUT_PRIORITY i_priority);
+
+/* Add User Details Data to the Error Log */
+void addUsrDtlsToErrl(
+ errlHndl_t io_err,
+ uint8_t *i_dataPtr,
+ const uint16_t i_size,
+ const uint8_t i_version,
+ const ERRL_USR_DETAIL_TYPE i_type);
+
+/* Change Severity of Error Log to Informational */
+void setErrlSevToInfo( errlHndl_t io_err );
+
+/* Set Actions to an Errl */
+void setErrlActions(errlHndl_t io_err, const uint8_t i_mask);
+
+/* Return Error Log ID to report to TMGT */
+uint8_t getErrlLogId( errlHndl_t io_err );
+
+// @nh004a - start
+/* Get Error Slot Num By Error Id */
+uint8_t getErrSlotNumByErrId( uint8_t i_errlId);
+
+/* Get Error Slot OCI address */
+uint32_t getErrSlotOCIAddr(const uint8_t i_SlotNum);
+
+/* Get the oldest error log ID so that we can pass it to TMGT */
+uint8_t getOldestErrlID();
+
+/* Return Length of an Error Log based on ID, to send to TMGT */
+uint16_t getErrlLengthByID(const uint8_t i_id);
+
+/* Return Address of an Error Log based on ID, to send to TMGT */
+uint32_t getErrlOCIAddrByID(const uint8_t i_id);
+
+// @nh004a - end
+
+
+// NOTE: Not defining these in the .h since they are INTERNAL
+// methods!
+
+/* Report the Error Log */
+//void reportErrorLog( errlHndl_t i_err, uint16_t i_entrySize );
+
+/* Get Error Log Slot Number and Error Id */
+//uint8_t getErrSlotNumAndErrId(
+// ERRL_SEVERITY i_severity,
+// uint8_t *o_errlId,
+// uint64_t *o_timeStamp
+// );
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+#endif //_ERRL_H
diff --git a/src/occ/errl/test/Makefile b/src/occ/errl/test/Makefile
new file mode 100755
index 0000000..b450fc5
--- /dev/null
+++ b/src/occ/errl/test/Makefile
@@ -0,0 +1,55 @@
+# $Id$
+
+# @file Makefile
+#
+# @brief Makefile occ application
+#
+
+# @page ChangeLogs Change Logs
+# @section Makefile
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+# @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+#
+# @endverbatim
+#
+
+include test.mk
+
+APP = errltest
+APP_INCLUDES += -I../../../ssx
+APP_INCLUDES += -I../../../lib
+APP_INCLUDES += -I../../incl
+APP_INCLUDES += -I../../trac
+APP_INCLUDES += -I../../async
+APP_INCLUDES += -I../../errl
+APP_INCLUDES += -I../../gpe
+APP_INCLUDES += -I../../thread
+APP_INCLUDES += -I.
+
+
+
+
+#D = -DVERIFICATION=1 \
+ -DSSX_STACK_CHECK=0 \
+ -DINITIALIZE_PMC=0 \
+ -DINITIALIZE_SIMICS_IO=0 \
+ -DINITIALIZE_RTX_IO=1 \
+ -DINITIALIZE_PBA=1 \
+ -DSIMICS_MAGIC_PANIC=1 \
+ -DSSX_KERNEL_TRACE_ENABLE=1
+
+
+SOURCES = ${all_cfiles}
+MODE = validation
+
+PGP_ASYNC_SUPPORT = 1
+
+include ./app.mk
+
+pgas:
+ $(CC) $(CFLAGS) -c -Wa,-al -Wa,--listing-cont-lines='10'
diff --git a/src/occ/errl/test/app.mk b/src/occ/errl/test/app.mk
new file mode 100755
index 0000000..3f674bf
--- /dev/null
+++ b/src/occ/errl/test/app.mk
@@ -0,0 +1,99 @@
+# $Id$
+
+# @file app.mk
+#
+# @brief mk occ application
+#
+# This Makefile is included-ed into application Makefiles and
+# encapsulates the steps necessary to create application images.
+#
+# The application Makefile (user) must define the following variables:
+#
+# APP - The name of the application
+# SOURCES - The list of local source files that implement the
+# application.
+#
+# The application Makefile (user) may optionally define the following
+# variables:
+#
+# D - The value of $(D) is appended to DEFS defined by ssx.mk
+#
+# MODE - The following modes are recognized:
+#
+# validation - (Default) An application that requires all SSX
+# services.
+#
+# firmware - An interrupt only configuration.
+#
+# The make process creates the following files:
+#
+# $(APP).out - The PowerPC-ELF version of the application
+# $(APP).bin - A binary SRAM image of the application
+# $(APP).map - The linker map of the application
+
+# @page ChangeLogs Change Logs
+# @section app.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+#
+# @endverbatim
+#
+
+OCC = ../../
+SSX = ../../../ssx
+LIB = ../../../lib
+PGP = $(SSX)/pgp
+
+ifeq "$(MODE)" "firmware"
+SSX_TIMER_SUPPORT = 0
+SSX_THREAD_SUPPORT = 0
+endif
+
+export SSX_TIMER_SUPPORT
+export SSX_THREAD_SUPPORT
+export PPC405_MMU_SUPPORT
+export PGP_ASYNC_SUPPORT
+
+INCLUDES = -I $(OCC) -I$(LIB)
+
+include $(PGP)/ssx.mk
+
+C-OBJECTS = $(SOURCES:.c=.o)
+OBJECTS = $(C-OBJECTS:.S=.o)
+
+LDFLAGS = -L $(SSX)/ssx -L $(SSX)/ppc32 -L $(SSX)/ppc405 -L $(SSX)/pgp \
+ -L $(OCC) -L $(LIB) -lssx -lppc32
+
+DEFS += $(D)
+
+all: $(OBJECTS) libssx.a
+ $(MAKE) -C $(PGP) DEFS="$(DEFS)" -e
+ $(CPP) -P $(DEFS) < $(OCC)/linkocc.cmd > linkscript
+ $(LD) $(OBJECTS) \
+ -Tlinkscript $(LDFLAGS) -Map $(APP).map -Bstatic -o $(APP).out
+ $(OBJCOPY) -O binary $(APP).out $(APP).bin
+ $(OBJDUMP) -d $(APP).out > $(APP).dis
+
+libssx.a:
+ $(MAKE) -C $(LIB) DEFS="$(DEFS)" -e
+
+
+.PHONY : clean
+clean:
+ rm -f *.o *.d *.d.* *.out *.bin *.srec *.dis *.map linkscript
+ rm -f ./*/*.o ./*/*.d ./*/*.d.*
+
+.PHONY : clean_all
+clean_all:
+ $(MAKE) clean
+ $(MAKE) -C $(PGP) clean
+
+.PHONY : doc
+doc:
+ doxygen doc/Doxyfile
+
+include $(OBJECTS:.o=.d)
diff --git a/src/occ/errl/test/errltest.c b/src/occ/errl/test/errltest.c
new file mode 100755
index 0000000..b820fb7
--- /dev/null
+++ b/src/occ/errl/test/errltest.c
@@ -0,0 +1,786 @@
+/******************************************************************************
+// @file errltest.c
+// @brief OCC ERRL TEST
+*/
+/******************************************************************************
+ *
+ * @page ChangeLogs Change Logs
+ * @section errltest.c ERRLTEST.C
+ * @verbatim
+ *
+ * Flag Def/Fea Userid Date Description
+ * ------- ---------- -------- ---------- ----------------------------------
+ * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+ *
+ * @endverbatim
+ *
+ *///*************************************************************************/
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include "ssx.h"
+#include "ssx_io.h"
+#include "simics_stdio.h"
+#include <thread.h>
+#include <threadSch.h>
+#include <errl.h>
+#include <rand.h>
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+
+uint8_t noncritical_stack[NONCRITICAL_STACK_SIZE];
+uint8_t critical_stack[CRITICAL_STACK_SIZE];
+/*@}*/ // Ending tag for stack module in doxygen
+
+/// Period in which to run #timer_routine
+#define TIMER_INTERVAL (SsxInterval) SSX_MICROSECONDS(100)
+
+#define SevAsciiValue( _v_ ) \
+ ( ( _v_ == ERRL_SEV_INFORMATIONAL ) ? "Informational" : \
+ ( _v_ == ERRL_SEV_PREDICTIVE ) ? "Predictive" : \
+ ( _v_ == ERRL_SEV_UNRECOVERABLE ) ? "Unrecovrable" : \
+ ( _v_ == ERRL_SEV_CALLHOME_DATA ) ? "Call Home" : \
+ "Unknown" )
+
+/*----------------------------------------------------------------------------*/
+/* SsxTimer and SsxThread Declarations and Priorities */
+/*----------------------------------------------------------------------------*/
+/** \defgroup TimersAndThreads Timer and Thread Information */ /*@{*/
+
+/// Our timer based on TIMER_INTERVAL that kicks off most of the work. See #timer_routine
+SsxTimer timer;
+
+/// Our idle thread. See #main_thread_routine
+SsxThread main_thread;
+
+/// \todo Goes away due to Bishop's device driver layer
+SsxThread prcd_thread;
+
+/*@}*/ // Ending tag for TimersAndThreads module in doxygen
+
+
+
+
+/*----------------------------------------------------------------------------*/
+/* SsxSemaphore Declarations */
+/*----------------------------------------------------------------------------*/
+SsxSemaphore prcd_sem;
+
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+
+int g_j = 0;
+int g_k = 0;
+
+SimicsStdio simics_stdout;
+SimicsStdio simics_stderr;
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+extern void timer_routine(void *private);
+extern void rtloop_ocb_init(void);
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+// Function Specification
+//
+// Name: pgp_validation_ssx_main_hook
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void pgp_validation_ssx_main_hook(void)
+{
+
+}
+
+// Function Specification
+//
+// Name: Cmd_Hndl_thread_routine
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+//TODO placeholder
+void Cmd_Hndl_thread_routine(void *arg)
+{
+}
+
+// Function Specification
+//
+// Name: App_thread_routine
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void App_thread_routine(void *arg)
+{
+}
+
+// Function Specification
+//
+// Name: Thermal_Monitor_thread_routine
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void Thermal_Monitor_thread_routine(void *arg)
+{
+}
+
+// Function Specification
+//
+// Name: Hlth_Monitor_thread_routine
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void Hlth_Monitor_thread_routine(void *arg)
+{
+}
+
+// Function Specification
+//
+// Name: FFDC_thread_routine
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void FFDC_thread_routine(void *arg)
+{
+}
+
+
+// Function Specification
+//
+// Name: prcd_thread_routine
+//
+// Description: This thread loops as the highest priority thread, where it currently just
+//
+// Flow: FN=None
+//
+// End Function Specification
+void prcd_thread_routine(void *private)
+{
+ while(1)
+ {
+ // Just sit here until this semaphore is posted, which will never happen.
+ ssx_semaphore_pend(&prcd_sem, SSX_WAIT_FOREVER);
+
+ // Only trace the first XX times that this function loops
+ if(g_j < 20)
+ {
+ g_k = 0;
+ g_j++;
+
+ }
+ }
+}
+
+// Function Specification
+//
+// Name: dumpLog
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void dumpLog( errlHndl_t i_log, uint32_t i_len )
+{
+ uint32_t l_written = 0;
+ uint32_t l_counter = 0;
+ uint8_t * l_data = (uint8_t*) i_log;
+
+ printf("----------%p---------- \n", i_log );
+
+ if ( i_log == NULL )
+ return;
+
+ while ( l_counter < i_len)
+ {
+ printf("| %08X ", (uint32_t) l_data + l_counter);
+
+ // Display 16 bytes in Hex with 2 spaces in between
+ l_written = 0;
+ uint8_t i = 0;
+ for ( i = 0; i < 16 && l_counter < i_len; i++ )
+ {
+ l_written += printf("%02X",l_data[l_counter++]);
+
+ if ( ! ( l_counter % 4 ) )
+ {
+ l_written += printf(" ");
+ }
+ }
+
+ // Pad with spaces
+ uint8_t l_space[64] = {0};
+ memset( l_space, 0x00, sizeof( l_space ));
+ memset( l_space, ' ', 43-l_written);
+ printf("%s", l_space );
+
+ // Display ASCII
+ l_written = 0;
+ uint8_t l_char;
+ for ( ; i > 0 ; i-- )
+ {
+ l_char = l_data[ l_counter-i ];
+
+ if ( isprint( l_char ) &&
+ ( l_char != '&' ) &&
+ ( l_char != '<' ) &&
+ ( l_char != '>' )
+ )
+ {
+ l_written += printf("%c",l_char );
+ }
+ else
+ {
+ l_written += printf("." );
+ }
+ }
+
+ // Pad with spaces
+ uint8_t l_space2[64] = {0};
+ memset( l_space2, 0x00, sizeof( l_space2 ));
+ memset( l_space2, ' ', 19-l_written);
+ printf("%s\n", l_space2 );
+ }
+ printf("----------%p---------- \n", i_log );
+
+}
+
+// Function Specification
+//
+// Name: ppdumpslot
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void ppdumpslot(void)
+{
+ errlHndl_t l_array[ERRL_MAX_SLOTS] = {
+ (errlHndl_t)G_errslot1,
+ (errlHndl_t)G_errslot2,
+ (errlHndl_t)G_errslot3,
+ (errlHndl_t)G_errslot4,
+ (errlHndl_t)G_errslot5,
+ (errlHndl_t)G_errslot6,
+ (errlHndl_t)G_errslot7,
+ (errlHndl_t)G_infoslot,
+ (errlHndl_t)G_callslot,
+ };
+
+
+ printf("-------- \n");
+
+ uint8_t l_index = 0;
+ for(l_index =0; l_index < ERRL_MAX_SLOTS; l_index++)
+ {
+ if(l_array[l_index]->iv_version !=0)
+ {
+ printf("slot[%01d] sz[%04d] id[%03d] @[%p] \n",l_index,l_array[l_index]->iv_userDetails.iv_entrySize, l_array[l_index]->iv_entryId, l_array[l_index]);
+ }
+ else
+ {
+ printf("slot[%01d] [0] \n",l_index);
+ }
+ }
+ printf("-------- \n");
+}
+
+
+// Function Specification
+//
+// Name: testsizelimit
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void testsizelimit(const tracDesc_t i_trace)
+{
+ printf("%s: START \n", __FUNCTION__ );
+ errlHndl_t l_handle = NULL;
+ errlHndl_t l_handle2 = NULL;
+ errlHndl_t l_handle3 = NULL;
+
+ l_handle = createErrl( 0x1616, 0x08, ERRL_SEV_PREDICTIVE, i_trace, 512, 0x1, 0x2);
+ l_handle2 = createErrl( 0x1616, 0x08, ERRL_SEV_CALLHOME_DATA, i_trace, 512, 0x1, 0x2);
+ l_handle3 = createErrl( 0x1616, 0x08, ERRL_SEV_INFORMATIONAL, i_trace, 512, 0x1, 0x2);
+ errlHndl_t l_handleX = l_handle;
+ errlHndl_t l_handle2X = l_handle2;
+ errlHndl_t l_handle3X = l_handle3;
+ printf("%s: Slots after Create - 3 slots should be used (one of each)\n", __FUNCTION__ );
+ ppdumpslot();
+
+ uint8_t l_data[ MAX_ERRL_CALL_HOME_SZ * 2 ];
+
+ memset( l_data, 0xCC, sizeof( l_data ) );
+
+ addUsrDtlsToErrl( l_handle, l_data, sizeof( l_data ), ERRL_USR_DTL_STRUCT_VERSION_1, ERRL_USR_DTL_TRACE_DATA );
+
+ memset( l_data, 0xEE, sizeof( l_data ) );
+
+ addUsrDtlsToErrl( l_handle2, l_data, sizeof( l_data ), ERRL_USR_DTL_STRUCT_VERSION_1, ERRL_USR_DTL_CALLHOME_DATA );
+
+ memset( l_data, 0xDD, sizeof( l_data ) );
+
+ addUsrDtlsToErrl( l_handle3, l_data, 76, ERRL_USR_DTL_STRUCT_VERSION_1, ERRL_USR_DTL_TRACE_DATA );
+
+ dumpLog( l_handle, l_handle->iv_userDetails.iv_entrySize );
+ dumpLog( l_handle2, l_handle2->iv_userDetails.iv_entrySize );
+ dumpLog( l_handle3, l_handle3->iv_userDetails.iv_entrySize );
+
+ commitErrl( &l_handle );
+ commitErrl( &l_handle2 );
+ commitErrl( &l_handle3 );
+ printf("%s: Slots after Commit - 3 slots should be used/committed \n", __FUNCTION__ );
+ ppdumpslot();
+
+ deleteErrl(&l_handleX);
+ deleteErrl(&l_handle2X);
+ deleteErrl(&l_handle3X);
+ printf("%s: Slots after delete Log - All slots should be empty\n", __FUNCTION__ );
+ ppdumpslot();
+ printf("%s: END \n", __FUNCTION__ );
+}
+
+// Function Specification
+//
+// Name: testdtlsizelimit
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void testdtlsizelimit(const tracDesc_t i_trace)
+{
+ printf("%s: START \n", __FUNCTION__ );
+ errlHndl_t l_handle = NULL;
+
+ l_handle = createErrl( 0x1616, 0x08, ERRL_SEV_PREDICTIVE, i_trace, 512, 0x1, 0x2);
+ errlHndl_t l_handleX = l_handle;
+ ppdumpslot();
+
+ uint8_t l_data[ MAX_ERRL_CALL_HOME_SZ * 2 ];
+
+ memset( l_data, 0xAA, sizeof( l_data ) );
+ addUsrDtlsToErrl( l_handle, l_data, 256, ERRL_USR_DTL_STRUCT_VERSION_1, ERRL_USR_DTL_TRACE_DATA );
+ //dumpLog( l_handle, l_handle->iv_userDetails.iv_entrySize );
+ printf("%s: Slots after create + 256 bytes \n", __FUNCTION__ );
+ ppdumpslot();
+
+ memset( l_data, 0xBB, sizeof( l_data ) );
+ addUsrDtlsToErrl( l_handle, l_data, 512, ERRL_USR_DTL_STRUCT_VERSION_1, ERRL_USR_DTL_TRACE_DATA );
+ //dumpLog( l_handle, l_handle->iv_userDetails.iv_entrySize );
+ printf("%s: Slots after create + 256 + 512 bytes \n", __FUNCTION__ );
+ ppdumpslot();
+
+ memset( l_data, 0xCC, sizeof( l_data ) );
+ addUsrDtlsToErrl( l_handle, l_data, 1024, ERRL_USR_DTL_STRUCT_VERSION_1, ERRL_USR_DTL_TRACE_DATA );
+ //dumpLog( l_handle, l_handle->iv_userDetails.iv_entrySize );
+ printf("%s: Slots after create + 256 + 512 +1024 bytes \n", __FUNCTION__ );
+ ppdumpslot();
+
+ memset( l_data, 0xDD, sizeof( l_data ) );
+ addUsrDtlsToErrl( l_handle, l_data, 2048, ERRL_USR_DTL_STRUCT_VERSION_1, ERRL_USR_DTL_TRACE_DATA );
+ printf("%s: Slots after create 2k should be full with DD having only 72 bytes \n", __FUNCTION__ );
+ dumpLog( l_handle, l_handle->iv_userDetails.iv_entrySize );
+ ppdumpslot();
+
+
+ commitErrl( &l_handle );
+ deleteErrl(&l_handleX);
+ printf("%s: Slots should now be empty \n", __FUNCTION__ );
+ ppdumpslot();
+ printf("%s: END \n", __FUNCTION__ );
+}
+
+// Function Specification
+//
+// Name: timetest
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void timetest(const tracDesc_t i_trace)
+{
+ printf("%s: START \n", __FUNCTION__ );
+ errlHndl_t l_handle = NULL;
+ uint64_t l_start = 0;
+ uint64_t l_end = 0;
+
+ l_start = ssx_timebase_get();
+ l_handle = createErrl( 0x1716, 0x08, ERRL_SEV_CALLHOME_DATA, i_trace, 128, 0x1, 0x2);
+ errlHndl_t l_handle2 = l_handle;
+ commitErrl( &l_handle );
+ l_end = ssx_timebase_get();
+ printf("%s: Time to create/delete secs[%d] \n",__FUNCTION__, (int)SSX_MICROSECONDS(l_end-l_start));
+
+ deleteErrl(&l_handle2);
+ printf("%s: END \n", __FUNCTION__ );
+}
+
+// Function Specification
+//
+// Name: createcommitdeletelog
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void createcommitdeletelog(const tracDesc_t i_trace)
+{
+ printf("%s: START \n", __FUNCTION__ );
+ errlHndl_t l_handle = NULL;
+ l_handle = createErrl( 0x1616, 0x08, ERRL_SEV_CALLHOME_DATA, i_trace, 512, 0x1, 0x2);
+ printf("%s: Slots after Creating call home log \n", __FUNCTION__ );
+ ppdumpslot();
+
+
+ errlHndl_t l_handle2 = l_handle;
+ commitErrl( &l_handle );
+ printf("%s: Slots after Commiting call home log \n ", __FUNCTION__ );
+ dumpLog( l_handle2, l_handle2->iv_userDetails.iv_entrySize );
+ ppdumpslot();
+
+ deleteErrl(&l_handle2);
+ printf("%s: Slots after delete Log \n", __FUNCTION__ );
+ ppdumpslot();
+
+ printf("%s: END \n", __FUNCTION__ );
+}
+
+
+// Function Specification
+//
+// Name: create2infologtest
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void create2infologtest(const tracDesc_t i_trace)
+{
+ printf("%s: START \n", __FUNCTION__ );
+ printf("--------------------------------\n");
+ errlHndl_t l_handle = NULL;
+ errlHndl_t l_handle2= NULL;
+ l_handle = createErrl( 0x1616, 0x08, ERRL_SEV_INFORMATIONAL,i_trace, 5, 0x1, 0x2);
+
+ l_handle2 = createErrl( 0x2727, 0x19, ERRL_SEV_INFORMATIONAL, i_trace, 6, 0x2, 0x3);
+
+ if( l_handle2 == INVALID_ERR_HNDL )
+ {
+ printf("%s: Creating 2 info logs PASSED, only 1 was created @ %p \n", __FUNCTION__, l_handle );
+ ppdumpslot();
+ }
+ else
+ {
+ printf("%s: Creating 2 info logs FAILED, only 1 info log should be created! %p \n", __FUNCTION__, l_handle2 );
+ dumpLog( l_handle, l_handle->iv_userDetails.iv_entrySize );
+ dumpLog( l_handle2, l_handle2->iv_userDetails.iv_entrySize );
+ ppdumpslot();
+ }
+
+ deleteErrl(&l_handle);
+
+ printf("%s: END \n", __FUNCTION__ );
+}
+
+// Function Specification
+//
+// Name: createMaxLogs
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void createMaxLogs(const tracDesc_t i_trace)
+{
+ ERRL_SEVERITY l_sevs[4] =
+ {
+ ERRL_SEV_UNRECOVERABLE,
+ ERRL_SEV_PREDICTIVE,
+ ERRL_SEV_CALLHOME_DATA,
+ ERRL_SEV_INFORMATIONAL
+ };
+
+ uint8_t l_chars[6] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
+
+
+ printf("%s: START \n", __FUNCTION__ );
+ errlHndl_t l_handle = NULL;
+ printf("--------------------------------\n");
+
+
+ uint32_t l_index = 0;
+ for(l_index =0; l_index < ERRL_MAX_SLOTS; l_index++)
+ {
+ uint32_t l_sev = (uint32_t)rand32(4);
+ uint32_t l_trace = (uint32_t)rand32( 512 );
+ l_handle = createErrl( 0x1616, 0x08, l_sevs[ l_sev ], i_trace, l_trace, 0x1, 0x2);
+
+ if( ( l_handle != INVALID_ERR_HNDL) &&
+ ( l_handle != NULL ) )
+ {
+ printf("Log Created @ %p with Sev[%s]\n",l_handle, SevAsciiValue( l_sevs[ l_sev ]) );
+
+ uint8_t l_ud = (uint8_t) rand32(2);
+ if ( l_ud )
+ {
+ uint8_t l_data[ (uint32_t) rand32( 512 ) ];
+
+ memset( l_data, l_chars[(uint8_t) rand32(6)], sizeof( l_data ) );
+ addUsrDtlsToErrl( l_handle, l_data, sizeof(l_data), ERRL_USR_DTL_STRUCT_VERSION_1, ERRL_USR_DTL_TRACE_DATA );
+ }
+
+ commitErrl( &l_handle );
+ }
+ else
+ {
+ printf("Could not create error log with Sev[%s]\n",SevAsciiValue( l_sevs[ l_sev ]) );
+
+ uint8_t l_purge = (uint8_t) rand32(2);
+
+ if ( l_purge )
+ {
+ uint32_t l_slots = (uint32_t)rand32(ERRL_MAX_SLOTS);
+
+ if ((G_occErrSlots[l_slots] != INVALID_ERR_HNDL) &&
+ (G_occErrSlots[l_slots] != NULL ))
+ {
+ printf("Deleting log with id[%d] @ %p (slot %d)\n", G_occErrSlots[l_slots]->iv_entryId, G_occErrSlots[l_slots], l_slots );
+ errlHndl_t l_handle = G_occErrSlots[l_slots];
+ deleteErrl( &l_handle );
+ }
+ }
+
+ }
+
+ uint8_t l_dumpfile = (uint8_t) rand32(2);
+
+ if ( l_dumpfile )
+ {
+ uint32_t l_slots = (uint32_t)rand32(ERRL_MAX_SLOTS);
+
+ if ((G_occErrSlots[l_slots] != INVALID_ERR_HNDL) &&
+ (G_occErrSlots[l_slots] != NULL ))
+ {
+ errlHndl_t l_handle = G_occErrSlots[l_slots];
+ dumpLog( l_handle, l_handle->iv_userDetails.iv_entrySize );
+ }
+ }
+
+ ppdumpslot();
+ }
+
+ printf("%s: END \n", __FUNCTION__ );
+}
+
+
+// Function Specification
+//
+// Name: testcallouts
+//
+// Description:
+//
+// Flow: FN=None
+//
+// End Function Specification
+void testcallouts(const tracDesc_t i_trace)
+{
+ printf("%s: START \n", __FUNCTION__ );
+ errlHndl_t l_handle = NULL;
+ printf("--------------------------------\n");
+
+ l_handle = createErrl( 0x1616, 0x08,ERRL_SEV_PREDICTIVE,i_trace, 5, 0x1, 0x2);
+ errlHndl_t l_log = l_handle;
+
+ if(l_handle != INVALID_ERR_HNDL)
+ {
+// printf("Commiting log @p %p\n",l_handle);
+ ERRL_CALLOUT_PRIORITY l_array[8] = {
+ ERRL_CALLOUT_PRIORITY_HIGH,
+ ERRL_CALLOUT_PRIORITY_MED,
+ ERRL_CALLOUT_PRIORITY_LOW,
+ ERRL_CALLOUT_PRIORITY_HIGH,
+ ERRL_CALLOUT_PRIORITY_MED,
+ ERRL_CALLOUT_PRIORITY_MED,
+ ERRL_CALLOUT_PRIORITY_LOW,
+ ERRL_CALLOUT_PRIORITY_LOW,
+ };
+ uint8_t l_index = 0;
+ for(l_index =0; l_index < 8; l_index++)
+ {
+ printf("%s: current callouts %d attempting to add callout # %d with priority %d\n", __FUNCTION__, l_handle->iv_numCallouts, l_index, l_array[l_index] );
+ addCalloutToErrl(l_handle,l_index,l_array[l_index]);
+ }
+
+ dumpLog( l_handle, l_handle->iv_userDetails.iv_entrySize );
+
+ commitErrl( &l_handle );
+ }
+ else
+ {
+ printf("could not create error log with [%s]\n",SevAsciiValue(ERRL_SEV_CALLHOME_DATA));
+ }
+
+ ppdumpslot();
+
+ deleteErrl( &l_log );
+
+ printf("%s: END \n", __FUNCTION__ );
+}
+
+// Function Specification
+//
+// Name: main_thread_routine
+//
+// Description: This thread currently just loops as the lowest priority thread, handling
+// the lowest priority tasks.
+//
+// Flow: FN=None
+//
+// End Function Specification
+void main_thread_routine(void *private)
+{
+ // Start the critical 250uS timer
+ ssx_timer_schedule(&timer, 1, TIMER_INTERVAL);
+
+ while(1)
+ {
+ // Only trace the first XX times that this function loops
+ if(g_k < 3)
+ {
+ g_k++;
+
+ }
+
+ // Sleep for 1000 before we run the loop again
+ ssx_sleep_absolute(1000);
+ }
+}
+
+
+// Function Specification
+//
+// Name: main
+//
+// Description: main() currently initalizes our trace buffer along with creating threads
+// and timers for execution. Note that once main runs ssx_start_threads, we
+// never return as the SSX kernel takes over.
+//
+// Flow: FN=None
+//
+// End Function Specification
+int main(int argc, char **argv)
+{
+
+ // Initialize stdout so we can do printf from within simics env
+ simics_stdout_create(&simics_stdout);
+ simics_stderr_create(&simics_stderr);
+ stdout = (FILE *)(&simics_stdout);
+ stderr = (FILE *)(&simics_stderr);
+
+ // Initialize SSX Stacks (note that this also reinitializes the time base to 0)
+ ssx_initialize((SsxAddress)noncritical_stack, NONCRITICAL_STACK_SIZE,
+ (SsxAddress)critical_stack, CRITICAL_STACK_SIZE,
+ 0);
+
+ // TRACE: Trace buffers initialized
+ tracDesc_t g_trac_main = NULL;
+
+ timetest(g_trac_main);
+
+ //createcommitdeletelog(g_trac_main);
+
+ //testsizelimit( g_trac_main );
+
+ //testdtlsizelimit( g_trac_main );
+
+ //create2infologtest(g_trac_main);
+
+ //createMaxLogs(g_trac_main);
+
+ //testcallouts(g_trac_main);
+
+
+ // Create Timers
+ //ssx_timer_create(&timer, timer_routine, 0);
+
+ // Create Global Semaphores
+ ssx_semaphore_create(&prcd_sem, 0, 13);
+
+ // Create Threads
+ ssx_thread_create(&main_thread,
+ main_thread_routine,
+ (void *)0,
+ (SsxAddress)main_thread_stack,
+ THREAD_STACK_SIZE,
+ 1);
+
+ // Create Threads
+ ssx_thread_create(&prcd_thread,
+ prcd_thread_routine,
+ (void *)0,
+ (SsxAddress)prcd_thread_stack,
+ THREAD_STACK_SIZE,
+ 0);
+
+ // Make Threads runnable
+ ssx_thread_resume(&main_thread);
+ ssx_thread_resume(&prcd_thread);
+
+ // Initialize Realtime Loop Timer Interrupt
+ //rtloop_ocb_init();
+
+ // Enter SSX Kernel
+ ssx_start_threads();
+
+ return 0;
+}
+
diff --git a/src/occ/errl/test/gpefiles.mk b/src/occ/errl/test/gpefiles.mk
new file mode 100755
index 0000000..ee9dbec
--- /dev/null
+++ b/src/occ/errl/test/gpefiles.mk
@@ -0,0 +1,24 @@
+# $Id$
+
+# @file gpefiles.mk
+#
+# @brief mk occ application
+#
+
+# @page ChangeLogs Change Logs
+# @section gpefiles.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+# @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+#
+# @endverbatim
+#
+
+occ_GPEFILES = ../../gpe/pore_test.S
+
+all_gpefiles = ${occ_GPEFILES}
+
diff --git a/src/occ/errl/test/parser.c b/src/occ/errl/test/parser.c
new file mode 100755
index 0000000..ee5c805
--- /dev/null
+++ b/src/occ/errl/test/parser.c
@@ -0,0 +1,292 @@
+/******************************************************************************
+// @file parser.c
+// @brief OCC ERRL TEST
+*/
+/******************************************************************************
+ *
+ * @page ChangeLogs Change Logs
+ * @section parser.c PARSER.C
+ * @verbatim
+ *
+ * Flag Def/Fea Userid Date Description
+ * ------- ---------- -------- ---------- ----------------------------------
+ * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+ *
+ * @endverbatim
+ *
+ *///*************************************************************************/
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+typedef uint32_t UINT32;
+typedef int32_t INT32;
+typedef uint8_t UCHAR;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef char CHAR;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+typedef int INT;
+typedef void VOID;
+typedef uint32_t size_t ;
+
+
+// Max size of non call home data logs (2048 bytes)
+#define MAX_ERRL_ENTRY_SZ 0x800
+
+// Max size of call home data log (3072 bytes)
+#define MAX_ERRL_CALL_HOME_SZ 0xC00
+
+// Max size of callouts
+#define ERRL_MAX_CALLOUTS 6
+
+// Max number of error logs
+#define ERRL_MAX_SLOTS 9
+
+// Used to default a old/bad error handle
+#define INVALID_ERR_HNDL (errlHndl_t)INVALID_ERR
+
+// These bits are used to acquire a slot number. When used with the global
+// slot bit mask, we are able to get 7 slots for predictive/unrecoverable errors,
+// 1 slot for informational logs, and 1 slot for call home data log
+/* Slot Masks */
+typedef enum
+{
+ ERRL_SLOT_MASK_DEFAULT = 0xFFFFFFFF,
+ ERRL_SLOT_MASK_INFORMATIONAL = 0xFEFFFFFF,
+ ERRL_SLOT_MASK_PREDICTIVE = 0x01FFFFFF,
+ ERRL_SLOT_MASK_UNRECOVERABLE = 0x01FFFFFF,
+ ERRL_SLOT_MASK_CALL_HOME_DATA = 0xFF7FFFFF,
+} ERRL_SLOT_MASK;
+
+// These are the possible severities that an error log can have.
+// Users must ONLY use these enum values for severity.
+/* Error Severity */
+typedef enum
+{
+ ERRL_SEV_INFORMATIONAL = 0x00,
+ ERRL_SEV_PREDICTIVE = 0x01,
+ ERRL_SEV_UNRECOVERABLE = 0x02,
+ ERRL_SEV_CALLHOME_DATA = 0x03,
+} ERRL_SEVERITY;
+
+// These are the possible callout priorities that a callout can have.
+// Users must ONLY use these enum values for callout priority
+/* Callout Priority */
+typedef enum
+{
+ ERRL_CALLOUT_PRIORITY_INVALID = 0x00,
+ ERRL_CALLOUT_PRIORITY_LOW = 0x01,
+ ERRL_CALLOUT_PRIORITY_MED = 0x02,
+ ERRL_CALLOUT_PRIORITY_HIGH = 0x03,
+} ERRL_CALLOUT_PRIORITY;
+
+// These are the user detail types that a user details can have.
+// Users must ONLY use these enum values for user detail type
+/* User Detail Type */
+typedef enum
+{
+ ERRL_USR_DTL_TRACE_DATA = 0x01,
+ ERRL_USR_DTL_CALLHOME_DATA = 0x02,
+} ERRL_USR_DETAIL_TYPE;
+
+// These are the possible OCC States.
+/* OCC States */
+typedef enum
+{
+ ERRL_OCC_STATE_INVALID = 0xFF,
+} ERRL_OCC_STATE;
+
+//Versions
+/* Errl Structure Version */
+typedef enum
+{
+ ERRL_STRUCT_VERSION_1 = 0x01,
+} ERRL_STRUCT_VERSION;
+
+/* Errl User Details Version */
+typedef enum
+{
+ ERRL_USR_DTL_STRUCT_VERSION_1 = 0x01,
+} ERRL_USR_DTL_STRUCT_VERSION;
+
+
+/* Errl Trace Version */
+typedef enum
+{
+ ERRL_TRACE_VERSION_1 = 0x00,
+} ERRL_TRACE_VERSION;
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+
+/* Callout Structure */
+struct ErrlCallout
+{
+ uint64_t iv_homUnitId; // HOM Unit ID
+ uint8_t iv_priority; // Callout Priority
+ // NOTE: Users must use ERRL_CALLOUT_PRIORITY enum
+ uint8_t iv_reserved1; // Reserved 1
+ uint16_t iv_reserved2; // Reserved 2
+
+} __attribute__ ((__packed__));
+
+typedef struct ErrlCallout ErrlCallout_t;
+
+// The User Detail Entry Structure consists of the fields below followed
+// by the actual data the user is trying to collect.
+// NOTE: A data pointer field is NOT defined but rather inferred here. In the
+// error log contents, the user will see all the subsequent fields followed
+// by the actual data
+/* User Detail Entry Structure */
+struct ErrlUserDetailsEntry
+{
+ uint8_t iv_version; // User Details Entry Version
+ uint8_t iv_type; // User Details Entry Type
+ // Note: Users must use ERRL_USR_DETAIL_TYPE enum
+ uint16_t iv_size; // User Details Entry Size
+} __attribute__ ((__packed__));
+
+typedef struct ErrlUserDetailsEntry ErrlUserDetailsEntry_t;
+
+// The User Detail Structure consists of the fields below followed
+// by each individual User Details Entry structure & data
+// NOTE: A data pointer field is NOT defined but rather inferred here. In the
+// error log contents, the user will see all the subsequent fields followed
+// by each User Details Entry structure and its data
+/* User Detail Structure */
+struct ErrlUserDetails
+{
+ uint8_t iv_version; // User Details Version
+ uint8_t iv_reserved; // Reserved
+ uint16_t iv_modId; // Module Id
+ uint32_t iv_fwLevel; // Firmware Level
+ uint64_t iv_timeStamp; // Time Stamp
+ uint8_t iv_occId; // OCC ID
+ uint8_t iv_occRole; // OCC Role
+ uint8_t iv_operatingState; // OCC State
+ uint8_t iv_committed:1; // Log Committed?
+ uint8_t iv_reserved1:7;
+ uint32_t iv_userData1; // User Data Word 1
+ uint32_t iv_userData2; // User Data Word 2
+ uint32_t iv_userData3; // User Data Word 3
+ uint32_t iv_userData4; // User Data Word 4
+ uint16_t iv_entrySize; // Log Size
+ uint16_t iv_userDetailEntrySize; // User Details Size
+} __attribute__ ((__packed__));
+
+typedef struct ErrlUserDetails ErrlUserDetails_t;
+
+/* Error Log Structure */
+struct ErrlEntry
+{
+ uint16_t iv_checkSum; // Log CheckSum
+ uint8_t iv_version; // Log Version
+ uint8_t iv_entryId; // Log Entry ID
+ uint8_t iv_reasonCode; // Log Reason Code
+ uint8_t iv_severity; // Log Severity
+ // NOTE: Users must use ERRL_SEVERITY enum
+ uint8_t iv_reserved1; // Reserved
+
+ uint8_t iv_numCallouts; // Log Callout Number
+ ErrlCallout_t iv_callouts[ERRL_MAX_CALLOUTS];
+ ErrlUserDetails_t iv_userDetails; // User Details section for Log
+
+} __attribute__ ((__packed__));
+
+typedef struct ErrlEntry ErrlEntry_t;
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+// Function Specification
+//
+// Name: main
+//
+// Description: main function
+//
+// Flow: FN=None
+//
+// End Function Specification
+main()
+{
+ FILE * l_fptr = fopen( "occ.log.bin", "r");
+ uint32_t l_sizeRead = 0;
+ uint32_t l_readBuf[3072] = {0};
+
+ if ( l_fptr )
+ {
+ fseek( l_fptr, 0, SEEK_END);
+ uint32_t l_len = ftell( l_fptr );
+ fseek( l_fptr, 0, SEEK_SET);
+
+ l_sizeRead = fread( l_readBuf, 1, l_len, l_fptr );
+
+ printf("File read contains %d bytes read %d \n", l_len, l_sizeRead );
+ }
+
+ fclose( l_fptr );
+
+ ErrlEntry_t l_log;
+
+ memcpy( &l_log, l_readBuf, l_sizeRead );
+
+ printf(" CheckSum : 0x%04X \n", ntohs(l_log.iv_checkSum) );
+ printf(" Version : 0x%02X \n", l_log.iv_version);
+ printf(" Entry Id : 0x%02X \n", l_log.iv_entryId);
+ printf(" Reason Code: 0x%02X \n", l_log.iv_reasonCode);
+ printf(" Severity : 0x%02X \n", l_log.iv_severity);
+ printf(" Callouts : 0x%02X \n", l_log.iv_numCallouts);
+ uint8_t l_index=0;
+ for( l_index=0; l_index < ERRL_MAX_CALLOUTS; l_index++)
+ {
+ printf(" Callout%d : \n", l_index+1);
+ printf(" HOM UID : 0x%08X \n", ntohl(l_log.iv_callouts[l_index].iv_homUnitId));
+ printf(" Priority : 0x%02X \n", l_log.iv_callouts[l_index].iv_priority );
+ }
+ printf(" UserDetails : \n" );
+ printf(" Version : 0x%02X \n", l_log.iv_userDetails.iv_version );
+ printf(" Module Id : 0x%04X \n", ntohs(l_log.iv_userDetails.iv_modId) );
+ printf(" Firmware Level : 0x%08X \n", l_log.iv_userDetails.iv_fwLevel );
+ printf(" Time : 0x%08X \n", l_log.iv_userDetails.iv_timeStamp );
+ printf(" OCC ID : 0x%02X \n", l_log.iv_userDetails.iv_occId );
+ printf(" OCC Role : 0x%02X \n", l_log.iv_userDetails.iv_occRole );
+ printf(" OCC State : 0x%02X \n", l_log.iv_userDetails.iv_operatingState );
+ printf(" Committed : %s \n", (l_log.iv_userDetails.iv_committed != 0) ? "true":"false" );
+ printf(" Word 1 : 0x%08X \n", ntohl(l_log.iv_userDetails.iv_userData1) );
+ printf(" Word 2 : 0x%08X \n", ntohl(l_log.iv_userDetails.iv_userData2) );
+ printf(" Word 3 : 0x%08X \n", ntohl(l_log.iv_userDetails.iv_userData3) );
+ printf(" Word 4 : 0x%08X \n", ntohl(l_log.iv_userDetails.iv_userData4) );
+ printf(" Entry Size : 0x%04X \n", ntohs(l_log.iv_userDetails.iv_entrySize) );
+
+
+ return 0;
+}
diff --git a/src/occ/errl/test/test.mk b/src/occ/errl/test/test.mk
new file mode 100755
index 0000000..a4b5b4b
--- /dev/null
+++ b/src/occ/errl/test/test.mk
@@ -0,0 +1,28 @@
+# $Id$
+
+# @file test.mk
+#
+# @brief mk occ application
+#
+
+# @page ChangeLogs Change Logs
+# @section test.mk
+# @verbatim
+#
+#
+# Change Log ******************************************************************
+# Flag Defect/Feature User Date Description
+# ------ -------------- ---------- ------------ -----------
+# @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments
+#
+# @endverbatim
+#
+
+errltest_CFILES = \
+ ../../common.c \
+ ../errl.c \
+ ../../thread/threadSch.c \
+ errltest.c
+
+all_cfiles = ${errltest_CFILES}
+
OpenPOWER on IntegriCloud