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