📄 ftahbram.c
字号:
/****************************************************************************** *Tests the on-chip ram and returns an error code if an error is detected. *Do not enable MULTIPLEERROR since it will halt the cpu unless a modified *traptable is used. AUTOSCRUB and ERRCNT must not be enabled unless EDACEN *is enabled ******************************************************************************/#include "ftahbram.h"#include "ftlib.h"#include <stdio.h>#define RAMADDR 0xa0000000 //Address to the RAM under test#define CONFADDR 0x80000b00 //Address to the configuration register of the RAM#define AHBSTATADR 0x80000d00 //Address to AHB Status Module //Testcontrol #define AUTOSCRUB 1 //Autoscrubbing enabled#define ERRCNT 1 //Error counter enabled#define EDACEN 1 //EDAC Enabled#define CNTBITS 1 //Number of bits used for the single error counter (1 - 8)#define MULTIPLEERROR 0 //Do multiple error test (Requires modified traptable)#define AHBSTATAV 1 //AHB status register availablestruct control_reg { unsigned reserved : 19 - CNTBITS; //currently unused unsigned sec : CNTBITS; //Single error counter unsigned memsize : 3; //memorysize unsigned wb : 1; //write diagnostics enable unsigned rb : 1; //read diagnostics enable unsigned en : 1; //edac enable unsigned tcb : 7; //checkbits used for diagnostics};extern void *catch_interrupt(void func(int irq), int irq);void irq_handler(int irq);static int irqcnt = 0;static int irqerror = 0;static int *creg_val;static volatile int *creg_pnt = (int *) CONFADDR;static volatile int *ahbstat = (int *) AHBSTATADR; int ftahbram_test(void) { volatile int *iram = (int *) RAMADDR; volatile char *cram = (char *) RAMADDR; volatile short int *sram = (short int *) RAMADDR; int size; int i; int temp1; int temp4; int temp5; unsigned int temp6; int ctrl; int cachectrl; short int temp2; char temp3; struct control_reg creg; struct control_reg *read; read = (struct control_reg *) &ctrl; int countmax; creg_val = (int *) &creg; size = 1024 * pow2( (int)( (*creg_pnt >> 9) & 7) ); countmax = pow2(CNTBITS) - 1; //initialization creg.tcb = 0; creg.rb = 0; creg.wb = 0; creg.memsize = 0; creg.sec = countmax; creg.reserved = 0; *creg_pnt = *creg_val; //Disable caches cachectrl = cache_disable(); /* printf("write test words\n"); */ i = 0;while(i < 2) { //test all memory locations with word accesses for(i = 0; i < (size / 4); i++) { *(iram + i) = i; } /* printf("read test words\n"); */ for(i = 0; i < (size / 4); i = i++) { if ( *(iram + i) != i ) { //word has been read or written incorrectly return 1; } } /* printf("write test halfwords\n"); */ //test all memory locations with halfword accesses for(i = 0; i < (size / 2); i = i++) { *(sram + i) = i; } /* printf("read test halfwords\n"); */ for(i = 0; i < (size / 2) ; i = i++ ) { if ( *(sram + i) != i ) { //halfword has been read or written incorrectly return 2; } }/* printf("write test bytes\n"); */ //test all memory locations with halfword accesses for(i = 0; i < size; i = i++) { *(cram + i) = (char)i; } /* printf("read test bytes\n"); */ for(i = 0; i < size ; i = i++ ) { if ( *(cram + i) != (char) i ) { //halfword has been read or written incorrectly return 3; } } /* printf("word read after write test\n"); */ for(i = 0; i < (size / 4); i++) { *(iram + i) = i; temp1 = *(iram + i); if (temp1 != i) { //read after write error return 4; } } /* printf("halfword read after write test\n"); */ for(i = 0; i < (size / 2); i++) { *(sram + i) = i; temp2 = *(sram + i); if (temp2 != i) { //read after write error return 5; } } /* printf("byte read after write test\n"); */ for(i = 0; i < size; i++) { *(cram + i) = (char)i; temp3 = *(cram + i); if (temp3 != (char)i) { //read after write error return 6; } }#if EDACEN == 1 i++; creg.en = 0; *creg_pnt = *creg_val;#else i = 2;#endif}#if EDACEN == 1 creg.en = 1; *creg_pnt = *creg_val; //Single error tests /* printf("checkbit test\n"); */ creg.rb = 1; *creg_pnt = *creg_val; ctrl = *creg_pnt; for(i = 0; i < 1024; i++) { temp4 = rand(); *iram = temp4; temp1 = *iram; temp1 = encode(temp4); ctrl = *creg_pnt; /* printf("Value: %i\n", temp4); */ /* printf("Calc check: %x\n", temp1); */ /* printf("Read check: %x\n", read->tcb); */ if(read->tcb != temp1) { //checkbit mismatch /* printf("Checkbit error in iteration : %i\n", i); */ return 7; } } /* printf("Single error correction test\n"); */ creg.wb = 1; creg.rb = 0; *creg_pnt = *creg_val; temp1 = 0xdbac8754; /* printf("Data: %x\n", temp1); */ temp4 = encode(temp1); /* printf("Checkbits : %x\n", temp4); */ for(i = 0; i < 32; i++) { /* printf("Iteration : %i\n", i); */ creg.tcb = scramble(temp4, i, 0); /* printf("Scrambled cbits: %x\n", creg.tcb); */ *creg_pnt = *creg_val; *iram = temp1; temp5 = *iram; /* printf("Read data: %x\n", temp5); */ if(temp5 != (temp1 ^ (1 << i))) { //data not corrected properly return 8; } } //Single error counter and Interrupt tests#if ERRCNT == 1 *creg_pnt = *creg_val; temp1 = 0x9b304d24; temp4 = scramble(encode(temp1), 0, 0); creg.sec = 0; creg.tcb = temp4; *creg_pnt = *creg_val; /* printf("Single error counter and interrupt test\n"); */ for(i = 0; i < countmax; i++) { *iram = temp1; temp5 = *iram; ctrl = *creg_pnt; /* printf("sec: %i\n", read->sec); */ if (read->sec != i + 1) { //Single error counter error //printf("iteration: %i\n", i); return 9; } } *iram = temp1; temp5 = *iram; ctrl = *creg_pnt; if(read->sec != countmax) { //Single error counter saturation error return 10; } creg.sec = countmax; *creg_pnt = *creg_val; *ahbstat = 0;#if AHBSTATAV == 1 catch_interrupt(irq_handler, IRQ); enable_irq(IRQ); while(irqcnt < 100) { *(iram + irqcnt) = temp1; temp5 = *(iram + irqcnt); } disable_irq(IRQ); if(irqerror != 0) { //interrupt error if (irqerror == 1) { return 11; } else { return 21; } }#endif *creg_pnt = *creg_val; *iram = temp1; creg.wb = 0; *creg_pnt = *creg_val; *cram = (char) 0x01; ctrl = *creg_pnt; if(read->sec != 1) { //Incorrect single error detection return 12; } *creg_pnt = *creg_val; temp5 = *iram; ctrl = *creg_pnt; if(read->sec != 0) { //Incorrect single error correction return 13; }#endif //Autoscrub tests#if AUTOSCRUB == 1 creg.wb = 1; *creg_pnt = *creg_val; *iram = temp1; temp5 = *iram; ctrl = *creg_pnt; if(read->sec != 1) { //Incorrect single error detection return 14; } *creg_pnt = *creg_val; temp5 = *iram; ctrl = *creg_pnt; if(read->sec != 0) { //Autoscrub error return 15; }#endif#if MULTIPLEERROR == 1 //Multiple error tests creg.sec = countmax; creg.rb = 1; *creg_pnt = *creg_val; creg.sec = 0; temp1 = 0x30a9c15b; temp4 = encode(temp1); for(i = 0; i < 88; i++) { //printf("Iteration : %i\n", i); creg.tcb = scramble(temp4, i, 1); *creg_pnt = *creg_val; ctrl = *creg_pnt; *iram = temp1; creg.tcb = 0; *creg_pnt = *creg_val; temp5 = *iram; ctrl = *creg_pnt; if(read->sec != 0) { //printf("Iteration : %i\n", i); //Multiple error detected as single error return 16; } } #endif#if ERRCNT == 1 //Single error on checkbits test /* printf("Single error on checkbits test\n"); */ creg.sec = countmax; creg.wb = 1; creg.rb = 0; *creg_pnt = *creg_val; temp1 = 0x1234567; for(i = 32; i < 39; i++) { temp4 = scramble(encode(temp1), i, 0); creg.tcb = temp4; *creg_pnt = *creg_val; *iram = temp1; creg.wb = 0; *creg_pnt = *creg_val; temp5 = *iram; ctrl = *creg_pnt; if(read->sec != 1 || temp5 != temp1) { //Incorrect checkbit error handling return 17; } creg.wb = 1; *creg_pnt = *creg_val;#if AUTOSCRUB == 1 temp5 = *iram; ctrl = *creg_pnt; if(read->sec != 0 || temp5 != temp1) { //Autoscrub handles checkbit error incorrectly return 18; } #endif }#endif creg.wb = 0; creg.rb = 0; creg.sec = countmax; *creg_pnt = *creg_val; //Mixed size reads and writes *iram = 0xaabbccdd; *(cram + 2) = 0xee; temp1 = *iram; *(cram + 3) = 0xff; temp4 = *iram; *(iram + 1) = 0xffffeeee; *(sram + 2) = 0x1111; temp2 = *(sram + 2); *(cram + 6) = 0x22; temp3 = *(cram + 7); temp5 = (int)temp3; if( (temp1 != 0xaabbeedd) || (temp4 != 0xaabbeeff) || ( (temp5 & 0xff) != 0xee) || (temp2 != 0x1111) ) { //Write error, read error return 19; } //Mixed size with single errors creg.wb = 1; temp1 = 0xaabbccdd; creg.tcb = scramble(encode(temp1), 8, 0); *creg_pnt = *creg_val; *iram = temp1; *(iram + 1) = temp1; *(iram + 2) = temp1; creg.wb = 0; *creg_pnt = *creg_val; *(cram + 1) = 0x22; temp4 = *iram; *(sram + 2) = 0x4455; temp2 = *(sram + 2); temp5 = *(iram + 2); temp3 = *(cram + 1); if( (temp2 != 0x4455) || ((int) temp3 != 0x22) || (temp4 != 0xaa22cddd) || (temp5 != 0xaabbcddd) ) { //Write error, read error return 20; }#endif //Set caches to old state cache_reset(cachectrl); //no errors return 0;}void irq_handler(int irq) { int ctrl; int temp; struct control_reg *reg; reg = (struct control_reg *) &ctrl; ctrl = *creg_pnt; if(reg->sec != 1) { irqerror = 1; } *creg_pnt = *creg_val; temp = *(ahbstat + 1); if ( temp != (RAMADDR + irqcnt * 4)) { //ahb stat error irqerror = 2; } *ahbstat = 0; irqcnt++;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -