xref: /optee_os/core/mm/page_alloc.c (revision 809e07449eec1898bfc861b402ecf9df70bd6477)
1*809e0744SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2*809e0744SJens Wiklander /*
3*809e0744SJens Wiklander  * Copyright (c) 2024, Linaro Limited
4*809e0744SJens Wiklander  */
5*809e0744SJens Wiklander 
6*809e0744SJens Wiklander #include <kernel/boot.h>
7*809e0744SJens Wiklander #include <kernel/panic.h>
8*809e0744SJens Wiklander #include <malloc.h>
9*809e0744SJens Wiklander #include <mm/core_mmu.h>
10*809e0744SJens Wiklander #include <mm/page_alloc.h>
11*809e0744SJens Wiklander #include <mm/phys_mem.h>
12*809e0744SJens Wiklander #include <mm/tee_mm.h>
13*809e0744SJens Wiklander #include <string.h>
14*809e0744SJens Wiklander #include <types_ext.h>
15*809e0744SJens Wiklander 
16*809e0744SJens Wiklander static tee_mm_pool_t core_virt_nex_pool __nex_bss;
17*809e0744SJens Wiklander static tee_mm_pool_t core_virt_tee_pool;
18*809e0744SJens Wiklander 
init_virt_pool(tee_mm_pool_t * pool,uint32_t flags,enum teecore_memtypes memtype)19*809e0744SJens Wiklander static void init_virt_pool(tee_mm_pool_t *pool, uint32_t flags,
20*809e0744SJens Wiklander 			   enum teecore_memtypes memtype)
21*809e0744SJens Wiklander {
22*809e0744SJens Wiklander 	vaddr_t start = 0;
23*809e0744SJens Wiklander 	vaddr_t end = 0;
24*809e0744SJens Wiklander 
25*809e0744SJens Wiklander 	core_mmu_get_mem_by_type(memtype, &start, &end);
26*809e0744SJens Wiklander 	if (!start || !end)
27*809e0744SJens Wiklander 		panic();
28*809e0744SJens Wiklander 
29*809e0744SJens Wiklander 	if (!tee_mm_init(pool, start, end - start, SMALL_PAGE_SHIFT, flags))
30*809e0744SJens Wiklander 		panic();
31*809e0744SJens Wiklander }
32*809e0744SJens Wiklander 
nex_page_alloc_init(void)33*809e0744SJens Wiklander void nex_page_alloc_init(void)
34*809e0744SJens Wiklander {
35*809e0744SJens Wiklander 	init_virt_pool(&core_virt_nex_pool, TEE_MM_POOL_NEX_MALLOC,
36*809e0744SJens Wiklander 		       MEM_AREA_NEX_DYN_VASPACE);
37*809e0744SJens Wiklander }
38*809e0744SJens Wiklander 
page_alloc_init(void)39*809e0744SJens Wiklander void page_alloc_init(void)
40*809e0744SJens Wiklander {
41*809e0744SJens Wiklander 	init_virt_pool(&core_virt_tee_pool, TEE_MM_POOL_NO_FLAGS,
42*809e0744SJens Wiklander 		       MEM_AREA_TEE_DYN_VASPACE);
43*809e0744SJens Wiklander }
44*809e0744SJens Wiklander 
virt_page_alloc(size_t count,uint32_t flags)45*809e0744SJens Wiklander vaddr_t virt_page_alloc(size_t count, uint32_t flags)
46*809e0744SJens Wiklander {
47*809e0744SJens Wiklander 	enum teecore_memtypes memtype = 0;
48*809e0744SJens Wiklander 	TEE_Result res = TEE_SUCCESS;
49*809e0744SJens Wiklander 	tee_mm_pool_t *pool = NULL;
50*809e0744SJens Wiklander 	tee_mm_entry_t *mmv = NULL;
51*809e0744SJens Wiklander 	tee_mm_entry_t *mmp = NULL;
52*809e0744SJens Wiklander 	size_t vcount = count;
53*809e0744SJens Wiklander 	size_t pcount = count;
54*809e0744SJens Wiklander 	vaddr_t va = 0;
55*809e0744SJens Wiklander 	paddr_t pa = 0;
56*809e0744SJens Wiklander 
57*809e0744SJens Wiklander 	if (IS_ENABLED(CFG_NS_VIRTUALIZATION) && (flags & MAF_NEX)) {
58*809e0744SJens Wiklander 		pool = &core_virt_nex_pool;
59*809e0744SJens Wiklander 		memtype = MEM_AREA_NEX_DYN_VASPACE;
60*809e0744SJens Wiklander 	} else {
61*809e0744SJens Wiklander 		pool = &core_virt_tee_pool;
62*809e0744SJens Wiklander 		memtype = MEM_AREA_TEE_DYN_VASPACE;
63*809e0744SJens Wiklander 	}
64*809e0744SJens Wiklander 
65*809e0744SJens Wiklander 	if (flags & MAF_GUARD_HEAD)
66*809e0744SJens Wiklander 		vcount++;
67*809e0744SJens Wiklander 	if (flags & MAF_GUARD_TAIL)
68*809e0744SJens Wiklander 		vcount++;
69*809e0744SJens Wiklander 
70*809e0744SJens Wiklander 	/* We're allocating one extra page to use as unmapped guard */
71*809e0744SJens Wiklander 	mmv = tee_mm_alloc_flags(pool, vcount * SMALL_PAGE_SIZE, flags);
72*809e0744SJens Wiklander 	if (!mmv)
73*809e0744SJens Wiklander 		return 0;
74*809e0744SJens Wiklander 	va = tee_mm_get_smem(mmv);
75*809e0744SJens Wiklander 	if (flags & MAF_GUARD_HEAD)
76*809e0744SJens Wiklander 		va += SMALL_PAGE_SIZE;
77*809e0744SJens Wiklander 
78*809e0744SJens Wiklander 	mmp = phys_mem_alloc_flags(pcount * SMALL_PAGE_SIZE, flags);
79*809e0744SJens Wiklander 	if (!mmp)
80*809e0744SJens Wiklander 		goto err_free_mmv;
81*809e0744SJens Wiklander 	pa = tee_mm_get_smem(mmp);
82*809e0744SJens Wiklander 	assert(pa);
83*809e0744SJens Wiklander 
84*809e0744SJens Wiklander 	res = core_mmu_map_contiguous_pages(va, pa, pcount, memtype);
85*809e0744SJens Wiklander 	if (res)
86*809e0744SJens Wiklander 		goto err;
87*809e0744SJens Wiklander 
88*809e0744SJens Wiklander 	if (flags & MAF_ZERO_INIT)
89*809e0744SJens Wiklander 		memset((void *)va, 0, pcount * SMALL_PAGE_SIZE);
90*809e0744SJens Wiklander 
91*809e0744SJens Wiklander 	return va;
92*809e0744SJens Wiklander err:
93*809e0744SJens Wiklander 	tee_mm_free(mmp);
94*809e0744SJens Wiklander err_free_mmv:
95*809e0744SJens Wiklander 	tee_mm_free(mmv);
96*809e0744SJens Wiklander 	return 0;
97*809e0744SJens Wiklander }
98