This is an automated email from the ASF dual-hosted git repository. utzig pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push: new b257c71 mcu: kinetis: fix QSPI HW reset race b257c71 is described below commit b257c715193c14ff92b279208ffca15eec9476a0 Author: Fabio Utzig <ut...@apache.org> AuthorDate: Wed Sep 22 18:26:16 2021 -0300 mcu: kinetis: fix QSPI HW reset race Lock the OS when calling `QSPI_SoftwareReset`; this API sets bits that result in a QSPI HW reset, loops for a while, and manually resets the same bits. If a context switch happens while those bits are set, and the next task reads the QSPI flash through the AHB mapping, this read results in zeroes being returned instead of the expected data. Also removed a non-required busy wait after the HW reset. Signed-off-by: Fabio Utzig <ut...@apache.org> --- hw/mcu/nxp/kinetis/src/hal_qspi.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hw/mcu/nxp/kinetis/src/hal_qspi.c b/hw/mcu/nxp/kinetis/src/hal_qspi.c index a9eff8a..66d5ad1 100644 --- a/hw/mcu/nxp/kinetis/src/hal_qspi.c +++ b/hw/mcu/nxp/kinetis/src/hal_qspi.c @@ -196,6 +196,7 @@ nxp_qspi_write(const struct hal_flash *dev, int32_t remaining; uint32_t *src32; int i; + os_sr_t sr; align = dev->hf_align; if (address % align) { @@ -263,8 +264,9 @@ nxp_qspi_write(const struct hal_flash *dev, } while (qspi_in_use(QuadSPI0)); + OS_ENTER_CRITICAL(sr); QSPI_SoftwareReset(QuadSPI0); - while (qspi_in_use(QuadSPI0)); + OS_EXIT_CRITICAL(sr); os_mutex_release(&g_mtx); @@ -274,6 +276,8 @@ nxp_qspi_write(const struct hal_flash *dev, static int nxp_qspi_erase_sector(const struct hal_flash *dev, uint32_t sector_address) { + os_sr_t sr; + while (qspi_is_busy(QuadSPI0)); os_mutex_pend(&g_mtx, OS_TIMEOUT_NEVER); @@ -289,7 +293,9 @@ nxp_qspi_erase_sector(const struct hal_flash *dev, uint32_t sector_address) QSPI_ClearCache(QuadSPI0); #endif + OS_ENTER_CRITICAL(sr); QSPI_SoftwareReset(QuadSPI0); + OS_EXIT_CRITICAL(sr); os_mutex_release(&g_mtx); @@ -299,6 +305,8 @@ nxp_qspi_erase_sector(const struct hal_flash *dev, uint32_t sector_address) void nxp_qspi_erase_chip(void) { + os_sr_t sr; + int chips = (MYNEWT_VAL(QSPIA_ENABLE) ? 1 : 0) + (MYNEWT_VAL(QSPIB_ENABLE) ? 1 : 0); uint32_t address; @@ -320,7 +328,9 @@ nxp_qspi_erase_chip(void) QSPI_ClearCache(QuadSPI0); #endif + OS_ENTER_CRITICAL(sr); QSPI_SoftwareReset(QuadSPI0); + OS_EXIT_CRITICAL(sr); address += MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) * MYNEWT_VAL(QSPI_FLASH_SECTOR_COUNT); @@ -336,6 +346,7 @@ nxp_qspi_erase(const struct hal_flash *dev, uint32_t size) { uint32_t erased_size; + os_sr_t sr; if (address % MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE) || size % MYNEWT_VAL(QSPI_FLASH_SECTOR_SIZE)) { @@ -370,7 +381,9 @@ nxp_qspi_erase(const struct hal_flash *dev, size -= erased_size; } + OS_ENTER_CRITICAL(sr); QSPI_SoftwareReset(QuadSPI0); + OS_EXIT_CRITICAL(sr); os_mutex_release(&g_mtx);