src/occ_405/errl/errl.c
// Function Specification
//
// Name:  addTraceToErrl
//
// Description: Add trace to an error log
//
// End Function Specification
Function Specification
Name:  addTraceToErrl

Add trace to an error log

End Function Specification
Function Specification Name : addTraceToErrl Add trace to an error log End Function Specification
void addTraceToErrl(
            const trace_descriptor_array_t* i_trace,
            const uint16_t i_traceSz,
            errlHndl_t io_err)
{
    UINT l_expectLen = 0, l_rtLen = 0, l_bytes_left;
    void * l_traceAddr = io_err;
    uint16_t l_actualSizeOfUsrDtls = 0;
    ocb_oisr0_t  l_oisr0_status;       
    static bool L_sys_checkstop_traced = FALSE;
    l_oisr0_status.value    = in32(OCB_OISR0);
    if (l_oisr0_status.fields.check_stop_ppc405 &&
        !L_sys_checkstop_traced)
    {
            L_sys_checkstop_traced = TRUE;
            TRAC_IMP("addTraceToErrl: System checkstop detected: ppc405, OISR0[0x%08x]",
                     l_oisr0_status.value);
    }
    if( (io_err != NULL) &&
        (io_err != INVALID_ERR_HNDL) &&
        (io_err->iv_userDetails.iv_committed == 0) &&
        (i_traceSz != 0) &&
        ((io_err->iv_userDetails.iv_entrySize + sizeof(ErrlUserDetailsEntry_t)) < MAX_ERRL_ENTRY_SZ ) &&
        ((i_trace==&g_des_array[INF_TRACE_DESCRIPTOR]) ||
         (i_trace==&g_des_array[ERR_TRACE_DESCRIPTOR]) ||
         (i_trace==&g_des_array[IMP_TRACE_DESCRIPTOR]) ||
         (i_trace==NULL)) )
    {
        ErrlUserDetailsEntry_t l_usrDtlsEntry;
        uint16_t l_headerSz = sizeof( l_usrDtlsEntry );
        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; 
        l_usrDtlsEntry.iv_type = (uint8_t) ERRL_USR_DTL_TRACE_DATA;
        l_usrDtlsEntry.iv_version = ERRL_TRACE_VERSION_1;
        void * l_p = io_err;
        l_traceAddr = l_p + io_err->iv_userDetails.iv_entrySize + l_headerSz;
        if (i_trace != NULL)
        {
            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);
                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);
                l_usrDtlsEntry.iv_size = 0;
            }
        }
        else
        {
            l_bytes_left = l_usrDtlsEntry.iv_size;
            l_expectLen = l_bytes_left / NUM_OF_TRACE_TYPE;
            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;
                l_rtLen = l_bytes_left / 2;
                TRAC_get_buffer_partial(TRAC_get_td("IMP"), (l_traceAddr + l_actualSizeOfUsrDtls), &l_rtLen);
                l_actualSizeOfUsrDtls += l_rtLen;
                l_bytes_left -= l_rtLen;
                l_rtLen = l_bytes_left;
                TRAC_get_buffer_partial(TRAC_get_td("INF"), (l_traceAddr + l_actualSizeOfUsrDtls), &l_rtLen);
                l_actualSizeOfUsrDtls += l_rtLen;
                l_usrDtlsEntry.iv_size = l_actualSizeOfUsrDtls;
            }
            else
            {
                if (l_usrDtlsEntry.iv_size > sizeof (trace_buf_head_t))
                {
                    l_rtLen = l_usrDtlsEntry.iv_size;
                    TRAC_get_buffer_partial(TRAC_get_td("ERR"), l_traceAddr, &l_rtLen);
                    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);
                    l_usrDtlsEntry.iv_size = 0;
                }
            }
        }
        if (l_usrDtlsEntry.iv_size)
        {
            l_actualSizeOfUsrDtls = l_usrDtlsEntry.iv_size + l_headerSz;
              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 );
        }
        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
}
void addTraceToErrl ( const trace_descriptor_array_t * i_trace , const uint16_t i_traceSz , errlHndl_t io_err ) { UINT l_expectLen = 0 , l_rtLen = 0 , l_bytes_left ; void * l_traceAddr = io_err ; uint16_t l_actualSizeOfUsrDtls = 0 ; ocb_oisr0_t l_oisr0_status ; static bool L_sys_checkstop_traced = FALSE ; l_oisr0_status . value = in32 ( OCB_OISR0 ) ; if ( l_oisr0_status . fields . check_stop_ppc405 && ! L_sys_checkstop_traced ) { L_sys_checkstop_traced = TRUE ; TRAC_IMP ( " " , l_oisr0_status . value ) ; } if ( ( io_err != NULL ) && ( io_err != INVALID_ERR_HNDL ) && ( io_err -> iv_userDetails . iv_committed == 0 ) && ( i_traceSz != 0 ) && ( ( io_err -> iv_userDetails . iv_entrySize + sizeof ( ErrlUserDetailsEntry_t ) ) < MAX_ERRL_ENTRY_SZ ) && ( ( i_trace == & g_des_array [ INF_TRACE_DESCRIPTOR ] ) || ( i_trace == & g_des_array [ ERR_TRACE_DESCRIPTOR ] ) || ( i_trace == & g_des_array [ IMP_TRACE_DESCRIPTOR ] ) || ( i_trace == NULL ) ) ) { ErrlUserDetailsEntry_t l_usrDtlsEntry ; uint16_t l_headerSz = sizeof ( l_usrDtlsEntry ) ; 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 ; l_usrDtlsEntry . iv_type = ( uint8_t ) ERRL_USR_DTL_TRACE_DATA ; l_usrDtlsEntry . iv_version = ERRL_TRACE_VERSION_1 ; void * l_p = io_err ; l_traceAddr = l_p + io_err -> iv_userDetails . iv_entrySize + l_headerSz ; if ( i_trace != NULL ) { 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 ) ; l_usrDtlsEntry . iv_size = l_rtLen ; } else { TRAC_IMP ( " \n " , l_availableSize , l_usrDtlsEntry . iv_size ) ; l_usrDtlsEntry . iv_size = 0 ; } } else { l_bytes_left = l_usrDtlsEntry . iv_size ; l_expectLen = l_bytes_left / NUM_OF_TRACE_TYPE ; if ( l_expectLen >= sizeof ( trace_buf_head_t ) ) { l_rtLen = l_expectLen ; TRAC_get_buffer_partial ( TRAC_get_td ( " " ) , l_traceAddr , & l_rtLen ) ; l_actualSizeOfUsrDtls += l_rtLen ; l_bytes_left -= l_rtLen ; l_rtLen = l_bytes_left / 2 ; TRAC_get_buffer_partial ( TRAC_get_td ( " " ) , ( l_traceAddr + l_actualSizeOfUsrDtls ) , & l_rtLen ) ; l_actualSizeOfUsrDtls += l_rtLen ; l_bytes_left -= l_rtLen ; l_rtLen = l_bytes_left ; TRAC_get_buffer_partial ( TRAC_get_td ( " " ) , ( l_traceAddr + l_actualSizeOfUsrDtls ) , & l_rtLen ) ; l_actualSizeOfUsrDtls += l_rtLen ; l_usrDtlsEntry . iv_size = l_actualSizeOfUsrDtls ; } else { if ( l_usrDtlsEntry . iv_size > sizeof ( trace_buf_head_t ) ) { l_rtLen = l_usrDtlsEntry . iv_size ; TRAC_get_buffer_partial ( TRAC_get_td ( " " ) , l_traceAddr , & l_rtLen ) ; l_usrDtlsEntry . iv_size = l_rtLen ; } else { TRAC_IMP ( " \n " , l_availableSize , l_usrDtlsEntry . iv_size ) ; l_usrDtlsEntry . iv_size = 0 ; } } } if ( l_usrDtlsEntry . iv_size ) { l_actualSizeOfUsrDtls = l_usrDtlsEntry . iv_size + l_headerSz ; l_p = memcpy ( l_p + ( ( io_err -> iv_userDetails . iv_entrySize ) ) , & l_usrDtlsEntry , l_headerSz ) ; } io_err -> iv_userDetails . iv_userDetailEntrySize += l_actualSizeOfUsrDtls ; io_err -> iv_userDetails . iv_entrySize += l_actualSizeOfUsrDtls ; } }
Function Specification
Name:  addTraceToErrl
Function Specification Name : addTraceToErrl
// OCC Interrupt Source 0 Register // Check if there is any system checkstop // Level triggered interrupts? // 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 //local copy of the usr details entry //adjust user details entry size to available size (word align ) // @jh001c //set type //set version //copy the data into error the offset is the size of the current errorlog // Caculate trace data address. Starting from errl address + sizeof(ErrlEntry_t + ErrlUserDetailsEntry_t). // check if user request to add trace from a specific trace buffer // Ensure requested length are larger than one trace info size. // Update data size //Requested size is not able to fill in any trace info. Clear data length and give up. // 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. // Ensure the size are able to fill in at least one trace info. // Update data size // Check to see if we are still able to fill in 1 or 2 traces into this Err log. // Added only ERR trace info // Update data size //We do not have enough size to fill in any trace info. Clear data length. // Finally, cacluate entire data length including usrDtl header. // 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)                 | //          |         ...                            | // //update usr data entry size //update error log size //end validation check