diff --git a/components/esp_hw_support/include/esp_intr_alloc.h b/components/esp_hw_support/include/esp_intr_alloc.h index 3106332c0d..60e3576187 100644 --- a/components/esp_hw_support/include/esp_intr_alloc.h +++ b/components/esp_hw_support/include/esp_intr_alloc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -317,6 +317,18 @@ static inline int esp_intr_level_to_flags(int level) */ esp_err_t esp_intr_dump(FILE *stream); + +/** + * @brief Check if the given pointer is in the safe ISR area. + * In other words, make sure that the pointer's content is accessible at + * any time, regardless of the cache status + * + * @param ptr Pointer to check + * + * @return true if `ptr` points to ISR area, false else + */ +bool esp_intr_ptr_in_isr_region(void* ptr); + /**@}*/ diff --git a/components/esp_hw_support/include/esp_memory_utils.h b/components/esp_hw_support/include/esp_memory_utils.h index 1e22dc4c67..427dc4912e 100644 --- a/components/esp_hw_support/include/esp_memory_utils.h +++ b/components/esp_hw_support/include/esp_memory_utils.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -307,7 +307,7 @@ inline static bool esp_ptr_in_drom(const void *p) { /* For ESP32-S3, when the DCACHE size is set to 16 kB, the unused 48 kB is * added to the heap in 2 blocks of 32 kB (from 0x3FCF0000) and 16 kB * (from 0x3C000000 (SOC_DROM_LOW) - 0x3C004000). - * The drom_start_addr has to be moved by 0x4000 (16kB) to accomodate + * The drom_start_addr has to be moved by 0x4000 (16kB) to accommodate * this addition. */ drom_start_addr += 0x4000; #endif @@ -315,6 +315,29 @@ inline static bool esp_ptr_in_drom(const void *p) { return ((intptr_t)p >= drom_start_addr && (intptr_t)p < SOC_DROM_HIGH); } + +/** + * @brief Check if the given pointer is in ROM + * + * @param ptr Pointer to check + * + * @return true if `ptr` points to ROM, false else + */ +__attribute__((always_inline)) +inline static bool esp_ptr_in_rom(const void *p) +{ + intptr_t ip = (intptr_t) p; + return + /** + * The following DROM macros are only defined on RISC-V targets, moreover, to prevent + * the compiler from generating a `logical-op` warning, make sure the macros are + * distinct. */ +#if CONFIG_IDF_TARGET_ARCH_RISCV && SOC_DROM_MASK_LOW != SOC_IROM_MASK_LOW + (ip >= SOC_DROM_MASK_LOW && ip < SOC_DROM_MASK_HIGH) || +#endif + (ip >= SOC_IROM_MASK_LOW && ip < SOC_IROM_MASK_HIGH); +} + /** * @brief Check if the stack pointer is in dram * diff --git a/components/esp_hw_support/intr_alloc.c b/components/esp_hw_support/intr_alloc.c index 993e90f27c..dec1d1e24b 100644 --- a/components/esp_hw_support/intr_alloc.c +++ b/components/esp_hw_support/intr_alloc.c @@ -472,6 +472,13 @@ static void IRAM_ATTR non_shared_intr_isr(void *arg) } #endif + +bool esp_intr_ptr_in_isr_region(void* ptr) +{ + return esp_ptr_in_iram(ptr) || esp_ptr_in_rtc_iram_fast(ptr) || esp_ptr_in_rom(ptr); +} + + //We use ESP_EARLY_LOG* here because this can be called before the scheduler is running. esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusreg, uint32_t intrstatusmask, intr_handler_t handler, void *arg, intr_handle_t *ret_handle) @@ -499,7 +506,7 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre //ToDo: if we are to allow placing interrupt handlers into the 0x400c0000—0x400c2000 region, //we need to make sure the interrupt is connected to the CPU0. //CPU1 does not have access to the RTC fast memory through this region. - if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_ptr_in_iram(handler) && !esp_ptr_in_rtc_iram_fast(handler)) { + if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_intr_ptr_in_isr_region(handler)) { return ESP_ERR_INVALID_ARG; }