1 /**
2 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 ******************************************************************************
6 * @file drv_heap.c
7 * @version V0.2
8 * @brief heap interface
9 *
10 * Change Logs:
11 * Date Author Notes
12 * 2019-03-26 Cliff.Chen first implementation
13 * 2019-05-15 Cliff.Chen Add large heap
14 *
15 ******************************************************************************
16 */
17 #include <rtthread.h>
18 #include "drv_heap.h"
19
20 #ifdef RT_USING_UNCACHE_HEAP
21 static struct rt_memheap _uncache_heap;
22
rt_uncache_heap_init(void * begin_addr,void * end_addr)23 rt_err_t rt_uncache_heap_init(void *begin_addr, void *end_addr)
24 {
25 /* initialize a default heap in the system */
26 return rt_memheap_init(&_uncache_heap,
27 "ucheap",
28 begin_addr,
29 (rt_uint32_t)end_addr - (rt_uint32_t)begin_addr);
30 }
31
rt_malloc_uncache(rt_size_t size)32 void *rt_malloc_uncache(rt_size_t size)
33 {
34 return rt_memheap_alloc(&_uncache_heap, size);
35 }
36
rt_free_uncache(void * ptr)37 void rt_free_uncache(void *ptr)
38 {
39 rt_memheap_free(ptr);
40 }
41 #endif
42
43 #ifdef RT_USING_LARGE_HEAP
44 #include "hal_base.h"
45
46 static struct rt_memheap _large_heap;
47
rt_large_heap_init(void * begin_addr,void * end_addr)48 rt_err_t rt_large_heap_init(void *begin_addr, void *end_addr)
49 {
50 /* initialize a default heap in the system */
51 return rt_memheap_init(&_large_heap,
52 "large",
53 begin_addr,
54 (rt_uint32_t)end_addr - (rt_uint32_t)begin_addr);
55 }
56
rt_malloc_large(rt_size_t size)57 void *rt_malloc_large(rt_size_t size)
58 {
59 if (size < RT_LARGE_MALLOC_THRRESH)
60 return NULL;
61
62 return rt_memheap_alloc(&_large_heap, size);
63 }
64 RTM_EXPORT(rt_malloc_large);
65
rt_free_large(void * ptr)66 void rt_free_large(void *ptr)
67 {
68 rt_memheap_free(ptr);
69 }
70 RTM_EXPORT(rt_free_large);
71
rt_dma_malloc_large(rt_size_t size)72 void *rt_dma_malloc_large(rt_size_t size)
73 {
74 void *align_ptr;
75 void *ptr;
76 rt_size_t align, align_size;
77
78 if (size < RT_LARGE_MALLOC_THRRESH)
79 return NULL;
80
81 align = 4;
82 align_size = 0;
83
84 #ifdef CACHE_LINE_SIZE
85 align = CACHE_LINE_SIZE;
86 #endif
87
88 #ifdef DMA_ALIGN_SIZE
89 align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
90 #endif
91
92 align_size = RT_ALIGN(size, align) + align;
93 ptr = rt_memheap_alloc(&_large_heap, align_size);
94 if (ptr != RT_NULL)
95 {
96 /* the allocated memory block is aligned */
97 if (((rt_uint32_t)ptr & (align - 1)) == 0)
98 {
99 align_ptr = (void *)((rt_uint32_t)ptr + align);
100 }
101 else
102 {
103 align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
104 }
105
106 /* set the pointer before alignment pointer to the real pointer */
107 *((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
108
109 ptr = align_ptr;
110 }
111
112 return ptr;
113 }
114 RTM_EXPORT(rt_dma_malloc_large);
115
rt_dma_free_large(void * ptr)116 void rt_dma_free_large(void *ptr)
117 {
118 void *real_ptr;
119
120 real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
121 rt_memheap_free(real_ptr);
122 }
123 RTM_EXPORT(rt_dma_free_large);
124
125 #endif
126
127
128 #ifdef RT_USING_DTCM_HEAP
129 #include "hal_base.h"
130
131 static struct rt_memheap _dtcm_heap;
132 extern int __dtcm_start__, __dtcm_end__;
133
134 #define RK_DTCM_BEGIN (&__dtcm_start__)
135 #define RK_DTCM_END (&__dtcm_end__)
136
rt_dtcm_heap_init(void)137 int rt_dtcm_heap_init(void)
138 {
139 rt_err_t ret;
140 rt_device_t dsp;
141
142 dsp = rt_device_find("dsp0");
143 RT_ASSERT(dsp != RT_NULL);
144
145 ret = rt_device_open(dsp, RT_DEVICE_FLAG_RDWR);
146 RT_ASSERT(ret == RT_EOK);
147
148 return rt_memheap_init(&_dtcm_heap,
149 "dtcmheap",
150 RK_DTCM_BEGIN,
151 (rt_uint32_t)RK_DTCM_END - (rt_uint32_t)RK_DTCM_BEGIN);
152
153 return RT_EOK;
154 }
155 INIT_COMPONENT_EXPORT(rt_dtcm_heap_init);
156
rt_malloc_dtcm(rt_size_t size)157 void *rt_malloc_dtcm(rt_size_t size)
158 {
159 //rt_kprintf("rt_malloc_dtcm: size = %d\n", size);
160 if (size < RT_DTCM_MALLOC_THRRESH)
161 return NULL;
162
163 return rt_memheap_alloc(&_dtcm_heap, size);
164 }
165 RTM_EXPORT(rt_malloc_dtcm);
166
rt_free_dtcm(void * ptr)167 void rt_free_dtcm(void *ptr)
168 {
169 rt_memheap_free(ptr);
170 }
171 RTM_EXPORT(rt_free_dtcm);
172
rt_dma_malloc_dtcm(rt_size_t size)173 void *rt_dma_malloc_dtcm(rt_size_t size)
174 {
175 void *align_ptr;
176 void *ptr;
177 rt_size_t align, align_size;
178
179 //rt_kprintf("rt_dma_malloc_dtcm: size = %d\n", size);
180 if (size < RT_DTCM_MALLOC_THRRESH)
181 return NULL;
182
183 align = 4;
184 align_size = 0;
185
186 #ifdef CACHE_LINE_SIZE
187 align = CACHE_LINE_SIZE;
188 #endif
189
190 #ifdef DMA_ALIGN_SIZE
191 align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
192 #endif
193
194 align_size = RT_ALIGN(size, align) + align;
195 ptr = rt_memheap_alloc(&_dtcm_heap, align_size);
196 if (ptr != RT_NULL)
197 {
198 /* the allocated memory block is aligned */
199 if (((rt_uint32_t)ptr & (align - 1)) == 0)
200 {
201 align_ptr = (void *)((rt_uint32_t)ptr + align);
202 }
203 else
204 {
205 align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
206 }
207
208 /* set the pointer before alignment pointer to the real pointer */
209 *((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
210
211 ptr = align_ptr;
212 }
213
214 return ptr;
215 }
216 RTM_EXPORT(rt_dma_malloc_dtcm);
217
rt_dma_free_dtcm(void * ptr)218 void rt_dma_free_dtcm(void *ptr)
219 {
220 void *real_ptr;
221
222 real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
223 rt_memheap_free(real_ptr);
224 }
225 RTM_EXPORT(rt_dma_free_dtcm);
226
227 #endif
228
229
230 #ifdef RT_USING_PSRAM_HEAP
231 #include "hal_base.h"
232
233 static struct rt_memheap _psram_heap;
234 extern int __psramheap_start__, __psramheap_end__;
235
236 #define RK_PSRAMHEAP_BEGIN (&__psramheap_start__)
237 #define RK_PSRAMHEAP_END (&__psramheap_end__)
238
rt_psram_heap_init(void)239 int rt_psram_heap_init(void)
240 {
241 return rt_memheap_init(&_psram_heap,
242 "psramheap",
243 RK_PSRAMHEAP_BEGIN,
244 (rt_uint32_t)RK_PSRAMHEAP_END - (rt_uint32_t)RK_PSRAMHEAP_BEGIN);
245 }
246 INIT_COMPONENT_EXPORT(rt_psram_heap_init);
247
rt_malloc_psram(rt_size_t size)248 void *rt_malloc_psram(rt_size_t size)
249 {
250 //rt_kprintf("rt_malloc_dtcm: size = %d\n", size);
251 if (size < RT_PSRAM_MALLOC_THRRESH)
252 return NULL;
253
254 return rt_memheap_alloc(&_psram_heap, size);
255 }
256 RTM_EXPORT(rt_malloc_psram);
257
rt_free_psram(void * ptr)258 void rt_free_psram(void *ptr)
259 {
260 rt_memheap_free(ptr);
261 }
262 RTM_EXPORT(rt_free_psram);
263
rt_dma_malloc_psram(rt_size_t size)264 void *rt_dma_malloc_psram(rt_size_t size)
265 {
266 void *align_ptr;
267 void *ptr;
268 rt_size_t align, align_size;
269
270 //rt_kprintf("rt_dma_malloc_dtcm: size = %d\n", size);
271 if (size < RT_PSRAM_MALLOC_THRRESH)
272 return NULL;
273
274 align = 4;
275 align_size = 0;
276
277 #ifdef CACHE_LINE_SIZE
278 align = CACHE_LINE_SIZE;
279 #endif
280
281 #ifdef DMA_ALIGN_SIZE
282 align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
283 #endif
284
285 align_size = RT_ALIGN(size, align) + align;
286 ptr = rt_memheap_alloc(&_psram_heap, align_size);
287 if (ptr != RT_NULL)
288 {
289 /* the allocated memory block is aligned */
290 if (((rt_uint32_t)ptr & (align - 1)) == 0)
291 {
292 align_ptr = (void *)((rt_uint32_t)ptr + align);
293 }
294 else
295 {
296 align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
297 }
298
299 /* set the pointer before alignment pointer to the real pointer */
300 *((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
301
302 ptr = align_ptr;
303 }
304
305 return ptr;
306 }
307 RTM_EXPORT(rt_dma_malloc_psram);
308
rt_dma_free_psram(void * ptr)309 void rt_dma_free_psram(void *ptr)
310 {
311 void *real_ptr;
312
313 real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
314 rt_memheap_free(real_ptr);
315 }
316 RTM_EXPORT(rt_dma_free_psram);
317
318 #endif
319