1 /*
2  * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <zephyr/types.h>
11 #include <zephyr/kernel.h>
12 #include <soc.h>
13 #include <esp_err.h>
14 #include <esp_heap_runtime.h>
15 #include "esp_log.h"
16 
17 #define TAG "heap_runtime"
18 
19 /* ESP dynamic pool heap */
20 extern unsigned int z_mapped_end;
21 extern unsigned int _heap_sentry;
22 static void *esp_heap_runtime_init_mem = &z_mapped_end;
23 
24 #define ESP_HEAP_RUNTIME_MAX_SIZE ((uintptr_t)&_heap_sentry - (uintptr_t)&z_mapped_end)
25 
26 static struct k_heap esp_heap_runtime;
27 
esp_heap_runtime_init(void)28 static int esp_heap_runtime_init(void)
29 {
30 	ESP_EARLY_LOGI(TAG, "ESP heap runtime init at 0x%x size %d kB.\n",
31 		       esp_heap_runtime_init_mem, ESP_HEAP_RUNTIME_MAX_SIZE / 1024);
32 
33 	k_heap_init(&esp_heap_runtime, esp_heap_runtime_init_mem, ESP_HEAP_RUNTIME_MAX_SIZE);
34 
35 #if defined(CONFIG_WIFI_ESP32) && defined(CONFIG_BT_ESP32)
36 	assert(ESP_HEAP_RUNTIME_MAX_SIZE > 65535);
37 #elif defined(CONFIG_WIFI_ESP32)
38 	assert(ESP_HEAP_RUNTIME_MAX_SIZE > 51200);
39 #elif defined(CONFIG_BT_ESP32)
40 	assert(ESP_HEAP_RUNTIME_MAX_SIZE > 40960);
41 #endif
42 
43 	return 0;
44 }
45 
esp_heap_runtime_malloc(size_t size)46 void *esp_heap_runtime_malloc(size_t size)
47 {
48 	return k_heap_alloc(&esp_heap_runtime, size, K_NO_WAIT);
49 }
50 
esp_heap_runtime_calloc(size_t n,size_t size)51 void *esp_heap_runtime_calloc(size_t n, size_t size)
52 {
53 	size_t sz;
54 
55 	if (__builtin_mul_overflow(n, size, &sz)) {
56 		return NULL;
57 	}
58 	void *ptr = k_heap_alloc(&esp_heap_runtime, sz, K_NO_WAIT);
59 
60 	if (ptr) {
61 		memset(ptr, 0, sz);
62 	}
63 
64 	return ptr;
65 }
66 
esp_heap_runtime_realloc(void * ptr,size_t bytes)67 void *esp_heap_runtime_realloc(void *ptr, size_t bytes)
68 {
69 	return k_heap_realloc(&esp_heap_runtime, ptr, bytes, K_NO_WAIT);
70 }
71 
esp_heap_runtime_free(void * mem)72 void esp_heap_runtime_free(void *mem)
73 {
74 	k_heap_free(&esp_heap_runtime, mem);
75 }
76 
77 SYS_INIT(esp_heap_runtime_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
78