xref: /openbmc/u-boot/include/trace.h (revision e8f80a5a)
1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
2b2e16a85SSimon Glass /*
3b2e16a85SSimon Glass  * Copyright (c) 2012 The Chromium OS Authors.
4b2e16a85SSimon Glass  */
5b2e16a85SSimon Glass 
6b2e16a85SSimon Glass #ifndef __TRACE_H
7b2e16a85SSimon Glass #define __TRACE_H
8b2e16a85SSimon Glass 
9b2e16a85SSimon Glass enum {
10b2e16a85SSimon Glass 	/*
11b2e16a85SSimon Glass 	 * This affects the granularity of our trace. We can bin function
12b2e16a85SSimon Glass 	 * entry points into groups on the basis that functions typically
13b2e16a85SSimon Glass 	 * have a minimum size, so entry points can't appear any closer
14b2e16a85SSimon Glass 	 * than this to each other.
15b2e16a85SSimon Glass 	 *
16b2e16a85SSimon Glass 	 * The value here assumes a minimum instruction size of 4 bytes,
17b2e16a85SSimon Glass 	 * or that instructions are 2 bytes but there are at least 2 of
18b2e16a85SSimon Glass 	 * them in every function.
19b2e16a85SSimon Glass 	 *
20b2e16a85SSimon Glass 	 * Increasing this value reduces the number of functions we can
21b2e16a85SSimon Glass 	 * resolve, but reduces the size of the uintptr_t array used for
22b2e16a85SSimon Glass 	 * our function list, which is the length of the code divided by
23b2e16a85SSimon Glass 	 * this value.
24b2e16a85SSimon Glass 	 */
25b2e16a85SSimon Glass 	FUNC_SITE_SIZE	= 4,	/* distance between function sites */
26b2e16a85SSimon Glass };
27b2e16a85SSimon Glass 
28b2e16a85SSimon Glass enum trace_chunk_type {
29b2e16a85SSimon Glass 	TRACE_CHUNK_FUNCS,
30b2e16a85SSimon Glass 	TRACE_CHUNK_CALLS,
31b2e16a85SSimon Glass };
32b2e16a85SSimon Glass 
33b2e16a85SSimon Glass /* A trace record for a function, as written to the profile output file */
34b2e16a85SSimon Glass struct trace_output_func {
35b2e16a85SSimon Glass 	uint32_t offset;		/* Function offset into code */
36b2e16a85SSimon Glass 	uint32_t call_count;		/* Number of times called */
37b2e16a85SSimon Glass };
38b2e16a85SSimon Glass 
39b2e16a85SSimon Glass /* A header at the start of the trace output buffer */
40b2e16a85SSimon Glass struct trace_output_hdr {
41b2e16a85SSimon Glass 	enum trace_chunk_type type;	/* Record type */
42b2e16a85SSimon Glass 	uint32_t rec_count;		/* Number of records */
43b2e16a85SSimon Glass };
44b2e16a85SSimon Glass 
45b2e16a85SSimon Glass /* Print statistics about traced function calls */
46b2e16a85SSimon Glass void trace_print_stats(void);
47b2e16a85SSimon Glass 
48b2e16a85SSimon Glass /**
49b2e16a85SSimon Glass  * Dump a list of functions and call counts into a buffer
50b2e16a85SSimon Glass  *
51b2e16a85SSimon Glass  * Each record in the buffer is a struct trace_func_stats. The 'needed'
52b2e16a85SSimon Glass  * parameter returns the number of bytes needed to complete the operation,
53b2e16a85SSimon Glass  * which may be more than buff_size if your buffer is too small.
54b2e16a85SSimon Glass  *
55b2e16a85SSimon Glass  * @param buff		Buffer in which to place data, or NULL to count size
56b2e16a85SSimon Glass  * @param buff_size	Size of buffer
57b2e16a85SSimon Glass  * @param needed	Returns number of bytes used / needed
58b2e16a85SSimon Glass  * @return 0 if ok, -1 on error (buffer exhausted)
59b2e16a85SSimon Glass  */
60b2e16a85SSimon Glass int trace_list_functions(void *buff, int buff_size, unsigned *needed);
61b2e16a85SSimon Glass 
62b2e16a85SSimon Glass /* Flags for ftrace_record */
63b2e16a85SSimon Glass enum ftrace_flags {
64b2e16a85SSimon Glass 	FUNCF_EXIT		= 0UL << 30,
65b2e16a85SSimon Glass 	FUNCF_ENTRY		= 1UL << 30,
66b2e16a85SSimon Glass 	FUNCF_TEXTBASE		= 2UL << 30,
67b2e16a85SSimon Glass 
68b2e16a85SSimon Glass 	FUNCF_TIMESTAMP_MASK	= 0x3fffffff,
69b2e16a85SSimon Glass };
70b2e16a85SSimon Glass 
71b2e16a85SSimon Glass #define TRACE_CALL_TYPE(call)	((call)->flags & 0xc0000000UL)
72b2e16a85SSimon Glass 
73b2e16a85SSimon Glass /* Information about a single function entry/exit */
74b2e16a85SSimon Glass struct trace_call {
75b2e16a85SSimon Glass 	uint32_t func;		/* Function offset */
76b2e16a85SSimon Glass 	uint32_t caller;	/* Caller function offset */
77b2e16a85SSimon Glass 	uint32_t flags;		/* Flags and timestamp */
78b2e16a85SSimon Glass };
79b2e16a85SSimon Glass 
80b2e16a85SSimon Glass int trace_list_calls(void *buff, int buff_size, unsigned int *needed);
81b2e16a85SSimon Glass 
82b2e16a85SSimon Glass /**
83b2e16a85SSimon Glass  * Turn function tracing on and off
84b2e16a85SSimon Glass  *
85b2e16a85SSimon Glass  * Don't enable trace if it has not been initialised.
86b2e16a85SSimon Glass  *
87b2e16a85SSimon Glass  * @param enabled	1 to enable trace, 0 to disable
88b2e16a85SSimon Glass  */
89b2e16a85SSimon Glass void trace_set_enabled(int enabled);
90b2e16a85SSimon Glass 
91b2e16a85SSimon Glass int trace_early_init(void);
92b2e16a85SSimon Glass 
93b2e16a85SSimon Glass /**
94b2e16a85SSimon Glass  * Init the trace system
95b2e16a85SSimon Glass  *
96b2e16a85SSimon Glass  * This should be called after relocation with a suitably large buffer
97b2e16a85SSimon Glass  * (typically as large as the U-Boot text area)
98b2e16a85SSimon Glass  *
99b2e16a85SSimon Glass  * @param buff		Pointer to trace buffer
100b2e16a85SSimon Glass  * @param buff_size	Size of trace buffer
101b2e16a85SSimon Glass  */
102b2e16a85SSimon Glass int trace_init(void *buff, size_t buff_size);
103b2e16a85SSimon Glass 
104b2e16a85SSimon Glass #endif
105