diff options
Diffstat (limited to 'src/occ/errl')
-rwxr-xr-x | src/occ/errl/errl.c | 984 | ||||
-rwxr-xr-x | src/occ/errl/errl.h | 404 | ||||
-rwxr-xr-x | src/occ/errl/test/Makefile | 55 | ||||
-rwxr-xr-x | src/occ/errl/test/app.mk | 99 | ||||
-rwxr-xr-x | src/occ/errl/test/errltest.c | 786 | ||||
-rwxr-xr-x | src/occ/errl/test/gpefiles.mk | 24 | ||||
-rwxr-xr-x | src/occ/errl/test/parser.c | 292 | ||||
-rwxr-xr-x | src/occ/errl/test/test.mk | 28 |
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} + |