1c86f218cSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 2c86f218cSJens Wiklander /* 3c86f218cSJens Wiklander * Copyright (c) 2019, Linaro Limited 4c86f218cSJens Wiklander */ 5c86f218cSJens Wiklander 6c86f218cSJens Wiklander #include <assert.h> 7c86f218cSJens Wiklander #include <printk.h> 8c86f218cSJens Wiklander #include <sys/queue.h> 9c86f218cSJens Wiklander #include <types_ext.h> 10c86f218cSJens Wiklander #include <util.h> 11c86f218cSJens Wiklander 12c86f218cSJens Wiklander #include "ftrace.h" 13c86f218cSJens Wiklander #include "ta_elf.h" 14c86f218cSJens Wiklander 15c86f218cSJens Wiklander #define MIN_FTRACE_BUF_SIZE 1024 16c86f218cSJens Wiklander #define MAX_HEADER_STRLEN 128 17c86f218cSJens Wiklander 18c86f218cSJens Wiklander static struct ftrace_buf *fbuf; 19c86f218cSJens Wiklander 20f90488afSSumit Garg bool ftrace_init(struct ftrace_buf **fbuf_ptr) 21c86f218cSJens Wiklander { 22f90488afSSumit Garg struct __ftrace_info *finfo = NULL; 23c86f218cSJens Wiklander struct ta_elf *elf = TAILQ_FIRST(&main_elf_queue); 24c86f218cSJens Wiklander TEE_Result res = TEE_SUCCESS; 25c86f218cSJens Wiklander vaddr_t val = 0; 26c86f218cSJens Wiklander int count = 0; 27c86f218cSJens Wiklander size_t fbuf_size = 0; 28c86f218cSJens Wiklander 29ebef121cSJerome Forissier res = ta_elf_resolve_sym("__ftrace_info", &val, NULL); 30c86f218cSJens Wiklander if (res) 31c86f218cSJens Wiklander return false; 32c86f218cSJens Wiklander 33c86f218cSJens Wiklander finfo = (struct __ftrace_info *)val; 34c86f218cSJens Wiklander 35c86f218cSJens Wiklander assert(elf && elf->is_main); 36c86f218cSJens Wiklander 37c96d7091SSumit Garg if (SUB_OVERFLOW(finfo->buf_end.ptr64, finfo->buf_start.ptr64, 38c96d7091SSumit Garg &fbuf_size)) 39c86f218cSJens Wiklander return false; 40c86f218cSJens Wiklander 41c86f218cSJens Wiklander if (fbuf_size < MIN_FTRACE_BUF_SIZE) { 42c86f218cSJens Wiklander DMSG("ftrace buffer too small"); 43c86f218cSJens Wiklander return false; 44c86f218cSJens Wiklander } 45c86f218cSJens Wiklander 46e260ea8dSJens Wiklander fbuf = (struct ftrace_buf *)(vaddr_t)finfo->buf_start.ptr64; 47c86f218cSJens Wiklander fbuf->head_off = sizeof(struct ftrace_buf); 48c86f218cSJens Wiklander count = snprintk((char *)fbuf + fbuf->head_off, MAX_HEADER_STRLEN, 49c86f218cSJens Wiklander "Function graph for TA: %pUl @ %lx\n", 50c86f218cSJens Wiklander (void *)&elf->uuid, elf->load_addr); 51c86f218cSJens Wiklander assert(count < MAX_HEADER_STRLEN); 52c86f218cSJens Wiklander 53c96d7091SSumit Garg fbuf->ret_func_ptr = finfo->ret_ptr.ptr64; 54c86f218cSJens Wiklander fbuf->ret_idx = 0; 55c86f218cSJens Wiklander fbuf->lr_idx = 0; 56f5df167cSSumit Garg fbuf->suspend_time = 0; 57c86f218cSJens Wiklander fbuf->buf_off = fbuf->head_off + count; 58c86f218cSJens Wiklander fbuf->curr_size = 0; 59c86f218cSJens Wiklander fbuf->max_size = fbuf_size - sizeof(struct ftrace_buf) - count; 60*099918f6SSumit Garg fbuf->syscall_trace_enabled = false; 61*099918f6SSumit Garg fbuf->syscall_trace_suspended = false; 62c86f218cSJens Wiklander 63f90488afSSumit Garg *fbuf_ptr = fbuf; 64f90488afSSumit Garg 65c86f218cSJens Wiklander return true; 66c86f218cSJens Wiklander } 67c86f218cSJens Wiklander 68c86f218cSJens Wiklander void ftrace_copy_buf(void *pctx, void (*copy_func)(void *pctx, void *b, 69c86f218cSJens Wiklander size_t bl)) 70c86f218cSJens Wiklander { 71c86f218cSJens Wiklander if (fbuf) { 72c86f218cSJens Wiklander struct ta_elf *elf = TAILQ_FIRST(&main_elf_queue); 73c86f218cSJens Wiklander size_t dump_size = fbuf->buf_off - fbuf->head_off + 74c86f218cSJens Wiklander fbuf->curr_size; 75c86f218cSJens Wiklander 76c86f218cSJens Wiklander assert(elf && elf->is_main); 77c86f218cSJens Wiklander copy_func(pctx, (char *)fbuf + fbuf->head_off, dump_size); 78c86f218cSJens Wiklander } 79c86f218cSJens Wiklander } 80c86f218cSJens Wiklander 81c86f218cSJens Wiklander void ftrace_map_lr(uint64_t *lr) 82c86f218cSJens Wiklander { 83c86f218cSJens Wiklander if (fbuf) { 84c86f218cSJens Wiklander if (*lr == fbuf->ret_func_ptr && 85c86f218cSJens Wiklander fbuf->lr_idx < fbuf->ret_idx) { 86c86f218cSJens Wiklander fbuf->lr_idx++; 87c86f218cSJens Wiklander *lr = fbuf->ret_stack[fbuf->ret_idx - fbuf->lr_idx]; 88c86f218cSJens Wiklander } 89c86f218cSJens Wiklander } 90c86f218cSJens Wiklander } 91