//--------- Flash_NOR.c --------- // Requires Ndless 1.1.xxxx for prototypes // This program is a tool for Flashing/verifying Boot1 Images. // This software has the potential to seriously brick the calculator. // Even TI's own diagnostic software warns not to power down the device while reflashing the NOR. // The only way to reflash a corrupt NOR is by hardware equipment for memory chips. #include #include "SST39WF400A.h" #include "utils.h" #define BOOT1_SIZE 0x20000 // boot1_1.1.6818 is actually bigger than this !!! #define NORBASE 0xD4000000 // put in SST39WF400A.h ? asm(".string \"PRG\"\n"); // Ndless 1.1 required.... int main(void) { void *boot1; FILE *ifile; int i,bytesread, WordOffset = 0; short WordToWrite; char message[80]; // --- load the boot1 image to be flashed -------- ifile = fopen("/documents/ndless/boot1.img.tns", "rb"); if (!ifile) { errormsg("Can't open input file boot1.img.tns"); return 1; } boot1 = malloc(BOOT1_SIZE); if (!boot1) { errormsg("Can't malloc"); fclose(ifile); return 1; } bytesread = fread(boot1, 1,BOOT1_SIZE, ifile); if (bytesread != BOOT1_SIZE) { fclose(ifile); free(boot1); errormsg("Can't read BOOT1 from input file"); return 1; } fclose(ifile); // ---- Map in the NOR flash - another way to dump boot1, dump directly from D4000000 ----- // ---- this also works on production models :) asm volatile( ".arm \n" "ldr r1,=0x00000C12 @ 0x00000C12 == map to physical address 0, noncached\n" "mrc p15,0,r0,c2,c0,0 @ get MMU Translation Table Base Register\n" "add r0, r0, #0x3500 @ 0x3500 is table offset to 0xD4000000 mapping\n" "str r1,[r0] @ set to 0x00000c12 enables access\n" "clean_loop: @ entering instruction memory barrier operation\n" "MRC p15, 0, PC,c7,c14, 3 @ clean entire dcache using test & clean\n" "BNE clean_loop\n" "MOV R0, #0\n" "MCR p15, 0, R0,c7,c10, 4 @ drain write buffer\n" "MOV R0, #0\n" "MCR p15, 0, R0,c7,c5 @ invalidate icache \n" "ldr r0,=0xD4000000\n" "MCR p15, 0, R0,c8,c5, 1 @ Invalidate instruction TLB entry\n" "MCR p15, 0, R0,c8,c6, 1 @ Invalidate data TLB entry\n" ); // ----- erase the chip ------ errormsg("Do not power down or reboot till successful flashing !!!!"); chip_erase_SST39WF400_nor_flash(NORBASE); // :-o // ----- write to the chip two bytes(1 word) at a time ------ for(i = 0 ; i < BOOT1_SIZE ; i+=2, ++WordOffset){ WordToWrite = *(short *)(boot1 + i) ; program_word_SST39WF400_nor_flash(WordOffset, WordToWrite , 1 ); // ----- did it get written ? ----- if(WordToWrite != *(short *)(NORBASE + i)){ sprintf(message, "Fail at %x/%x- Please Try Again", (unsigned)i , BOOT1_SIZE); // :-/ errormsg(message); free(boot1); return 1 ; } } free(boot1); errormsg("Image successfully written !!!"); // :-) return 0; }