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