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