drivers: flash: stm32g4: Flush caches after erase

This commit fixes sporadic kernel panics when writing big data chunks
to the flash. (data bus errors)
Reference manual:
If an erase operation in Flash memory also concerns data in the data
or instruction cache, you have to make sure that these data are
rewritten before they are accessed during code execution.
If this cannot be done safely, it is recommended to flush the caches
by setting the DCRST and ICRST bits in the Flash access control
register (FLASH_ACR).

Signed-off-by: Alexander Wachter <alexander.wachter@leica-geosystems.com>
This commit is contained in:
Alexander Wachter 2021-02-11 15:57:22 +01:00 committed by Anas Nashif
parent 8c9b06ad82
commit 09fea5cc5e

View file

@ -46,6 +46,29 @@ bool flash_stm32_valid_range(const struct device *dev, off_t offset,
flash_stm32_range_exists(dev, offset, len);
}
static inline void flush_cache(FLASH_TypeDef *regs)
{
if (regs->ACR & FLASH_ACR_DCEN) {
regs->ACR &= ~FLASH_ACR_DCEN;
/* Datasheet: DCRST: Data cache reset
* This bit can be written only when thes data cache is disabled
*/
regs->ACR |= FLASH_ACR_DCRST;
regs->ACR &= ~FLASH_ACR_DCRST;
regs->ACR |= FLASH_ACR_DCEN;
}
if (regs->ACR & FLASH_ACR_ICEN) {
regs->ACR &= ~FLASH_ACR_ICEN;
/* Datasheet: ICRST: Instruction cache reset :
* This bit can be written only when the instruction cache
* is disabled
*/
regs->ACR |= FLASH_ACR_ICRST;
regs->ACR &= ~FLASH_ACR_ICRST;
regs->ACR |= FLASH_ACR_ICEN;
}
}
static int write_dword(const struct device *dev, off_t offset, uint64_t val)
{
@ -159,6 +182,8 @@ static int erase_page(const struct device *dev, unsigned int offset)
/* Wait for the BSY bit */
rc = flash_stm32_wait_flash_idle(dev);
flush_cache(regs);
#ifdef FLASH_OPTR_DBANK
regs->CR &= ~(FLASH_CR_PER | FLASH_CR_BKER);
#else