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