mirror of https://github.com/wolfSSL/wolfBoot.git
fix tc3xx HAL to properly handle flash writes across sector boundariese
parent
8ae5ec27ff
commit
21a726ab46
|
@ -364,52 +364,66 @@ void hal_init(void)
|
||||||
*/
|
*/
|
||||||
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t* data, int size)
|
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t* data, int size)
|
||||||
{
|
{
|
||||||
/* base address of containing sector (TODO what if size spans sectors?)
|
const IfxFlash_FlashType type = getFlashTypeFromAddr(address);
|
||||||
*/
|
uint32_t currentAddress = address;
|
||||||
const uint32_t sectorAddress = GET_SECTOR_ADDR(address);
|
int remainingSize = size;
|
||||||
const IfxFlash_FlashType type = getFlashTypeFromAddr(address);
|
int bytesWrittenTotal = 0;
|
||||||
|
|
||||||
/* Determine the range of pages affected */
|
|
||||||
const uint32_t startPage = GET_PAGE_ADDR(address);
|
|
||||||
const uint32_t endPage = GET_PAGE_ADDR(address + size - 1);
|
|
||||||
uint32_t page;
|
|
||||||
|
|
||||||
/* Flag to check if sector read-modify-write is necessary */
|
|
||||||
int needsSectorRmw;
|
|
||||||
|
|
||||||
LED_ON(LED_PROG);
|
LED_ON(LED_PROG);
|
||||||
|
|
||||||
/* Check if any page within the range is not erased */
|
/* Process the data sector by sector */
|
||||||
needsSectorRmw = 0;
|
while (remainingSize > 0) {
|
||||||
for (page = startPage; page <= endPage;
|
uint32_t currentSectorAddress = GET_SECTOR_ADDR(currentAddress);
|
||||||
page += IFXFLASH_PFLASH_PAGE_LENGTH) {
|
uint32_t offsetInSector = currentAddress - currentSectorAddress;
|
||||||
if (!flashIsErased(page, IFXFLASH_PFLASH_PAGE_LENGTH, type)) {
|
uint32_t bytesInThisSector = WOLFBOOT_SECTOR_SIZE - offsetInSector;
|
||||||
needsSectorRmw = 1;
|
|
||||||
break;
|
/* Adjust bytes to write if this would overflow the current sector */
|
||||||
|
if (bytesInThisSector > remainingSize) {
|
||||||
|
bytesInThisSector = remainingSize;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* If a page within the range is erased, we need to read-modify-write the
|
/* Determine the range of pages affected in this sector */
|
||||||
* whole sector */
|
const uint32_t startPage = GET_PAGE_ADDR(currentAddress);
|
||||||
if (needsSectorRmw) {
|
const uint32_t endPage =
|
||||||
size_t offsetInSector;
|
GET_PAGE_ADDR(currentAddress + bytesInThisSector - 1);
|
||||||
|
uint32_t page;
|
||||||
|
int needsSectorRmw = 0;
|
||||||
|
|
||||||
/* Read entire sector into RAM */
|
/* Check if any page within the range is not erased */
|
||||||
cacheSector(sectorAddress, type);
|
for (page = startPage; page <= endPage;
|
||||||
|
page += IFXFLASH_PFLASH_PAGE_LENGTH) {
|
||||||
|
if (!flashIsErased(page, IFXFLASH_PFLASH_PAGE_LENGTH, type)) {
|
||||||
|
needsSectorRmw = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Erase the entire sector */
|
/* If a page within the range is not erased, we need to
|
||||||
hal_flash_erase(sectorAddress, WOLFBOOT_SECTOR_SIZE);
|
* read-modify-write the sector */
|
||||||
|
if (needsSectorRmw) {
|
||||||
|
/* Read entire sector into RAM */
|
||||||
|
cacheSector(currentSectorAddress, type);
|
||||||
|
|
||||||
/* Modify the relevant part of the RAM sector buffer */
|
/* Erase the entire sector */
|
||||||
offsetInSector = address - sectorAddress;
|
hal_flash_erase(currentSectorAddress, WOLFBOOT_SECTOR_SIZE);
|
||||||
memcpy((uint8_t*)sectorBuffer + offsetInSector, data, size);
|
|
||||||
|
|
||||||
/* Program the modified sector back into flash */
|
/* Modify the relevant part of the RAM sector buffer */
|
||||||
programCachedSector(sectorAddress, type);
|
memcpy((uint8_t*)sectorBuffer + offsetInSector,
|
||||||
}
|
data + bytesWrittenTotal, bytesInThisSector);
|
||||||
else {
|
|
||||||
/* All affected pages are erased, program the data directly */
|
/* Program the modified sector back into flash */
|
||||||
programBytesToErasedFlash(address, data, size, type);
|
programCachedSector(currentSectorAddress, type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* All affected pages are erased, program the data directly */
|
||||||
|
programBytesToErasedFlash(currentAddress, data + bytesWrittenTotal,
|
||||||
|
bytesInThisSector, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update pointers and counters */
|
||||||
|
bytesWrittenTotal += bytesInThisSector;
|
||||||
|
currentAddress += bytesInThisSector;
|
||||||
|
remainingSize -= bytesInThisSector;
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_OFF(LED_PROG);
|
LED_OFF(LED_PROG);
|
||||||
|
|
Loading…
Reference in New Issue