1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <ldelf.h> 8 #include <malloc.h> 9 #include <sys/queue.h> 10 #include <tee_api_types.h> 11 #include <trace.h> 12 #include <types_ext.h> 13 14 #include "ta_elf.h" 15 #include "sys.h" 16 17 static struct ta_elf_queue elf_queue = TAILQ_HEAD_INITIALIZER(elf_queue); 18 static size_t mpool_size = 2 * SMALL_PAGE_SIZE; 19 static vaddr_t mpool_base; 20 21 static void __noreturn __maybe_unused dump_ta_state(struct dump_entry_arg *arg) 22 { 23 struct ta_elf *elf = TAILQ_FIRST(&main_elf_queue); 24 25 assert(elf && elf->is_main); 26 EMSG_RAW("Status of TA %pUl", (void *)&elf->uuid); 27 EMSG_RAW(" arch: %s", elf->is_32bit ? "arm" : "aarch64"); 28 29 30 ta_elf_print_mappings(&elf_queue, arg->num_maps, arg->maps, mpool_base); 31 sys_return_cleanup(); 32 } 33 34 /* 35 * ldelf()- Loads ELF into memory 36 * @arg: Argument passing to/from TEE Core 37 * 38 * Only called from assembly 39 */ 40 void __noreturn ldelf(struct ldelf_arg *arg); 41 void ldelf(struct ldelf_arg *arg) 42 { 43 TEE_Result res = TEE_SUCCESS; 44 struct ta_elf *elf = NULL; 45 46 DMSG("Loading TA %pUl", (void *)&arg->uuid); 47 res = sys_map_zi(mpool_size, 0, &mpool_base, 0, 0); 48 if (res) { 49 EMSG("sys_map_zi(%zu): result %"PRIx32, mpool_size, res); 50 panic(); 51 } 52 malloc_add_pool((void *)mpool_base, mpool_size); 53 54 /* Load the main binary and get a list of dependencies, if any. */ 55 ta_elf_load_main(&arg->uuid, &arg->is_32bit, &arg->entry_func, 56 &arg->stack_ptr, &arg->flags); 57 58 /* 59 * Load binaries, ta_elf_load() may add external libraries to the 60 * list, so the loop will end when all the dependencies are 61 * satisfied. 62 */ 63 TAILQ_FOREACH(elf, &main_elf_queue, link) 64 ta_elf_load_dependency(elf, arg->is_32bit); 65 66 TAILQ_FOREACH(elf, &main_elf_queue, link) { 67 ta_elf_relocate(elf); 68 ta_elf_finalize_mappings(elf); 69 } 70 71 TAILQ_FOREACH(elf, &main_elf_queue, link) 72 DMSG("ELF (%pUl) at %#"PRIxVA, 73 (void *)&elf->uuid, elf->load_addr); 74 75 #if TRACE_LEVEL >= TRACE_ERROR 76 arg->dump_entry = (vaddr_t)(void *)dump_ta_state; 77 #else 78 arg->dump_entry = 0; 79 #endif 80 81 sys_return_cleanup(); 82 } 83