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#if defined(STM32F4XX)
254 PWR->CR = (PWR->CR & ~PWR_CR_PLS_Msk) | PWR_CR_PLS_VALUE;
256 PWR->CR |= PWR_CR_PVDE;
257#elif defined(STM32F7XX)
259 PWR->CR1 = (PWR->CR1 & ~PWR_CR1_PLS_Msk) | PWR_CR1_PLS_VALUE;
261 PWR->CR1 |= PWR_CR1_PVDE;
262#elif defined(STM32H7XX)
264 PWR->CR1 = (PWR->CR1 & ~PWR_CR1_PLS_Msk) | PWR_CR1_PLS_VALUE;
266 PWR->CR1 |= PWR_CR1_PVDEN;
272#if defined(STM32F4XX)
273 return !(PWR->CSR & PWR_CSR_PVDO);
275 return !(PWR->CSR1 & PWR_CSR1_PVDO);
281 while (address <= endAddress) {
297 SCB_InvalidateDCache_by_Addr((uint32_t*)address,
size);
310 if (*(
char*) address != 0xFF)
330 if (*(
volatile char*) address != *
buffer)
344 SCB_InvalidateDCache_by_Addr((uint32_t*)source,
size);
347 memcpy(destination, (
char*) source,
size);
355 return FLASH_RETURN_LOWVOLTAGEERROR;
360 return FLASH_RETURN_NO_PERMISSION;
363 intFlashWaitWhileBusy();
366 FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
367 FLASH_CR |= FLASH_CR_PSIZE_VALUE;
370 size_t flashWordCount = (
size - 1) / 32 + 1;
376 for (
size_t word = 0; word < flashWordCount; word++) {
379 return FLASH_RETURN_LOWVOLTAGEERROR;
383 FLASH_CR |= FLASH_CR_PG;
389 static_assert(
sizeof(*pWrite) == 4,
"Driver supports only 32bit PSIZE");
392 for (
size_t i = 0; i < 8; i++) {
393 *pWrite++ = *pRead++;
401 intFlashWaitWhileBusy();
404 FLASH_CR &= ~FLASH_CR_PG;
423 FLASH->CR |= FLASH_CR_PG;
435 intFlashWaitWhileBusy();
438 FLASH->CR &= ~FLASH_CR_PG;
446 return FLASH_RETURN_LOWVOLTAGEERROR;
453 return FLASH_RETURN_NO_PERMISSION;
456 intFlashWaitWhileBusy();
459 FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
460 FLASH->CR |= FLASH_CR_PSIZE_VALUE;
465 return FLASH_RETURN_LOWVOLTAGEERROR;
469 size_t alignOffset = address %
sizeof(
flashdata_t);
471 if (alignOffset != 0) {
476 flashaddr_t alignedFlashAddress = address - alignOffset;
482 size_t chunkSize =
sizeof(
flashdata_t) - alignOffset;
483 if (chunkSize >
size)
487 memcpy((
char*) &tmp + alignOffset,
buffer, chunkSize);
495 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 bool intFlashGetPVDStatus()
static int intFlashCheckErrors()
static void intFlashSetPVD()
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