From 5a4ff6bb6a1a9f04a159d2ee1d9d7f80b6cdfc5a 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/esp32c5/system_internal.c | 7 ++++++- .../port/soc/esp32c6/system_internal.c | 3 +++ .../port/soc/esp32c61/system_internal.c | 6 ++++++ .../port/soc/esp32h2/system_internal.c | 3 +++ .../port/soc/esp32h21/system_internal.c | 3 +++ .../port/soc/esp32h4/system_internal.c | 3 +++ .../port/soc/esp32p4/system_internal.c | 18 ++++++++++++++---- .../port/soc/esp32s3/system_internal.c | 4 +++- 9 files changed, 48 insertions(+), 8 deletions(-) diff --git a/components/esp_system/port/soc/esp32/system_internal.c b/components/esp_system/port/soc/esp32/system_internal.c index b64320d70d..cd15e1e230 100644 --- a/components/esp_system/port/soc/esp32/system_internal.c +++ b/components/esp_system/port/soc/esp32/system_internal.c @@ -48,8 +48,13 @@ void 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/esp32c5/system_internal.c b/components/esp_system/port/soc/esp32c5/system_internal.c index 6c1e701d26..f9b8c95bd2 100644 --- a/components/esp_system/port/soc/esp32c5/system_internal.c +++ b/components/esp_system/port/soc/esp32c5/system_internal.c @@ -52,6 +52,10 @@ void 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); + // The DMA inside SDIO slave needs to be reset to avoid memory corruption after restart. + SET_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_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,9 +63,10 @@ void esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); - // CLEAR_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_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_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_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/esp32c6/system_internal.c b/components/esp_system/port/soc/esp32c6/system_internal.c index 4652cda722..98536cfae9 100644 --- a/components/esp_system/port/soc/esp32c6/system_internal.c +++ b/components/esp_system/port/soc/esp32c6/system_internal.c @@ -51,6 +51,8 @@ void 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); @@ -61,6 +63,7 @@ void 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/esp32c61/system_internal.c b/components/esp_system/port/soc/esp32c61/system_internal.c index 6a64bf21db..60d38fdd3e 100644 --- a/components/esp_system/port/soc/esp32c61/system_internal.c +++ b/components/esp_system/port/soc/esp32c61/system_internal.c @@ -54,6 +54,10 @@ void esp_system_reset_modules_on_exit(void) SET_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); SET_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); + // The DMA inside SDIO slave needs to be reset to avoid memory corruption after restart. + SET_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_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); @@ -62,6 +66,8 @@ void esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); 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_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_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 eb750868b9..afd0384c70 100644 --- a/components/esp_system/port/soc/esp32h2/system_internal.c +++ b/components/esp_system/port/soc/esp32h2/system_internal.c @@ -48,6 +48,8 @@ void 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); @@ -57,6 +59,7 @@ void 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/esp32h21/system_internal.c b/components/esp_system/port/soc/esp32h21/system_internal.c index 4f88da7e16..9ce076894c 100644 --- a/components/esp_system/port/soc/esp32h21/system_internal.c +++ b/components/esp_system/port/soc/esp32h21/system_internal.c @@ -48,6 +48,8 @@ void 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); @@ -57,6 +59,7 @@ void 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/esp32h4/system_internal.c b/components/esp_system/port/soc/esp32h4/system_internal.c index 0dec7b9510..2c8dd1a8c9 100644 --- a/components/esp_system/port/soc/esp32h4/system_internal.c +++ b/components/esp_system/port/soc/esp32h4/system_internal.c @@ -43,6 +43,8 @@ void esp_system_reset_modules_on_exit(void) SET_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); SET_PERI_REG_MASK(PCR_PWM0_CONF_REG, PCR_PWM0_RST_EN); SET_PERI_REG_MASK(PCR_PWM1_CONF_REG, PCR_PWM1_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); @@ -53,6 +55,7 @@ void esp_system_reset_modules_on_exit(void) CLEAR_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); CLEAR_PERI_REG_MASK(PCR_PWM0_CONF_REG, PCR_PWM0_RST_EN); CLEAR_PERI_REG_MASK(PCR_PWM1_CONF_REG, PCR_PWM1_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 3b9955a629..e9abe6472f 100644 --- a/components/esp_system/port/soc/esp32p4/system_internal.c +++ b/components/esp_system/port/soc/esp32p4/system_internal.c @@ -69,28 +69,38 @@ void 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 9e9fd4960d..0420bde990 100644 --- a/components/esp_system/port/soc/esp32s3/system_internal.c +++ b/components/esp_system/port/soc/esp32s3/system_internal.c @@ -56,7 +56,9 @@ void 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);