/********************************************************** * Verifies the current firmware against the locally * stored original. This function assumes the firmware * has been written to target starting at address 0x00. * * @param fwImage * Pointer to locally stored copy of firmware image * * @param size * Size (in bytes) of firmware image * * @returns * True if target firmware matches local copy. * False otherwise. **********************************************************/ bool verifyFirmware(uint32_t *fwImage, uint32_t size) { int i; int numWords = size / 4; bool ret = true; uint32_t value; uint32_t addr; uint32_t tarWrap = getTarWrap(); printf("Verifying firmware\n"); /* Set autoincrement on TAR */ writeAP(AP_CSW, AP_CSW_DEFAULT | AP_CSW_AUTO_INCREMENT); for ( i=0; i<numWords; i++ ) { /* Get current address */ addr = i*4; /* TAR must be initialized at every TAR wrap boundary * because the autoincrement wraps around at these */ if ( (addr & tarWrap) == 0 ) { writeAP(AP_TAR, addr); /* Do one dummy read. Subsequent reads will return the * correct result. */ readAP(AP_DRW, &value); } /* Read the value from addr */ readAP(AP_DRW, &value); /* Verify that the read value matches what is expected */ if ( value != fwImage[i] ) { printf("Verification failed at address 0x%.8x\n", addr); printf("Value is 0x%.8x, should have been 0x%.8x\n", value, fwImage[i]); ret = false; break; } } /* Disable autoincrement on TAR */ writeAP(AP_CSW, AP_CSW_DEFAULT); return ret; }
/********************************************************** * Uploads and runs the flashloader on the target * The flashloader is written directly to the start * of RAM. Then the PC and SP are loaded from the * flashloader image. **********************************************************/ void uploadFlashloader(uint32_t *flImage, uint32_t size) { int w; uint32_t addr; uint32_t tarWrap; uint32_t numWords = size / 4; if ( numWords * 4 < size ) numWords++; resetAndHaltTarget(); /* Get the TAR wrap-around period */ tarWrap = getTarWrap(); printf("Uploading flashloader\n"); /* Enable autoincrement on TAR */ writeAP(AP_CSW, AP_CSW_DEFAULT | AP_CSW_AUTO_INCREMENT); for ( w=0; w<numWords; w++ ) { /* Get address of current word */ addr = RAM_START + w * 4; /* At the TAR wrap boundary we need to reinitialize TAR * since the autoincrement wraps at these */ if ( (addr & tarWrap) == 0 ) { writeAP(AP_TAR, addr); } writeAP(AP_DRW, flImage[w]); } writeAP(AP_CSW, AP_CSW_DEFAULT); printf("Booting flashloader\n"); /* Load SP (Reg 13) from flashloader image */ writeCpuReg(13, flImage[0]); /* Load PC (Reg 15) from flashloader image */ writeCpuReg(15, flImage[1]); runTarget(); }
/********************************************************** * Writes a chunk of data to a buffer in the flashloader. * This function does not make any checks or assumptions. * It simply copies a number of words from the * local to the remote buffer. * * @param remoteAddr * Address of the flashloader buffer at the target * * @param localBuffer * The local buffer to write from * * @param numWords * Number of words to write to buffer **********************************************************/ void writeToFlashloaderBuffer(uint32_t remoteAddr, uint32_t *localBuffer, int numWords) { uint32_t bufferPointer = (uint32_t)remoteAddr; int curWord = 0; uint32_t tarWrap; /* Get the TAR wrap-around period */ tarWrap = getTarWrap(); /* Set auto increment on TAR to allow faster writes */ writeAP(AP_CSW, AP_CSW_DEFAULT | AP_CSW_AUTO_INCREMENT); /* Initialize TAR with the start of buffer */ writeAP(AP_TAR, bufferPointer); /* Send up to one full buffer of data */ while ( curWord < numWords ) { /* At TAR wrap boundary we need to reinitialize TAR * since the autoincrement wraps at these */ if ( (bufferPointer & tarWrap) == 0 ) { writeAP(AP_TAR, bufferPointer); } /* Write one word */ writeAP(AP_DRW, localBuffer[curWord]); /* Increment local and remote pointers */ bufferPointer += 4; curWord += 1; } /* Disable auto increment on TAR */ writeAP(AP_CSW, AP_CSW_DEFAULT); }