1185b4595SMarouene Boubakri // SPDX-License-Identifier: BSD-2-Clause 2185b4595SMarouene Boubakri /* 3d5ad7ccfSJens Wiklander * Copyright (c) 2016-2021, Linaro Limited 4185b4595SMarouene Boubakri */ 5185b4595SMarouene Boubakri 6185b4595SMarouene Boubakri #include <assert.h> 7ff01e245SAnton Rybakov #include <config.h> 8185b4595SMarouene Boubakri #include <initcall.h> 9185b4595SMarouene Boubakri #include <keep.h> 10185b4595SMarouene Boubakri #include <kernel/linker.h> 11185b4595SMarouene Boubakri #include <kernel/mutex.h> 12185b4595SMarouene Boubakri #include <kernel/panic.h> 13185b4595SMarouene Boubakri #include <kernel/refcount.h> 14185b4595SMarouene Boubakri #include <kernel/spinlock.h> 15185b4595SMarouene Boubakri #include <kernel/tee_misc.h> 16185b4595SMarouene Boubakri #include <mm/core_mmu.h> 17185b4595SMarouene Boubakri #include <mm/mobj.h> 18185b4595SMarouene Boubakri #include <mm/tee_pager.h> 19185b4595SMarouene Boubakri #include <mm/vm.h> 20185b4595SMarouene Boubakri #include <optee_msg.h> 21185b4595SMarouene Boubakri #include <stdlib.h> 22185b4595SMarouene Boubakri #include <tee_api_types.h> 23185b4595SMarouene Boubakri #include <types_ext.h> 24185b4595SMarouene Boubakri #include <util.h> 25185b4595SMarouene Boubakri 26185b4595SMarouene Boubakri struct mobj *mobj_sec_ddr; 27ff01e245SAnton Rybakov struct mobj *mobj_tee_ram_rx; 28ff01e245SAnton Rybakov struct mobj *mobj_tee_ram_rw; 29185b4595SMarouene Boubakri 30185b4595SMarouene Boubakri /* 31185b4595SMarouene Boubakri * mobj_phys implementation 32185b4595SMarouene Boubakri */ 33185b4595SMarouene Boubakri 34185b4595SMarouene Boubakri struct mobj_phys { 35185b4595SMarouene Boubakri struct mobj mobj; 36185b4595SMarouene Boubakri enum buf_is_attr battr; 37*8afe7a7cSJens Wiklander /* Defined by TEE_MATTR_MEM_TYPE_* in tee_mmu_types.h */ 38*8afe7a7cSJens Wiklander uint32_t mem_type; 39185b4595SMarouene Boubakri vaddr_t va; 40185b4595SMarouene Boubakri paddr_t pa; 41185b4595SMarouene Boubakri }; 42185b4595SMarouene Boubakri 43185b4595SMarouene Boubakri static struct mobj_phys *to_mobj_phys(struct mobj *mobj); 44185b4595SMarouene Boubakri 459c4aaf67SJens Wiklander static void *mobj_phys_get_va(struct mobj *mobj, size_t offset, size_t len) 46185b4595SMarouene Boubakri { 47185b4595SMarouene Boubakri struct mobj_phys *moph = to_mobj_phys(mobj); 48185b4595SMarouene Boubakri 499c4aaf67SJens Wiklander if (!moph->va || !mobj_check_offset_and_len(mobj, offset, len)) 50185b4595SMarouene Boubakri return NULL; 51185b4595SMarouene Boubakri 52185b4595SMarouene Boubakri return (void *)(moph->va + offset); 53185b4595SMarouene Boubakri } 54185b4595SMarouene Boubakri 55185b4595SMarouene Boubakri static TEE_Result mobj_phys_get_pa(struct mobj *mobj, size_t offs, 56185b4595SMarouene Boubakri size_t granule, paddr_t *pa) 57185b4595SMarouene Boubakri { 58185b4595SMarouene Boubakri struct mobj_phys *moph = to_mobj_phys(mobj); 59185b4595SMarouene Boubakri paddr_t p; 60185b4595SMarouene Boubakri 61185b4595SMarouene Boubakri if (!pa) 62185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 63185b4595SMarouene Boubakri 64185b4595SMarouene Boubakri p = moph->pa + offs; 65185b4595SMarouene Boubakri 66185b4595SMarouene Boubakri if (granule) { 67185b4595SMarouene Boubakri if (granule != SMALL_PAGE_SIZE && 68185b4595SMarouene Boubakri granule != CORE_MMU_PGDIR_SIZE) 69185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 70185b4595SMarouene Boubakri p &= ~(granule - 1); 71185b4595SMarouene Boubakri } 72185b4595SMarouene Boubakri 73185b4595SMarouene Boubakri *pa = p; 74185b4595SMarouene Boubakri return TEE_SUCCESS; 75185b4595SMarouene Boubakri } 76185b4595SMarouene Boubakri DECLARE_KEEP_PAGER(mobj_phys_get_pa); 77185b4595SMarouene Boubakri 78*8afe7a7cSJens Wiklander static TEE_Result mobj_phys_get_mem_type(struct mobj *mobj, uint32_t *mem_type) 79185b4595SMarouene Boubakri { 80185b4595SMarouene Boubakri struct mobj_phys *moph = to_mobj_phys(mobj); 81185b4595SMarouene Boubakri 82*8afe7a7cSJens Wiklander if (!mem_type) 83185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 84185b4595SMarouene Boubakri 85*8afe7a7cSJens Wiklander *mem_type = moph->mem_type; 86185b4595SMarouene Boubakri return TEE_SUCCESS; 87185b4595SMarouene Boubakri } 88185b4595SMarouene Boubakri 89185b4595SMarouene Boubakri static bool mobj_phys_matches(struct mobj *mobj, enum buf_is_attr attr) 90185b4595SMarouene Boubakri { 91185b4595SMarouene Boubakri struct mobj_phys *moph = to_mobj_phys(mobj); 92185b4595SMarouene Boubakri enum buf_is_attr a; 93185b4595SMarouene Boubakri 94185b4595SMarouene Boubakri a = moph->battr; 95185b4595SMarouene Boubakri 96185b4595SMarouene Boubakri switch (attr) { 97185b4595SMarouene Boubakri case CORE_MEM_SEC: 98185b4595SMarouene Boubakri return a == CORE_MEM_SEC || a == CORE_MEM_TEE_RAM || 99185b4595SMarouene Boubakri a == CORE_MEM_TA_RAM || a == CORE_MEM_SDP_MEM; 100185b4595SMarouene Boubakri case CORE_MEM_NON_SEC: 101185b4595SMarouene Boubakri return a == CORE_MEM_NSEC_SHM; 102185b4595SMarouene Boubakri case CORE_MEM_TEE_RAM: 103185b4595SMarouene Boubakri case CORE_MEM_TA_RAM: 104185b4595SMarouene Boubakri case CORE_MEM_NSEC_SHM: 105185b4595SMarouene Boubakri case CORE_MEM_SDP_MEM: 106185b4595SMarouene Boubakri return attr == a; 107185b4595SMarouene Boubakri default: 108185b4595SMarouene Boubakri return false; 109185b4595SMarouene Boubakri } 110185b4595SMarouene Boubakri } 111185b4595SMarouene Boubakri 112185b4595SMarouene Boubakri static void mobj_phys_free(struct mobj *mobj) 113185b4595SMarouene Boubakri { 114185b4595SMarouene Boubakri struct mobj_phys *moph = to_mobj_phys(mobj); 115185b4595SMarouene Boubakri 116185b4595SMarouene Boubakri free(moph); 117185b4595SMarouene Boubakri } 118185b4595SMarouene Boubakri 11900361c18SJens Wiklander /* 12000361c18SJens Wiklander * Note: this variable is weak just to ease breaking its dependency chain 12100361c18SJens Wiklander * when added to the unpaged area. 12200361c18SJens Wiklander */ 12339e8c200SJerome Forissier const struct mobj_ops mobj_phys_ops 12439e8c200SJerome Forissier __weak __relrodata_unpaged("mobj_phys_ops") = { 125185b4595SMarouene Boubakri .get_va = mobj_phys_get_va, 126185b4595SMarouene Boubakri .get_pa = mobj_phys_get_pa, 127185b4595SMarouene Boubakri .get_phys_offs = NULL, /* only offset 0 */ 128*8afe7a7cSJens Wiklander .get_mem_type = mobj_phys_get_mem_type, 129185b4595SMarouene Boubakri .matches = mobj_phys_matches, 130185b4595SMarouene Boubakri .free = mobj_phys_free, 131185b4595SMarouene Boubakri }; 132185b4595SMarouene Boubakri 133185b4595SMarouene Boubakri static struct mobj_phys *to_mobj_phys(struct mobj *mobj) 134185b4595SMarouene Boubakri { 135185b4595SMarouene Boubakri assert(mobj->ops == &mobj_phys_ops); 136185b4595SMarouene Boubakri return container_of(mobj, struct mobj_phys, mobj); 137185b4595SMarouene Boubakri } 138185b4595SMarouene Boubakri 139*8afe7a7cSJens Wiklander static struct mobj *mobj_phys_init(paddr_t pa, size_t size, uint32_t mem_type, 140ff01e245SAnton Rybakov enum buf_is_attr battr, 141ff01e245SAnton Rybakov enum teecore_memtypes area_type) 142185b4595SMarouene Boubakri { 143ff01e245SAnton Rybakov void *va = NULL; 144ff01e245SAnton Rybakov struct mobj_phys *moph = NULL; 145b715a420SAnton Rybakov struct tee_mmap_region *map = NULL; 146185b4595SMarouene Boubakri 147185b4595SMarouene Boubakri if ((pa & CORE_MMU_USER_PARAM_MASK) || 148185b4595SMarouene Boubakri (size & CORE_MMU_USER_PARAM_MASK)) { 149185b4595SMarouene Boubakri DMSG("Expect %#x alignment", CORE_MMU_USER_PARAM_SIZE); 150185b4595SMarouene Boubakri return NULL; 151185b4595SMarouene Boubakri } 152185b4595SMarouene Boubakri 153b715a420SAnton Rybakov if (pa) { 154c2e4eb43SAnton Rybakov va = phys_to_virt(pa, area_type, size); 155b715a420SAnton Rybakov } else { 156b715a420SAnton Rybakov map = core_mmu_find_mapping_exclusive(area_type, size); 157b715a420SAnton Rybakov if (!map) 158b715a420SAnton Rybakov return NULL; 159b715a420SAnton Rybakov 160b715a420SAnton Rybakov pa = map->pa; 161b715a420SAnton Rybakov va = (void *)map->va; 162b715a420SAnton Rybakov } 163b715a420SAnton Rybakov 164b715a420SAnton Rybakov /* Only SDP memory may not have a virtual address */ 165185b4595SMarouene Boubakri if (!va && battr != CORE_MEM_SDP_MEM) 166185b4595SMarouene Boubakri return NULL; 167185b4595SMarouene Boubakri 168185b4595SMarouene Boubakri moph = calloc(1, sizeof(*moph)); 169185b4595SMarouene Boubakri if (!moph) 170185b4595SMarouene Boubakri return NULL; 171185b4595SMarouene Boubakri 172185b4595SMarouene Boubakri moph->battr = battr; 173*8afe7a7cSJens Wiklander moph->mem_type = mem_type; 174185b4595SMarouene Boubakri moph->mobj.size = size; 175185b4595SMarouene Boubakri moph->mobj.ops = &mobj_phys_ops; 176185b4595SMarouene Boubakri refcount_set(&moph->mobj.refc, 1); 177185b4595SMarouene Boubakri moph->pa = pa; 178185b4595SMarouene Boubakri moph->va = (vaddr_t)va; 179185b4595SMarouene Boubakri 180185b4595SMarouene Boubakri return &moph->mobj; 181185b4595SMarouene Boubakri } 182185b4595SMarouene Boubakri 183*8afe7a7cSJens Wiklander struct mobj *mobj_phys_alloc(paddr_t pa, size_t size, uint32_t mem_type, 184ff01e245SAnton Rybakov enum buf_is_attr battr) 185ff01e245SAnton Rybakov { 186ff01e245SAnton Rybakov enum teecore_memtypes area_type; 187ff01e245SAnton Rybakov 188ff01e245SAnton Rybakov switch (battr) { 189ff01e245SAnton Rybakov case CORE_MEM_TEE_RAM: 190ff01e245SAnton Rybakov area_type = MEM_AREA_TEE_RAM_RW_DATA; 191ff01e245SAnton Rybakov break; 192ff01e245SAnton Rybakov case CORE_MEM_TA_RAM: 193ff01e245SAnton Rybakov area_type = MEM_AREA_TA_RAM; 194ff01e245SAnton Rybakov break; 195ff01e245SAnton Rybakov case CORE_MEM_NSEC_SHM: 196ff01e245SAnton Rybakov area_type = MEM_AREA_NSEC_SHM; 197ff01e245SAnton Rybakov break; 198ff01e245SAnton Rybakov case CORE_MEM_SDP_MEM: 199ff01e245SAnton Rybakov area_type = MEM_AREA_SDP_MEM; 200ff01e245SAnton Rybakov break; 201ff01e245SAnton Rybakov default: 202ff01e245SAnton Rybakov DMSG("can't allocate with specified attribute"); 203ff01e245SAnton Rybakov return NULL; 204ff01e245SAnton Rybakov } 205ff01e245SAnton Rybakov 206*8afe7a7cSJens Wiklander return mobj_phys_init(pa, size, mem_type, battr, area_type); 207ff01e245SAnton Rybakov } 208ff01e245SAnton Rybakov 209185b4595SMarouene Boubakri /* 210185b4595SMarouene Boubakri * mobj_virt implementation 211185b4595SMarouene Boubakri */ 212185b4595SMarouene Boubakri 213185b4595SMarouene Boubakri static void mobj_virt_assert_type(struct mobj *mobj); 214185b4595SMarouene Boubakri 2159c4aaf67SJens Wiklander static void *mobj_virt_get_va(struct mobj *mobj, size_t offset, 2169c4aaf67SJens Wiklander size_t len __maybe_unused) 217185b4595SMarouene Boubakri { 218185b4595SMarouene Boubakri mobj_virt_assert_type(mobj); 2199c4aaf67SJens Wiklander assert(mobj_check_offset_and_len(mobj, offset, len)); 220185b4595SMarouene Boubakri 221185b4595SMarouene Boubakri return (void *)(vaddr_t)offset; 222185b4595SMarouene Boubakri } 223185b4595SMarouene Boubakri 22400361c18SJens Wiklander /* 22500361c18SJens Wiklander * Note: this variable is weak just to ease breaking its dependency chain 22600361c18SJens Wiklander * when added to the unpaged area. 22700361c18SJens Wiklander */ 22839e8c200SJerome Forissier const struct mobj_ops mobj_virt_ops 22939e8c200SJerome Forissier __weak __relrodata_unpaged("mobj_virt_ops") = { 230185b4595SMarouene Boubakri .get_va = mobj_virt_get_va, 231185b4595SMarouene Boubakri }; 232185b4595SMarouene Boubakri 233185b4595SMarouene Boubakri static void mobj_virt_assert_type(struct mobj *mobj __maybe_unused) 234185b4595SMarouene Boubakri { 235185b4595SMarouene Boubakri assert(mobj->ops == &mobj_virt_ops); 236185b4595SMarouene Boubakri } 237185b4595SMarouene Boubakri 238185b4595SMarouene Boubakri struct mobj mobj_virt = { .ops = &mobj_virt_ops, .size = SIZE_MAX }; 239185b4595SMarouene Boubakri 240185b4595SMarouene Boubakri /* 241185b4595SMarouene Boubakri * mobj_mm implementation 242185b4595SMarouene Boubakri */ 243185b4595SMarouene Boubakri 244185b4595SMarouene Boubakri struct mobj_mm { 245185b4595SMarouene Boubakri tee_mm_entry_t *mm; 246185b4595SMarouene Boubakri struct mobj *parent_mobj; 247185b4595SMarouene Boubakri struct mobj mobj; 248185b4595SMarouene Boubakri }; 249185b4595SMarouene Boubakri 250185b4595SMarouene Boubakri static struct mobj_mm *to_mobj_mm(struct mobj *mobj); 251185b4595SMarouene Boubakri 252185b4595SMarouene Boubakri static size_t mobj_mm_offs(struct mobj *mobj, size_t offs) 253185b4595SMarouene Boubakri { 254185b4595SMarouene Boubakri tee_mm_entry_t *mm = to_mobj_mm(mobj)->mm; 255185b4595SMarouene Boubakri 256185b4595SMarouene Boubakri return (mm->offset << mm->pool->shift) + offs; 257185b4595SMarouene Boubakri } 258185b4595SMarouene Boubakri 2599c4aaf67SJens Wiklander static void *mobj_mm_get_va(struct mobj *mobj, size_t offs, size_t len) 260185b4595SMarouene Boubakri { 261185b4595SMarouene Boubakri return mobj_get_va(to_mobj_mm(mobj)->parent_mobj, 2629c4aaf67SJens Wiklander mobj_mm_offs(mobj, offs), len); 263185b4595SMarouene Boubakri } 264185b4595SMarouene Boubakri 265185b4595SMarouene Boubakri 266185b4595SMarouene Boubakri static TEE_Result mobj_mm_get_pa(struct mobj *mobj, size_t offs, 267185b4595SMarouene Boubakri size_t granule, paddr_t *pa) 268185b4595SMarouene Boubakri { 269185b4595SMarouene Boubakri return mobj_get_pa(to_mobj_mm(mobj)->parent_mobj, 270185b4595SMarouene Boubakri mobj_mm_offs(mobj, offs), granule, pa); 271185b4595SMarouene Boubakri } 272185b4595SMarouene Boubakri DECLARE_KEEP_PAGER(mobj_mm_get_pa); 273185b4595SMarouene Boubakri 274185b4595SMarouene Boubakri static size_t mobj_mm_get_phys_offs(struct mobj *mobj, size_t granule) 275185b4595SMarouene Boubakri { 276185b4595SMarouene Boubakri return mobj_get_phys_offs(to_mobj_mm(mobj)->parent_mobj, granule); 277185b4595SMarouene Boubakri } 278185b4595SMarouene Boubakri 279*8afe7a7cSJens Wiklander static TEE_Result mobj_mm_get_mem_type(struct mobj *mobj, uint32_t *mem_type) 280185b4595SMarouene Boubakri { 281*8afe7a7cSJens Wiklander return mobj_get_mem_type(to_mobj_mm(mobj)->parent_mobj, mem_type); 282185b4595SMarouene Boubakri } 283185b4595SMarouene Boubakri 284185b4595SMarouene Boubakri static bool mobj_mm_matches(struct mobj *mobj, enum buf_is_attr attr) 285185b4595SMarouene Boubakri { 286185b4595SMarouene Boubakri return mobj_matches(to_mobj_mm(mobj)->parent_mobj, attr); 287185b4595SMarouene Boubakri } 288185b4595SMarouene Boubakri 289185b4595SMarouene Boubakri static void mobj_mm_free(struct mobj *mobj) 290185b4595SMarouene Boubakri { 291185b4595SMarouene Boubakri struct mobj_mm *m = to_mobj_mm(mobj); 292185b4595SMarouene Boubakri 293185b4595SMarouene Boubakri tee_mm_free(m->mm); 294185b4595SMarouene Boubakri free(m); 295185b4595SMarouene Boubakri } 296185b4595SMarouene Boubakri 29700361c18SJens Wiklander /* 29800361c18SJens Wiklander * Note: this variable is weak just to ease breaking its dependency chain 29900361c18SJens Wiklander * when added to the unpaged area. 30000361c18SJens Wiklander */ 30139e8c200SJerome Forissier const struct mobj_ops mobj_mm_ops __weak __relrodata_unpaged("mobj_mm_ops") = { 302185b4595SMarouene Boubakri .get_va = mobj_mm_get_va, 303185b4595SMarouene Boubakri .get_pa = mobj_mm_get_pa, 304185b4595SMarouene Boubakri .get_phys_offs = mobj_mm_get_phys_offs, 305*8afe7a7cSJens Wiklander .get_mem_type = mobj_mm_get_mem_type, 306185b4595SMarouene Boubakri .matches = mobj_mm_matches, 307185b4595SMarouene Boubakri .free = mobj_mm_free, 308185b4595SMarouene Boubakri }; 309185b4595SMarouene Boubakri 310185b4595SMarouene Boubakri static struct mobj_mm *to_mobj_mm(struct mobj *mobj) 311185b4595SMarouene Boubakri { 312185b4595SMarouene Boubakri assert(mobj->ops == &mobj_mm_ops); 313185b4595SMarouene Boubakri return container_of(mobj, struct mobj_mm, mobj); 314185b4595SMarouene Boubakri } 315185b4595SMarouene Boubakri 316185b4595SMarouene Boubakri struct mobj *mobj_mm_alloc(struct mobj *mobj_parent, size_t size, 317185b4595SMarouene Boubakri tee_mm_pool_t *pool) 318185b4595SMarouene Boubakri { 319185b4595SMarouene Boubakri struct mobj_mm *m = calloc(1, sizeof(*m)); 320185b4595SMarouene Boubakri 321185b4595SMarouene Boubakri if (!m) 322185b4595SMarouene Boubakri return NULL; 323185b4595SMarouene Boubakri 324185b4595SMarouene Boubakri m->mm = tee_mm_alloc(pool, size); 325185b4595SMarouene Boubakri if (!m->mm) { 326185b4595SMarouene Boubakri free(m); 327185b4595SMarouene Boubakri return NULL; 328185b4595SMarouene Boubakri } 329185b4595SMarouene Boubakri 330185b4595SMarouene Boubakri m->parent_mobj = mobj_parent; 331185b4595SMarouene Boubakri m->mobj.size = size; 332185b4595SMarouene Boubakri m->mobj.ops = &mobj_mm_ops; 333185b4595SMarouene Boubakri refcount_set(&m->mobj.refc, 1); 334185b4595SMarouene Boubakri 335185b4595SMarouene Boubakri return &m->mobj; 336185b4595SMarouene Boubakri } 337185b4595SMarouene Boubakri 338185b4595SMarouene Boubakri 339185b4595SMarouene Boubakri /* 340185b4595SMarouene Boubakri * mobj_shm implementation. mobj_shm represents buffer in predefined shm region 341185b4595SMarouene Boubakri * - it is physically contiguous. 342185b4595SMarouene Boubakri * - it is identified in static physical layout as MEM_AREA_NSEC_SHM. 343185b4595SMarouene Boubakri * - it creates mobjs that match specific CORE_MEM_NSEC_SHM and non secure 344185b4595SMarouene Boubakri * generic CORE_MEM_NON_SEC. 345185b4595SMarouene Boubakri */ 346185b4595SMarouene Boubakri 347185b4595SMarouene Boubakri struct mobj_shm { 348185b4595SMarouene Boubakri struct mobj mobj; 349185b4595SMarouene Boubakri paddr_t pa; 350185b4595SMarouene Boubakri uint64_t cookie; 351185b4595SMarouene Boubakri }; 352185b4595SMarouene Boubakri 353185b4595SMarouene Boubakri static struct mobj_shm *to_mobj_shm(struct mobj *mobj); 354185b4595SMarouene Boubakri 3559c4aaf67SJens Wiklander static void *mobj_shm_get_va(struct mobj *mobj, size_t offset, size_t len) 356185b4595SMarouene Boubakri { 357185b4595SMarouene Boubakri struct mobj_shm *m = to_mobj_shm(mobj); 358185b4595SMarouene Boubakri 3599c4aaf67SJens Wiklander if (!mobj_check_offset_and_len(mobj, offset, len)) 360185b4595SMarouene Boubakri return NULL; 361185b4595SMarouene Boubakri 362c2e4eb43SAnton Rybakov return phys_to_virt(m->pa + offset, MEM_AREA_NSEC_SHM, 363c2e4eb43SAnton Rybakov mobj->size - offset); 364185b4595SMarouene Boubakri } 365185b4595SMarouene Boubakri 366185b4595SMarouene Boubakri static TEE_Result mobj_shm_get_pa(struct mobj *mobj, size_t offs, 367185b4595SMarouene Boubakri size_t granule, paddr_t *pa) 368185b4595SMarouene Boubakri { 369185b4595SMarouene Boubakri struct mobj_shm *m = to_mobj_shm(mobj); 370185b4595SMarouene Boubakri paddr_t p; 371185b4595SMarouene Boubakri 372185b4595SMarouene Boubakri if (!pa || offs >= mobj->size) 373185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 374185b4595SMarouene Boubakri 375185b4595SMarouene Boubakri p = m->pa + offs; 376185b4595SMarouene Boubakri 377185b4595SMarouene Boubakri if (granule) { 378185b4595SMarouene Boubakri if (granule != SMALL_PAGE_SIZE && 379185b4595SMarouene Boubakri granule != CORE_MMU_PGDIR_SIZE) 380185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 381185b4595SMarouene Boubakri p &= ~(granule - 1); 382185b4595SMarouene Boubakri } 383185b4595SMarouene Boubakri 384185b4595SMarouene Boubakri *pa = p; 385185b4595SMarouene Boubakri return TEE_SUCCESS; 386185b4595SMarouene Boubakri } 387185b4595SMarouene Boubakri DECLARE_KEEP_PAGER(mobj_shm_get_pa); 388185b4595SMarouene Boubakri 389185b4595SMarouene Boubakri static size_t mobj_shm_get_phys_offs(struct mobj *mobj, size_t granule) 390185b4595SMarouene Boubakri { 391185b4595SMarouene Boubakri assert(IS_POWER_OF_TWO(granule)); 392185b4595SMarouene Boubakri return to_mobj_shm(mobj)->pa & (granule - 1); 393185b4595SMarouene Boubakri } 394185b4595SMarouene Boubakri 395185b4595SMarouene Boubakri static bool mobj_shm_matches(struct mobj *mobj __unused, enum buf_is_attr attr) 396185b4595SMarouene Boubakri { 397185b4595SMarouene Boubakri return attr == CORE_MEM_NSEC_SHM || attr == CORE_MEM_NON_SEC; 398185b4595SMarouene Boubakri } 399185b4595SMarouene Boubakri 400*8afe7a7cSJens Wiklander static TEE_Result mobj_shm_get_mem_type(struct mobj *mobj __unused, 401*8afe7a7cSJens Wiklander uint32_t *mem_type) 402e31a75b3SLejia Zhang { 403*8afe7a7cSJens Wiklander if (!mem_type) 404e31a75b3SLejia Zhang return TEE_ERROR_GENERIC; 405e31a75b3SLejia Zhang 406*8afe7a7cSJens Wiklander *mem_type = TEE_MATTR_MEM_TYPE_CACHED; 407e31a75b3SLejia Zhang 408e31a75b3SLejia Zhang return TEE_SUCCESS; 409e31a75b3SLejia Zhang } 410e31a75b3SLejia Zhang 411185b4595SMarouene Boubakri static void mobj_shm_free(struct mobj *mobj) 412185b4595SMarouene Boubakri { 413185b4595SMarouene Boubakri struct mobj_shm *m = to_mobj_shm(mobj); 414185b4595SMarouene Boubakri 415185b4595SMarouene Boubakri free(m); 416185b4595SMarouene Boubakri } 417185b4595SMarouene Boubakri 418185b4595SMarouene Boubakri static uint64_t mobj_shm_get_cookie(struct mobj *mobj) 419185b4595SMarouene Boubakri { 420185b4595SMarouene Boubakri return to_mobj_shm(mobj)->cookie; 421185b4595SMarouene Boubakri } 422185b4595SMarouene Boubakri 42300361c18SJens Wiklander /* 42400361c18SJens Wiklander * Note: this variable is weak just to ease breaking its dependency chain 42500361c18SJens Wiklander * when added to the unpaged area. 42600361c18SJens Wiklander */ 42739e8c200SJerome Forissier const struct mobj_ops mobj_shm_ops 42839e8c200SJerome Forissier __weak __relrodata_unpaged("mobj_shm_ops") = { 429185b4595SMarouene Boubakri .get_va = mobj_shm_get_va, 430185b4595SMarouene Boubakri .get_pa = mobj_shm_get_pa, 431185b4595SMarouene Boubakri .get_phys_offs = mobj_shm_get_phys_offs, 432*8afe7a7cSJens Wiklander .get_mem_type = mobj_shm_get_mem_type, 433185b4595SMarouene Boubakri .matches = mobj_shm_matches, 434185b4595SMarouene Boubakri .free = mobj_shm_free, 435185b4595SMarouene Boubakri .get_cookie = mobj_shm_get_cookie, 436185b4595SMarouene Boubakri }; 437185b4595SMarouene Boubakri 438185b4595SMarouene Boubakri static struct mobj_shm *to_mobj_shm(struct mobj *mobj) 439185b4595SMarouene Boubakri { 440185b4595SMarouene Boubakri assert(mobj->ops == &mobj_shm_ops); 441185b4595SMarouene Boubakri return container_of(mobj, struct mobj_shm, mobj); 442185b4595SMarouene Boubakri } 443185b4595SMarouene Boubakri 444185b4595SMarouene Boubakri struct mobj *mobj_shm_alloc(paddr_t pa, size_t size, uint64_t cookie) 445185b4595SMarouene Boubakri { 446185b4595SMarouene Boubakri struct mobj_shm *m; 447185b4595SMarouene Boubakri 448185b4595SMarouene Boubakri if (!core_pbuf_is(CORE_MEM_NSEC_SHM, pa, size)) 449185b4595SMarouene Boubakri return NULL; 450185b4595SMarouene Boubakri 451185b4595SMarouene Boubakri m = calloc(1, sizeof(*m)); 452185b4595SMarouene Boubakri if (!m) 453185b4595SMarouene Boubakri return NULL; 454185b4595SMarouene Boubakri 455185b4595SMarouene Boubakri m->mobj.size = size; 456185b4595SMarouene Boubakri m->mobj.ops = &mobj_shm_ops; 457e31a75b3SLejia Zhang m->mobj.phys_granule = SMALL_PAGE_SIZE; 458185b4595SMarouene Boubakri refcount_set(&m->mobj.refc, 1); 459185b4595SMarouene Boubakri m->pa = pa; 460185b4595SMarouene Boubakri m->cookie = cookie; 461185b4595SMarouene Boubakri 462185b4595SMarouene Boubakri return &m->mobj; 463185b4595SMarouene Boubakri } 464185b4595SMarouene Boubakri 465185b4595SMarouene Boubakri #ifdef CFG_PAGED_USER_TA 466185b4595SMarouene Boubakri /* 467185b4595SMarouene Boubakri * mobj_seccpy_shm implementation 468185b4595SMarouene Boubakri */ 469185b4595SMarouene Boubakri 470185b4595SMarouene Boubakri struct mobj_seccpy_shm { 471185b4595SMarouene Boubakri struct user_ta_ctx *utc; 472185b4595SMarouene Boubakri vaddr_t va; 473185b4595SMarouene Boubakri struct mobj mobj; 474185b4595SMarouene Boubakri struct fobj *fobj; 475185b4595SMarouene Boubakri }; 476185b4595SMarouene Boubakri 477185b4595SMarouene Boubakri static bool __maybe_unused mobj_is_seccpy_shm(struct mobj *mobj); 478185b4595SMarouene Boubakri 479185b4595SMarouene Boubakri static struct mobj_seccpy_shm *to_mobj_seccpy_shm(struct mobj *mobj) 480185b4595SMarouene Boubakri { 481185b4595SMarouene Boubakri assert(mobj_is_seccpy_shm(mobj)); 482185b4595SMarouene Boubakri return container_of(mobj, struct mobj_seccpy_shm, mobj); 483185b4595SMarouene Boubakri } 484185b4595SMarouene Boubakri 4859c4aaf67SJens Wiklander static void *mobj_seccpy_shm_get_va(struct mobj *mobj, size_t offs, size_t len) 486185b4595SMarouene Boubakri { 487185b4595SMarouene Boubakri struct mobj_seccpy_shm *m = to_mobj_seccpy_shm(mobj); 488185b4595SMarouene Boubakri 489185b4595SMarouene Boubakri if (&m->utc->ta_ctx.ts_ctx != thread_get_tsd()->ctx) 490185b4595SMarouene Boubakri return NULL; 491185b4595SMarouene Boubakri 4929c4aaf67SJens Wiklander if (!mobj_check_offset_and_len(mobj, offs, len)) 493185b4595SMarouene Boubakri return NULL; 494185b4595SMarouene Boubakri return (void *)(m->va + offs); 495185b4595SMarouene Boubakri } 496185b4595SMarouene Boubakri 497185b4595SMarouene Boubakri static bool mobj_seccpy_shm_matches(struct mobj *mobj __maybe_unused, 498185b4595SMarouene Boubakri enum buf_is_attr attr) 499185b4595SMarouene Boubakri { 500185b4595SMarouene Boubakri assert(mobj_is_seccpy_shm(mobj)); 501185b4595SMarouene Boubakri 502185b4595SMarouene Boubakri return attr == CORE_MEM_SEC || attr == CORE_MEM_TEE_RAM; 503185b4595SMarouene Boubakri } 504185b4595SMarouene Boubakri 505185b4595SMarouene Boubakri static void mobj_seccpy_shm_free(struct mobj *mobj) 506185b4595SMarouene Boubakri { 507185b4595SMarouene Boubakri struct mobj_seccpy_shm *m = to_mobj_seccpy_shm(mobj); 508185b4595SMarouene Boubakri 509185b4595SMarouene Boubakri tee_pager_rem_um_region(&m->utc->uctx, m->va, mobj->size); 510185b4595SMarouene Boubakri vm_rem_rwmem(&m->utc->uctx, mobj, m->va); 511185b4595SMarouene Boubakri fobj_put(m->fobj); 512185b4595SMarouene Boubakri free(m); 513185b4595SMarouene Boubakri } 514185b4595SMarouene Boubakri 515185b4595SMarouene Boubakri static struct fobj *mobj_seccpy_shm_get_fobj(struct mobj *mobj) 516185b4595SMarouene Boubakri { 517185b4595SMarouene Boubakri return fobj_get(to_mobj_seccpy_shm(mobj)->fobj); 518185b4595SMarouene Boubakri } 519185b4595SMarouene Boubakri 52000361c18SJens Wiklander /* 52100361c18SJens Wiklander * Note: this variable is weak just to ease breaking its dependency chain 52200361c18SJens Wiklander * when added to the unpaged area. 52300361c18SJens Wiklander */ 52400361c18SJens Wiklander const struct mobj_ops mobj_seccpy_shm_ops 52539e8c200SJerome Forissier __weak __relrodata_unpaged("mobj_seccpy_shm_ops") = { 526185b4595SMarouene Boubakri .get_va = mobj_seccpy_shm_get_va, 527185b4595SMarouene Boubakri .matches = mobj_seccpy_shm_matches, 528185b4595SMarouene Boubakri .free = mobj_seccpy_shm_free, 529185b4595SMarouene Boubakri .get_fobj = mobj_seccpy_shm_get_fobj, 530185b4595SMarouene Boubakri }; 531185b4595SMarouene Boubakri 532185b4595SMarouene Boubakri static bool mobj_is_seccpy_shm(struct mobj *mobj) 533185b4595SMarouene Boubakri { 534185b4595SMarouene Boubakri return mobj && mobj->ops == &mobj_seccpy_shm_ops; 535185b4595SMarouene Boubakri } 536185b4595SMarouene Boubakri 537185b4595SMarouene Boubakri struct mobj *mobj_seccpy_shm_alloc(size_t size) 538185b4595SMarouene Boubakri { 539185b4595SMarouene Boubakri struct thread_specific_data *tsd = thread_get_tsd(); 540185b4595SMarouene Boubakri struct mobj_seccpy_shm *m; 541185b4595SMarouene Boubakri struct user_ta_ctx *utc; 542185b4595SMarouene Boubakri vaddr_t va = 0; 543185b4595SMarouene Boubakri 544185b4595SMarouene Boubakri if (!is_user_ta_ctx(tsd->ctx)) 545185b4595SMarouene Boubakri return NULL; 546185b4595SMarouene Boubakri utc = to_user_ta_ctx(tsd->ctx); 547185b4595SMarouene Boubakri 548185b4595SMarouene Boubakri m = calloc(1, sizeof(*m)); 549185b4595SMarouene Boubakri if (!m) 550185b4595SMarouene Boubakri return NULL; 551185b4595SMarouene Boubakri 552185b4595SMarouene Boubakri m->mobj.size = size; 553185b4595SMarouene Boubakri m->mobj.ops = &mobj_seccpy_shm_ops; 554185b4595SMarouene Boubakri refcount_set(&m->mobj.refc, 1); 555185b4595SMarouene Boubakri 556185b4595SMarouene Boubakri if (vm_add_rwmem(&utc->uctx, &m->mobj, &va) != TEE_SUCCESS) 557185b4595SMarouene Boubakri goto bad; 558185b4595SMarouene Boubakri 559185b4595SMarouene Boubakri m->fobj = fobj_rw_paged_alloc(ROUNDUP(size, SMALL_PAGE_SIZE) / 560185b4595SMarouene Boubakri SMALL_PAGE_SIZE); 561d5ad7ccfSJens Wiklander if (tee_pager_add_um_region(&utc->uctx, va, m->fobj, 562185b4595SMarouene Boubakri TEE_MATTR_PRW | TEE_MATTR_URW)) 563185b4595SMarouene Boubakri goto bad; 564185b4595SMarouene Boubakri 565185b4595SMarouene Boubakri m->va = va; 566185b4595SMarouene Boubakri m->utc = to_user_ta_ctx(tsd->ctx); 567185b4595SMarouene Boubakri return &m->mobj; 568185b4595SMarouene Boubakri bad: 569185b4595SMarouene Boubakri if (va) 570185b4595SMarouene Boubakri vm_rem_rwmem(&utc->uctx, &m->mobj, va); 571185b4595SMarouene Boubakri fobj_put(m->fobj); 572185b4595SMarouene Boubakri free(m); 573185b4595SMarouene Boubakri return NULL; 574185b4595SMarouene Boubakri } 575185b4595SMarouene Boubakri 576185b4595SMarouene Boubakri 577185b4595SMarouene Boubakri #endif /*CFG_PAGED_USER_TA*/ 578185b4595SMarouene Boubakri 579185b4595SMarouene Boubakri struct mobj_with_fobj { 580185b4595SMarouene Boubakri struct fobj *fobj; 581185b4595SMarouene Boubakri struct file *file; 582185b4595SMarouene Boubakri struct mobj mobj; 583185b4595SMarouene Boubakri }; 584185b4595SMarouene Boubakri 58500361c18SJens Wiklander const struct mobj_ops mobj_with_fobj_ops; 586185b4595SMarouene Boubakri 587185b4595SMarouene Boubakri struct mobj *mobj_with_fobj_alloc(struct fobj *fobj, struct file *file) 588185b4595SMarouene Boubakri { 589185b4595SMarouene Boubakri struct mobj_with_fobj *m = NULL; 590185b4595SMarouene Boubakri 591185b4595SMarouene Boubakri if (!fobj) 592185b4595SMarouene Boubakri return NULL; 593185b4595SMarouene Boubakri 594185b4595SMarouene Boubakri m = calloc(1, sizeof(*m)); 595185b4595SMarouene Boubakri if (!m) 596185b4595SMarouene Boubakri return NULL; 597185b4595SMarouene Boubakri 598185b4595SMarouene Boubakri m->mobj.ops = &mobj_with_fobj_ops; 599185b4595SMarouene Boubakri refcount_set(&m->mobj.refc, 1); 600185b4595SMarouene Boubakri m->mobj.size = fobj->num_pages * SMALL_PAGE_SIZE; 601185b4595SMarouene Boubakri m->mobj.phys_granule = SMALL_PAGE_SIZE; 602185b4595SMarouene Boubakri m->fobj = fobj_get(fobj); 603185b4595SMarouene Boubakri m->file = file_get(file); 604185b4595SMarouene Boubakri 605185b4595SMarouene Boubakri return &m->mobj; 606185b4595SMarouene Boubakri } 607185b4595SMarouene Boubakri 608185b4595SMarouene Boubakri static struct mobj_with_fobj *to_mobj_with_fobj(struct mobj *mobj) 609185b4595SMarouene Boubakri { 610185b4595SMarouene Boubakri assert(mobj && mobj->ops == &mobj_with_fobj_ops); 611185b4595SMarouene Boubakri 612185b4595SMarouene Boubakri return container_of(mobj, struct mobj_with_fobj, mobj); 613185b4595SMarouene Boubakri } 614185b4595SMarouene Boubakri 615185b4595SMarouene Boubakri static bool mobj_with_fobj_matches(struct mobj *mobj __maybe_unused, 616185b4595SMarouene Boubakri enum buf_is_attr attr) 617185b4595SMarouene Boubakri { 618185b4595SMarouene Boubakri assert(to_mobj_with_fobj(mobj)); 619185b4595SMarouene Boubakri 620185b4595SMarouene Boubakri /* 621185b4595SMarouene Boubakri * All fobjs are supposed to be mapped secure so classify it as 622185b4595SMarouene Boubakri * CORE_MEM_SEC. Stay out of CORE_MEM_TEE_RAM etc, if that information 623185b4595SMarouene Boubakri * needed it can probably be carried in another way than to put the 624185b4595SMarouene Boubakri * burden directly on fobj. 625185b4595SMarouene Boubakri */ 626185b4595SMarouene Boubakri return attr == CORE_MEM_SEC; 627185b4595SMarouene Boubakri } 628185b4595SMarouene Boubakri 629185b4595SMarouene Boubakri static void mobj_with_fobj_free(struct mobj *mobj) 630185b4595SMarouene Boubakri { 631185b4595SMarouene Boubakri struct mobj_with_fobj *m = to_mobj_with_fobj(mobj); 632185b4595SMarouene Boubakri 633185b4595SMarouene Boubakri fobj_put(m->fobj); 634185b4595SMarouene Boubakri file_put(m->file); 635185b4595SMarouene Boubakri free(m); 636185b4595SMarouene Boubakri } 637185b4595SMarouene Boubakri 638185b4595SMarouene Boubakri static struct fobj *mobj_with_fobj_get_fobj(struct mobj *mobj) 639185b4595SMarouene Boubakri { 640185b4595SMarouene Boubakri return fobj_get(to_mobj_with_fobj(mobj)->fobj); 641185b4595SMarouene Boubakri } 642185b4595SMarouene Boubakri 643*8afe7a7cSJens Wiklander static TEE_Result mobj_with_fobj_get_mem_type(struct mobj *mobj __unused, 644*8afe7a7cSJens Wiklander uint32_t *mem_type) 645185b4595SMarouene Boubakri { 646*8afe7a7cSJens Wiklander if (!mem_type) 647185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 648185b4595SMarouene Boubakri 649185b4595SMarouene Boubakri /* All fobjs are mapped as normal cached memory */ 650*8afe7a7cSJens Wiklander *mem_type = TEE_MATTR_MEM_TYPE_CACHED; 651185b4595SMarouene Boubakri 652185b4595SMarouene Boubakri return TEE_SUCCESS; 653185b4595SMarouene Boubakri } 654185b4595SMarouene Boubakri 655185b4595SMarouene Boubakri static TEE_Result mobj_with_fobj_get_pa(struct mobj *mobj, size_t offs, 656185b4595SMarouene Boubakri size_t granule, paddr_t *pa) 657185b4595SMarouene Boubakri { 658185b4595SMarouene Boubakri struct mobj_with_fobj *f = to_mobj_with_fobj(mobj); 659185b4595SMarouene Boubakri paddr_t p = 0; 660185b4595SMarouene Boubakri 661185b4595SMarouene Boubakri if (!f->fobj->ops->get_pa) { 662185b4595SMarouene Boubakri assert(mobj_is_paged(mobj)); 663185b4595SMarouene Boubakri return TEE_ERROR_NOT_SUPPORTED; 664185b4595SMarouene Boubakri } 665185b4595SMarouene Boubakri 666185b4595SMarouene Boubakri p = f->fobj->ops->get_pa(f->fobj, offs / SMALL_PAGE_SIZE) + 667185b4595SMarouene Boubakri offs % SMALL_PAGE_SIZE; 668185b4595SMarouene Boubakri 669185b4595SMarouene Boubakri if (granule) { 670185b4595SMarouene Boubakri if (granule != SMALL_PAGE_SIZE && 671185b4595SMarouene Boubakri granule != CORE_MMU_PGDIR_SIZE) 672185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 673185b4595SMarouene Boubakri p &= ~(granule - 1); 674185b4595SMarouene Boubakri } 675185b4595SMarouene Boubakri 676185b4595SMarouene Boubakri *pa = p; 677185b4595SMarouene Boubakri 678185b4595SMarouene Boubakri return TEE_SUCCESS; 679185b4595SMarouene Boubakri } 680185b4595SMarouene Boubakri DECLARE_KEEP_PAGER(mobj_with_fobj_get_pa); 681185b4595SMarouene Boubakri 68200361c18SJens Wiklander /* 68300361c18SJens Wiklander * Note: this variable is weak just to ease breaking its dependency chain 68400361c18SJens Wiklander * when added to the unpaged area. 68500361c18SJens Wiklander */ 68600361c18SJens Wiklander const struct mobj_ops mobj_with_fobj_ops 68739e8c200SJerome Forissier __weak __relrodata_unpaged("mobj_with_fobj_ops") = { 688185b4595SMarouene Boubakri .matches = mobj_with_fobj_matches, 689185b4595SMarouene Boubakri .free = mobj_with_fobj_free, 690185b4595SMarouene Boubakri .get_fobj = mobj_with_fobj_get_fobj, 691*8afe7a7cSJens Wiklander .get_mem_type = mobj_with_fobj_get_mem_type, 692185b4595SMarouene Boubakri .get_pa = mobj_with_fobj_get_pa, 693185b4595SMarouene Boubakri }; 694185b4595SMarouene Boubakri 695185b4595SMarouene Boubakri #ifdef CFG_PAGED_USER_TA 696185b4595SMarouene Boubakri bool mobj_is_paged(struct mobj *mobj) 697185b4595SMarouene Boubakri { 698185b4595SMarouene Boubakri if (mobj->ops == &mobj_seccpy_shm_ops) 699185b4595SMarouene Boubakri return true; 700185b4595SMarouene Boubakri 701185b4595SMarouene Boubakri if (mobj->ops == &mobj_with_fobj_ops && 702185b4595SMarouene Boubakri !to_mobj_with_fobj(mobj)->fobj->ops->get_pa) 703185b4595SMarouene Boubakri return true; 704185b4595SMarouene Boubakri 705185b4595SMarouene Boubakri return false; 706185b4595SMarouene Boubakri } 707185b4595SMarouene Boubakri #endif /*CFG_PAGED_USER_TA*/ 708185b4595SMarouene Boubakri 709185b4595SMarouene Boubakri static TEE_Result mobj_init(void) 710185b4595SMarouene Boubakri { 711185b4595SMarouene Boubakri mobj_sec_ddr = mobj_phys_alloc(tee_mm_sec_ddr.lo, 7122380d700SLionel Debieve tee_mm_sec_ddr.size, 7138b427282SJelle Sels TEE_MATTR_MEM_TYPE_CACHED, 7148b427282SJelle Sels CORE_MEM_TA_RAM); 715185b4595SMarouene Boubakri if (!mobj_sec_ddr) 716185b4595SMarouene Boubakri panic("Failed to register secure ta ram"); 717185b4595SMarouene Boubakri 718ff01e245SAnton Rybakov if (IS_ENABLED(CFG_CORE_RWDATA_NOEXEC)) { 719b715a420SAnton Rybakov mobj_tee_ram_rx = mobj_phys_init(0, 720ff01e245SAnton Rybakov VCORE_UNPG_RX_SZ, 7218b427282SJelle Sels TEE_MATTR_MEM_TYPE_CACHED, 722ff01e245SAnton Rybakov CORE_MEM_TEE_RAM, 723ff01e245SAnton Rybakov MEM_AREA_TEE_RAM_RX); 724ff01e245SAnton Rybakov if (!mobj_tee_ram_rx) 725ff01e245SAnton Rybakov panic("Failed to register tee ram rx"); 726ff01e245SAnton Rybakov 727b715a420SAnton Rybakov mobj_tee_ram_rw = mobj_phys_init(0, 728ff01e245SAnton Rybakov VCORE_UNPG_RW_SZ, 7298b427282SJelle Sels TEE_MATTR_MEM_TYPE_CACHED, 730ff01e245SAnton Rybakov CORE_MEM_TEE_RAM, 731ff01e245SAnton Rybakov MEM_AREA_TEE_RAM_RW_DATA); 732ff01e245SAnton Rybakov if (!mobj_tee_ram_rw) 733ff01e245SAnton Rybakov panic("Failed to register tee ram rw"); 734ff01e245SAnton Rybakov } else { 735ff01e245SAnton Rybakov mobj_tee_ram_rw = mobj_phys_init(TEE_RAM_START, 736ff01e245SAnton Rybakov VCORE_UNPG_RW_PA + 737ff01e245SAnton Rybakov VCORE_UNPG_RW_SZ - 738185b4595SMarouene Boubakri TEE_RAM_START, 7398b427282SJelle Sels TEE_MATTR_MEM_TYPE_CACHED, 740ff01e245SAnton Rybakov CORE_MEM_TEE_RAM, 741ff01e245SAnton Rybakov MEM_AREA_TEE_RAM_RW_DATA); 742ff01e245SAnton Rybakov if (!mobj_tee_ram_rw) 743185b4595SMarouene Boubakri panic("Failed to register tee ram"); 744185b4595SMarouene Boubakri 745ff01e245SAnton Rybakov mobj_tee_ram_rx = mobj_tee_ram_rw; 746ff01e245SAnton Rybakov } 747ff01e245SAnton Rybakov 748185b4595SMarouene Boubakri return TEE_SUCCESS; 749185b4595SMarouene Boubakri } 750185b4595SMarouene Boubakri 751185b4595SMarouene Boubakri driver_init_late(mobj_init); 752