blob: a98648bd26af1aea9bf583da17195a8e4b1da6e7 [file] [log] [blame]
Ranjani Sridharan46704022018-05-31 19:29:05 -07001/*
2 * Copyright (c) 2018, Intel Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the Intel Corporation nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
29 * Liam Girdwood <liam.r.girdwood@linux.intel.com>
30 * Keyon Jie <yang.jie@linux.intel.com>
31 * Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
32 */
33
34#include <stdint.h>
35#include <stdio.h>
36#include <string.h>
37#include "host/common_test.h"
38#include "host/trace.h"
39
40#define MAX_TRACE_CLASSES 255
41/* testbench trace definition */
42
43/* enable trace by default in testbench */
44static int test_bench_trace = 1;
45int num_trace_classes;
46
47/* set up trace class identifier table based on SOF trace header file */
48void setup_trace_table(void)
49{
50 char buffer[2048];
51 char *trace = "sof/trace.h";
52 char *trace_filename = malloc(strlen(SOF_INC) + strlen(trace) + 2);
53 char *token;
54 int ret, i = 0;
55 size_t size;
56 FILE *fp;
57
58 /* set up trace file name using include directory prefix */
59 sprintf(trace_filename, "%s/%s", SOF_INC, trace);
60
61 fp = fopen(trace_filename, "r");
62 if (!fp) {
63 fprintf(stderr, "error: opening trace include file %s\n",
64 trace_filename);
65 }
66
67 /* find number of trace classes defined */
68 while (fgets(buffer, sizeof(buffer), fp)) {
69 char identifier[1024];
70 int value = 0, shift = 0;
71
72 ret = sscanf(buffer, "#define %s (%d << %d)", identifier,
73 &value, &shift);
74 if (ret == 3) {
75 /* if TRACE_CLASS definition */
76 if (strstr(identifier, "TRACE_CLASS"))
77 i++;
78 }
79 }
80
81 num_trace_classes = i;
82
83 /* allocate memory for trace table */
84 size = sizeof(struct trace_class_table);
85 trace_table = (struct trace_class_table *)malloc(size *
86 num_trace_classes);
87
88 /* rewind file pointer */
89 fseek(fp, 0, SEEK_SET);
90
91 i = 0;
92
93 /* read lines from header */
94 while (fgets(buffer, sizeof(buffer), fp)) {
95 char identifier[1024];
96 int value = 0, shift = 0;
97
98 ret = sscanf(buffer, "#define %s (%d << %d)", identifier,
99 &value, &shift);
100 if (ret == 3) {
101 /* if TRACE_CLASS definition */
102 if (strstr(identifier, "TRACE_CLASS")) {
103 /* extract subsystem name */
104 token = strtok(identifier, "_");
105 token = strtok(NULL, "_");
106 token = strtok(NULL, "_");
107
108 /* add trace class entry */
109 trace_table[i].trace_class = value;
110 trace_table[i].class_name = strdup(token);
111 i++;
112 }
113 }
114 }
115 fclose(fp);
116 free(trace_filename);
117}
118
119void free_trace_table(void)
120{
121 int i;
122
123 for (i = 0; i < num_trace_classes; i++)
124 free(trace_table[i].class_name);
125
126 free(trace_table);
127}
128
129/* look up subsystem class name from table */
130static char *get_trace_class(uint32_t trace_class)
131{
132 int i;
133
134 /* look up trace class table and return subsystem name */
135 for (i = 0; i < num_trace_classes; i++) {
136 if (trace_table[i].trace_class == trace_class)
137 return trace_table[i].class_name;
138 }
139
140 return "value";
141}
142
143/* print trace event */
144void _trace_event(uint32_t event)
145{
146 char a, b, c;
147 char *trace_class = NULL;
148
149 if (test_bench_trace > 0) {
150 a = event & 0xff;
151 b = (event >> 8) & 0xff;
152 c = (event >> 16) & 0xff;
153
154 /* look up subsystem from trace class table */
155 trace_class = strdup(get_trace_class(event >> 24));
156
157 /* print trace event stderr*/
158 if (strcmp(trace_class, "value") == 0)
159 fprintf(stderr, "Trace value %d\n", event);
160 else
161 fprintf(stderr, "Trace %s %c%c%c\n", trace_class,
162 c, b, a);
163 }
164
165 free(trace_class);
166}
167
168void _trace_event_mbox_atomic(uint32_t event)
169{
170 _trace_event(event);
171}
172
173/* enable trace in testbench */
174void tb_enable_trace(bool enable)
175{
176 test_bench_trace = enable;
177 if (enable)
178 debug_print("trace print enabled\n");
179 else
180 debug_print("trace print disabled\n");
181}