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 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 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 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 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 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 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 */ 142f4e1db95SHisping Lin int OpteeClientMemInit(void) 143abdd2437Shisping { 144981b7916SHisping Lin ARM_SMC_ARGS ArmSmcArgs = {0}; 145981b7916SHisping Lin 146981b7916SHisping Lin #ifdef CONFIG_OPTEE_V1 147cb49af8fSHisping Lin ArmSmcArgs.Arg0 = TEESMC32_OPTEE_FASTCALL_GET_SHM_CONFIG; 148abdd2437Shisping #endif 149981b7916SHisping Lin #ifdef CONFIG_OPTEE_V2 150981b7916SHisping Lin ArmSmcArgs.Arg0 = OPTEE_SMC_GET_SHM_CONFIG_V2; 1511f25ada2SHisping Lin #endif 152981b7916SHisping Lin 153981b7916SHisping Lin tee_smc_call(&ArmSmcArgs); 154981b7916SHisping Lin 155*efb93541SHisping Lin debug("TEEC: get share memory, arg0=0x%x arg1=0x%x arg2=0x%x arg3=0x%x\n", 156981b7916SHisping Lin ArmSmcArgs.Arg0, ArmSmcArgs.Arg1, ArmSmcArgs.Arg2, ArmSmcArgs.Arg3); 157981b7916SHisping Lin 158f4e1db95SHisping Lin return my_malloc_init((void *)(size_t)ArmSmcArgs.Arg1, ArmSmcArgs.Arg2); 159abdd2437Shisping } 160abdd2437Shisping 161abdd2437Shisping /* 162abdd2437Shisping * Allocate a page aligned block of memory from the TrustZone 163abdd2437Shisping * shared memory block. 164abdd2437Shisping */ 165abdd2437Shisping void *OpteeClientMemAlloc(uint32_t length) 166abdd2437Shisping { 167abdd2437Shisping return my_malloc(length); 168abdd2437Shisping } 169abdd2437Shisping 170abdd2437Shisping /* 171abdd2437Shisping * Free a block of memory previously allocated using the 172abdd2437Shisping * OpteeClientMemAlloc function. 173abdd2437Shisping */ 174abdd2437Shisping void OpteeClientMemFree(void *mem) 175abdd2437Shisping { 176abdd2437Shisping my_free(mem); 177abdd2437Shisping } 178