1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.6.6
3 * Copyright 2021 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The implementation for ISR tagging.
9 */
10 
11 #include <trcRecorder.h>
12 
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1)
14 
15 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
16 
17 TraceISRInfo_t* pxTraceISRInfo;
18 
xTraceISRInitialize(TraceISRInfoBuffer_t * pxBuffer)19 traceResult xTraceISRInitialize(TraceISRInfoBuffer_t *pxBuffer)
20 {
21 	uint32_t uiCoreIndex;
22 	uint32_t uiStackIndex;
23 
24 	TRC_ASSERT_EQUAL_SIZE(TraceISRInfoBuffer_t, TraceISRInfo_t);
25 
26 	/* This should never fail */
27 	TRC_ASSERT(pxBuffer != 0);
28 
29 	pxTraceISRInfo = (TraceISRInfo_t*)pxBuffer;
30 
31 	for (uiCoreIndex = 0; uiCoreIndex < (TRC_CFG_CORE_COUNT); uiCoreIndex++)
32 	{
33 		TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[uiCoreIndex];
34 
35 		/* Initialize ISR stack */
36 		for (uiStackIndex = 0; uiStackIndex < (TRC_CFG_MAX_ISR_NESTING); uiStackIndex++)
37 		{
38 			pxCoreInfo->handleStack[uiStackIndex] = 0;
39 		}
40 
41 		pxCoreInfo->stackIndex = -1;
42 		pxCoreInfo->isPendingContextSwitch = 0;
43 	}
44 
45 	xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ISR);
46 
47 	return TRC_SUCCESS;
48 }
49 
xTraceISRRegister(const char * szName,uint32_t uiPriority,TraceISRHandle_t * pxISRHandle)50 traceResult xTraceISRRegister(const char* szName, uint32_t uiPriority, TraceISRHandle_t *pxISRHandle)
51 {
52 	TraceEntryHandle_t xEntryHandle;
53 	TraceEventHandle_t xEventHandle = 0;
54 	uint32_t i = 0, uiLength = 0, uiValue = 0;
55 
56 	/* We need to check this */
57 	if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR))
58 	{
59 		return TRC_FAIL;
60 	}
61 
62 	/* This should never fail */
63 	TRC_ASSERT(pxISRHandle != 0);
64 
65 	if (szName == 0)
66 	{
67 		szName = "";
68 	}
69 
70 	/* Always save in symbol table, in case the recording has not yet started */
71 	/* We need to check this */
72 	if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
73 	{
74 		return TRC_FAIL;
75 	}
76 
77 	/* This should never fail */
78 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetSymbol(xEntryHandle, szName) == TRC_SUCCESS);
79 
80 	/* This should never fail */
81 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, 0, (TraceUnsignedBaseType_t)uiPriority) == TRC_SUCCESS);
82 
83 	*pxISRHandle = (TraceISRHandle_t)xEntryHandle;
84 
85 	for (i = 0; (szName[i] != 0) && (i < 128); i++) {}
86 
87 	uiLength = i;
88 
89 	/* We need to check this */
90 	if (xTraceEventBegin(PSF_EVENT_DEFINE_ISR, uiLength + sizeof(void*) + sizeof(uint32_t), &xEventHandle) == TRC_SUCCESS)
91 	{
92 		xTraceEventAddPointer(xEventHandle, (void*)xEntryHandle);
93 		xTraceEventAdd32(xEventHandle, uiPriority);
94 		xTraceEventAddData(xEventHandle, (void*)szName, uiLength);
95 
96 		/* Check if we can truncate */
97 		xTraceEventPayloadRemaining(xEventHandle, &uiValue);
98 		if (uiValue > 0)
99 		{
100 			xTraceEventAdd8(xEventHandle, 0);
101 		}
102 
103 		xTraceEventEnd(xEventHandle);
104 	}
105 
106 	return TRC_SUCCESS;
107 }
108 
xTraceISRBegin(TraceISRHandle_t xISRHandle)109 traceResult xTraceISRBegin(TraceISRHandle_t xISRHandle)
110 {
111 	TraceEventHandle_t xEventHandle = 0;
112 	TraceISRCoreInfo_t* pxCoreInfo;
113 	TRACE_ALLOC_CRITICAL_SECTION();
114 
115 	(void)xEventHandle;
116 
117 	/* This should never fail */
118 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
119 
120 	TRACE_ENTER_CRITICAL_SECTION();
121 
122 	/* We are at the start of a possible ISR chain.
123 	 * No context switches should have been triggered now.
124 	 */
125 	pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()];
126 
127 	if (pxCoreInfo->stackIndex == -1)
128 	{
129 		pxCoreInfo->isPendingContextSwitch = 0;
130 	}
131 
132 	if (pxCoreInfo->stackIndex < (TRC_CFG_MAX_ISR_NESTING) - 1)
133 	{
134 		pxCoreInfo->stackIndex++;
135 		pxCoreInfo->handleStack[pxCoreInfo->stackIndex] = xISRHandle;
136 
137 #if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
138 		/* We need to check this */
139 		if (xTraceEventBegin(PSF_EVENT_ISR_BEGIN, sizeof(void*), &xEventHandle) == TRC_SUCCESS)
140 		{
141 			xTraceEventAddPointer(xEventHandle, (void*)xISRHandle);
142 			xTraceEventEnd(xEventHandle);
143 		}
144 #endif
145 	}
146 	else
147 	{
148 		TRACE_EXIT_CRITICAL_SECTION();
149 
150 		xTraceError(TRC_ERROR_ISR_NESTING_OVERFLOW);
151 
152 		return TRC_FAIL;
153 	}
154 
155 	TRACE_EXIT_CRITICAL_SECTION();
156 
157 	return TRC_SUCCESS;
158 }
159 
xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired)160 traceResult xTraceISREnd(TraceBaseType_t xIsTaskSwitchRequired)
161 {
162 	TraceEventHandle_t xEventHandle = 0;
163 	TraceISRCoreInfo_t* pxCoreInfo;
164 	TRACE_ALLOC_CRITICAL_SECTION();
165 
166 	(void)xEventHandle;
167 
168 	/* This should never fail */
169 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
170 
171 	TRACE_ENTER_CRITICAL_SECTION();
172 
173 	pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()];
174 
175 	/* Is there a pending task-switch? (perhaps from an earlier ISR) */
176 	pxCoreInfo->isPendingContextSwitch |= xIsTaskSwitchRequired;
177 
178 	if (pxCoreInfo->stackIndex > 0)
179 	{
180 		pxCoreInfo->stackIndex--;
181 
182 #if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
183 		/* Store return to interrupted ISR (if nested ISRs)*/
184 		/* We need to check this */
185 		if (xTraceEventBegin(PSF_EVENT_ISR_RESUME, sizeof(void*), &xEventHandle) == TRC_SUCCESS)
186 		{
187 			xTraceEventAddPointer(xEventHandle, (void*)pxCoreInfo->handleStack[pxCoreInfo->stackIndex]);
188 			xTraceEventEnd(xEventHandle);
189 		}
190 #endif
191 	}
192 	else
193 	{
194 		pxCoreInfo->stackIndex--;
195 
196 		/* Store return to interrupted task, if no context switch will occur in between. */
197 		if ((pxCoreInfo->isPendingContextSwitch == 0) || (xTraceKernelPortIsSchedulerSuspended()))
198 		{
199 #if (TRC_CFG_INCLUDE_ISR_TRACING == 1)
200 			/* We need to check this */
201 			if (xTraceEventBegin(PSF_EVENT_TASK_ACTIVATE, sizeof(void*), &xEventHandle) == TRC_SUCCESS)
202 			{
203 				void *pvCurrentTask = 0;
204 
205 				xTraceTaskGetCurrent(&pvCurrentTask);
206 				xTraceEventAddPointer(xEventHandle, pvCurrentTask);
207 				xTraceEventEnd(xEventHandle);
208 			}
209 #endif
210 		}
211 	}
212 
213 	TRACE_EXIT_CRITICAL_SECTION();
214 
215 	return TRC_SUCCESS;
216 }
217 
218 #if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
219 
xTraceISRGetCurrentNesting(int32_t * puiValue)220 traceResult xTraceISRGetCurrentNesting(int32_t* puiValue)
221 {
222 	/* This should never fail */
223 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
224 
225 	/* This should never fail */
226 	TRC_ASSERT(puiValue != 0);
227 
228 	TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()];
229 	*puiValue = pxCoreInfo->stackIndex;
230 
231 	return TRC_SUCCESS;
232 }
233 
xTraceISRGetCurrentNestingReturned(void)234 int32_t xTraceISRGetCurrentNestingReturned(void)
235 {
236 	/* This should never fail */
237 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
238 
239 	return pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()].stackIndex;
240 }
241 
xTraceISRGetCurrent(TraceISRHandle_t * pxISRHandle)242 traceResult xTraceISRGetCurrent(TraceISRHandle_t* pxISRHandle)
243 {
244 	/* This should never fail */
245 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ISR));
246 
247 	/* This should never fail */
248 	TRC_ASSERT(pxISRHandle != 0);
249 
250 	TraceISRCoreInfo_t* pxCoreInfo = &pxTraceISRInfo->coreInfos[TRC_CFG_GET_CURRENT_CORE()];
251 
252 	if (pxCoreInfo->stackIndex < 0)
253 	{
254 		return TRC_FAIL;
255 	}
256 
257 	*pxISRHandle = pxCoreInfo->handleStack[pxCoreInfo->stackIndex];
258 
259 	return TRC_SUCCESS;
260 }
261 
262 #endif
263 
264 /* DEPRECATED */
xTraceSetISRProperties(const char * szName,uint32_t uiPriority)265 TraceISRHandle_t xTraceSetISRProperties(const char* szName, uint32_t uiPriority)
266 {
267 	TraceISRHandle_t xISRHandle = 0;
268 
269 	xTraceISRRegister(szName, uiPriority, &xISRHandle);
270 
271 	return xISRHandle;
272 }
273 
274 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
275 
276 #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
277