Skip to content

Commit dd00aa1

Browse files
author
Jiang Jiang Jian
committed
Merge branch 'fix/heap-allocate-in-rtc-iram_v5.4' into 'release/v5.4'
fix(heap): MALLOC_CAP_EXEC does not allocate in RTC IRAM (backport v5.4) See merge request espressif/esp-idf!35623
2 parents 7317a62 + 388ed34 commit dd00aa1

File tree

4 files changed

+59
-13
lines changed

4 files changed

+59
-13
lines changed

components/bootloader_support/include/bootloader_memory_utils.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ extern "C" {
2828
*/
2929
__attribute__((always_inline))
3030
inline static bool esp_dram_match_iram(void) {
31-
return (SOC_DRAM_LOW == SOC_IRAM_LOW && SOC_DRAM_HIGH == SOC_IRAM_HIGH);
31+
bool dram_match_iram = (SOC_DRAM_LOW == SOC_IRAM_LOW) &&
32+
(SOC_DRAM_HIGH == SOC_IRAM_HIGH);
33+
#if SOC_RTC_FAST_MEM_SUPPORTED
34+
dram_match_iram &= (SOC_RTC_IRAM_LOW == SOC_RTC_DRAM_LOW);
35+
#endif
36+
return dram_match_iram;
3237
}
3338

3439
/**
@@ -97,7 +102,7 @@ inline static bool esp_ptr_in_diram_iram(const void *p) {
97102
*/
98103
__attribute__((always_inline))
99104
inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
100-
#if SOC_RTC_FAST_MEM_SUPPORTED
105+
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
101106
return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
102107
#else
103108
return false;
@@ -151,6 +156,21 @@ inline static void * esp_ptr_diram_dram_to_iram(const void *p) {
151156
#endif
152157
}
153158

159+
/* Convert a RTC DRAM pointer to equivalent word address in RTC IRAM
160+
161+
- Address must be word aligned
162+
- Address must pass esp_ptr_in_rtc_dram_fast() test, or result will be invalid pointer
163+
*/
164+
__attribute__((always_inline))
165+
inline static void * esp_ptr_rtc_dram_to_iram(const void *p) {
166+
intptr_t ptr = (intptr_t)p;
167+
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
168+
return (void *) ( SOC_RTC_IRAM_LOW + (ptr - SOC_RTC_DRAM_LOW) );
169+
#else
170+
return (void *) ptr;
171+
#endif
172+
}
173+
154174
/* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
155175
156176
- Address must be word aligned

components/esp_hw_support/include/esp_memory_utils.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ extern "C" {
2727
*/
2828
__attribute__((always_inline))
2929
inline static bool esp_dram_match_iram(void) {
30-
return (SOC_DRAM_LOW == SOC_IRAM_LOW && SOC_DRAM_HIGH == SOC_IRAM_HIGH);
30+
bool dram_match_iram = (SOC_DRAM_LOW == SOC_IRAM_LOW) &&
31+
(SOC_DRAM_HIGH == SOC_IRAM_HIGH);
32+
#if SOC_RTC_FAST_MEM_SUPPORTED
33+
dram_match_iram &= (SOC_RTC_IRAM_LOW == SOC_RTC_DRAM_LOW);
34+
#endif
35+
return dram_match_iram;
3136
}
3237

3338
/**
@@ -96,7 +101,7 @@ inline static bool esp_ptr_in_diram_iram(const void *p) {
96101
*/
97102
__attribute__((always_inline))
98103
inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
99-
#if SOC_RTC_FAST_MEM_SUPPORTED
104+
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
100105
return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
101106
#else
102107
return false;
@@ -150,6 +155,21 @@ inline static void * esp_ptr_diram_dram_to_iram(const void *p) {
150155
#endif
151156
}
152157

158+
/* Convert a RTC DRAM pointer to equivalent word address in RTC IRAM
159+
160+
- Address must be word aligned
161+
- Address must pass esp_ptr_in_rtc_dram_fast() test, or result will be invalid pointer
162+
*/
163+
__attribute__((always_inline))
164+
inline static void * esp_ptr_rtc_dram_to_iram(const void *p) {
165+
intptr_t ptr = (intptr_t)p;
166+
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
167+
return (void *) ( SOC_RTC_IRAM_LOW + (ptr - SOC_RTC_DRAM_LOW) );
168+
#else
169+
return (void *) ptr;
170+
#endif
171+
}
172+
153173
/* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
154174
155175
- Address must be word aligned

components/heap/heap_caps_base.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,19 @@ HEAP_IRAM_ATTR static void *dram_alloc_to_iram_addr(void *addr, size_t len)
3838
{
3939
uintptr_t dstart = (uintptr_t)addr; //First word
4040
uintptr_t dend __attribute__((unused)) = dstart + len - 4; //Last word
41-
assert(esp_ptr_in_diram_dram((void *)dstart));
42-
assert(esp_ptr_in_diram_dram((void *)dend));
41+
assert(esp_ptr_in_diram_dram((void *)dstart) || esp_ptr_in_rtc_dram_fast((void *)dstart));
42+
assert(esp_ptr_in_diram_dram((void *)dend) || esp_ptr_in_rtc_dram_fast((void *)dend));
4343
assert((dstart & 3) == 0);
4444
assert((dend & 3) == 0);
4545
#if SOC_DIRAM_INVERTED // We want the word before the result to hold the DRAM address
4646
uint32_t *iptr = esp_ptr_diram_dram_to_iram((void *)dend);
4747
#else
48-
uint32_t *iptr = esp_ptr_diram_dram_to_iram((void *)dstart);
48+
uint32_t *iptr = NULL;
49+
if (esp_ptr_in_rtc_dram_fast((void *)dstart)) {
50+
iptr = esp_ptr_rtc_dram_to_iram((void *)dstart);
51+
} else {
52+
iptr = esp_ptr_diram_dram_to_iram((void *)dstart);
53+
}
4954
#endif
5055
*iptr = dstart;
5156
return iptr + 1;
@@ -57,7 +62,7 @@ HEAP_IRAM_ATTR void heap_caps_free( void *ptr)
5762
return;
5863
}
5964

60-
if (esp_ptr_in_diram_iram(ptr)) {
65+
if (esp_ptr_in_diram_iram(ptr) || esp_ptr_in_rtc_iram_fast(ptr)) {
6166
//Memory allocated here is actually allocated in the DRAM alias region and
6267
//cannot be de-allocated as usual. dram_alloc_to_iram_addr stores a pointer to
6368
//the equivalent DRAM address, though; free that.
@@ -132,7 +137,8 @@ HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_aligned_alloc_base(size_t alignment
132137
//This heap can satisfy all the requested capabilities. See if we can grab some memory using it.
133138
// If MALLOC_CAP_EXEC is requested but the DRAM and IRAM are on the same addresses (like on esp32c6)
134139
// proceed as for a default allocation.
135-
if ((caps & MALLOC_CAP_EXEC) && !esp_dram_match_iram() && esp_ptr_in_diram_dram((void *)heap->start)) {
140+
if (((caps & MALLOC_CAP_EXEC) && !esp_dram_match_iram()) &&
141+
(esp_ptr_in_diram_dram((void *)heap->start) || esp_ptr_in_rtc_dram_fast((void *)heap->start))) {
136142
//This is special, insofar that what we're going to get back is a DRAM address. If so,
137143
//we need to 'invert' it (lowest address in DRAM == highest address in IRAM and vice-versa) and
138144
//add a pointer to the DRAM equivalent before the address we're going to return.

components/heap/port/esp32s2/memory_layout.c

Lines changed: 4 additions & 4 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
*/
@@ -51,11 +51,11 @@ enum {
5151
/**
5252
* Defined the attributes and allocation priority of each memory on the chip,
5353
* The heap allocator will traverse all types of memory types in column High Priority Matching and match the specified caps at first,
54-
* if no memory caps matched or the allocation is failed, it will go to columns Medium Priorty Matching and Low Priority Matching
54+
* if no memory caps matched or the allocation is failed, it will go to columns Medium Priority Matching and Low Priority Matching
5555
* in turn to continue matching.
5656
*/
5757
const soc_memory_type_desc_t soc_memory_types[] = {
58-
/* Mem Type Name | High Priority Matching | Medium Priorty Matching | Low Priority Matching */
58+
/* Mem Type Name | High Priority Matching | Medium Priority Matching | Low Priority Matching */
5959
[SOC_MEMORY_TYPE_DIRAM] = { "RAM", { MALLOC_DIRAM_BASE_CAPS, 0, 0 }},
6060
//TODO, in fact, part of them support EDMA, to be supported.
6161
[SOC_MEMORY_TYPE_SPIRAM] = { "SPIRAM", { MALLOC_CAP_SPIRAM, ESP32S2_MEM_COMMON_CAPS, 0 }},
@@ -113,7 +113,7 @@ const soc_memory_region_t soc_memory_regions[] = {
113113
{ 0x3FFF8000, 0x4000, SOC_MEMORY_TYPE_DIRAM, 0x40068000, false}, //Block 20, can be used for MAC dump, can be used as trace memory
114114
{ 0x3FFFC000, 0x4000, SOC_MEMORY_TYPE_DIRAM, 0x4006C000, true}, //Block 21, can be used for MAC dump, can be used as trace memory, used for startup stack
115115
#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
116-
{ SOC_RTC_DRAM_LOW, 0x2000, SOC_MEMORY_TYPE_RTCRAM, 0, false}, //RTC Fast Memory
116+
{ SOC_RTC_DRAM_LOW, 0x2000, SOC_MEMORY_TYPE_RTCRAM, SOC_RTC_IRAM_LOW, false}, //RTC Fast Memory
117117
#endif
118118
};
119119

0 commit comments

Comments
 (0)