From e53cf773e41620d99a5017149fa3afa60733fc3c Mon Sep 17 00:00:00 2001 From: Xiao Xufeng Date: Tue, 26 Aug 2025 15:09:53 +0800 Subject: [PATCH] dma: fixed issue that DMA are not reset when CPU reset When DMA keep writing the memory, some data may be corrupted after reset. For example, the stack of bootloader may be overwritten and failed to boot until a higher scope of reset (Core). --- .../port/soc/esp32/system_internal.c | 9 +++++++-- .../port/soc/esp32c6/system_internal.c | 3 +++ .../port/soc/esp32h2/system_internal.c | 3 +++ .../port/soc/esp32p4/system_internal.c | 18 ++++++++++++++---- .../port/soc/esp32s3/system_internal.c | 4 +++- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/components/esp_system/port/soc/esp32/system_internal.c b/components/esp_system/port/soc/esp32/system_internal.c index 6089ea6968..56e1a4479d 100644 --- a/components/esp_system/port/soc/esp32/system_internal.c +++ b/components/esp_system/port/soc/esp32/system_internal.c @@ -47,8 +47,13 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, //UART TX FIFO cannot be reset correctly on ESP32, so reset the UART memory by DPORT here. DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_SPI2_RST | DPORT_SPI3_RST | - DPORT_SPI_DMA_RST | DPORT_UART_RST | DPORT_UART1_RST | DPORT_UART2_RST | - DPORT_UART_MEM_RST | DPORT_PWM0_RST | DPORT_PWM1_RST); + // The DMA inside SPI needs to be reset to avoid memory corruption after restart. + DPORT_SPI_DMA_RST | + DPORT_UART_RST | DPORT_UART1_RST | DPORT_UART2_RST | DPORT_UART_MEM_RST | + DPORT_PWM0_RST | DPORT_PWM1_RST | + // The DMA inside I2S needs to be reset to avoid memory corruption after restart. + DPORT_I2S0_RST | DPORT_I2S1_RST | + DPORT_UHCI0_RST | DPORT_UHCI1_RST); DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0); // Reset crypto peripherals. This ensures a clean state for the crypto peripherals after a CPU restart and hence diff --git a/components/esp_system/port/soc/esp32c6/system_internal.c b/components/esp_system/port/soc/esp32c6/system_internal.c index 94dac0aa25..cdb289aef4 100644 --- a/components/esp_system/port/soc/esp32c6/system_internal.c +++ b/components/esp_system/port/soc/esp32c6/system_internal.c @@ -49,6 +49,8 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) SET_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); SET_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); SET_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); + //ETM may directly control the GPIO or other peripherals even after CPU reset. Reset to stop these control. + SET_PERI_REG_MASK(PCR_ETM_CONF_REG, PCR_ETM_RST_EN); // Clear Peripheral clk rst CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); @@ -59,6 +61,7 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); CLEAR_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); CLEAR_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); + CLEAR_PERI_REG_MASK(PCR_ETM_CONF_REG, PCR_ETM_RST_EN); // Reset crypto peripherals. This ensures a clean state for the crypto peripherals after a CPU restart // and hence avoiding any possibility with crypto failure in ROM security workflows. diff --git a/components/esp_system/port/soc/esp32h2/system_internal.c b/components/esp_system/port/soc/esp32h2/system_internal.c index 4202d2afc1..7857f99747 100644 --- a/components/esp_system/port/soc/esp32h2/system_internal.c +++ b/components/esp_system/port/soc/esp32h2/system_internal.c @@ -46,6 +46,8 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); SET_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); SET_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); + //ETM may directly control the GPIO or other peripherals even after CPU reset. Reset to stop these control. + SET_PERI_REG_MASK(PCR_ETM_CONF_REG, PCR_ETM_RST_EN); // Clear Peripheral clk rst CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); @@ -55,6 +57,7 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); CLEAR_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); CLEAR_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); + CLEAR_PERI_REG_MASK(PCR_ETM_CONF_REG, PCR_ETM_RST_EN); // Reset crypto peripherals. This ensures a clean state for the crypto peripherals after a CPU restart // and hence avoiding any possibility with crypto failure in ROM security workflows. diff --git a/components/esp_system/port/soc/esp32p4/system_internal.c b/components/esp_system/port/soc/esp32p4/system_internal.c index dfe1be33cb..98e669d036 100644 --- a/components/esp_system/port/soc/esp32p4/system_internal.c +++ b/components/esp_system/port/soc/esp32p4/system_internal.c @@ -68,28 +68,38 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) } // Set Peripheral clk rst + SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI); + SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_DUAL_MSPI_AXI); + // DMA needs to be reset to avoid memory corruption after restart. Now only AHB supports this. + // For other AXI DMAs, we have already stop them above. + SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_AHB_PDMA); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_TIMERGRP1); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_STIMER); - SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_DUAL_MSPI_AXI); - SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART0_CORE); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART1_CORE); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART2_CORE); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART3_CORE); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART4_CORE); SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_ADC); + SET_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_H264); // Clear Peripheral clk rst + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI); + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_DUAL_MSPI_AXI); + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_AHB_PDMA); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_TIMERGRP1); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_STIMER); - CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_DUAL_MSPI_AXI); - CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_MSPI_AXI); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART0_CORE); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART1_CORE); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART2_CORE); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART3_CORE); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN1_REG, HP_SYS_CLKRST_REG_RST_EN_UART4_CORE); CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_ADC); + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_HP_RST_EN2_REG, HP_SYS_CLKRST_REG_RST_EN_H264); + + // The DMA inside SDMMC Host needs to be reset to avoid memory corruption after restart. + SET_PERI_REG_MASK(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG, LP_CLKRST_RST_EN_SDMMC); + CLEAR_PERI_REG_MASK(LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG, LP_CLKRST_RST_EN_SDMMC); // Reset crypto peripherals. This ensures a clean state for the crypto peripherals after a CPU restart // and hence avoiding any possibility with crypto failure in ROM security workflows. diff --git a/components/esp_system/port/soc/esp32s3/system_internal.c b/components/esp_system/port/soc/esp32s3/system_internal.c index 663fedc847..23b4f56a98 100644 --- a/components/esp_system/port/soc/esp32s3/system_internal.c +++ b/components/esp_system/port/soc/esp32s3/system_internal.c @@ -55,7 +55,9 @@ void IRAM_ATTR esp_system_reset_modules_on_exit(void) // Reset dma and crypto peripherals. This ensures a clean state for the crypto peripherals after a CPU restart // and hence avoiding any possibility with crypto failure in ROM security workflows. SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST | SYSTEM_CRYPTO_AES_RST | SYSTEM_CRYPTO_DS_RST | - SYSTEM_CRYPTO_HMAC_RST | SYSTEM_CRYPTO_RSA_RST | SYSTEM_CRYPTO_SHA_RST); + SYSTEM_CRYPTO_HMAC_RST | SYSTEM_CRYPTO_RSA_RST | SYSTEM_CRYPTO_SHA_RST | + // The DMA inside SDMMC Host needs to be reset to avoid memory corruption after restart. + SYSTEM_SDIO_HOST_RST); REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0); SET_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET);