1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright(C) 2022 Linaro Limited. All rights reserved. |
4 | * Author: Mike Leach <mike.leach@linaro.org> |
5 | */ |
6 | |
7 | #ifndef _CORESIGHT_TRACE_ID_H |
8 | #define _CORESIGHT_TRACE_ID_H |
9 | |
10 | /* |
11 | * Coresight trace ID allocation API |
12 | * |
13 | * With multi cpu systems, and more additional trace sources a scalable |
14 | * trace ID reservation system is required. |
15 | * |
16 | * The system will allocate Ids on a demand basis, and allow them to be |
17 | * released when done. |
18 | * |
19 | * In order to ensure that a consistent cpu / ID matching is maintained |
20 | * throughout a perf cs_etm event session - a session in progress flag will |
21 | * be maintained, and released IDs not cleared until the perf session is |
22 | * complete. This allows the same CPU to be re-allocated its prior ID. |
23 | * |
24 | * |
25 | * Trace ID maps will be created and initialised to prevent architecturally |
26 | * reserved IDs from being allocated. |
27 | * |
28 | * API permits multiple maps to be maintained - for large systems where |
29 | * different sets of cpus trace into different independent sinks. |
30 | */ |
31 | |
32 | #include <linux/bitops.h> |
33 | #include <linux/types.h> |
34 | |
35 | |
36 | /* architecturally we have 128 IDs some of which are reserved */ |
37 | #define CORESIGHT_TRACE_IDS_MAX 128 |
38 | |
39 | /* ID 0 is reserved */ |
40 | #define CORESIGHT_TRACE_ID_RES_0 0 |
41 | |
42 | /* ID 0x70 onwards are reserved */ |
43 | #define CORESIGHT_TRACE_ID_RES_TOP 0x70 |
44 | |
45 | /* check an ID is in the valid range */ |
46 | #define IS_VALID_CS_TRACE_ID(id) \ |
47 | ((id > CORESIGHT_TRACE_ID_RES_0) && (id < CORESIGHT_TRACE_ID_RES_TOP)) |
48 | |
49 | /** |
50 | * Trace ID map. |
51 | * |
52 | * @used_ids: Bitmap to register available (bit = 0) and in use (bit = 1) IDs. |
53 | * Initialised so that the reserved IDs are permanently marked as |
54 | * in use. |
55 | * @pend_rel_ids: CPU IDs that have been released by the trace source but not |
56 | * yet marked as available, to allow re-allocation to the same |
57 | * CPU during a perf session. |
58 | */ |
59 | struct coresight_trace_id_map { |
60 | DECLARE_BITMAP(used_ids, CORESIGHT_TRACE_IDS_MAX); |
61 | DECLARE_BITMAP(pend_rel_ids, CORESIGHT_TRACE_IDS_MAX); |
62 | }; |
63 | |
64 | /* Allocate and release IDs for a single default trace ID map */ |
65 | |
66 | /** |
67 | * Read and optionally allocate a CoreSight trace ID and associate with a CPU. |
68 | * |
69 | * Function will read the current trace ID for the associated CPU, |
70 | * allocating an new ID if one is not currently allocated. |
71 | * |
72 | * Numeric ID values allocated use legacy allocation algorithm if possible, |
73 | * otherwise any available ID is used. |
74 | * |
75 | * @cpu: The CPU index to allocate for. |
76 | * |
77 | * return: CoreSight trace ID or -EINVAL if allocation impossible. |
78 | */ |
79 | int coresight_trace_id_get_cpu_id(int cpu); |
80 | |
81 | /** |
82 | * Release an allocated trace ID associated with the CPU. |
83 | * |
84 | * This will release the CoreSight trace ID associated with the CPU, |
85 | * unless a perf session is in operation. |
86 | * |
87 | * If a perf session is in operation then the ID will be marked as pending |
88 | * release. |
89 | * |
90 | * @cpu: The CPU index to release the associated trace ID. |
91 | */ |
92 | void coresight_trace_id_put_cpu_id(int cpu); |
93 | |
94 | /** |
95 | * Read the current allocated CoreSight Trace ID value for the CPU. |
96 | * |
97 | * Fast read of the current value that does not allocate if no ID allocated |
98 | * for the CPU. |
99 | * |
100 | * Used in perf context where it is known that the value for the CPU will not |
101 | * be changing, when perf starts and event on a core and outputs the Trace ID |
102 | * for the CPU as a packet in the data file. IDs cannot change during a perf |
103 | * session. |
104 | * |
105 | * This function does not take the lock protecting the ID lists, avoiding |
106 | * locking dependency issues with perf locks. |
107 | * |
108 | * @cpu: The CPU index to read. |
109 | * |
110 | * return: current value, will be 0 if unallocated. |
111 | */ |
112 | int coresight_trace_id_read_cpu_id(int cpu); |
113 | |
114 | /** |
115 | * Allocate a CoreSight trace ID for a system component. |
116 | * |
117 | * Unconditionally allocates a Trace ID, without associating the ID with a CPU. |
118 | * |
119 | * Used to allocate IDs for system trace sources such as STM. |
120 | * |
121 | * return: Trace ID or -EINVAL if allocation is impossible. |
122 | */ |
123 | int coresight_trace_id_get_system_id(void); |
124 | |
125 | /** |
126 | * Release an allocated system trace ID. |
127 | * |
128 | * Unconditionally release a trace ID allocated to a system component. |
129 | * |
130 | * @id: value of trace ID allocated. |
131 | */ |
132 | void coresight_trace_id_put_system_id(int id); |
133 | |
134 | /* notifiers for perf session start and stop */ |
135 | |
136 | /** |
137 | * Notify the Trace ID allocator that a perf session is starting. |
138 | * |
139 | * Increase the perf session reference count - called by perf when setting up |
140 | * a trace event. |
141 | * |
142 | * This reference count is used by the ID allocator to ensure that trace IDs |
143 | * associated with a CPU cannot change or be released during a perf session. |
144 | */ |
145 | void coresight_trace_id_perf_start(void); |
146 | |
147 | /** |
148 | * Notify the ID allocator that a perf session is stopping. |
149 | * |
150 | * Decrease the perf session reference count. |
151 | * if this causes the count to go to zero, then all Trace IDs marked as pending |
152 | * release, will be released. |
153 | */ |
154 | void coresight_trace_id_perf_stop(void); |
155 | |
156 | #endif /* _CORESIGHT_TRACE_ID_H */ |
157 | |