blob: b3dac543f0c2dce32a73db401625974a1beb5f97 [file] [log] [blame]
Jens Wiklander7509ff72019-05-23 17:42:08 +02001// SPDX-License-Identifier: BSD-2-Clause
2/*
3 * Copyright (c) 2019, Linaro Limited
4 */
5
Jens Wiklander65137432019-05-23 17:42:14 +02006#include <assert.h>
Jens Wiklander7509ff72019-05-23 17:42:08 +02007#include <ldelf.h>
8#include <malloc.h>
Jens Wiklanderc86f2182019-06-18 16:45:19 +02009#include <printk.h>
10#include <string.h>
Jens Wiklander7509ff72019-05-23 17:42:08 +020011#include <sys/queue.h>
12#include <tee_api_types.h>
13#include <trace.h>
14#include <types_ext.h>
Jens Wiklanderc86f2182019-06-18 16:45:19 +020015#include <util.h>
Jens Wiklander7509ff72019-05-23 17:42:08 +020016
Jens Wiklanderc86f2182019-06-18 16:45:19 +020017#include "ftrace.h"
Jens Wiklander7509ff72019-05-23 17:42:08 +020018#include "sys.h"
Jens Wiklanderc86f2182019-06-18 16:45:19 +020019#include "ta_elf.h"
Jens Wiklander7509ff72019-05-23 17:42:08 +020020
21static size_t mpool_size = 2 * SMALL_PAGE_SIZE;
22static vaddr_t mpool_base;
23
Jens Wiklanderc86f2182019-06-18 16:45:19 +020024static void __printf(2, 0) print_to_console(void *pctx __unused,
25 const char *fmt, va_list ap)
26{
27 trace_vprintf(NULL, 0, TRACE_ERROR, true, fmt, ap);
28}
29
Jens Wiklander65137432019-05-23 17:42:14 +020030static void __noreturn __maybe_unused dump_ta_state(struct dump_entry_arg *arg)
31{
32 struct ta_elf *elf = TAILQ_FIRST(&main_elf_queue);
33
34 assert(elf && elf->is_main);
35 EMSG_RAW("Status of TA %pUl", (void *)&elf->uuid);
36 EMSG_RAW(" arch: %s", elf->is_32bit ? "arm" : "aarch64");
37
38
Jens Wiklanderc86f2182019-06-18 16:45:19 +020039 ta_elf_print_mappings(NULL, print_to_console, &main_elf_queue,
40 arg->num_maps, arg->maps, mpool_base);
Jens Wiklander02428332019-05-23 17:42:15 +020041
42 if (arg->is_arm32)
43 ta_elf_stack_trace_a32(arg->arm32.regs);
44 else
45 ta_elf_stack_trace_a64(arg->arm64.fp, arg->arm64.sp,
46 arg->arm64.pc);
47
Jens Wiklander65137432019-05-23 17:42:14 +020048 sys_return_cleanup();
49}
50
Jens Wiklanderc86f2182019-06-18 16:45:19 +020051#ifdef CFG_TA_FTRACE_SUPPORT
52struct print_buf_ctx {
53 char *buf;
54 size_t blen;
55 size_t ret;
56};
57
58static void __printf(2, 0) print_to_pbuf(void *pctx, const char *fmt,
59 va_list ap)
60{
61 struct print_buf_ctx *pbuf = pctx;
62 char *buf = NULL;
63 size_t blen = 0;
64 int ret = 0;
65
66 if (pbuf->buf && pbuf->blen > pbuf->ret) {
67 buf = pbuf->buf + pbuf->ret;
68 blen = pbuf->blen - pbuf->ret;
69 }
70
71 ret = vsnprintk(buf, blen, fmt, ap);
72 assert(ret >= 0);
73
74 pbuf->ret += ret;
75}
76
77static void copy_to_pbuf(void *pctx, void *b, size_t bl)
78{
79 struct print_buf_ctx *pbuf = pctx;
80 char *buf = NULL;
81 size_t blen = 0;
82
83 if (pbuf->buf && pbuf->blen > pbuf->ret) {
84 buf = pbuf->buf + pbuf->ret;
85 blen = pbuf->blen - pbuf->ret;
86 memcpy(buf, b, MIN(blen, bl));
87 }
88
89 pbuf->ret += bl;
90
91}
92
93static void __noreturn ftrace_dump(void *buf, size_t *blen)
94{
95 struct print_buf_ctx pbuf = { .buf = buf, .blen = *blen };
96
97 ta_elf_print_mappings(&pbuf, print_to_pbuf, &main_elf_queue,
98 0, NULL, mpool_base);
99 ftrace_copy_buf(&pbuf, copy_to_pbuf);
100 *blen = pbuf.ret;
101 sys_return_cleanup();
102}
103#endif
104
Jens Wiklander7509ff72019-05-23 17:42:08 +0200105/*
106 * ldelf()- Loads ELF into memory
107 * @arg: Argument passing to/from TEE Core
108 *
109 * Only called from assembly
110 */
111void __noreturn ldelf(struct ldelf_arg *arg);
112void ldelf(struct ldelf_arg *arg)
113{
114 TEE_Result res = TEE_SUCCESS;
115 struct ta_elf *elf = NULL;
116
117 DMSG("Loading TA %pUl", (void *)&arg->uuid);
118 res = sys_map_zi(mpool_size, 0, &mpool_base, 0, 0);
119 if (res) {
120 EMSG("sys_map_zi(%zu): result %"PRIx32, mpool_size, res);
121 panic();
122 }
123 malloc_add_pool((void *)mpool_base, mpool_size);
124
125 /* Load the main binary and get a list of dependencies, if any. */
Jens Wiklanderc35dfd92019-07-30 08:39:27 +0200126 ta_elf_load_main(&arg->uuid, &arg->is_32bit, &arg->stack_ptr,
127 &arg->flags);
Jens Wiklander7509ff72019-05-23 17:42:08 +0200128
129 /*
130 * Load binaries, ta_elf_load() may add external libraries to the
131 * list, so the loop will end when all the dependencies are
132 * satisfied.
133 */
134 TAILQ_FOREACH(elf, &main_elf_queue, link)
135 ta_elf_load_dependency(elf, arg->is_32bit);
136
137 TAILQ_FOREACH(elf, &main_elf_queue, link) {
138 ta_elf_relocate(elf);
139 ta_elf_finalize_mappings(elf);
140 }
141
Jens Wiklanderc35dfd92019-07-30 08:39:27 +0200142 ta_elf_finalize_load_main(&arg->entry_func);
143
Jens Wiklanderc86f2182019-06-18 16:45:19 +0200144 arg->ftrace_entry = 0;
145#ifdef CFG_TA_FTRACE_SUPPORT
146 if (ftrace_init())
147 arg->ftrace_entry = (vaddr_t)(void *)ftrace_dump;
148#endif
149
Jens Wiklander7509ff72019-05-23 17:42:08 +0200150 TAILQ_FOREACH(elf, &main_elf_queue, link)
151 DMSG("ELF (%pUl) at %#"PRIxVA,
152 (void *)&elf->uuid, elf->load_addr);
153
Jens Wiklander65137432019-05-23 17:42:14 +0200154#if TRACE_LEVEL >= TRACE_ERROR
155 arg->dump_entry = (vaddr_t)(void *)dump_ta_state;
156#else
157 arg->dump_entry = 0;
158#endif
159
Jens Wiklander7509ff72019-05-23 17:42:08 +0200160 sys_return_cleanup();
161}