diff --git a/drv/stm32h7-update-server/src/main.rs b/drv/stm32h7-update-server/src/main.rs index ce7a73fea..ba2f8a302 100644 --- a/drv/stm32h7-update-server/src/main.rs +++ b/drv/stm32h7-update-server/src/main.rs @@ -172,6 +172,7 @@ impl<'a> ServerImpl<'a> { words: &[u32; FLASH_WORD_WORDS], ) -> Result<(), RequestError> { ringbuf_entry!(Trace::WriteStart); + self.clear_errors(); // These variables are _philosophically_ constants, but since they're // generated by taking the address of a linker-generated symbol, we @@ -243,9 +244,24 @@ impl<'a> ServerImpl<'a> { .write(|w| unsafe { w.optkeyr().bits(FLASH_OPT_KEY2) }); } + fn clear_errors(&mut self) { + // https://github.com/zephyrproject-rtos/zephyr/issues/60449 + // https://community.st.com/t5/stm32-mcus-products/spurious-rdperr-and-rdserr-when-all-protection-and-security/td-p/279852 + // There are issue with the CPU speculating into unknown + // areas. One workaround is to explicitly mark the reigon as NX + // via MPU but that's expensive/costs an MPU region + // Another workaround is to just clear errors we don't + // expect to see + self.flash + .bank2() + .ccr + .modify(|_, w| w.clr_rdperr().set_bit().clr_rdserr().set_bit()); + } + fn bank_erase(&mut self) -> Result<(), RequestError> { ringbuf_entry!(Trace::EraseStart); + self.clear_errors(); // Enable relevant interrupts for completion (or failure) of erasing // bank2. sys_irq_control(notifications::FLASH_IRQ_MASK, true);