#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_ESPIDF)
#if defined(WOLFSSL_USER_SETTINGS)
#include <wolfssl/wolfcrypt/types.h>
#else
#error "Missing WOLFSSL_USER_SETTINGS in CMakeLists or Makefile:\
CFLAGS +=-DWOLFSSL_USER_SETTINGS"
#endif
#ifndef SINGLE_THREADED
#ifdef PLATFORMIO
#include <freertos/semphr.h>
#else
#include "semphr.h"
#endif
#endif
#include "sdkconfig.h"
#include <esp_log.h>
#include <esp_err.h>
#include <wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h>
static const char* TAG = "mem lib";
static intptr_t _starting_stack_pointer = 0;
static int _stack_used = 0;
extern wc_ptr_t _data_start[];
extern wc_ptr_t _data_end[];
extern wc_ptr_t _rodata_start[];
extern wc_ptr_t _rodata_end[];
extern wc_ptr_t _bss_start[];
extern wc_ptr_t _bss_end[];
extern wc_ptr_t _rtc_bss_start[];
extern wc_ptr_t _rtc_bss_end[];
extern wc_ptr_t _iram_start[];
extern wc_ptr_t _iram_end[];
#if defined(CONFIG_IDF_TARGET_ESP8266)
extern wc_ptr_t _init_start[];
extern wc_ptr_t _init_end[];
#endif
extern wc_ptr_t _iram_text_start[];
extern wc_ptr_t _iram_text_end[];
#if defined(CONFIG_IDF_TARGET_ESP32S2)
#else
extern wc_ptr_t _iram_bss_start[];
extern wc_ptr_t _iram_bss_end[];
#endif
extern wc_ptr_t _noinit_start[];
extern wc_ptr_t _noinit_end[];
extern wc_ptr_t _text_start[];
extern wc_ptr_t _text_end[];
extern wc_ptr_t _heap_start[];
extern wc_ptr_t _heap_end[];
#ifdef CONFIG_IDF_TARGET_ESP32C2
#else
extern wc_ptr_t _rtc_data_start[];
extern wc_ptr_t _rtc_data_end[];
#endif
#if defined(CONFIG_IDF_TARGET_ARCH_XTENSA) && CONFIG_IDF_TARGET_ARCH_XTENSA == 1
extern void* _thread_local_start;
extern void* _thread_local_end;
#endif
#define MEM_MAP_IO_START ((void*)(0x3FF00000))
#define MEM_MAP_IO_END ((void*)(0x3FF0FFFF))
#define USER_DATA_START ((void*)(0x3FFE8000))
#define USER_DATA_END ((void*)(0x3FFE8000 + 0x14000))
#define ETS_SYS_START ((void*)(0x3FFFC000))
#define ETS_SYS_END ((void*)(0x3FFFC000 + 0x4000))
#define IRAM1_START ((void*)(0x40100000))
#define IRAM1_END ((void*)(0x40100000 + 0x8000))
#define IRAMF1_START ((void*)(0x40108000))
#define IRAMF1_END ((void*)(0x40108000 + 0x4000))
#define IRAMF2_START ((void*)(0x4010C000))
#define IRAMF2_END ((void*)(0x4010C000 + 0x4000))
#if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0))
#else
enum sdk_memory_segment
{
mem_map_io = 0,
thread_local,
data,
user_data_ram,
bss,
noinit,
ets_system,
iram1,
iramf1,
iramf2,
iram,
iram_text,
iram_bss,
init,
text,
rodata,
rtc_data,
SDK_MEMORY_SEGMENT_COUNT
};
static void* sdk_memory_segment_start[SDK_MEMORY_SEGMENT_COUNT + 1] = {};
static void* sdk_memory_segment_end[SDK_MEMORY_SEGMENT_COUNT + 1] = {};
static const char* sdk_memory_segment_text[SDK_MEMORY_SEGMENT_COUNT + 1] = {
"C memory map io ",
"* thread_local ",
"C data ",
"* user data ram ",
"* bss ",
"* noinit ",
"C ets system ",
"C iram1 ",
"C iramf1 ",
"C iramf2 ",
"* iram ",
"* iram_text ",
"* iram_bss ",
"* init ",
"* text ",
"* rodata ",
"* rtc data ",
"last item",
};
int sdk_log_meminfo(enum sdk_memory_segment m, void* start, void* end)
{
const char* str;
word32 len = 0;
str = sdk_memory_segment_text[m];
sdk_memory_segment_start[m] = start;
sdk_memory_segment_end[m] = end;
if (m == SDK_MEMORY_SEGMENT_COUNT) {
ESP_LOGI(TAG, " Linker Memory Map");
ESP_LOGI(TAG, "-----------------------------------------------------");
ESP_LOGI(TAG, " Start End Length");
}
else {
len = (word32)end - (word32)start;
ESP_LOGI(TAG, "%s: %p ~ %p : 0x%05x (%d)", str, start, end, len, len );
}
return ESP_OK;
}
#endif
int sdk_init_meminfo(void)
{
#if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0))
ESP_LOGI(TAG, "sdk_init_meminfo not available for ESP-IDF V6.0");
#else
void* sample_heap_var;
int sample_stack_var = 0;
sdk_log_meminfo(SDK_MEMORY_SEGMENT_COUNT, NULL, NULL);
sdk_log_meminfo(mem_map_io, MEM_MAP_IO_START, MEM_MAP_IO_END);
#if defined(CONFIG_IDF_TARGET_ARCH_XTENSA) && CONFIG_IDF_TARGET_ARCH_XTENSA == 1
sdk_log_meminfo(thread_local, _thread_local_start, _thread_local_end);
#endif
sdk_log_meminfo(data, _data_start, _data_end);
sdk_log_meminfo(user_data_ram, USER_DATA_START, USER_DATA_END);
#if defined(CONFIG_IDF_TARGET_ESP32S2)
#else
sdk_log_meminfo(bss, _bss_start, _bss_end);
#endif
sdk_log_meminfo(noinit, _noinit_start, _noinit_end);
sdk_log_meminfo(ets_system, ETS_SYS_START, ETS_SYS_END);
sdk_log_meminfo(rodata, _rodata_start, _rodata_end);
sdk_log_meminfo(iram1, IRAM1_START, IRAM1_END);
sdk_log_meminfo(iramf1, IRAMF1_START, IRAMF1_END);
sdk_log_meminfo(iramf2, IRAMF2_START, IRAMF2_END);
sdk_log_meminfo(iram, _iram_start, _iram_end);
sdk_log_meminfo(iram_text, _iram_text_start, _iram_text_end);
#if defined(CONFIG_IDF_TARGET_ESP32S2)
#else
sdk_log_meminfo(iram_bss, _iram_bss_start, _iram_bss_end);
#endif
#if defined(CONFIG_IDF_TARGET_ESP8266)
sdk_log_meminfo(init, _init_start, _init_end);
#endif
sdk_log_meminfo(text, _text_start, _text_end);
#if defined(CONFIG_IDF_TARGET_ESP32C2)
#else
sdk_log_meminfo(rtc_data, _rtc_data_start, _rtc_data_end);
#endif
ESP_LOGI(TAG, "-----------------------------------------------------");
sample_heap_var = malloc(1);
if (sample_heap_var == NULL) {
ESP_LOGE(TAG, "Unable to allocate heap memory in sdk_var_whereis().");
}
else {
sdk_var_whereis("sample_stack_var", (void*)&sample_stack_var);
sdk_var_whereis("sample_heap_var", sample_heap_var);
free(sample_heap_var);
}
#endif
return ESP_OK;
}
esp_err_t sdk_var_whereis(const char* v_name, void* v)
{
esp_err_t ret = ESP_FAIL;
#if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0))
ESP_LOGI(TAG, "sdk_var_whereis not available for ESP-IDF V6.0");
#else
for (enum sdk_memory_segment m = 0 ;m < SDK_MEMORY_SEGMENT_COUNT; m++) {
if (v >= sdk_memory_segment_start[m] &&
v <= sdk_memory_segment_end[m]) {
ret = ESP_OK;
ESP_LOGI(TAG, "Variable [%s] found at %p in %s", v_name, v,
sdk_memory_segment_text[m]);
if (m == user_data_ram) {
}
}
}
#endif
if (ret == ESP_FAIL) {
ESP_LOGW(TAG, "%s not found in known memory map: %p", v_name, v);
}
return ret;
}
intptr_t esp_sdk_stack_pointer(void)
{
intptr_t sp = 0;
#if defined(CONFIG_IDF_TARGET_ARCH_RISCV)
if (CONFIG_IDF_TARGET_ARCH_RISCV == 1) {
__asm volatile("mv %0, sp" : "=r" (sp));
}
#elif defined(CONFIG_IDF_TARGET_ARCH_XTENSA)
if (CONFIG_IDF_TARGET_ARCH_XTENSA == 1) {
__asm volatile("mov %0, sp" : "=r"(sp));
}
#endif
if (_starting_stack_pointer == 0) {
_starting_stack_pointer = sp;
}
_stack_used = _starting_stack_pointer - sp;
return sp;
}
esp_err_t esp_sdk_mem_lib_init(void)
{
int ret = ESP_OK;
sdk_init_meminfo();
ESP_LOGI(TAG, "esp_sdk_mem_lib_init Ver %d", ESP_SDK_MEM_LIB_VERSION);
return ret;
}
#if defined(DEBUG_WOLFSSL_MALLOC) || defined(DEBUG_WOLFSSL)
void* wc_debug_pvPortMalloc(size_t size,
const char* file, int line, const char* fname)
#else
void* wc_pvPortMalloc(size_t size)
#endif
{
void* ret = NULL;
wolfSSL_Malloc_cb mc;
wolfSSL_Free_cb fc;
wolfSSL_Realloc_cb rc;
wolfSSL_GetAllocators(&mc, &fc, &rc);
if (mc == NULL) {
ret = pvPortMalloc(size);
}
else {
#if defined(USE_WOLFSSL_MEMORY) && !defined(NO_WOLFSSL_MEMORY)
ret = mc(size);
#else
ret = pvPortMalloc(size);
#endif
}
#if defined(DEBUG_WOLFSSL_MALLOC) || defined(DEBUG_WOLFSSL)
if (ret == NULL) {
ESP_LOGE("malloc", "%s:%d (%s)", file, line, fname);
ESP_LOGE("malloc", "Failed Allocating memory of size: %d bytes", size);
}
#endif
return ret;
}
#if defined(DEBUG_WOLFSSL_MALLOC) || defined(DEBUG_WOLFSSL)
void wc_debug_pvPortFree(void *ptr,
const char* file, int line, const char* fname)
#else
void wc_pvPortFree(void *ptr)
#endif
{
wolfSSL_Malloc_cb mc;
wolfSSL_Free_cb fc;
wolfSSL_Realloc_cb rc;
if (ptr == NULL) {
#ifdef DEBUG_WOLFSSL_MALLOC
#endif
}
else {
wolfSSL_GetAllocators(&mc, &fc, &rc);
if (fc == NULL) {
vPortFree(ptr);
}
else {
#if defined(USE_WOLFSSL_MEMORY) && !defined(NO_WOLFSSL_MEMORY)
fc(ptr);
#else
vPortFree(ptr);
#endif
}
}
}
#ifndef WOLFSSL_NO_REALLOC
#if defined(DEBUG_WOLFSSL_MALLOC) || defined(DEBUG_WOLFSSL)
void* wc_debug_pvPortRealloc(void* ptr, size_t size,
const char* file, int line, const char* fname)
#else
void* wc_pvPortRealloc(void* ptr, size_t size)
#endif
{
void* ret = NULL;
wolfSSL_Malloc_cb mc;
wolfSSL_Free_cb fc;
wolfSSL_Realloc_cb rc;
wolfSSL_GetAllocators(&mc, &fc, &rc);
if (mc == NULL) {
ret = realloc(ptr, size);
}
else {
#if defined(USE_WOLFSSL_MEMORY) && !defined(NO_WOLFSSL_MEMORY)
if (rc != NULL) {
ret = rc(ptr, size);
}
else {
ret = realloc(ptr, size);
}
#else
ret = realloc(ptr, size);
#endif
}
#if defined(DEBUG_WOLFSSL_MALLOC) || defined(DEBUG_WOLFSSL)
if (ret == NULL) {
ESP_LOGE("realloc", "%s:%d (%s)", file, line, fname);
ESP_LOGE("realloc", "Failed Re-allocating memory of size: %d bytes",
size);
}
#endif
return ret;
}
#endif
#endif