heap/heap_caps: added special case for esp32s2 when handling memory allocated (and aliased) from IRAM
This commit is contained in:
parent
ecc4955c68
commit
4a392932f1
3 changed files with 28 additions and 3 deletions
|
@ -107,6 +107,7 @@ IRAM_ATTR void *heap_caps_malloc( size_t size, uint32_t caps )
|
|||
//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.
|
||||
ret = multi_heap_malloc(heap->heap, size + 4); // int overflow checked above
|
||||
|
||||
if (ret != NULL) {
|
||||
return dram_alloc_to_iram_addr(ret, size + 4); // int overflow checked above
|
||||
}
|
||||
|
@ -287,8 +288,18 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
heap_t *heap = find_containing_heap(ptr);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
//On esp32s2 the pointer to heap may be aliased, we need to
|
||||
//recover it before to manage a new allocation:
|
||||
if(esp_ptr_in_diram_iram((void *)ptr)) {
|
||||
//pointer must be already aliased, otherwise just ignore this part:
|
||||
uint32_t *dram_addr = (uint32_t *)ptr;
|
||||
ptr = (void *)dram_addr[-1];
|
||||
//printf("[HEAP_CAPS_MALLOC]: obtained pointer that was aliased: %p \n", (void *)ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
heap_t *heap = find_containing_heap(ptr);
|
||||
assert(heap != NULL && "realloc() pointer is outside heap areas");
|
||||
|
||||
// are the existing heap's capabilities compatible with the
|
||||
|
@ -308,6 +319,7 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps)
|
|||
// in a different heap with requested capabilities.
|
||||
void *new_p = heap_caps_malloc(size, caps);
|
||||
if (new_p != NULL) {
|
||||
|
||||
size_t old_size = multi_heap_get_allocated_size(heap->heap, ptr);
|
||||
assert(old_size > 0);
|
||||
memcpy(new_p, ptr, MIN(size, old_size));
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <sys/param.h>
|
||||
#include <multi_heap.h>
|
||||
#include "multi_heap_internal.h"
|
||||
#include "heap_private.h"
|
||||
|
||||
/* Note: Keep platform-specific parts in this header, this source
|
||||
file should depend on libc only */
|
||||
|
@ -268,7 +269,20 @@ void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size)
|
|||
new_head = multi_heap_malloc_impl(heap, size + POISON_OVERHEAD);
|
||||
if (new_head != NULL) {
|
||||
result = poison_allocated_region(new_head, size);
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
//We may need to deal with aliased heap pointers. here too,
|
||||
//mainly because the heap canary is located before the
|
||||
//the slot reserved to preserve original DRAM address
|
||||
//so the original user data is actually p + 4 ahead :
|
||||
if(esp_ptr_in_diram_dram((void *)p)) {
|
||||
memcpy(result, p + sizeof(intptr_t), MIN(size, orig_alloc_size));
|
||||
} else {
|
||||
memcpy(result, p , MIN(size, orig_alloc_size));
|
||||
}
|
||||
#else
|
||||
memcpy(result, p, MIN(size, orig_alloc_size));
|
||||
#endif
|
||||
multi_heap_free(heap, p);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -31,7 +31,6 @@ TEST_CASE("realloc move data to a new heap type", "[heap]")
|
|||
|
||||
char *a = malloc(64);
|
||||
memcpy(a, buf, 64);
|
||||
|
||||
// move data from 'a' to IRAM
|
||||
char *b = heap_caps_realloc(a, 64, MALLOC_CAP_EXEC);
|
||||
TEST_ASSERT_NOT_NULL(b);
|
||||
|
|
Loading…
Reference in a new issue