diff options
author | Nick Brassel <[email protected]> | 2023-11-26 22:59:38 +1100 |
---|---|---|
committer | GitHub <[email protected]> | 2023-11-26 22:59:38 +1100 |
commit | f96a7bbd6304410e15fa6fc744a9b0fa660f1eeb (patch) | |
tree | 09672f15b55d62540b80cd3fa52fd0d89b6e5407 /platforms/chibios/interrupt_handlers.c | |
parent | 3ef06aa732ce8063e11b2f983592529883f7ecbc (diff) | |
download | qmk_firmware-f96a7bbd6304410e15fa6fc744a9b0fa660f1eeb.tar.gz qmk_firmware-f96a7bbd6304410e15fa6fc744a9b0fa660f1eeb.zip |
Cater for ECC failures in EFL wear-leveling. (#19749)
Co-authored-by: Sergey Vlasov <[email protected]>
Diffstat (limited to 'platforms/chibios/interrupt_handlers.c')
-rw-r--r-- | platforms/chibios/interrupt_handlers.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/platforms/chibios/interrupt_handlers.c b/platforms/chibios/interrupt_handlers.c new file mode 100644 index 0000000000..4ba32d58e4 --- /dev/null +++ b/platforms/chibios/interrupt_handlers.c @@ -0,0 +1,45 @@ +// Copyright 2023 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later + +/////////////////////////////////////////////////////////////////////////////// +// BEGIN: STM32 EFL Wear-leveling ECC fault handling +// +// Some STM32s have ECC checks for all flash memory access. Whenever there's an +// ECC failure, the MCU raises the NMI interrupt. Whenever we receive such an +// interrupt whilst reading the wear-leveling EEPROM area, we gracefully cater +// for it, signalling the wear-leveling code that a failure has occurred. +/////////////////////////////////////////////////////////////////////////////// + +#include <ch.h> +#include <chcore.h> + +#ifdef WEAR_LEVELING_EMBEDDED_FLASH +# ifdef QMK_MCU_SERIES_STM32L4XX +# define ECC_ERRORS_TRIGGER_NMI_INTERRUPT +# define ECC_CHECK_REGISTER FLASH->ECCR +# define ECC_CHECK_FLAG FLASH_ECCR_ECCD +# endif // QMK_MCU_SERIES_STM32L4XX +#endif // WEAR_LEVELING_EMBEDDED_FLASH + +#ifdef ECC_ERRORS_TRIGGER_NMI_INTERRUPT + +extern bool backing_store_allow_ecc_errors(void); +extern void backing_store_signal_ecc_error(void); + +void NMI_Handler(void) { + if ((ECC_CHECK_REGISTER) & (ECC_CHECK_FLAG)) { + if (backing_store_allow_ecc_errors()) { + (ECC_CHECK_REGISTER) = (ECC_CHECK_FLAG); + backing_store_signal_ecc_error(); + return; + } + } + + chSysHalt("NMI"); +} + +#endif // ECC_ERRORS_TRIGGER_NMI_INTERRUPT + +/////////////////////////////////////////////////////////////////////////////// +// END: STM32 EFL Wear-leveling ECC fault handling +/////////////////////////////////////////////////////////////////////////////// |