17509ff7cSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 27509ff7cSJens Wiklander /* 37509ff7cSJens Wiklander * Copyright (c) 2019, Linaro Limited 47509ff7cSJens Wiklander */ 57509ff7cSJens Wiklander 665137432SJens Wiklander #include <assert.h> 77509ff7cSJens Wiklander #include <ldelf.h> 87509ff7cSJens Wiklander #include <malloc.h> 97509ff7cSJens Wiklander #include <sys/queue.h> 107509ff7cSJens Wiklander #include <tee_api_types.h> 117509ff7cSJens Wiklander #include <trace.h> 127509ff7cSJens Wiklander #include <types_ext.h> 137509ff7cSJens Wiklander 147509ff7cSJens Wiklander #include "ta_elf.h" 157509ff7cSJens Wiklander #include "sys.h" 167509ff7cSJens Wiklander 177509ff7cSJens Wiklander static size_t mpool_size = 2 * SMALL_PAGE_SIZE; 187509ff7cSJens Wiklander static vaddr_t mpool_base; 197509ff7cSJens Wiklander 2065137432SJens Wiklander static void __noreturn __maybe_unused dump_ta_state(struct dump_entry_arg *arg) 2165137432SJens Wiklander { 2265137432SJens Wiklander struct ta_elf *elf = TAILQ_FIRST(&main_elf_queue); 2365137432SJens Wiklander 2465137432SJens Wiklander assert(elf && elf->is_main); 2565137432SJens Wiklander EMSG_RAW("Status of TA %pUl", (void *)&elf->uuid); 2665137432SJens Wiklander EMSG_RAW(" arch: %s", elf->is_32bit ? "arm" : "aarch64"); 2765137432SJens Wiklander 2865137432SJens Wiklander 29*0242833aSJens Wiklander ta_elf_print_mappings(&main_elf_queue, arg->num_maps, arg->maps, 30*0242833aSJens Wiklander mpool_base); 31*0242833aSJens Wiklander 32*0242833aSJens Wiklander if (arg->is_arm32) 33*0242833aSJens Wiklander ta_elf_stack_trace_a32(arg->arm32.regs); 34*0242833aSJens Wiklander else 35*0242833aSJens Wiklander ta_elf_stack_trace_a64(arg->arm64.fp, arg->arm64.sp, 36*0242833aSJens Wiklander arg->arm64.pc); 37*0242833aSJens Wiklander 3865137432SJens Wiklander sys_return_cleanup(); 3965137432SJens Wiklander } 4065137432SJens Wiklander 417509ff7cSJens Wiklander /* 427509ff7cSJens Wiklander * ldelf()- Loads ELF into memory 437509ff7cSJens Wiklander * @arg: Argument passing to/from TEE Core 447509ff7cSJens Wiklander * 457509ff7cSJens Wiklander * Only called from assembly 467509ff7cSJens Wiklander */ 477509ff7cSJens Wiklander void __noreturn ldelf(struct ldelf_arg *arg); 487509ff7cSJens Wiklander void ldelf(struct ldelf_arg *arg) 497509ff7cSJens Wiklander { 507509ff7cSJens Wiklander TEE_Result res = TEE_SUCCESS; 517509ff7cSJens Wiklander struct ta_elf *elf = NULL; 527509ff7cSJens Wiklander 537509ff7cSJens Wiklander DMSG("Loading TA %pUl", (void *)&arg->uuid); 547509ff7cSJens Wiklander res = sys_map_zi(mpool_size, 0, &mpool_base, 0, 0); 557509ff7cSJens Wiklander if (res) { 567509ff7cSJens Wiklander EMSG("sys_map_zi(%zu): result %"PRIx32, mpool_size, res); 577509ff7cSJens Wiklander panic(); 587509ff7cSJens Wiklander } 597509ff7cSJens Wiklander malloc_add_pool((void *)mpool_base, mpool_size); 607509ff7cSJens Wiklander 617509ff7cSJens Wiklander /* Load the main binary and get a list of dependencies, if any. */ 627509ff7cSJens Wiklander ta_elf_load_main(&arg->uuid, &arg->is_32bit, &arg->entry_func, 637509ff7cSJens Wiklander &arg->stack_ptr, &arg->flags); 647509ff7cSJens Wiklander 657509ff7cSJens Wiklander /* 667509ff7cSJens Wiklander * Load binaries, ta_elf_load() may add external libraries to the 677509ff7cSJens Wiklander * list, so the loop will end when all the dependencies are 687509ff7cSJens Wiklander * satisfied. 697509ff7cSJens Wiklander */ 707509ff7cSJens Wiklander TAILQ_FOREACH(elf, &main_elf_queue, link) 717509ff7cSJens Wiklander ta_elf_load_dependency(elf, arg->is_32bit); 727509ff7cSJens Wiklander 737509ff7cSJens Wiklander TAILQ_FOREACH(elf, &main_elf_queue, link) { 747509ff7cSJens Wiklander ta_elf_relocate(elf); 757509ff7cSJens Wiklander ta_elf_finalize_mappings(elf); 767509ff7cSJens Wiklander } 777509ff7cSJens Wiklander 787509ff7cSJens Wiklander TAILQ_FOREACH(elf, &main_elf_queue, link) 797509ff7cSJens Wiklander DMSG("ELF (%pUl) at %#"PRIxVA, 807509ff7cSJens Wiklander (void *)&elf->uuid, elf->load_addr); 817509ff7cSJens Wiklander 8265137432SJens Wiklander #if TRACE_LEVEL >= TRACE_ERROR 8365137432SJens Wiklander arg->dump_entry = (vaddr_t)(void *)dump_ta_state; 8465137432SJens Wiklander #else 8565137432SJens Wiklander arg->dump_entry = 0; 8665137432SJens Wiklander #endif 8765137432SJens Wiklander 887509ff7cSJens Wiklander sys_return_cleanup(); 897509ff7cSJens Wiklander } 90