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