diff --git a/FSW-qt/fsw-qt.pro b/FSW-qt/fsw-qt.pro --- a/FSW-qt/fsw-qt.pro +++ b/FSW-qt/fsw-qt.pro @@ -1,7 +1,15 @@ TEMPLATE = app # CONFIG += console v8 sim -# CONFIG options = verbose *** boot_messages *** debug_messages *** cpu_usage_report *** stack_report *** vhdl_dev *** debug_tch -# lpp_dpu_destid +# CONFIG options = +# verbose +# boot_messages +# debug_messages +# cpu_usage_report +# stack_report +# vhdl_dev +# debug_tch +# lpp_dpu_destid REMOVE BEFORE DELIVERY TO LESIA +# debug_watchdog CONFIG += console verbose lpp_dpu_destid CONFIG -= qt @@ -12,7 +20,7 @@ SWVERSION=-1-0 DEFINES += SW_VERSION_N1=3 # major DEFINES += SW_VERSION_N2=0 # minor DEFINES += SW_VERSION_N3=0 # patch -DEFINES += SW_VERSION_N4=13 # internal +DEFINES += SW_VERSION_N4=14 # internal # #QMAKE_CFLAGS_RELEASE += -fprofile-arcs -ftest-coverage diff --git a/header/GscMemoryLPP.hpp b/header/GscMemoryLPP.hpp --- a/header/GscMemoryLPP.hpp +++ b/header/GscMemoryLPP.hpp @@ -5,65 +5,188 @@ #define LEON3 #endif -static unsigned int getCacheControlRegister(){ -#ifdef LEON3 - unsigned int cacheControlRegister = 0; - __asm__ __volatile__("lda [%%g0] 2, %0" : "=r"(cacheControlRegister) : ); - return cacheControlRegister; -#endif -} +#define REGS_ADDR_PLUGANDPLAY 0xFFFFF000 +#define ASR16_REG_ADDRESS 0x90400040 // Ancillary State Register 16 = Register protection control register (FT only) + +#define DEVICEID_LEON3 0x003 +#define DEVICEID_LEON3FT 0x053 +#define VENDORID_GAISLER 0x01 -static void setCacheControlRegister(unsigned int cacheControlRegister) +// CCR +#define POS_ITE 12 +#define COUNTER_FIELD_ITE 0x00003000 // 0000 0000 0000 0000 0011 0000 0000 0000 +#define COUNTER_MASK_ITE 0xffffcfff // 1111 1111 1111 1111 1100 1111 1111 1111 +#define POS_IDE 10 +#define COUNTER_FIELD_IDE 0x00000c00 // 0000 0000 0000 0000 0000 1100 0000 0000 +#define COUNTER_MASK_IDE 0xfffff3ff // 1111 1111 1111 1111 1111 0011 1111 1111 +// +#define POS_DTE 8 +#define COUNTER_FIELD_DTE 0x00000300 // 0000 0000 0000 0000 0000 0011 0000 0000 +#define COUNTER_MASK_DTE 0xfffffcff // 1111 1111 1111 1111 1111 1100 1111 1111 +#define POS_DDE 6 +#define COUNTER_FIELD_DDE 0x000000c0 // 0000 0000 0000 0000 0000 0000 1100 0000 +#define COUNTER_MASK_DDE 0xffffff3f // 1111 1111 1111 1111 1111 1111 0011 1111 + +// ASR16 +#define POS_FPRF 27 +#define COUNTER_FIELD_FPRF 0x38000000 // 0011 1000 0000 0000 0000 0000 0000 0000 +#define COUNTER_MASK_FPRF 0xc7ffffff // 1100 0111 1111 1111 1111 1111 1111 1111 +#define POS_IURF 11 +#define COUNTER_FIELD_IURF 0x00003800 // 0000 0000 0000 0000 0011 1000 0000 0000 +#define COUNTER_MASK_IURF 0xffffc7ff // 1111 1111 1111 1111 1100 0111 1111 1111 + +volatile unsigned int *asr16Ptr = (volatile unsigned int *) ASR16_REG_ADDRESS; + +static inline void flushCache() { -#ifdef LEON3 - __asm__ __volatile__("sta %0, [%%g0] 2" : : "r"(cacheControlRegister)); -#endif -} - + /** + * Flush the data cache and the instruction cache. + * + * @param void + * + * @return void + */ -/** -* Flush the data cache and the instruction cache. -* -* @return -*/ -static inline void flushCache() { asm("flush"); } -static void resetCacheControlRegister() { -#ifdef LEON3 +//*************************** +// CCR Cache control register + +static unsigned int CCR_getValue() +{ + unsigned int cacheControlRegister = 0; + __asm__ __volatile__("lda [%%g0] 2, %0" : "=r"(cacheControlRegister) : ); + return cacheControlRegister; +} + +static void CCR_setValue(unsigned int cacheControlRegister) +{ + __asm__ __volatile__("sta %0, [%%g0] 2" : : "r"(cacheControlRegister)); +} + +static void CCR_resetCacheControlRegister() +{ unsigned int cacheControlRegister; cacheControlRegister = 0x00; - setCacheControlRegister(cacheControlRegister); -#endif + CCR_setValue(cacheControlRegister); +} + +static void CCR_enableInstructionCache() +{ + // [1:0] Instruction Cache state (ICS) + // Indicates the current data cache state according to the following: X0 = disabled, 01 = frozen, 11 = enabled. + unsigned int cacheControlRegister; + cacheControlRegister = CCR_getValue(); + cacheControlRegister = (cacheControlRegister | 0x3); + CCR_setValue(cacheControlRegister); } -static void enableInstructionCache() { -#ifdef LEON3 +static void CCR_enableDataCache() +{ + // [3:2] Data Cache state (DCS) + // Indicates the current data cache state according to the following: X0 = disabled, 01 = frozen, 11 = enabled. + unsigned int cacheControlRegister; + cacheControlRegister = CCR_getValue(); + cacheControlRegister = (cacheControlRegister | 0xc); + CCR_setValue(cacheControlRegister); +} + +static void CCR_faultTolerantScheme() +{ + // [20:19] FT scheme (FT) - “00” = no FT, “01” = 4-bit checking implemented unsigned int cacheControlRegister; - cacheControlRegister = getCacheControlRegister(); - cacheControlRegister = (cacheControlRegister | 0x3); - setCacheControlRegister(cacheControlRegister); -#endif + unsigned int *plugAndPlayRegister; + unsigned int vendorId; + unsigned int deviceId; + + plugAndPlayRegister = (unsigned int*) REGS_ADDR_PLUGANDPLAY; + vendorId = ( (*plugAndPlayRegister) & 0xff000000 ) >> 24; + deviceId = ( (*plugAndPlayRegister) & 0x00fff000 ) >> 12; + + if( (vendorId == VENDORID_GAISLER) & (deviceId ==DEVICEID_LEON3FT) ) + { + PRINTF("in faultTolerantScheme *** Leon3FT detected, configure the CCR FT bits"); + cacheControlRegister = CCR_getValue(); + cacheControlRegister = (cacheControlRegister | 0xc); + CCR_setValue(cacheControlRegister); + } + else + { + PRINTF("in faultTolerantScheme *** not a Leon3FT, no need to configure the CCR FT bits\n"); + PRINTF2(" *** vendorID = 0x%x, deviceId = 0x%x\n", vendorId, deviceId); + } } -static void enableDataCache() { -#ifdef LEON3 +static void CCR_enableInstructionBurstFetch() +{ + // [16] Instruction burst fetch (IB). This bit enables burst fill during instruction fetch. unsigned int cacheControlRegister; - cacheControlRegister = getCacheControlRegister(); - cacheControlRegister = (cacheControlRegister | 0xc); - setCacheControlRegister(cacheControlRegister); -#endif + cacheControlRegister = CCR_getValue(); + // set the bit IB to 1 + cacheControlRegister = (cacheControlRegister | 0x10000); + CCR_setValue(cacheControlRegister); } -static void enableInstructionBurstFetch() { -#ifdef LEON3 +static void CCR_getInstructionAndDataErrorCounters( unsigned int* instructionErrorCounter, unsigned int* dataErrorCounter ) +{ + // [13:12] Instruction Tag Errors (ITE) - Number of detected parity errors in the instruction tag cache. + // Only available if fault-tolerance is enabled (FT field in this register is non-zero). + // [11:10] Instruction Data Errors (IDE) - Number of detected parity errors in the instruction data cache. + // Only available if fault-tolerance is enabled (FT field in this register is non-zero). + unsigned int cacheControlRegister; - cacheControlRegister = getCacheControlRegister(); - // set the bit IB to 1 - cacheControlRegister = (cacheControlRegister | 0x10000); - setCacheControlRegister(cacheControlRegister); -#endif + unsigned int iTE; + unsigned int iDE; + unsigned int dTE; + unsigned int dDE; + + cacheControlRegister = CCR_getValue(); + iTE = (cacheControlRegister & COUNTER_FIELD_ITE) >> POS_ITE; + iDE = (cacheControlRegister & COUNTER_FIELD_IDE) >> POS_IDE; + dTE = (cacheControlRegister & COUNTER_FIELD_DTE) >> POS_DTE; + dDE = (cacheControlRegister & COUNTER_FIELD_DDE) >> POS_DDE; + + *instructionErrorCounter = iTE + iDE; + *dataErrorCounter = dTE + dDE; + + // reset counters + cacheControlRegister = cacheControlRegister + & COUNTER_FIELD_ITE + & COUNTER_FIELD_IDE + & COUNTER_FIELD_DTE + & COUNTER_FIELD_DDE; + + CCR_setValue(cacheControlRegister); +} + +//******************************************* +// ASR16 Register protection control register + +static unsigned int ASR16_get_FPRF_IURF_ErrorCounters( unsigned int* fprfErrorCounter, unsigned int* iurfErrorCounter) +{ + /** This function is used to retrieve the integer unit register file error counter and the floating point unit + * register file error counter + * + * @return void + * + * [29:27] FP RF error counter - Number of detected parity errors in the FP register file. + * [13:11] IU RF error counter - Number of detected parity errors in the IU register file. + * + */ + + unsigned int asr16; + + asr16 = *asr16Ptr; + *fprfErrorCounter = ( asr16 & COUNTER_FIELD_FPRF ) >> POS_FPRF; + *iurfErrorCounter = ( asr16 & COUNTER_FIELD_IURF ) >> POS_IURF; + + // reset the counter to 0 + asr16 = asr16Ptr + & COUNTER_MASK_FPRF + & COUNTER_FIELD_IURF; + + *asr16Ptr = asr16; } #endif /* GSCMEMORY_HPP_ */ diff --git a/src/fsw_init.c b/src/fsw_init.c --- a/src/fsw_init.c +++ b/src/fsw_init.c @@ -64,19 +64,38 @@ void initCache() { + // ASI 2 contains a few control registers that have not been assigned as ancillary state registers. + // These should only be read and written using 32-bit LDA/STA instructions. + // All cache registers are accessed through load/store operations to the alternate address space (LDA/STA), using ASI = 2. + // The table below shows the register addresses: + // 0x00 Cache control register + // 0x04 Reserved + // 0x08 Instruction cache configuration register + // 0x0C Data cache configuration register + + // Cache Control Register Leon3 / Leon3FT + // 31..30 29 28 27..24 23 22 21 20..19 18 17 16 + // RFT PS TB DS FD FI FT ST IB + // 15 14 13..12 11..10 9..8 7..6 5 4 3..2 1..0 + // IP DP ITE IDE DTE DDE DF IF DCS ICS + unsigned int cacheControlRegister; - cacheControlRegister = getCacheControlRegister(); - PRINTF1("(0) cacheControlRegister = %x\n", cacheControlRegister) + cacheControlRegister = CCR_getValue(); + PRINTF1("(0) cacheControlRegister = %x\n", cacheControlRegister); - resetCacheControlRegister(); + CCR_resetCacheControlRegister(); - enableInstructionCache(); - enableDataCache(); - enableInstructionBurstFetch(); + CCR_enableInstructionCache(); // ICS bits + CCR_enableDataCache(); // DCS bits + CCR_enableInstructionBurstFetch(); // IB bit - cacheControlRegister = getCacheControlRegister(); - PRINTF1("(1) cacheControlRegister = %x\n", cacheControlRegister) + cacheControlRegister = CCR_getValue(); + PRINTF1("(1) cacheControlRegister = %x\n", cacheControlRegister); + + CCR_faultTolerantScheme(); + + // FT activation } rtems_task Init( rtems_task_argument ignored ) diff --git a/src/fsw_misc.c b/src/fsw_misc.c --- a/src/fsw_misc.c +++ b/src/fsw_misc.c @@ -117,6 +117,9 @@ void watchdog_reload(void) { /** This function reloads the watchdog timer counter with the timer reload value. * + * @param void + * + * @return void * */