uint8_t flashrom_erase(uint8_t *addr) { uint8_t sec = iap_get_sector((uint32_t) addr); unsigned intstate; if (sec == INVALID_ADDRESS) { DEBUG("Invalid address\n"); return 0; } /* check sector */ if (!blank_check_sector(sec, sec)) { DEBUG("Sector already blank!\n"); return 1; } /* prepare sector */ if (prepare_sectors(sec, sec)) { DEBUG("-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION --\n"); return 0; } intstate = disableIRQ(); /* erase sector */ if (erase_sectors(sec, sec)) { DEBUG("-- ERROR: ERASE SECTOR --\n"); restoreIRQ(intstate); return 0; } restoreIRQ(intstate); /* check again */ if (blank_check_sector(sec, sec)) { DEBUG("-- ERROR: BLANK_CHECK_SECTOR\n"); return 0; } DEBUG("Sector successfully erased.\n"); return 1; }
/*FUNCTION*---------------------------------------------------------------- * * Function Name : FlashLineCW * Returned Value : 0 if successful, other value if error * Comments : Parse and flash a full line * *END*--------------------------------------------------------------------*/ static uint_8 FlashLineCW ( /* [IN] the Line to parse */ uint_8 *Line ) { /* Body */ uint_8 result = FLASH_IMAGE_SUCCESS; uint_32 write_addr; uint_32 data_length; write_addr = get_uint32(Line,0); /* address to flash */ data_length = get_uint32(Line,4); /* length of data */ #ifdef _MC9S08_H if((write_addr >= (uint_32)MIN_FLASH1_ADDRESS) && (write_addr <= FLASH_PROTECTED_ADDRESS)) #else if((write_addr >= (uint_32)FLASH_PROTECTED_ADDRESS) && (write_addr <= MAX_FLASH1_ADDRESS)) #endif { DisableInterrupts; (void)erase_sectors((uint_32*)(write_addr),data_length); if (Flash_ByteProgram((uint_32*)(write_addr),(uint_32 *)(Line + 8),data_length)) result = FLASH_IMAGE_ERROR; SizeOfFirmware = write_addr - (uint_32) IMAGE_ADDR + data_length; EnableInterrupts; } /* EndIf */ return result; } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : FlashLineS19 * Returned Value : 0 if successful, other value if error * Comments : Parse and flash a full line * *END*--------------------------------------------------------------------*/ static uint_8 FlashLineS19 ( /* [IN] the Line to parse */ uint_8 *Line ) { /* Body */ static uint_8 length; static uint_8 checksum; static uint_8 i, offset,temp,c_temp,j; static uint_8 type; static uint_8 data; static uint_8 cur_point; /* current pointer */ uint_8 buffer_to_flash[256]; c_temp=Line[0]; if (c_temp!='S') { BootloaderStatus = BootloaderS19Error; return FLASH_IMAGE_ERROR; } /* EndIf */ /* Get record length */ cur_point = 2; length = GetSpair(Line,cur_point); if(S19FileDone) { /* not a valid S19 file */ BootloaderStatus = BootloaderS19Error; return FLASH_IMAGE_ERROR; } /* EndIf */ cur_point--; checksum = length; type=Line[1]; /* Take appropriate action */ switch (type) { case '1': case '2': case '3': S19Address = (uint_32) NULL; type -= '0'; cur_point=4; for (i = 0; i <= type ; i++) { /* Formulate address */ /* Address needs to be word aligned for successful flash program */ data = GetSpair(Line,cur_point); if(S19FileDone) { /* not a valid S19 file */ BootloaderStatus = BootloaderS19Error; return FLASH_IMAGE_ERROR; } /* EndIf */ S19Address = (S19Address << 8) | data; /* Maintain 8-bit checksum */ checksum = (unsigned char)((data + checksum) & 0x00FF); cur_point+=2; } /* EndFor */ if (CheckAddressValid(S19Address)) { /* 32-bit cores program flash in 32-bit words */ /* Therefore S19 address needs to be adjusted to be word aligned */ /* Pad beginning of buffer if address not word aligned */ #ifndef _MC9S08_H offset = (uint_8) (S19Address & 0x0003); S19Address = (uint_32) (S19Address & 0xFFFFFFFC); length += offset; for (i = 0; i < offset; i++) { buffer_to_flash[i] = 0xFF; } /* EndFor */ #endif /* Get data and put into buffer */ for (i = offset; i < (length - (type+2)); i++) { data=GetSpair(Line,cur_point); buffer_to_flash[i] =data; cur_point+=2; if(S19FileDone) { /* not a valid S19 file */ BootloaderStatus = BootloaderS19Error; return FLASH_IMAGE_ERROR; } /* EndIf */ } /* EndFor */ /* Calculate checksum */ for (i = offset; i < (length - (type+2)); i++) { checksum = (unsigned char)((buffer_to_flash[i] + checksum) & 0x00FF); } /* EndFor */ /* Get checksum byte */ data = GetSpair(Line,cur_point); cur_point+=2; if(S19FileDone) { /* not a valid S19 file */ BootloaderStatus = BootloaderS19Error; return FLASH_IMAGE_ERROR; } /* EndIf */ if (((data - ~checksum) & 0x00FF) != 0) { BootloaderStatus = BootloaderS19Error; S19FileDone = TRUE; return FLASH_IMAGE_ERROR; } /* EndIf */ #ifndef _MC9S08_H /* For 32-bit cores Flash_Prog writes 32-bit words, not bytes */ /* if last 32-bit word in s-record is not complete, finish word */ if((i & 0x0003) != 0x0000) { /* 32-bit word not complete */ buffer_to_flash[i++] = 0xFF; /* pad end of word */ buffer_to_flash[i++] = 0xFF; /* pad end of word */ buffer_to_flash[i++] = 0xFF; /* pad end of word */ } /* EndIf */ /* NOTE: 8-bit core does not need to pad the end */ #endif /* Write buffered data to Flash */ #ifdef _MC9S08_H if((S19Address <= (uint_32)FLASH_PROTECTED_ADDRESS) && (S19Address >= MIN_FLASH1_ADDRESS)) #else if((S19Address >= (uint_32)FLASH_PROTECTED_ADDRESS) && (S19Address <= MAX_FLASH1_ADDRESS)) #endif { /* call flash program */ DisableInterrupts; (void)erase_sectors((uint_32*)S19Address,i); temp = Flash_ByteProgram((uint_32*)S19Address,(uint_32*)buffer_to_flash,i); SizeOfFirmware = S19Address - (uint_32) IMAGE_ADDR +i; EnableInterrupts; if(Flash_OK != temp) { BootloaderStatus = BootloaderFlashError; return FLASH_IMAGE_ERROR; } /* EndIf */ } /* EndIf */ } else /* S-Record points to invalid address */ { BootloaderStatus = BootloaderS19Error; return FLASH_IMAGE_ERROR; } /* EndIf */ break; case '7': case '8': case '9': S19Address = (uint_32) NULL; type = (unsigned char)(type - '0'); type = (unsigned char)(10 - type); cur_point=4; checksum = length; /* Get Address */ for (i = 0; i <= type ; i++) { for(j=0;j<length-1;j++) { data = GetSpair(Line,cur_point); if(S19FileDone) { /* not a valid S19 file */ BootloaderStatus = BootloaderS19Error; return FLASH_IMAGE_ERROR; } /* EndIf */ checksum = (unsigned char)((data + checksum) & 0x00FF); cur_point+=2; } /* EndFor */ /* Read checksum value */ data=GetSpair(Line,cur_point); if(S19FileDone) { /* not a valid S19 file */ BootloaderStatus = BootloaderS19Error; return FLASH_IMAGE_ERROR; } /* EndIf */ /* Check checksum */ if (((data - ~checksum) & 0x00FF) != 0) { BootloaderStatus = BootloaderS19Error; S19FileDone = TRUE; return FLASH_IMAGE_ERROR; } else { /* File completely read successfully */ BootloaderStatus = BootloaderSuccess; S19FileDone = TRUE; return FLASH_IMAGE_SUCCESS; } /* EndIf */ } /* EndFor */ break; case '0': case '4': case '5': case '6': default: break; } /* EndSwitch */ return FLASH_IMAGE_SUCCESS; } /* EndBody */
/*FUNCTION*---------------------------------------------------------------- * * Function Name : FlashApplication * Returned Value : 0 if successful, other value if error * Comments : parse and flash an array to flash memory * *END*--------------------------------------------------------------------*/ uint_8 FlashApplication ( /* [IN] the array to parse */ uint_8* arr, /* [IN] data length of the array */ uint_32 length ) { /* Body */ uint_8 result; uint_32 write_addr; /* address to write to flash */ static uint_32 bytes_written; /* number of bytes was written to flash */ #ifdef _MC9S08_H uint_16 header; #else uint_32 header; #endif #ifdef _MC9S08_H header = (uint_16)*(uint_16*)(arr); #else header = get_uint32(arr,0); #endif /* Get image type */ if(filetype == UNKNOWN) { bytes_written = 0; SizeOfFirmware = 0; /* first four bytes is SP */ if( (MIN_RAM1_ADDRESS <=header ) && (header<= MAX_RAM1_ADDRESS)) { #ifndef NO_PRINTF_SUPPORT printf("\nRaw binary file found\n\r"); printf("\nFLASHING....\n\rPlease do not remove your device\n\r"); #endif filetype = RAW_BINARY; } /* first four bytes is user application address */ if( (MIN_FLASH1_ADDRESS <=header ) && (header<= MAX_FLASH1_ADDRESS)) { #ifdef _MC9S08_H /* HCS08 don't have code warrior binary file */ filetype = RAW_BINARY; #else #ifndef NO_PRINTF_SUPPORT printf("\n\rCodeWarrior binary file found\n\r"); printf("\n\rFLASHING....\n\rPlease do not remove your device\n\r"); #endif filetype = CODE_WARRIOR_BINARY; #endif } /* first four bytes is S-Record header */ #ifdef LITTLE_ENDIAN header = BYTESWAP32(header); #endif #ifdef _MC9S08_H /*FSL: restrection for 8 bit architecture only*/ if(header ==(uint_32)(S19_RECORD_HEADER)) #else if((header&0xFFFF0000) ==(uint_32)(S19_RECORD_HEADER)) #endif { #ifndef NO_PRINTF_SUPPORT printf("\n\rS-Record file found\n\r"); printf("\n\rFLASHING....\n\rPlease do not remove your device\n\r"); #endif filetype = S19_RECORD; } if(filetype == UNKNOWN) { #if (!(defined _MC9S08_H)) #ifndef NO_PRINTF_SUPPORT printf("\n\r\t\tERROR......\n\rUnknown file type"); #endif #endif return (uint_8)-1;/*FSL: error*/ } /* EndIf */ } /* EndIf */ /* Flash image */ switch (filetype) { case RAW_BINARY: /* Raw binary file found*/ /* the address to write to flash */ write_addr =(uint_32) IMAGE_ADDR + bytes_written; /* if flash error , break the loop */ DisableInterrupts; (void)erase_sectors((uint_32*)(write_addr),length); result = Flash_ByteProgram((uint_32*)(write_addr),(uint_32*)arr,length); EnableInterrupts; bytes_written += length; SizeOfFirmware = bytes_written; break; case CODE_WARRIOR_BINARY: /* CodeWarrior binary file found */ result = FlashArrayCW(arr,length,line); /* DES parse and flash array */ break; case S19_RECORD: /* S19 file found */ result = FlashArrayS19(arr,length,line); /* DES parse and flash array */ break; } /* EndSwitch */ /* DES Should add programming verification code ...minimal code to see if "#Flash Programming Signature" present from linker script */ #ifndef NO_PRINTF_SUPPORT printf("&"); /* flashing indicator */ #endif return result; } /* EndBody */