1 /*
2 * Copyright (c) 2016, Linaro Limited
3 * SPDX-License-Identifier: BSD-2-Clause
4 */
5 #include <fcntl.h>
6 #include <libgen.h>
7 #include <linux/limits.h>
8 #include <math.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/mman.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15
16 #include "benchmark_aux.h"
17 #include "common.h"
18
19 /* Misc auxilary functions */
tee_errx(const char * msg,TEEC_Result res)20 void tee_errx(const char *msg, TEEC_Result res)
21 {
22 ERROR_EXIT("%s: 0x%08x\n", msg, res);
23 }
24
tee_check_res(TEEC_Result res,const char * errmsg)25 void tee_check_res(TEEC_Result res, const char *errmsg)
26 {
27 if (res != TEEC_SUCCESS)
28 tee_errx(errmsg, res);
29 }
30
bench_str_src(uint64_t source)31 const char *bench_str_src(uint64_t source)
32 {
33 switch (source) {
34 case TEE_BENCH_CORE:
35 return "core";
36 case TEE_BENCH_KMOD:
37 return "kmodule";
38 case TEE_BENCH_CLIENT:
39 return "libteec";
40 case TEE_BENCH_UTEE:
41 return "libutee";
42 default:
43 return "-";
44 }
45 }
46
print_line(void)47 void print_line(void)
48 {
49 int n = 115;
50
51 while (n-- > 0)
52 printf("=");
53 printf("\n");
54 }
55
alloc_argv(int argc,char * argv[],char ** new_argv[])56 void alloc_argv(int argc, char *argv[], char **new_argv[])
57 {
58 char *res, *base;
59 char path[PATH_MAX];
60 char **testapp_argv;
61 int i;
62
63 res = realpath(argv[1], path);
64 if (!res)
65 _exit(EXIT_FAILURE);
66
67 *new_argv = malloc(argc * sizeof(void *));
68 if (!(*new_argv))
69 _exit(EXIT_FAILURE);
70
71 testapp_argv = *new_argv;
72 testapp_argv[argc-1] = NULL;
73 base = basename(path);
74
75 testapp_argv[0] = malloc(strlen(base) + 1);
76 if (!testapp_argv[0])
77 _exit(EXIT_FAILURE);
78
79 memcpy(testapp_argv[0], base, strlen(base) + 1);
80
81 for (i = 2; i < argc; i++) {
82 size_t length = strlen(argv[i]) + 1;
83
84 testapp_argv[i - 1] = malloc(length);
85 if (!testapp_argv[i - 1])
86 _exit(EXIT_FAILURE);
87
88 memcpy(testapp_argv[i-1], argv[i], length);
89 }
90 }
91
dealloc_argv(int new_argc,char ** new_argv)92 void dealloc_argv(int new_argc, char **new_argv)
93 {
94 int i;
95 for (i = 0; i < new_argc; ++i)
96 free(new_argv[i]);
97
98 free(new_argv);
99 }
100
get_cores(void)101 uint32_t get_cores(void)
102 {
103 return sysconf(_SC_NPROCESSORS_ONLN);
104 }
105
mmap_paddr(intptr_t paddr,uint64_t size)106 void *mmap_paddr(intptr_t paddr, uint64_t size)
107 {
108 int devmem;
109 off_t offset = 0;
110 off_t page_addr;
111 intptr_t *hw_addr = (intptr_t *)paddr;
112
113 devmem = open("/dev/mem", O_RDWR);
114 if (!devmem)
115 return NULL;
116
117 offset = (off_t)(uintptr_t)hw_addr % getpagesize();
118 page_addr = (off_t)(uintptr_t)(hw_addr - offset);
119
120 hw_addr = (intptr_t *)mmap(0, size, PROT_READ|PROT_WRITE,
121 MAP_SHARED, devmem, page_addr);
122 if (hw_addr == MAP_FAILED) {
123 close(devmem);
124 return NULL;
125 }
126
127 close(devmem);
128 return (hw_addr + offset);
129 }
130
get_library_load_offset(pid_t pid,const char * libname)131 size_t get_library_load_offset(pid_t pid, const char *libname)
132 {
133 char path[256];
134 char buf[256];
135 FILE *file;
136 size_t addr = 0;
137 size_t start, end, offset;
138 char flags[4];
139 int len;
140 int len_libname = strlen(libname);
141
142 snprintf(path, sizeof(path), "/proc/%d/smaps", pid);
143
144 file = fopen(path, "rt");
145 if (file == NULL)
146 return 0;
147
148 while (fgets(buf, sizeof(buf), file) != NULL) {
149 len = strlen(buf);
150 if (len > 0 && buf[len-1] == '\n')
151 buf[--len] = '\0';
152
153 if (len <= len_libname || !strstr(buf, libname))
154 continue;
155
156 if (sscanf(buf, "%zx-%zx %c%c%c%c %zx", &start, &end,
157 &flags[0], &flags[1],
158 &flags[2], &flags[3], &offset) != 7)
159 continue;
160
161 if (flags[0] != 'r' || flags[2] != 'x')
162 continue;
163
164 addr = start - offset;
165 break;
166 }
167
168 fclose(file);
169
170 return addr;
171 }
172
173