xref: /optee_os/core/mm/mobj.c (revision 8afe7a7c52204da38fc082c55f908fb819079f30)
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