xref: /optee_os/core/mm/tee_mm.c (revision fc5e0894704fd0f42d80edbf2322d4938792d1db)
1*fc5e0894SMarouene Boubakri // SPDX-License-Identifier: BSD-2-Clause
2*fc5e0894SMarouene Boubakri /*
3*fc5e0894SMarouene Boubakri  * Copyright (c) 2014, STMicroelectronics International N.V.
4*fc5e0894SMarouene Boubakri  */
5*fc5e0894SMarouene Boubakri 
6*fc5e0894SMarouene Boubakri #include <kernel/panic.h>
7*fc5e0894SMarouene Boubakri #include <kernel/spinlock.h>
8*fc5e0894SMarouene Boubakri #include <kernel/tee_common.h>
9*fc5e0894SMarouene Boubakri #include <mm/tee_mm.h>
10*fc5e0894SMarouene Boubakri #include <mm/tee_pager.h>
11*fc5e0894SMarouene Boubakri #include <trace.h>
12*fc5e0894SMarouene Boubakri #include <util.h>
13*fc5e0894SMarouene Boubakri 
14*fc5e0894SMarouene Boubakri static void *pmalloc(tee_mm_pool_t *pool, size_t size)
15*fc5e0894SMarouene Boubakri {
16*fc5e0894SMarouene Boubakri 	if (pool->flags & TEE_MM_POOL_NEX_MALLOC)
17*fc5e0894SMarouene Boubakri 		return nex_malloc(size);
18*fc5e0894SMarouene Boubakri 	else
19*fc5e0894SMarouene Boubakri 		return malloc(size);
20*fc5e0894SMarouene Boubakri }
21*fc5e0894SMarouene Boubakri 
22*fc5e0894SMarouene Boubakri static void *pcalloc(tee_mm_pool_t *pool, size_t num_el, size_t size)
23*fc5e0894SMarouene Boubakri {
24*fc5e0894SMarouene Boubakri 	if (pool->flags & TEE_MM_POOL_NEX_MALLOC)
25*fc5e0894SMarouene Boubakri 		return nex_calloc(num_el, size);
26*fc5e0894SMarouene Boubakri 	else
27*fc5e0894SMarouene Boubakri 		return calloc(num_el, size);
28*fc5e0894SMarouene Boubakri }
29*fc5e0894SMarouene Boubakri 
30*fc5e0894SMarouene Boubakri static void pfree(tee_mm_pool_t *pool, void *ptr)
31*fc5e0894SMarouene Boubakri {
32*fc5e0894SMarouene Boubakri 	if (pool->flags & TEE_MM_POOL_NEX_MALLOC)
33*fc5e0894SMarouene Boubakri 		nex_free(ptr);
34*fc5e0894SMarouene Boubakri 	else
35*fc5e0894SMarouene Boubakri 		free(ptr);
36*fc5e0894SMarouene Boubakri }
37*fc5e0894SMarouene Boubakri 
38*fc5e0894SMarouene Boubakri bool tee_mm_init(tee_mm_pool_t *pool, paddr_t lo, paddr_size_t size,
39*fc5e0894SMarouene Boubakri 		 uint8_t shift, uint32_t flags)
40*fc5e0894SMarouene Boubakri {
41*fc5e0894SMarouene Boubakri 	paddr_size_t rounded = 0;
42*fc5e0894SMarouene Boubakri 	paddr_t initial_lo = lo;
43*fc5e0894SMarouene Boubakri 
44*fc5e0894SMarouene Boubakri 	if (pool == NULL)
45*fc5e0894SMarouene Boubakri 		return false;
46*fc5e0894SMarouene Boubakri 
47*fc5e0894SMarouene Boubakri 	lo = ROUNDUP(lo, 1 << shift);
48*fc5e0894SMarouene Boubakri 	rounded = lo - initial_lo;
49*fc5e0894SMarouene Boubakri 	size = ROUNDDOWN(size - rounded, 1 << shift);
50*fc5e0894SMarouene Boubakri 
51*fc5e0894SMarouene Boubakri 	assert(((uint64_t)size >> shift) < (uint64_t)UINT32_MAX);
52*fc5e0894SMarouene Boubakri 
53*fc5e0894SMarouene Boubakri 	pool->lo = lo;
54*fc5e0894SMarouene Boubakri 	pool->size = size;
55*fc5e0894SMarouene Boubakri 	pool->shift = shift;
56*fc5e0894SMarouene Boubakri 	pool->flags = flags;
57*fc5e0894SMarouene Boubakri 	pool->entry = pcalloc(pool, 1, sizeof(tee_mm_entry_t));
58*fc5e0894SMarouene Boubakri 
59*fc5e0894SMarouene Boubakri 	if (pool->entry == NULL)
60*fc5e0894SMarouene Boubakri 		return false;
61*fc5e0894SMarouene Boubakri 
62*fc5e0894SMarouene Boubakri 	if (pool->flags & TEE_MM_POOL_HI_ALLOC)
63*fc5e0894SMarouene Boubakri 		pool->entry->offset = ((size - 1) >> shift) + 1;
64*fc5e0894SMarouene Boubakri 
65*fc5e0894SMarouene Boubakri 	pool->entry->pool = pool;
66*fc5e0894SMarouene Boubakri 	pool->lock = SPINLOCK_UNLOCK;
67*fc5e0894SMarouene Boubakri 
68*fc5e0894SMarouene Boubakri 	return true;
69*fc5e0894SMarouene Boubakri }
70*fc5e0894SMarouene Boubakri 
71*fc5e0894SMarouene Boubakri void tee_mm_final(tee_mm_pool_t *pool)
72*fc5e0894SMarouene Boubakri {
73*fc5e0894SMarouene Boubakri 	if (pool == NULL || pool->entry == NULL)
74*fc5e0894SMarouene Boubakri 		return;
75*fc5e0894SMarouene Boubakri 
76*fc5e0894SMarouene Boubakri 	while (pool->entry->next != NULL)
77*fc5e0894SMarouene Boubakri 		tee_mm_free(pool->entry->next);
78*fc5e0894SMarouene Boubakri 	pfree(pool, pool->entry);
79*fc5e0894SMarouene Boubakri 	pool->entry = NULL;
80*fc5e0894SMarouene Boubakri }
81*fc5e0894SMarouene Boubakri 
82*fc5e0894SMarouene Boubakri static void tee_mm_add(tee_mm_entry_t *p, tee_mm_entry_t *nn)
83*fc5e0894SMarouene Boubakri {
84*fc5e0894SMarouene Boubakri 	/* add to list */
85*fc5e0894SMarouene Boubakri 	nn->next = p->next;
86*fc5e0894SMarouene Boubakri 	p->next = nn;
87*fc5e0894SMarouene Boubakri }
88*fc5e0894SMarouene Boubakri 
89*fc5e0894SMarouene Boubakri #ifdef CFG_WITH_STATS
90*fc5e0894SMarouene Boubakri static size_t tee_mm_stats_allocated(tee_mm_pool_t *pool)
91*fc5e0894SMarouene Boubakri {
92*fc5e0894SMarouene Boubakri 	tee_mm_entry_t *entry;
93*fc5e0894SMarouene Boubakri 	uint32_t sz = 0;
94*fc5e0894SMarouene Boubakri 
95*fc5e0894SMarouene Boubakri 	if (!pool)
96*fc5e0894SMarouene Boubakri 		return 0;
97*fc5e0894SMarouene Boubakri 
98*fc5e0894SMarouene Boubakri 	entry = pool->entry;
99*fc5e0894SMarouene Boubakri 	while (entry) {
100*fc5e0894SMarouene Boubakri 		sz += entry->size;
101*fc5e0894SMarouene Boubakri 		entry = entry->next;
102*fc5e0894SMarouene Boubakri 	}
103*fc5e0894SMarouene Boubakri 
104*fc5e0894SMarouene Boubakri 	return sz << pool->shift;
105*fc5e0894SMarouene Boubakri }
106*fc5e0894SMarouene Boubakri 
107*fc5e0894SMarouene Boubakri void tee_mm_get_pool_stats(tee_mm_pool_t *pool, struct malloc_stats *stats,
108*fc5e0894SMarouene Boubakri 			   bool reset)
109*fc5e0894SMarouene Boubakri {
110*fc5e0894SMarouene Boubakri 	uint32_t exceptions;
111*fc5e0894SMarouene Boubakri 
112*fc5e0894SMarouene Boubakri 	if (!pool)
113*fc5e0894SMarouene Boubakri 		return;
114*fc5e0894SMarouene Boubakri 
115*fc5e0894SMarouene Boubakri 	memset(stats, 0, sizeof(*stats));
116*fc5e0894SMarouene Boubakri 
117*fc5e0894SMarouene Boubakri 	exceptions = cpu_spin_lock_xsave(&pool->lock);
118*fc5e0894SMarouene Boubakri 
119*fc5e0894SMarouene Boubakri 	stats->size = pool->size;
120*fc5e0894SMarouene Boubakri 	stats->max_allocated = pool->max_allocated;
121*fc5e0894SMarouene Boubakri 	stats->allocated = tee_mm_stats_allocated(pool);
122*fc5e0894SMarouene Boubakri 
123*fc5e0894SMarouene Boubakri 	if (reset)
124*fc5e0894SMarouene Boubakri 		pool->max_allocated = 0;
125*fc5e0894SMarouene Boubakri 	cpu_spin_unlock_xrestore(&pool->lock, exceptions);
126*fc5e0894SMarouene Boubakri }
127*fc5e0894SMarouene Boubakri 
128*fc5e0894SMarouene Boubakri static void update_max_allocated(tee_mm_pool_t *pool)
129*fc5e0894SMarouene Boubakri {
130*fc5e0894SMarouene Boubakri 	size_t sz = tee_mm_stats_allocated(pool);
131*fc5e0894SMarouene Boubakri 
132*fc5e0894SMarouene Boubakri 	if (sz > pool->max_allocated)
133*fc5e0894SMarouene Boubakri 		pool->max_allocated = sz;
134*fc5e0894SMarouene Boubakri }
135*fc5e0894SMarouene Boubakri #else /* CFG_WITH_STATS */
136*fc5e0894SMarouene Boubakri static inline void update_max_allocated(tee_mm_pool_t *pool __unused)
137*fc5e0894SMarouene Boubakri {
138*fc5e0894SMarouene Boubakri }
139*fc5e0894SMarouene Boubakri #endif /* CFG_WITH_STATS */
140*fc5e0894SMarouene Boubakri 
141*fc5e0894SMarouene Boubakri tee_mm_entry_t *tee_mm_alloc(tee_mm_pool_t *pool, size_t size)
142*fc5e0894SMarouene Boubakri {
143*fc5e0894SMarouene Boubakri 	size_t psize;
144*fc5e0894SMarouene Boubakri 	tee_mm_entry_t *entry;
145*fc5e0894SMarouene Boubakri 	tee_mm_entry_t *nn;
146*fc5e0894SMarouene Boubakri 	size_t remaining;
147*fc5e0894SMarouene Boubakri 	uint32_t exceptions;
148*fc5e0894SMarouene Boubakri 
149*fc5e0894SMarouene Boubakri 	/* Check that pool is initialized */
150*fc5e0894SMarouene Boubakri 	if (!pool || !pool->entry)
151*fc5e0894SMarouene Boubakri 		return NULL;
152*fc5e0894SMarouene Boubakri 
153*fc5e0894SMarouene Boubakri 	nn = pmalloc(pool, sizeof(tee_mm_entry_t));
154*fc5e0894SMarouene Boubakri 	if (!nn)
155*fc5e0894SMarouene Boubakri 		return NULL;
156*fc5e0894SMarouene Boubakri 
157*fc5e0894SMarouene Boubakri 	exceptions = cpu_spin_lock_xsave(&pool->lock);
158*fc5e0894SMarouene Boubakri 
159*fc5e0894SMarouene Boubakri 	entry = pool->entry;
160*fc5e0894SMarouene Boubakri 	if (!size)
161*fc5e0894SMarouene Boubakri 		psize = 0;
162*fc5e0894SMarouene Boubakri 	else
163*fc5e0894SMarouene Boubakri 		psize = ((size - 1) >> pool->shift) + 1;
164*fc5e0894SMarouene Boubakri 
165*fc5e0894SMarouene Boubakri 	/* find free slot */
166*fc5e0894SMarouene Boubakri 	if (pool->flags & TEE_MM_POOL_HI_ALLOC) {
167*fc5e0894SMarouene Boubakri 		while (entry->next != NULL && psize >
168*fc5e0894SMarouene Boubakri 		       (entry->offset - entry->next->offset -
169*fc5e0894SMarouene Boubakri 			entry->next->size))
170*fc5e0894SMarouene Boubakri 			entry = entry->next;
171*fc5e0894SMarouene Boubakri 	} else {
172*fc5e0894SMarouene Boubakri 		while (entry->next != NULL && psize >
173*fc5e0894SMarouene Boubakri 		       (entry->next->offset - entry->size - entry->offset))
174*fc5e0894SMarouene Boubakri 			entry = entry->next;
175*fc5e0894SMarouene Boubakri 	}
176*fc5e0894SMarouene Boubakri 
177*fc5e0894SMarouene Boubakri 	/* check if we have enough memory */
178*fc5e0894SMarouene Boubakri 	if (entry->next == NULL) {
179*fc5e0894SMarouene Boubakri 		if (pool->flags & TEE_MM_POOL_HI_ALLOC) {
180*fc5e0894SMarouene Boubakri 			/*
181*fc5e0894SMarouene Boubakri 			 * entry->offset is a "block count" offset from
182*fc5e0894SMarouene Boubakri 			 * pool->lo. The byte offset is
183*fc5e0894SMarouene Boubakri 			 * (entry->offset << pool->shift).
184*fc5e0894SMarouene Boubakri 			 * In the HI_ALLOC allocation scheme the memory is
185*fc5e0894SMarouene Boubakri 			 * allocated from the end of the segment, thus to
186*fc5e0894SMarouene Boubakri 			 * validate there is sufficient memory validate that
187*fc5e0894SMarouene Boubakri 			 * (entry->offset << pool->shift) > size.
188*fc5e0894SMarouene Boubakri 			 */
189*fc5e0894SMarouene Boubakri 			if ((entry->offset << pool->shift) < size) {
190*fc5e0894SMarouene Boubakri 				/* out of memory */
191*fc5e0894SMarouene Boubakri 				goto err;
192*fc5e0894SMarouene Boubakri 			}
193*fc5e0894SMarouene Boubakri 		} else {
194*fc5e0894SMarouene Boubakri 			if (!pool->size)
195*fc5e0894SMarouene Boubakri 				panic("invalid pool");
196*fc5e0894SMarouene Boubakri 
197*fc5e0894SMarouene Boubakri 			remaining = pool->size;
198*fc5e0894SMarouene Boubakri 			remaining -= ((entry->offset + entry->size) <<
199*fc5e0894SMarouene Boubakri 				      pool->shift);
200*fc5e0894SMarouene Boubakri 
201*fc5e0894SMarouene Boubakri 			if (remaining < size) {
202*fc5e0894SMarouene Boubakri 				/* out of memory */
203*fc5e0894SMarouene Boubakri 				goto err;
204*fc5e0894SMarouene Boubakri 			}
205*fc5e0894SMarouene Boubakri 		}
206*fc5e0894SMarouene Boubakri 	}
207*fc5e0894SMarouene Boubakri 
208*fc5e0894SMarouene Boubakri 	tee_mm_add(entry, nn);
209*fc5e0894SMarouene Boubakri 
210*fc5e0894SMarouene Boubakri 	if (pool->flags & TEE_MM_POOL_HI_ALLOC)
211*fc5e0894SMarouene Boubakri 		nn->offset = entry->offset - psize;
212*fc5e0894SMarouene Boubakri 	else
213*fc5e0894SMarouene Boubakri 		nn->offset = entry->offset + entry->size;
214*fc5e0894SMarouene Boubakri 	nn->size = psize;
215*fc5e0894SMarouene Boubakri 	nn->pool = pool;
216*fc5e0894SMarouene Boubakri 
217*fc5e0894SMarouene Boubakri 	update_max_allocated(pool);
218*fc5e0894SMarouene Boubakri 
219*fc5e0894SMarouene Boubakri 	cpu_spin_unlock_xrestore(&pool->lock, exceptions);
220*fc5e0894SMarouene Boubakri 	return nn;
221*fc5e0894SMarouene Boubakri err:
222*fc5e0894SMarouene Boubakri 	cpu_spin_unlock_xrestore(&pool->lock, exceptions);
223*fc5e0894SMarouene Boubakri 	pfree(pool, nn);
224*fc5e0894SMarouene Boubakri 	return NULL;
225*fc5e0894SMarouene Boubakri }
226*fc5e0894SMarouene Boubakri 
227*fc5e0894SMarouene Boubakri static inline bool fit_in_gap(tee_mm_pool_t *pool, tee_mm_entry_t *e,
228*fc5e0894SMarouene Boubakri 			      paddr_t offslo, paddr_t offshi)
229*fc5e0894SMarouene Boubakri {
230*fc5e0894SMarouene Boubakri 	if (pool->flags & TEE_MM_POOL_HI_ALLOC) {
231*fc5e0894SMarouene Boubakri 		if (offshi > e->offset ||
232*fc5e0894SMarouene Boubakri 		    (e->next != NULL &&
233*fc5e0894SMarouene Boubakri 		     (offslo < e->next->offset + e->next->size)) ||
234*fc5e0894SMarouene Boubakri 		    (offshi << pool->shift) - 1 > pool->size)
235*fc5e0894SMarouene Boubakri 			/* memory not available */
236*fc5e0894SMarouene Boubakri 			return false;
237*fc5e0894SMarouene Boubakri 	} else {
238*fc5e0894SMarouene Boubakri 		if (offslo < (e->offset + e->size) ||
239*fc5e0894SMarouene Boubakri 		    (e->next != NULL && (offshi > e->next->offset)) ||
240*fc5e0894SMarouene Boubakri 		    (offshi << pool->shift) > pool->size)
241*fc5e0894SMarouene Boubakri 			/* memory not available */
242*fc5e0894SMarouene Boubakri 			return false;
243*fc5e0894SMarouene Boubakri 	}
244*fc5e0894SMarouene Boubakri 
245*fc5e0894SMarouene Boubakri 	return true;
246*fc5e0894SMarouene Boubakri }
247*fc5e0894SMarouene Boubakri 
248*fc5e0894SMarouene Boubakri tee_mm_entry_t *tee_mm_alloc2(tee_mm_pool_t *pool, paddr_t base, size_t size)
249*fc5e0894SMarouene Boubakri {
250*fc5e0894SMarouene Boubakri 	tee_mm_entry_t *entry;
251*fc5e0894SMarouene Boubakri 	paddr_t offslo;
252*fc5e0894SMarouene Boubakri 	paddr_t offshi;
253*fc5e0894SMarouene Boubakri 	tee_mm_entry_t *mm;
254*fc5e0894SMarouene Boubakri 	uint32_t exceptions;
255*fc5e0894SMarouene Boubakri 
256*fc5e0894SMarouene Boubakri 	/* Check that pool is initialized */
257*fc5e0894SMarouene Boubakri 	if (!pool || !pool->entry)
258*fc5e0894SMarouene Boubakri 		return NULL;
259*fc5e0894SMarouene Boubakri 
260*fc5e0894SMarouene Boubakri 	/* Wrapping and sanity check */
261*fc5e0894SMarouene Boubakri 	if ((base + size) < base || base < pool->lo)
262*fc5e0894SMarouene Boubakri 		return NULL;
263*fc5e0894SMarouene Boubakri 
264*fc5e0894SMarouene Boubakri 	mm = pmalloc(pool, sizeof(tee_mm_entry_t));
265*fc5e0894SMarouene Boubakri 	if (!mm)
266*fc5e0894SMarouene Boubakri 		return NULL;
267*fc5e0894SMarouene Boubakri 
268*fc5e0894SMarouene Boubakri 	exceptions = cpu_spin_lock_xsave(&pool->lock);
269*fc5e0894SMarouene Boubakri 
270*fc5e0894SMarouene Boubakri 	entry = pool->entry;
271*fc5e0894SMarouene Boubakri 	offslo = (base - pool->lo) >> pool->shift;
272*fc5e0894SMarouene Boubakri 	offshi = ((base - pool->lo + size - 1) >> pool->shift) + 1;
273*fc5e0894SMarouene Boubakri 
274*fc5e0894SMarouene Boubakri 	/* find slot */
275*fc5e0894SMarouene Boubakri 	if (pool->flags & TEE_MM_POOL_HI_ALLOC) {
276*fc5e0894SMarouene Boubakri 		while (entry->next != NULL &&
277*fc5e0894SMarouene Boubakri 		       offshi < entry->next->offset + entry->next->size)
278*fc5e0894SMarouene Boubakri 			entry = entry->next;
279*fc5e0894SMarouene Boubakri 	} else {
280*fc5e0894SMarouene Boubakri 		while (entry->next != NULL && offslo > entry->next->offset)
281*fc5e0894SMarouene Boubakri 			entry = entry->next;
282*fc5e0894SMarouene Boubakri 	}
283*fc5e0894SMarouene Boubakri 
284*fc5e0894SMarouene Boubakri 	/* Check that memory is available */
285*fc5e0894SMarouene Boubakri 	if (!fit_in_gap(pool, entry, offslo, offshi))
286*fc5e0894SMarouene Boubakri 		goto err;
287*fc5e0894SMarouene Boubakri 
288*fc5e0894SMarouene Boubakri 	tee_mm_add(entry, mm);
289*fc5e0894SMarouene Boubakri 
290*fc5e0894SMarouene Boubakri 	mm->offset = offslo;
291*fc5e0894SMarouene Boubakri 	mm->size = offshi - offslo;
292*fc5e0894SMarouene Boubakri 	mm->pool = pool;
293*fc5e0894SMarouene Boubakri 
294*fc5e0894SMarouene Boubakri 	update_max_allocated(pool);
295*fc5e0894SMarouene Boubakri 	cpu_spin_unlock_xrestore(&pool->lock, exceptions);
296*fc5e0894SMarouene Boubakri 	return mm;
297*fc5e0894SMarouene Boubakri err:
298*fc5e0894SMarouene Boubakri 	cpu_spin_unlock_xrestore(&pool->lock, exceptions);
299*fc5e0894SMarouene Boubakri 	pfree(pool, mm);
300*fc5e0894SMarouene Boubakri 	return NULL;
301*fc5e0894SMarouene Boubakri }
302*fc5e0894SMarouene Boubakri 
303*fc5e0894SMarouene Boubakri void tee_mm_free(tee_mm_entry_t *p)
304*fc5e0894SMarouene Boubakri {
305*fc5e0894SMarouene Boubakri 	tee_mm_entry_t *entry;
306*fc5e0894SMarouene Boubakri 	uint32_t exceptions;
307*fc5e0894SMarouene Boubakri 
308*fc5e0894SMarouene Boubakri 	if (!p || !p->pool)
309*fc5e0894SMarouene Boubakri 		return;
310*fc5e0894SMarouene Boubakri 
311*fc5e0894SMarouene Boubakri 	exceptions = cpu_spin_lock_xsave(&p->pool->lock);
312*fc5e0894SMarouene Boubakri 	entry = p->pool->entry;
313*fc5e0894SMarouene Boubakri 
314*fc5e0894SMarouene Boubakri 	/* remove entry from list */
315*fc5e0894SMarouene Boubakri 	while (entry->next != NULL && entry->next != p)
316*fc5e0894SMarouene Boubakri 		entry = entry->next;
317*fc5e0894SMarouene Boubakri 
318*fc5e0894SMarouene Boubakri 	if (!entry->next)
319*fc5e0894SMarouene Boubakri 		panic("invalid mm_entry");
320*fc5e0894SMarouene Boubakri 
321*fc5e0894SMarouene Boubakri 	entry->next = entry->next->next;
322*fc5e0894SMarouene Boubakri 	cpu_spin_unlock_xrestore(&p->pool->lock, exceptions);
323*fc5e0894SMarouene Boubakri 
324*fc5e0894SMarouene Boubakri 	pfree(p->pool, p);
325*fc5e0894SMarouene Boubakri }
326*fc5e0894SMarouene Boubakri 
327*fc5e0894SMarouene Boubakri size_t tee_mm_get_bytes(const tee_mm_entry_t *mm)
328*fc5e0894SMarouene Boubakri {
329*fc5e0894SMarouene Boubakri 	if (!mm || !mm->pool)
330*fc5e0894SMarouene Boubakri 		return 0;
331*fc5e0894SMarouene Boubakri 	else
332*fc5e0894SMarouene Boubakri 		return mm->size << mm->pool->shift;
333*fc5e0894SMarouene Boubakri }
334*fc5e0894SMarouene Boubakri 
335*fc5e0894SMarouene Boubakri bool tee_mm_addr_is_within_range(const tee_mm_pool_t *pool, paddr_t addr)
336*fc5e0894SMarouene Boubakri {
337*fc5e0894SMarouene Boubakri 	return pool && addr >= pool->lo &&
338*fc5e0894SMarouene Boubakri 		addr <= (pool->lo + (pool->size - 1));
339*fc5e0894SMarouene Boubakri }
340*fc5e0894SMarouene Boubakri 
341*fc5e0894SMarouene Boubakri bool tee_mm_is_empty(tee_mm_pool_t *pool)
342*fc5e0894SMarouene Boubakri {
343*fc5e0894SMarouene Boubakri 	bool ret;
344*fc5e0894SMarouene Boubakri 	uint32_t exceptions;
345*fc5e0894SMarouene Boubakri 
346*fc5e0894SMarouene Boubakri 	if (pool == NULL || pool->entry == NULL)
347*fc5e0894SMarouene Boubakri 		return true;
348*fc5e0894SMarouene Boubakri 
349*fc5e0894SMarouene Boubakri 	exceptions = cpu_spin_lock_xsave(&pool->lock);
350*fc5e0894SMarouene Boubakri 	ret = pool->entry == NULL || pool->entry->next == NULL;
351*fc5e0894SMarouene Boubakri 	cpu_spin_unlock_xrestore(&pool->lock, exceptions);
352*fc5e0894SMarouene Boubakri 
353*fc5e0894SMarouene Boubakri 	return ret;
354*fc5e0894SMarouene Boubakri }
355*fc5e0894SMarouene Boubakri 
356*fc5e0894SMarouene Boubakri /* Physical Secure DDR pool */
357*fc5e0894SMarouene Boubakri tee_mm_pool_t tee_mm_sec_ddr;
358*fc5e0894SMarouene Boubakri 
359*fc5e0894SMarouene Boubakri /* Virtual eSRAM pool */
360*fc5e0894SMarouene Boubakri tee_mm_pool_t tee_mm_vcore;
361*fc5e0894SMarouene Boubakri 
362*fc5e0894SMarouene Boubakri /* Shared memory pool */
363*fc5e0894SMarouene Boubakri tee_mm_pool_t tee_mm_shm;
364*fc5e0894SMarouene Boubakri 
365*fc5e0894SMarouene Boubakri tee_mm_entry_t *tee_mm_find(const tee_mm_pool_t *pool, paddr_t addr)
366*fc5e0894SMarouene Boubakri {
367*fc5e0894SMarouene Boubakri 	tee_mm_entry_t *entry = pool->entry;
368*fc5e0894SMarouene Boubakri 	uint16_t offset = (addr - pool->lo) >> pool->shift;
369*fc5e0894SMarouene Boubakri 	uint32_t exceptions;
370*fc5e0894SMarouene Boubakri 
371*fc5e0894SMarouene Boubakri 	if (!tee_mm_addr_is_within_range(pool, addr))
372*fc5e0894SMarouene Boubakri 		return NULL;
373*fc5e0894SMarouene Boubakri 
374*fc5e0894SMarouene Boubakri 	exceptions = cpu_spin_lock_xsave(&((tee_mm_pool_t *)pool)->lock);
375*fc5e0894SMarouene Boubakri 
376*fc5e0894SMarouene Boubakri 	while (entry->next != NULL) {
377*fc5e0894SMarouene Boubakri 		entry = entry->next;
378*fc5e0894SMarouene Boubakri 
379*fc5e0894SMarouene Boubakri 		if ((offset >= entry->offset) &&
380*fc5e0894SMarouene Boubakri 		    (offset < (entry->offset + entry->size))) {
381*fc5e0894SMarouene Boubakri 			cpu_spin_unlock_xrestore(&((tee_mm_pool_t *)pool)->lock,
382*fc5e0894SMarouene Boubakri 						 exceptions);
383*fc5e0894SMarouene Boubakri 			return entry;
384*fc5e0894SMarouene Boubakri 		}
385*fc5e0894SMarouene Boubakri 	}
386*fc5e0894SMarouene Boubakri 
387*fc5e0894SMarouene Boubakri 	cpu_spin_unlock_xrestore(&((tee_mm_pool_t *)pool)->lock, exceptions);
388*fc5e0894SMarouene Boubakri 	return NULL;
389*fc5e0894SMarouene Boubakri }
390*fc5e0894SMarouene Boubakri 
391*fc5e0894SMarouene Boubakri uintptr_t tee_mm_get_smem(const tee_mm_entry_t *mm)
392*fc5e0894SMarouene Boubakri {
393*fc5e0894SMarouene Boubakri 	return (mm->offset << mm->pool->shift) + mm->pool->lo;
394*fc5e0894SMarouene Boubakri }
395