Skip to content

Commit 18d5457

Browse files
committed
fix(esp_hw_support): allow allocating interrupts with handlers in ROM with IRAM attribute
The interrupt allocator now allows allocating an interrupt with a handler in ROM and flags set to ESP_INTR_FLAG_IRAM
1 parent 7a5c05e commit 18d5457

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

components/esp_hw_support/include/esp_intr_alloc.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -317,6 +317,18 @@ static inline int esp_intr_level_to_flags(int level)
317317
*/
318318
esp_err_t esp_intr_dump(FILE *stream);
319319

320+
321+
/**
322+
* @brief Check if the given pointer is in the safe ISR area.
323+
* In other words, make sure that the pointer's content is accessible at
324+
* any time, regardless of the cache status
325+
*
326+
* @param ptr Pointer to check
327+
*
328+
* @return true if `ptr` points to ISR area, false else
329+
*/
330+
bool esp_intr_ptr_in_isr_region(void* ptr);
331+
320332
/**@}*/
321333

322334

components/esp_hw_support/include/esp_memory_utils.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -307,14 +307,37 @@ inline static bool esp_ptr_in_drom(const void *p) {
307307
/* For ESP32-S3, when the DCACHE size is set to 16 kB, the unused 48 kB is
308308
* added to the heap in 2 blocks of 32 kB (from 0x3FCF0000) and 16 kB
309309
* (from 0x3C000000 (SOC_DROM_LOW) - 0x3C004000).
310-
* The drom_start_addr has to be moved by 0x4000 (16kB) to accomodate
310+
* The drom_start_addr has to be moved by 0x4000 (16kB) to accommodate
311311
* this addition. */
312312
drom_start_addr += 0x4000;
313313
#endif
314314

315315
return ((intptr_t)p >= drom_start_addr && (intptr_t)p < SOC_DROM_HIGH);
316316
}
317317

318+
319+
/**
320+
* @brief Check if the given pointer is in ROM
321+
*
322+
* @param ptr Pointer to check
323+
*
324+
* @return true if `ptr` points to ROM, false else
325+
*/
326+
__attribute__((always_inline))
327+
inline static bool esp_ptr_in_rom(const void *p)
328+
{
329+
intptr_t ip = (intptr_t) p;
330+
return
331+
/**
332+
* The following DROM macros are only defined on RISC-V targets, moreover, to prevent
333+
* the compiler from generating a `logical-op` warning, make sure the macros are
334+
* distinct. */
335+
#if CONFIG_IDF_TARGET_ARCH_RISCV && SOC_DROM_MASK_LOW != SOC_IROM_MASK_LOW
336+
(ip >= SOC_DROM_MASK_LOW && ip < SOC_DROM_MASK_HIGH) ||
337+
#endif
338+
(ip >= SOC_IROM_MASK_LOW && ip < SOC_IROM_MASK_HIGH);
339+
}
340+
318341
/**
319342
* @brief Check if the stack pointer is in dram
320343
*

components/esp_hw_support/intr_alloc.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,13 @@ static void IRAM_ATTR non_shared_intr_isr(void *arg)
472472
}
473473
#endif
474474

475+
476+
bool esp_intr_ptr_in_isr_region(void* ptr)
477+
{
478+
return esp_ptr_in_iram(ptr) || esp_ptr_in_rtc_iram_fast(ptr) || esp_ptr_in_rom(ptr);
479+
}
480+
481+
475482
//We use ESP_EARLY_LOG* here because this can be called before the scheduler is running.
476483
esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusreg, uint32_t intrstatusmask, intr_handler_t handler,
477484
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
499506
//ToDo: if we are to allow placing interrupt handlers into the 0x400c0000—0x400c2000 region,
500507
//we need to make sure the interrupt is connected to the CPU0.
501508
//CPU1 does not have access to the RTC fast memory through this region.
502-
if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_ptr_in_iram(handler) && !esp_ptr_in_rtc_iram_fast(handler)) {
509+
if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_intr_ptr_in_isr_region(handler)) {
503510
return ESP_ERR_INVALID_ARG;
504511
}
505512

0 commit comments

Comments
 (0)