mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
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
This commit is contained in:
commit
dd00aa1776
@ -28,7 +28,12 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
inline static bool esp_dram_match_iram(void) {
|
inline static bool esp_dram_match_iram(void) {
|
||||||
return (SOC_DRAM_LOW == SOC_IRAM_LOW && SOC_DRAM_HIGH == SOC_IRAM_HIGH);
|
bool dram_match_iram = (SOC_DRAM_LOW == SOC_IRAM_LOW) &&
|
||||||
|
(SOC_DRAM_HIGH == SOC_IRAM_HIGH);
|
||||||
|
#if SOC_RTC_FAST_MEM_SUPPORTED
|
||||||
|
dram_match_iram &= (SOC_RTC_IRAM_LOW == SOC_RTC_DRAM_LOW);
|
||||||
|
#endif
|
||||||
|
return dram_match_iram;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,7 +102,7 @@ inline static bool esp_ptr_in_diram_iram(const void *p) {
|
|||||||
*/
|
*/
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
|
inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
|
||||||
#if SOC_RTC_FAST_MEM_SUPPORTED
|
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
|
||||||
return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
|
return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
@ -151,6 +156,21 @@ inline static void * esp_ptr_diram_dram_to_iram(const void *p) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a RTC DRAM pointer to equivalent word address in RTC IRAM
|
||||||
|
|
||||||
|
- Address must be word aligned
|
||||||
|
- Address must pass esp_ptr_in_rtc_dram_fast() test, or result will be invalid pointer
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
inline static void * esp_ptr_rtc_dram_to_iram(const void *p) {
|
||||||
|
intptr_t ptr = (intptr_t)p;
|
||||||
|
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
|
||||||
|
return (void *) ( SOC_RTC_IRAM_LOW + (ptr - SOC_RTC_DRAM_LOW) );
|
||||||
|
#else
|
||||||
|
return (void *) ptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
|
/* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
|
||||||
|
|
||||||
- Address must be word aligned
|
- Address must be word aligned
|
||||||
|
@ -27,7 +27,12 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
inline static bool esp_dram_match_iram(void) {
|
inline static bool esp_dram_match_iram(void) {
|
||||||
return (SOC_DRAM_LOW == SOC_IRAM_LOW && SOC_DRAM_HIGH == SOC_IRAM_HIGH);
|
bool dram_match_iram = (SOC_DRAM_LOW == SOC_IRAM_LOW) &&
|
||||||
|
(SOC_DRAM_HIGH == SOC_IRAM_HIGH);
|
||||||
|
#if SOC_RTC_FAST_MEM_SUPPORTED
|
||||||
|
dram_match_iram &= (SOC_RTC_IRAM_LOW == SOC_RTC_DRAM_LOW);
|
||||||
|
#endif
|
||||||
|
return dram_match_iram;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,7 +101,7 @@ inline static bool esp_ptr_in_diram_iram(const void *p) {
|
|||||||
*/
|
*/
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
|
inline static bool esp_ptr_in_rtc_iram_fast(const void *p) {
|
||||||
#if SOC_RTC_FAST_MEM_SUPPORTED
|
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
|
||||||
return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
|
return ((intptr_t)p >= SOC_RTC_IRAM_LOW && (intptr_t)p < SOC_RTC_IRAM_HIGH);
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
@ -150,6 +155,21 @@ inline static void * esp_ptr_diram_dram_to_iram(const void *p) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a RTC DRAM pointer to equivalent word address in RTC IRAM
|
||||||
|
|
||||||
|
- Address must be word aligned
|
||||||
|
- Address must pass esp_ptr_in_rtc_dram_fast() test, or result will be invalid pointer
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
inline static void * esp_ptr_rtc_dram_to_iram(const void *p) {
|
||||||
|
intptr_t ptr = (intptr_t)p;
|
||||||
|
#if SOC_RTC_FAST_MEM_SUPPORTED && (SOC_RTC_IRAM_LOW != SOC_RTC_DRAM_LOW)
|
||||||
|
return (void *) ( SOC_RTC_IRAM_LOW + (ptr - SOC_RTC_DRAM_LOW) );
|
||||||
|
#else
|
||||||
|
return (void *) ptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
|
/* Convert a D/IRAM IRAM pointer to equivalent word address in DRAM
|
||||||
|
|
||||||
- Address must be word aligned
|
- Address must be word aligned
|
||||||
|
@ -38,14 +38,19 @@ HEAP_IRAM_ATTR static void *dram_alloc_to_iram_addr(void *addr, size_t len)
|
|||||||
{
|
{
|
||||||
uintptr_t dstart = (uintptr_t)addr; //First word
|
uintptr_t dstart = (uintptr_t)addr; //First word
|
||||||
uintptr_t dend __attribute__((unused)) = dstart + len - 4; //Last word
|
uintptr_t dend __attribute__((unused)) = dstart + len - 4; //Last word
|
||||||
assert(esp_ptr_in_diram_dram((void *)dstart));
|
assert(esp_ptr_in_diram_dram((void *)dstart) || esp_ptr_in_rtc_dram_fast((void *)dstart));
|
||||||
assert(esp_ptr_in_diram_dram((void *)dend));
|
assert(esp_ptr_in_diram_dram((void *)dend) || esp_ptr_in_rtc_dram_fast((void *)dend));
|
||||||
assert((dstart & 3) == 0);
|
assert((dstart & 3) == 0);
|
||||||
assert((dend & 3) == 0);
|
assert((dend & 3) == 0);
|
||||||
#if SOC_DIRAM_INVERTED // We want the word before the result to hold the DRAM address
|
#if SOC_DIRAM_INVERTED // We want the word before the result to hold the DRAM address
|
||||||
uint32_t *iptr = esp_ptr_diram_dram_to_iram((void *)dend);
|
uint32_t *iptr = esp_ptr_diram_dram_to_iram((void *)dend);
|
||||||
#else
|
#else
|
||||||
uint32_t *iptr = esp_ptr_diram_dram_to_iram((void *)dstart);
|
uint32_t *iptr = NULL;
|
||||||
|
if (esp_ptr_in_rtc_dram_fast((void *)dstart)) {
|
||||||
|
iptr = esp_ptr_rtc_dram_to_iram((void *)dstart);
|
||||||
|
} else {
|
||||||
|
iptr = esp_ptr_diram_dram_to_iram((void *)dstart);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
*iptr = dstart;
|
*iptr = dstart;
|
||||||
return iptr + 1;
|
return iptr + 1;
|
||||||
@ -57,7 +62,7 @@ HEAP_IRAM_ATTR void heap_caps_free( void *ptr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_ptr_in_diram_iram(ptr)) {
|
if (esp_ptr_in_diram_iram(ptr) || esp_ptr_in_rtc_iram_fast(ptr)) {
|
||||||
//Memory allocated here is actually allocated in the DRAM alias region and
|
//Memory allocated here is actually allocated in the DRAM alias region and
|
||||||
//cannot be de-allocated as usual. dram_alloc_to_iram_addr stores a pointer to
|
//cannot be de-allocated as usual. dram_alloc_to_iram_addr stores a pointer to
|
||||||
//the equivalent DRAM address, though; free that.
|
//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
|
|||||||
//This heap can satisfy all the requested capabilities. See if we can grab some memory using it.
|
//This heap can satisfy all the requested capabilities. See if we can grab some memory using it.
|
||||||
// If MALLOC_CAP_EXEC is requested but the DRAM and IRAM are on the same addresses (like on esp32c6)
|
// If MALLOC_CAP_EXEC is requested but the DRAM and IRAM are on the same addresses (like on esp32c6)
|
||||||
// proceed as for a default allocation.
|
// proceed as for a default allocation.
|
||||||
if ((caps & MALLOC_CAP_EXEC) && !esp_dram_match_iram() && esp_ptr_in_diram_dram((void *)heap->start)) {
|
if (((caps & MALLOC_CAP_EXEC) && !esp_dram_match_iram()) &&
|
||||||
|
(esp_ptr_in_diram_dram((void *)heap->start) || esp_ptr_in_rtc_dram_fast((void *)heap->start))) {
|
||||||
//This is special, insofar that what we're going to get back is a DRAM address. If so,
|
//This is special, insofar that what we're going to get back is a DRAM address. If so,
|
||||||
//we need to 'invert' it (lowest address in DRAM == highest address in IRAM and vice-versa) and
|
//we need to 'invert' it (lowest address in DRAM == highest address in IRAM and vice-versa) and
|
||||||
//add a pointer to the DRAM equivalent before the address we're going to return.
|
//add a pointer to the DRAM equivalent before the address we're going to return.
|
||||||
|
@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -51,11 +51,11 @@ enum {
|
|||||||
/**
|
/**
|
||||||
* Defined the attributes and allocation priority of each memory on the chip,
|
* Defined the attributes and allocation priority of each memory on the chip,
|
||||||
* The heap allocator will traverse all types of memory types in column High Priority Matching and match the specified caps at first,
|
* The heap allocator will traverse all types of memory types in column High Priority Matching and match the specified caps at first,
|
||||||
* if no memory caps matched or the allocation is failed, it will go to columns Medium Priorty Matching and Low Priority Matching
|
* if no memory caps matched or the allocation is failed, it will go to columns Medium Priority Matching and Low Priority Matching
|
||||||
* in turn to continue matching.
|
* in turn to continue matching.
|
||||||
*/
|
*/
|
||||||
const soc_memory_type_desc_t soc_memory_types[] = {
|
const soc_memory_type_desc_t soc_memory_types[] = {
|
||||||
/* Mem Type Name | High Priority Matching | Medium Priorty Matching | Low Priority Matching */
|
/* Mem Type Name | High Priority Matching | Medium Priority Matching | Low Priority Matching */
|
||||||
[SOC_MEMORY_TYPE_DIRAM] = { "RAM", { MALLOC_DIRAM_BASE_CAPS, 0, 0 }},
|
[SOC_MEMORY_TYPE_DIRAM] = { "RAM", { MALLOC_DIRAM_BASE_CAPS, 0, 0 }},
|
||||||
//TODO, in fact, part of them support EDMA, to be supported.
|
//TODO, in fact, part of them support EDMA, to be supported.
|
||||||
[SOC_MEMORY_TYPE_SPIRAM] = { "SPIRAM", { MALLOC_CAP_SPIRAM, ESP32S2_MEM_COMMON_CAPS, 0 }},
|
[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[] = {
|
|||||||
{ 0x3FFF8000, 0x4000, SOC_MEMORY_TYPE_DIRAM, 0x40068000, false}, //Block 20, can be used for MAC dump, can be used as trace memory
|
{ 0x3FFF8000, 0x4000, SOC_MEMORY_TYPE_DIRAM, 0x40068000, false}, //Block 20, can be used for MAC dump, can be used as trace memory
|
||||||
{ 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
|
{ 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
|
||||||
#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
|
#ifdef CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
|
||||||
{ SOC_RTC_DRAM_LOW, 0x2000, SOC_MEMORY_TYPE_RTCRAM, 0, false}, //RTC Fast Memory
|
{ SOC_RTC_DRAM_LOW, 0x2000, SOC_MEMORY_TYPE_RTCRAM, SOC_RTC_IRAM_LOW, false}, //RTC Fast Memory
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user