xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientMem.c (revision 981b79162bacefa5d08f08caa210d293c7b6be3a)
1abdd2437Shisping /*
2abdd2437Shisping  * Copyright 2017, Rockchip Electronics Co., Ltd
3abdd2437Shisping  * hisping lin, <hisping.lin@rock-chips.com>
4abdd2437Shisping  *
5abdd2437Shisping  * SPDX-License-Identifier:	GPL-2.0+
6abdd2437Shisping  */
7abdd2437Shisping #include <common.h>
8abdd2437Shisping #include <stdlib.h>
9abdd2437Shisping #include <optee_include/OpteeClientMem.h>
10*981b7916SHisping Lin #include <optee_include/OpteeClientRPC.h>
11*981b7916SHisping Lin #include <optee_include/teesmc.h>
12*981b7916SHisping Lin #include <optee_include/teesmc_optee.h>
13*981b7916SHisping Lin #include <optee_include/teesmc_v2.h>
14abdd2437Shisping 
15abdd2437Shisping void *my_mem_start;
16abdd2437Shisping uint32_t my_count;
17abdd2437Shisping uint8_t *my_flag;
18abdd2437Shisping typedef struct {
19abdd2437Shisping 	void *addrBlock;
20abdd2437Shisping 	uint32_t sizeBlock;
21abdd2437Shisping 	uint8_t used;
22abdd2437Shisping } ALLOC_FLAG;
23abdd2437Shisping ALLOC_FLAG alloc_flags[50];
24abdd2437Shisping 
25abdd2437Shisping void my_malloc_init(void *start, uint32_t size)
26abdd2437Shisping {
27abdd2437Shisping 	memset(start, 0, size);
28abdd2437Shisping 	my_mem_start = start;
29abdd2437Shisping 	my_count = size/4096;
30abdd2437Shisping 	my_flag = malloc(size/4096);
31abdd2437Shisping 	memset(my_flag, 0, size/4096);
32abdd2437Shisping 	memset(alloc_flags, 0, 50 * sizeof(ALLOC_FLAG));
33abdd2437Shisping }
34abdd2437Shisping 
35abdd2437Shisping void write_usedblock(void *addr, uint32_t size)
36abdd2437Shisping {
37abdd2437Shisping 	uint8_t k;
38abdd2437Shisping 	for (k = 0; k < 50; k++) {
39abdd2437Shisping 		if (alloc_flags[k].used == 0) {
40abdd2437Shisping 			alloc_flags[k].used = 1;
41abdd2437Shisping 			alloc_flags[k].addrBlock = addr;
42abdd2437Shisping 			alloc_flags[k].sizeBlock = size;
43abdd2437Shisping 			break;
44abdd2437Shisping 		}
45abdd2437Shisping 	}
46abdd2437Shisping }
47abdd2437Shisping 
48abdd2437Shisping uint32_t find_sizeblock(void *addr)
49abdd2437Shisping {
50abdd2437Shisping 	uint8_t k;
51abdd2437Shisping 	for (k = 0; k < 50; k++)
52abdd2437Shisping 		if (alloc_flags[k].used == 1 &&
53abdd2437Shisping 				alloc_flags[k].addrBlock == addr)
54abdd2437Shisping 			return alloc_flags[k].sizeBlock;
55abdd2437Shisping 
56abdd2437Shisping 	return 0;
57abdd2437Shisping }
58abdd2437Shisping 
59abdd2437Shisping void free_usedblock(void *addr)
60abdd2437Shisping {
61abdd2437Shisping 	uint8_t k;
62abdd2437Shisping 	for (k = 0; k < 50; k++) {
63abdd2437Shisping 		if (alloc_flags[k].used == 1 &&
64abdd2437Shisping 				alloc_flags[k].addrBlock == addr) {
65abdd2437Shisping 			alloc_flags[k].used = 0;
66abdd2437Shisping 			alloc_flags[k].addrBlock = 0;
67abdd2437Shisping 			alloc_flags[k].sizeBlock = 0;
68abdd2437Shisping 			break;
69abdd2437Shisping 		}
70abdd2437Shisping 	}
71abdd2437Shisping }
72abdd2437Shisping 
73abdd2437Shisping void *my_malloc(uint32_t size)
74abdd2437Shisping {
75abdd2437Shisping 	uint32_t i, j, k, num;
76abdd2437Shisping 
77abdd2437Shisping 	num = (size - 1) / 4096 + 1;
78abdd2437Shisping 
79abdd2437Shisping 	for (i = 0; i < my_count - num; i++) {
80abdd2437Shisping 		if (*(my_flag + i) == 0) {
81abdd2437Shisping 			for (j = 0; j < num; j++) {
82abdd2437Shisping 				if (*(my_flag + i + j) != 0)
83abdd2437Shisping 					break;
84abdd2437Shisping 			}
85abdd2437Shisping 			if (j == num) {
86abdd2437Shisping 				for (k = 0; k < num; k++) {
87abdd2437Shisping 					*(my_flag + i + k) = 1;
88abdd2437Shisping 					memset(my_mem_start +
89abdd2437Shisping 						(i + k) * 4096, 0, 4096);
90abdd2437Shisping 				}
91abdd2437Shisping 				debug(" malloc is: 0x%X  0x%X\n",
92abdd2437Shisping 					(int)i, (int)num);
93abdd2437Shisping 				write_usedblock((my_mem_start + i * 4096),
94abdd2437Shisping 					num * 4096);
95abdd2437Shisping 
96abdd2437Shisping 				return my_mem_start + (i * 4096);
97abdd2437Shisping 			}
98abdd2437Shisping 		}
99abdd2437Shisping 	}
100abdd2437Shisping 
101abdd2437Shisping 	return 0;
102abdd2437Shisping }
103abdd2437Shisping 
104abdd2437Shisping void my_free(void *ptr)
105abdd2437Shisping {
106abdd2437Shisping 	uint32_t i, j, num, size;
107abdd2437Shisping 
108abdd2437Shisping 	if (ptr < my_mem_start)
109abdd2437Shisping 		return;
110abdd2437Shisping 
111abdd2437Shisping 	i = (ptr - my_mem_start) / 4096;
112abdd2437Shisping 	size = find_sizeblock(ptr);
113abdd2437Shisping 	free_usedblock(ptr);
114abdd2437Shisping 	if (size == 0)
115abdd2437Shisping 		return;
116abdd2437Shisping 
117abdd2437Shisping 	num = (size-1)/4096+1;
118abdd2437Shisping 	debug(" free is: 0x%X  0x%X\n", i, num);
119abdd2437Shisping 
120abdd2437Shisping 	for (j = 0; j < num; j++) {
121abdd2437Shisping 		*(my_flag + i + j) = 0;
122abdd2437Shisping 		memset(my_mem_start + (i + j) * 4096, 0, 4096);
123abdd2437Shisping 	}
124abdd2437Shisping }
125abdd2437Shisping 
126abdd2437Shisping /*
127abdd2437Shisping  * Initlialize the memory component, for example providing the
128abdd2437Shisping  * containing drivers handle.
129abdd2437Shisping  */
130abdd2437Shisping void OpteeClientMemInit(void)
131abdd2437Shisping {
132*981b7916SHisping Lin 	ARM_SMC_ARGS ArmSmcArgs = {0};
133*981b7916SHisping Lin 
134*981b7916SHisping Lin #ifdef CONFIG_OPTEE_V1
135*981b7916SHisping Lin 	ArmSmcArgs.Arg0 = TEESMC_OPTEE_FUNCID_GET_SHM_CONFIG;
136abdd2437Shisping #endif
137*981b7916SHisping Lin #ifdef CONFIG_OPTEE_V2
138*981b7916SHisping Lin 	ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_CONFIG_V2;
1391f25ada2SHisping Lin #endif
140*981b7916SHisping Lin 
141*981b7916SHisping Lin 	tee_smc_call(&ArmSmcArgs);
142*981b7916SHisping Lin 
143*981b7916SHisping Lin 	printf("get share memory, arg0=0x%x arg1=0x%x arg2=0x%x arg3=0x%x",
144*981b7916SHisping Lin 			ArmSmcArgs.Arg0, ArmSmcArgs.Arg1, ArmSmcArgs.Arg2, ArmSmcArgs.Arg3);
145*981b7916SHisping Lin 
146*981b7916SHisping Lin 	my_malloc_init((void *)(size_t)ArmSmcArgs.Arg1, ArmSmcArgs.Arg2);
147abdd2437Shisping }
148abdd2437Shisping 
149abdd2437Shisping /*
150abdd2437Shisping  * Allocate a page aligned block of memory from the TrustZone
151abdd2437Shisping  * shared memory block.
152abdd2437Shisping  */
153abdd2437Shisping void *OpteeClientMemAlloc(uint32_t length)
154abdd2437Shisping {
155abdd2437Shisping 	return my_malloc(length);
156abdd2437Shisping }
157abdd2437Shisping 
158abdd2437Shisping /*
159abdd2437Shisping  * Free a block of memory previously allocated using the
160abdd2437Shisping  * OpteeClientMemAlloc function.
161abdd2437Shisping  */
162abdd2437Shisping void OpteeClientMemFree(void *mem)
163abdd2437Shisping {
164abdd2437Shisping 	my_free(mem);
165abdd2437Shisping }
166