xref: /rk3399_rockchip-uboot/lib/optee_clientApi/OpteeClientMem.c (revision 74eb6027432600de60ed1c8bf892f1f8243c2c8a)
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>
10981b7916SHisping Lin #include <optee_include/OpteeClientRPC.h>
11981b7916SHisping Lin #include <optee_include/teesmc.h>
12981b7916SHisping Lin #include <optee_include/teesmc_optee.h>
13981b7916SHisping Lin #include <optee_include/teesmc_v2.h>
14abdd2437Shisping 
15abdd2437Shisping void *my_mem_start;
16abdd2437Shisping uint32_t my_count;
17f4e1db95SHisping Lin uint8_t *my_flag = NULL;
18abdd2437Shisping typedef struct {
19abdd2437Shisping 	void *addrBlock;
20abdd2437Shisping 	uint32_t sizeBlock;
21abdd2437Shisping 	uint8_t used;
22abdd2437Shisping } ALLOC_FLAG;
23abdd2437Shisping ALLOC_FLAG alloc_flags[50];
24abdd2437Shisping 
my_malloc_init(void * start,uint32_t size)25f4e1db95SHisping Lin int my_malloc_init(void *start, uint32_t size)
26abdd2437Shisping {
27f4e1db95SHisping Lin 	if (start == NULL || size == 0) {
28*efb93541SHisping Lin 		printf("TEEC: malloc init fail!\n");
29f4e1db95SHisping Lin 		return -1;
30f4e1db95SHisping Lin 	}
31abdd2437Shisping 	memset(start, 0, size);
32abdd2437Shisping 	my_mem_start = start;
33abdd2437Shisping 	my_count = size/4096;
34f4e1db95SHisping Lin 	if (my_flag == NULL) {
35abdd2437Shisping 		my_flag = malloc(size/4096);
36f4e1db95SHisping Lin 		if (my_flag == NULL) {
37*efb93541SHisping Lin 			printf("TEEC: malloc fail!\n");
38f4e1db95SHisping Lin 			return -1;
39f4e1db95SHisping Lin 		}
40f4e1db95SHisping Lin 	}
41abdd2437Shisping 	memset(my_flag, 0, size/4096);
42abdd2437Shisping 	memset(alloc_flags, 0, 50 * sizeof(ALLOC_FLAG));
43f4e1db95SHisping Lin 	return 0;
44abdd2437Shisping }
45abdd2437Shisping 
write_usedblock(void * addr,uint32_t size)46abdd2437Shisping void write_usedblock(void *addr, uint32_t size)
47abdd2437Shisping {
48abdd2437Shisping 	uint8_t k;
49abdd2437Shisping 	for (k = 0; k < 50; k++) {
50abdd2437Shisping 		if (alloc_flags[k].used == 0) {
51abdd2437Shisping 			alloc_flags[k].used = 1;
52abdd2437Shisping 			alloc_flags[k].addrBlock = addr;
53abdd2437Shisping 			alloc_flags[k].sizeBlock = size;
54abdd2437Shisping 			break;
55abdd2437Shisping 		}
56abdd2437Shisping 	}
57abdd2437Shisping }
58abdd2437Shisping 
find_sizeblock(void * addr)59abdd2437Shisping uint32_t find_sizeblock(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 			return alloc_flags[k].sizeBlock;
66abdd2437Shisping 
67abdd2437Shisping 	return 0;
68abdd2437Shisping }
69abdd2437Shisping 
free_usedblock(void * addr)70abdd2437Shisping void free_usedblock(void *addr)
71abdd2437Shisping {
72abdd2437Shisping 	uint8_t k;
73abdd2437Shisping 	for (k = 0; k < 50; k++) {
74abdd2437Shisping 		if (alloc_flags[k].used == 1 &&
75abdd2437Shisping 				alloc_flags[k].addrBlock == addr) {
76abdd2437Shisping 			alloc_flags[k].used = 0;
77abdd2437Shisping 			alloc_flags[k].addrBlock = 0;
78abdd2437Shisping 			alloc_flags[k].sizeBlock = 0;
79abdd2437Shisping 			break;
80abdd2437Shisping 		}
81abdd2437Shisping 	}
82abdd2437Shisping }
83abdd2437Shisping 
my_malloc(uint32_t size)84abdd2437Shisping void *my_malloc(uint32_t size)
85abdd2437Shisping {
86abdd2437Shisping 	uint32_t i, j, k, num;
87abdd2437Shisping 
88abdd2437Shisping 	num = (size - 1) / 4096 + 1;
89f4e1db95SHisping Lin 	if (my_count < num)
90f4e1db95SHisping Lin 		return 0;
91abdd2437Shisping 	for (i = 0; i < my_count - num; i++) {
92abdd2437Shisping 		if (*(my_flag + i) == 0) {
93abdd2437Shisping 			for (j = 0; j < num; j++) {
94abdd2437Shisping 				if (*(my_flag + i + j) != 0)
95abdd2437Shisping 					break;
96abdd2437Shisping 			}
97abdd2437Shisping 			if (j == num) {
98abdd2437Shisping 				for (k = 0; k < num; k++) {
99abdd2437Shisping 					*(my_flag + i + k) = 1;
100abdd2437Shisping 					memset(my_mem_start +
101abdd2437Shisping 						(i + k) * 4096, 0, 4096);
102abdd2437Shisping 				}
103*efb93541SHisping Lin 				debug("TEEC: malloc is: 0x%X  0x%X\n",
104abdd2437Shisping 					(int)i, (int)num);
105abdd2437Shisping 				write_usedblock((my_mem_start + i * 4096),
106abdd2437Shisping 					num * 4096);
107abdd2437Shisping 
108abdd2437Shisping 				return my_mem_start + (i * 4096);
109abdd2437Shisping 			}
110abdd2437Shisping 		}
111abdd2437Shisping 	}
112abdd2437Shisping 
113abdd2437Shisping 	return 0;
114abdd2437Shisping }
115abdd2437Shisping 
my_free(void * ptr)116abdd2437Shisping void my_free(void *ptr)
117abdd2437Shisping {
118abdd2437Shisping 	uint32_t i, j, num, size;
119abdd2437Shisping 
120abdd2437Shisping 	if (ptr < my_mem_start)
121abdd2437Shisping 		return;
122abdd2437Shisping 
123abdd2437Shisping 	i = (ptr - my_mem_start) / 4096;
124abdd2437Shisping 	size = find_sizeblock(ptr);
125abdd2437Shisping 	free_usedblock(ptr);
126abdd2437Shisping 	if (size == 0)
127abdd2437Shisping 		return;
128abdd2437Shisping 
129abdd2437Shisping 	num = (size-1)/4096+1;
130*efb93541SHisping Lin 	debug("TEEC: free is: 0x%X  0x%X\n", i, num);
131abdd2437Shisping 
132abdd2437Shisping 	for (j = 0; j < num; j++) {
133abdd2437Shisping 		*(my_flag + i + j) = 0;
134abdd2437Shisping 		memset(my_mem_start + (i + j) * 4096, 0, 4096);
135abdd2437Shisping 	}
136abdd2437Shisping }
137abdd2437Shisping 
138abdd2437Shisping /*
139abdd2437Shisping  * Initlialize the memory component, for example providing the
140abdd2437Shisping  * containing drivers handle.
141abdd2437Shisping  */
OpteeClientMemInit(void)142f4e1db95SHisping Lin int OpteeClientMemInit(void)
143abdd2437Shisping {
144981b7916SHisping Lin 	ARM_SMC_ARGS ArmSmcArgs = {0};
145981b7916SHisping Lin 
146981b7916SHisping Lin 	ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_CONFIG_V2;
147981b7916SHisping Lin 
148981b7916SHisping Lin 	tee_smc_call(&ArmSmcArgs);
149981b7916SHisping Lin 
150*efb93541SHisping Lin 	debug("TEEC: get share memory, arg0=0x%x arg1=0x%x arg2=0x%x arg3=0x%x\n",
151981b7916SHisping Lin 	      ArmSmcArgs.Arg0, ArmSmcArgs.Arg1, ArmSmcArgs.Arg2, ArmSmcArgs.Arg3);
152981b7916SHisping Lin 
153f4e1db95SHisping Lin 	return my_malloc_init((void *)(size_t)ArmSmcArgs.Arg1, ArmSmcArgs.Arg2);
154abdd2437Shisping }
155abdd2437Shisping 
156abdd2437Shisping /*
157abdd2437Shisping  * Allocate a page aligned block of memory from the TrustZone
158abdd2437Shisping  * shared memory block.
159abdd2437Shisping  */
OpteeClientMemAlloc(uint32_t length)160abdd2437Shisping void *OpteeClientMemAlloc(uint32_t length)
161abdd2437Shisping {
162abdd2437Shisping 	return my_malloc(length);
163abdd2437Shisping }
164abdd2437Shisping 
165abdd2437Shisping /*
166abdd2437Shisping  * Free a block of memory previously allocated using the
167abdd2437Shisping  * OpteeClientMemAlloc function.
168abdd2437Shisping  */
OpteeClientMemFree(void * mem)169abdd2437Shisping void OpteeClientMemFree(void *mem)
170abdd2437Shisping {
171abdd2437Shisping 	my_free(mem);
172abdd2437Shisping }
173