12#ifndef EFI_STORAGE_INT_FLASH_DRIVER
13#define EFI_STORAGE_INT_FLASH_DRIVER TRUE
16#if defined(EFI_BOOTLOADER) || EFI_STORAGE_INT_FLASH_DRIVER
26 #define FLASH_CR FLASH->CR2
27 #define FLASH_SR FLASH->SR2
28 #define FLASH_KEYR FLASH->KEYR2
29 #define FLASH_CCR FLASH->CCR2
32 #define FLASH_BASE 0x08100000
37 #define FLASH_CR FLASH->CR1
38 #define FLASH_SR FLASH->SR1
39 #define FLASH_KEYR FLASH->KEYR1
40 #define FLASH_CCR FLASH->CCR1
43 #define FLASH_BASE 0x08000000
47 #define FLASH_CR_STRT FLASH_CR_START
50 #define intFlashWaitWhileBusy() do { __DSB(); } while (FLASH_SR & FLASH_SR_QW);
52 #define FLASH_CR FLASH->CR
53 #define FLASH_SR FLASH->SR
54 #define FLASH_KEYR FLASH->KEYR
57 #define intFlashWaitWhileBusy() do { __DSB(); } while (FLASH->SR & FLASH_SR_BSY);
82 FLASH_CCR = 0xffffffff;
84 FLASH_SR = 0x0000ffff;
90 uint32_t sr = FLASH_SR;
93 if (sr & FLASH_SR_OPERR)
94 return FLASH_RETURN_OPERROR;
96 if (sr & FLASH_SR_WRPERR)
97 return FLASH_RETURN_WPERROR;
99 if (sr & FLASH_SR_PGAERR)
100 return FLASH_RETURN_ALIGNERROR;
102#ifdef FLASH_SR_PGPERR
103 if (sr & FLASH_SR_PGPERR)
104 return FLASH_RETURN_PPARALLERROR;
106#ifdef FLASH_SR_ERSERR
107 if (sr & FLASH_SR_ERSERR)
108 return FLASH_RETURN_ESEQERROR;
110#ifdef FLASH_SR_PGSERR
111 if (sr & FLASH_SR_PGSERR)
112 return FLASH_RETURN_PSEQERROR;
114#ifdef FLASH_SR_RDSERR
115 if (sr & FLASH_SR_RDSERR)
116 return FLASH_RETURN_SECURITYERROR;
118#ifdef FLASH_SR_RDPERR
119 if (sr & FLASH_SR_RDPERR)
120 return FLASH_RETURN_SECURITYERROR;
122#ifdef FLASH_SR_WRPERR
123 if (sr & FLASH_SR_WRPERR)
124 return FLASH_RETURN_SECURITYERROR;
126#ifdef FLASH_SR_CRCRDERR
127 if (sr & FLASH_SR_CRCRDERR)
128 return FLASH_RETURN_CRCERROR;
141 if (!(FLASH_CR & FLASH_CR_LOCK))
145 FLASH_KEYR = 0x45670123;
146 FLASH_KEYR = 0xCDEF89AB;
149 if (FLASH_CR & FLASH_CR_LOCK)
157#define intFlashLock() { FLASH_CR |= FLASH_CR_LOCK; }
161#ifdef FLASH_OPTCR_nDBANK
163 return (FLASH->OPTCR & FLASH_OPTCR_nDBANK) == 0;
182 uint8_t sectorRegIdx = sector;
193 sectorRegIdx |= 0x10;
199 return FLASH_RETURN_NO_PERMISSION;
202 intFlashWaitWhileBusy();
208 FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
209 FLASH_CR |= FLASH_CR_PSIZE_VALUE;
221 FLASH_CR &= ~FLASH_CR_SNB_Msk;
222 FLASH_CR |= (sectorRegIdx << FLASH_CR_SNB_Pos) & FLASH_CR_SNB_Msk;
224 FLASH_CR |= FLASH_CR_SER;
226 FLASH_CR |= FLASH_CR_STRT;
229 intFlashWaitWhileBusy();
232 FLASH_CR &= ~FLASH_CR_SER;
244 return FLASH_RETURN_BAD_FLASH;
252 while (address <= endAddress) {
268 SCB_InvalidateDCache_by_Addr((uint32_t*)address,
size);
281 if (*(
char*) address != 0xFF)
301 if (*(
volatile char*) address != *
buffer)
315 SCB_InvalidateDCache_by_Addr((uint32_t*)source,
size);
318 memcpy(destination, (
char*) source,
size);
326 return FLASH_RETURN_NO_PERMISSION;
329 intFlashWaitWhileBusy();
332 FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
333 FLASH_CR |= FLASH_CR_PSIZE_VALUE;
336 size_t flashWordCount = (
size - 1) / 32 + 1;
342 for (
size_t word = 0; word < flashWordCount; word++) {
344 FLASH_CR |= FLASH_CR_PG;
350 static_assert(
sizeof(*pWrite) == 4,
"Driver supports only 32bit PSIZE");
353 for (
size_t i = 0; i < 8; i++) {
354 *pWrite++ = *pRead++;
362 intFlashWaitWhileBusy();
365 FLASH_CR &= ~FLASH_CR_PG;
384 FLASH->CR |= FLASH_CR_PG;
396 intFlashWaitWhileBusy();
399 FLASH->CR &= ~FLASH_CR_PG;
409 return FLASH_RETURN_NO_PERMISSION;
412 intFlashWaitWhileBusy();
415 FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
416 FLASH->CR |= FLASH_CR_PSIZE_VALUE;
419 size_t alignOffset = address %
sizeof(
flashdata_t);
421 if (alignOffset != 0) {
426 flashaddr_t alignedFlashAddress = address - alignOffset;
432 size_t chunkSize =
sizeof(
flashdata_t) - alignOffset;
433 if (chunkSize >
size)
437 memcpy((
char*) &tmp + alignOffset,
buffer, chunkSize);
445 address += chunkSize;
return FLASH_RETURN_SUCCESS
int intFlashWrite(flashaddr_t address, const char *buffer, size_t size)
Copy data from a buffer to the flash memory.
bool intFlashIsErased(flashaddr_t address, size_t size)
Check if the size bytes of flash memory starting at address are erased.
int intFlashRead(flashaddr_t source, char *destination, size_t size)
Copy data from the flash memory to a destination.
bool intFlashCompare(flashaddr_t address, const char *buffer, size_t size)
Check if the data in buffer are identical to the one in flash memory.
int intFlashErase(flashaddr_t address, size_t size)
Erase the sectors containing the span of size bytes starting at address.
uintptr_t flashaddr_t
Address in the flash memory.
size_t flashSectorSize(flashsector_t sector)
Get the size of sector.
uint8_t flashsector_t
Index of a sector.
flashsector_t intFlashSectorAt(flashaddr_t address)
static bool isDualBank(void)
static int intFlashCheckErrors()
static int intFlashSectorErase(flashsector_t sector)
Erase the flash sector.
flashaddr_t intFlashSectorEnd(flashsector_t sector)
static void intFlashClearErrors()
flashaddr_t intFlashSectorBegin(flashsector_t sector)
static bool intFlashUnlock(void)
Unlock the flash memory for write access.
static int intFlashWriteData(flashaddr_t address, const flashdata_t data)
static BigBufferHandle buffer