Index: Integrity.c =================================================================== diff -u --- Integrity.c (revision 0) +++ Integrity.c (revision fd532326d84dc92f94ae7b4f9310c2c282b313a2) @@ -0,0 +1,163 @@ + + +#include + +#include "reg_tcram.h" + +#include "CpldInterface.h" +#include "Integrity.h" +#include "Messaging.h" +#include "TaskGeneral.h" +#include "Utilities.h" +#include "DDDefs.h" +#include "TDDefs.h" + +/** + * @addtogroup Integrity + * @{ + */ + +// ********** private definitions ********** + +#define CRC_TABLE_STARTING_ADDR 0x10020 ///< The starting address of CRC table for firmware image. +//#define CRC_TABLE_STARTING_ADDR 0x20 ///< The starting address of CRC table for firmware image. // TODO remove no bootloader version +#define MAX_CRC_CALC_DATA_SIZE 0x8000 ///< The maximum size of data for each CRC calculation. +#define SERR 0x00000001 ///< Bit 0 - Single-bit error in TCRAM Module Error Status Register +#define ADDR_DEC_FAIL 0x00000004 ///< Bit 2 - Address decode failed in TCRAM Module Error Status Register +#define ADDR_COMP_LOGIC_FAIL 0x00000010 ///< Bit 4 - Address decode logic element failed in TCRAM Module Error Status Register +#define DERR 0x00000020 ///< Bit 5 - Multiple bit error in TCRAM Module Error Status Register +#define RADDR_PAR_FAIL 0x00000100 ///< Bit 8 - Read Address Parity Failure in TCRAM Module Error Status Register +#define WADDR_PAR_FAIL 0x00000200 ///< Bit 9 - Write Address Parity Failure in TCRAM Module Error Status Register + +/// Time threshold to check RAM error is 2 seconds +static const U32 RAM_ERROR_CHECK_TIME_THRESHOLD = ( ( 2 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ); + +// ********** private data ********** + +static U32 currentRecord; ///< Current CRC table record to check. +static U32 currentProcessedSize; ///< Current data size processed for CRC calculation. +static U32 crcCalculated; ///< The calculated CRC value. +static SELF_TEST_STATUS_T integrityTestStatus; ///< Current firmware integrity test status. +static U32 processorRAMStatusCounter; ///< Counter used to check processor RAM error. +static BOOL singleBitRAMErrorFlag; ///< Flag to signal the processor RAM error. + +/*********************************************************************//** + * @brief + * The initIntegrity function initializes the Integrity module. + * @details Inputs: none + * @details Outputs: Integrity module initialized + * @return none + *************************************************************************/ +void initIntegrity( void ) +{ + currentRecord = 0; + currentProcessedSize = 0; + crcCalculated = 0; + integrityTestStatus = SELF_TEST_STATUS_IN_PROGRESS; + processorRAMStatusCounter = 0; + singleBitRAMErrorFlag = FALSE; +} + +/********************************************************************************//** + * @brief + * The execRAMMonitor function monitors the processor RAM status. + * @details Inputs: none + * @details Outputs: system event log or alarm activated if RAM error is detected. + * @return none + ***********************************************************************************/ +void execRAMMonitor( void ) +{ + U32 tcram1ErrStat, tcram2ErrStat = 0; + U32 err1, err2 = 0; + + // Check for processor RAM error + if ( ++processorRAMStatusCounter > RAM_ERROR_CHECK_TIME_THRESHOLD ) + { + tcram1ErrStat = tcram1REG->RAMERRSTATUS; // B0TCM in TCRAM Module Error Status Register + tcram2ErrStat = tcram2REG->RAMERRSTATUS; // B1TCM in TCRAM Module Error Status Register + + err1 = tcram1ErrStat & SERR; // Single-bit error, bit 0 in B0TCM in TCRAM Module Error Status Register + err2 = tcram2ErrStat & SERR; // Single-bit error, bit 0 in B1TCM in TCRAM Module Error Status Register + + if( ( err1 != 0 ) || ( err2 != 0 ) ) + { + if ( FALSE == singleBitRAMErrorFlag ) + { + // Log the single-bit RAM error event once only +#ifdef _TD_ + SEND_EVENT_WITH_2_U32_DATA( TD_EVENT_CPU_RAM_ERROR_STATUS, tcram1ErrStat, tcram2ErrStat ); +#else + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_CPU_RAM_ERROR_STATUS, tcram1ErrStat, tcram2ErrStat ); +#endif + singleBitRAMErrorFlag = TRUE; + } + } + + err1 = tcram1ErrStat & (ADDR_DEC_FAIL | ADDR_COMP_LOGIC_FAIL | DERR | RADDR_PAR_FAIL | WADDR_PAR_FAIL); + err2 = tcram2ErrStat & (ADDR_DEC_FAIL | ADDR_COMP_LOGIC_FAIL | DERR | RADDR_PAR_FAIL | WADDR_PAR_FAIL); + + if ( ( err1 != 0 ) || ( err2 != 0 ) ) + { +#ifdef _TD_ + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_CPU_RAM_ERROR, tcram1ErrStat, tcram2ErrStat ); +#else + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_CPU_RAM_ERROR, tcram1ErrStat, tcram2ErrStat ); +#endif + } + + processorRAMStatusCounter = 0; + } +} + +/*********************************************************************//** + * @brief + * The execIntegrityTest function executes the integrity check for firmware image. + * @details Inputs: firmware image CRC table + * @details Outputs: none + * @return firmware image integrity self-test status + *************************************************************************/ +SELF_TEST_STATUS_T execIntegrityTest( void ) +{ + CRC_TABLE const * const crcTablePtr = (CRC_TABLE *)CRC_TABLE_STARTING_ADDR; + CRC_RECORD const * const currentRecordPtr = &crcTablePtr->recs[ currentRecord ]; + BOOL integrityStatus = TRUE; + U32 remainingSize = 0; + + if ( currentRecord < crcTablePtr->num_recs ) + { + remainingSize = currentRecordPtr->size - currentProcessedSize; + + if ( remainingSize > MAX_CRC_CALC_DATA_SIZE ) + { + crcCalculated = crc32( crcCalculated, (U08 *)( currentRecordPtr->addr + currentProcessedSize ), MAX_CRC_CALC_DATA_SIZE ); + currentProcessedSize += MAX_CRC_CALC_DATA_SIZE; + } + else + { + crcCalculated = crc32( crcCalculated, (U08 *)( currentRecordPtr->addr + currentProcessedSize ), remainingSize ); + integrityStatus &= ( ( (U32)currentRecordPtr->crc_value == crcCalculated ) ? TRUE : FALSE ); + crcCalculated = 0; + currentProcessedSize = 0; + currentRecord++; + } + } + + if ( TRUE != integrityStatus ) + { + integrityTestStatus = SELF_TEST_STATUS_FAILED; +#ifdef _TD_ + activateAlarmNoData( ALARM_ID_TD_INTEGRITY_POST_TEST_FAILED ); + activateSafetyShutdown(); +#else + activateAlarmNoData( ALARM_ID_DD_INTEGRITY_POST_TEST_FAILED ); +#endif + } + else if ( currentRecord == crcTablePtr->num_recs ) + { + integrityTestStatus = SELF_TEST_STATUS_PASSED; + } + + return integrityTestStatus; +} + +/**@}*/ Index: Integrity.h =================================================================== diff -u --- Integrity.h (revision 0) +++ Integrity.h (revision fd532326d84dc92f94ae7b4f9310c2c282b313a2) @@ -0,0 +1,25 @@ + +#ifndef _INTEGRITY_H_ +#define _INTEGRITY_H_ + +#include "Common.h" + +/** + * @defgroup Integrity Integrity + * @brief Integrity module checks for firmware integrity using CRC table generated by TI linker. + * + * @addtogroup Integrity + * @{ + */ + +// ********** public definitions ********** + +// ********** public function prototypes ********** + +void initIntegrity( void ); +SELF_TEST_STATUS_T execIntegrityTest( void ); +void execRAMMonitor( void ); + +/**@}*/ + +#endif