1 // © 2021 Qualcomm Innovation Center, Inc. All rights reserved.
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 // Trace interface and helper macros
6 //
7 // Traces are enabled and disabled by trace class. There up to 64 classes, and
8 // they are mapped to corresponding bits in a global register_t sized value.
9 //
10 // Trace ID is used to identify the trace event. There is no correlation between
11 // trace-id and trace-class, the caller shall select the class, or classes
12 // they wish the trace event to be dependent on.
13 //
14 // Note, some trace classes may be used internally by implementations, for
15 // example TRACE_BUFFER or TRACE_ADD classes.
16 
17 #include <events/trace.h>
18 
19 #define TRACE_ID(id)	    (TRACE_ID_##id)
20 #define TRACE_CLASS(tclass) (TRACE_CLASS_##tclass)
21 #define TRACE_CLASS_BITS(tclass)                                               \
22 	((register_t)1 << (index_t)TRACE_CLASS_##tclass)
23 
24 #define TRACE_FUNC_I(id, action, a0, a1, a2, a3, a4, a5, n, ...)               \
25 	TRACE_ADD##n(TRACE_ID(id), action, a0, a1, a2, a3, a4, a5, __VA_ARGS__)
26 #define TRACE_FUNC(...)                                                        \
27 	TRACE_FUNC_I(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0, _unspecified_id)
28 
29 extern trace_control_t hyp_trace;
30 extern register_t      trace_public_class_flags;
31 
32 #define TRACE_MAYBE(classes, X)                                                \
33 	do {                                                                   \
34 		register_t class_enabled_ = atomic_load_explicit(              \
35 			&hyp_trace.enabled_class_flags, memory_order_relaxed); \
36 		if (compiler_unexpected((class_enabled_ & classes) != 0U)) {   \
37 			X;                                                     \
38 		}                                                              \
39 	} while (0)
40 
41 // Used for single class trace
42 #if defined(PARASOFT_CYCLO)
43 #define TRACE(tclass, id, ...)
44 #else
45 #define TRACE(tclass, id, ...)                                                 \
46 	TRACE_EVENT(tclass, id, TRACE_ACTION_TRACE, __VA_ARGS__)
47 #endif
48 #define TRACE_LOCAL(tclass, id, ...)                                           \
49 	TRACE_EVENT(tclass, id, TRACE_ACTION_TRACE_LOCAL, __VA_ARGS__)
50 
51 #define TRACE_EVENT(tclass, id, action, ...)                                   \
52 	TRACE_MAYBE(TRACE_CLASS_BITS(tclass),                                  \
53 		    TRACE_FUNC(id, action, __VA_ARGS__))
54 
55 #define TRACE_ADD0(id, action, ...)                                            \
56 	trigger_trace_log_event(id, action, 0, 0, 0, 0, 0, 0)
57 
58 #define TRACE_ADD1(id, action, a1, ...)                                        \
59 	trigger_trace_log_event(id, action, a1, 0, 0, 0, 0, 0)
60 
61 #define TRACE_ADD2(id, action, a1, a2, ...)                                    \
62 	trigger_trace_log_event(id, action, a1, a2, 0, 0, 0, 0)
63 
64 #define TRACE_ADD3(id, action, a1, a2, a3, ...)                                \
65 	trigger_trace_log_event(id, action, a1, a2, a3, 0, 0, 0)
66 
67 #define TRACE_ADD4(id, action, a1, a2, a3, a4, ...)                            \
68 	trigger_trace_log_event(id, action, a1, a2, a3, a4, 0, 0)
69 
70 #define TRACE_ADD5(id, action, a1, a2, a3, a4, a5, ...)                        \
71 	trigger_trace_log_event(id, action, a1, a2, a3, a4, a5, 0)
72 
73 #define TRACE_ADD6(id, action, a1, a2, a3, a4, a5, a6, ...)                    \
74 	trigger_trace_log_event(id, action, a1, a2, a3, a4, a5, a6)
75 
76 // Enable a set of trace classes.
77 //
78 // flags: the new flags to be enabled.
79 void
80 trace_set_class_flags(register_t flags);
81 
82 // Disable a set of trace classes.
83 //
84 // flags: the flags to be disabled.
85 void
86 trace_clear_class_flags(register_t flags);
87 
88 // Atomically update a set of trace classes.
89 //
90 // set_flags: the flags to be enabled.
91 // clear_flags: the flags to be disabled.
92 //
93 // Note: flags both set and cleared will remain set.
94 void
95 trace_update_class_flags(register_t set_flags, register_t clear_flags);
96 
97 // Return the current status of trace classes.
98 register_t
99 trace_get_class_flags(void);
100 
101 // Allocate and relocate trace buffer
102 //
103 // It stops using the trace boot buffer and starts using a dynamically allocated
104 // trace buffer of bigger size
105 void
106 trace_init(partition_t *partition, size_t size) REQUIRE_PREEMPT_DISABLED;
107 
108 #if defined(PLATFORM_TRACE_STANDALONE_REGION)
109 // Use pre-allocated memory for trace buffer
110 //
111 // It stops using the trace boot buffer and starts using a pre-allocated
112 // trace buffer of bigger size
113 void
114 trace_single_region_init(partition_t *partition, paddr_t base, size_t size)
115 	REQUIRE_PREEMPT_DISABLED;
116 #endif
117