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 events.
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 #define VERIFY_EVENT_SIZE(i) \
18 	if ((i) > (TRC_MAX_BLOB_SIZE)) \
19 	{ \
20 		xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED, (TraceUnsignedBaseType_t)((i) - (TRC_MAX_BLOB_SIZE))); \
21 		(i) = TRC_MAX_BLOB_SIZE; \
22 	}
23 
24 TraceEventDataTable_t *pxTraceEventDataTable;
25 
26 int32_t DUMMY_iTraceBytesCommitted;
27 
xTraceEventInitialize(TraceEventDataBuffer_t * pxBuffer)28 traceResult xTraceEventInitialize(TraceEventDataBuffer_t* pxBuffer)
29 {
30 	TraceCoreEventData_t* pxCoreEventData;
31 	uint32_t i, j;
32 
33 	TRC_ASSERT_EQUAL_SIZE(TraceEventDataBuffer_t, TraceEventDataTable_t);
34 
35 	/* This should never fail */
36 	TRC_ASSERT(pxBuffer != 0);
37 
38 	pxTraceEventDataTable = (TraceEventDataTable_t*)pxBuffer;
39 
40 	for (i = 0; i < TRC_CFG_CORE_COUNT; i++)
41 	{
42 		pxCoreEventData = &pxTraceEventDataTable->coreEventData[i];
43 
44 		pxCoreEventData->eventCounter = 0;
45 
46 		for (j = 0; j < (TRC_CFG_MAX_ISR_NESTING) + 1; j++)
47 		{
48 			RESET_EVENT_DATA(&pxCoreEventData->eventData[j]);
49 		}
50 	}
51 
52 	xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT);
53 
54 	return TRC_SUCCESS;
55 }
56 
xTraceEventBeginRawOffline(uint32_t uiSize,TraceEventHandle_t * pxEventHandle)57 traceResult xTraceEventBeginRawOffline(uint32_t uiSize, TraceEventHandle_t* pxEventHandle)
58 {
59 	TraceEventData_t* pxEventData;
60 	TraceCoreEventData_t* pxCoreEventData;
61 	int32_t ISR_nesting;
62 
63 	TRACE_ALLOC_CRITICAL_SECTION();
64 
65 	/* We need to check this */
66 	if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT))
67 	{
68 		return TRC_FAIL;
69 	}
70 
71 	/* This should never fail */
72 	TRC_ASSERT(pxEventHandle != 0);
73 
74 	TRACE_ENTER_CRITICAL_SECTION();
75 
76 	pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
77 
78 	/* We backup the local variable to the CORE specific variable */
79 	pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME = TRACE_ALLOC_CRITICAL_SECTION_NAME;
80 
81 	xTraceISRGetCurrentNesting(&ISR_nesting);
82 
83 	/* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */
84 	pxEventData = &pxCoreEventData->eventData[ISR_nesting + 1];
85 
86 	/* This should never fail */
87 	TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
88 
89 	VERIFY_EVENT_SIZE(uiSize);
90 
91 	pxEventData->size = ((uiSize + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t);	/* 4-byte align */
92 
93 	pxEventData->offset = 0;
94 
95 	/* This can fail and we should handle it */
96 	if (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) == TRC_FAIL)
97 	{
98 		TRACE_EXIT_CRITICAL_SECTION();
99 		return TRC_FAIL;
100 	}
101 
102 	*pxEventHandle = (TraceEventHandle_t)pxEventData;
103 
104 	return TRC_SUCCESS;
105 }
106 
xTraceEventBeginRawOfflineBlocking(uint32_t uiSize,TraceEventHandle_t * pxEventHandle)107 traceResult xTraceEventBeginRawOfflineBlocking(uint32_t uiSize, TraceEventHandle_t* pxEventHandle)
108 {
109 	TraceEventData_t* pxEventData;
110 	TraceCoreEventData_t* pxCoreEventData;
111 	int32_t ISR_nesting;
112 	uint32_t uiAttempts = 0;
113 
114 	TRACE_ALLOC_CRITICAL_SECTION();
115 
116 	/* We need to check this */
117 	if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT))
118 	{
119 		return TRC_FAIL;
120 	}
121 
122 	/* This should never fail */
123 	TRC_ASSERT(pxEventHandle != 0);
124 
125 	TRACE_ENTER_CRITICAL_SECTION();
126 
127 	pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
128 
129 	/* We backup the local variable to the CORE specific variable */
130 	pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME = TRACE_ALLOC_CRITICAL_SECTION_NAME;
131 
132 	xTraceGetCurrentISRNesting(&ISR_nesting);
133 
134 	/* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */
135 	pxEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventData[ISR_nesting + 1];
136 
137 	/* This should never fail */
138 	TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
139 
140 	VERIFY_EVENT_SIZE(uiSize);
141 
142 	pxEventData->size = ((uiSize + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t);	/* 4-byte align */
143 
144 	pxEventData->offset = 0;
145 
146 	/* This can fail and we should handle it */
147 	while (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) != TRC_SUCCESS)
148 	{
149 		uiAttempts++;
150 	}
151 
152 	*pxEventHandle = (TraceEventHandle_t)pxEventData;
153 
154 	return TRC_SUCCESS;
155 }
156 
xTraceEventEndOffline(TraceEventHandle_t xEventHandle)157 traceResult xTraceEventEndOffline(TraceEventHandle_t xEventHandle)
158 {
159 	TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle;
160 	TraceCoreEventData_t* pxCoreEventData;
161 	int32_t iBytesCommitted;
162 
163 	TRACE_ALLOC_CRITICAL_SECTION()
164 
165 	pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
166 
167 	/* We restore the CORE specific variable to the local variable before any EXIT */
168 	TRACE_ALLOC_CRITICAL_SECTION_NAME = pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME;
169 
170 	/* This should never fail */
171 	TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT), TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
172 
173 	/* This should never fail */
174 	TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
175 
176 	/* This should never fail */
177 	TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
178 
179 	xTraceStreamPortCommit(pxEventData->pvBlob, pxEventData->size, &iBytesCommitted);
180 
181 	/* We need to use iBytesCommitted for the above call but do not use the value,
182 	 * remove potential warnings */
183 	(void)iBytesCommitted;
184 
185 	RESET_EVENT_DATA(pxEventData);
186 
187 	TRACE_EXIT_CRITICAL_SECTION();
188 
189 	return TRC_SUCCESS;
190 }
191 
xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle)192 traceResult xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle)
193 {
194 	TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle;
195 	TraceCoreEventData_t* pxCoreEventData;
196 	int32_t iBytesCommitted;
197 
198 	TRACE_ALLOC_CRITICAL_SECTION()
199 
200 	pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
201 
202 	/* We restore the CORE specific variable to the local variable before any EXIT */
203 	TRACE_ALLOC_CRITICAL_SECTION_NAME = pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME;
204 
205 	/* This should never fail */
206 	TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT), TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
207 
208 	/* This should never fail */
209 	TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
210 
211 	/* This should never fail */
212 	TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
213 
214 	while (pxEventData->size > 0)
215 	{
216 		iBytesCommitted = 0;
217 		xTraceStreamPortCommit(pxEventData->pvBlob, pxEventData->size, &iBytesCommitted);
218 
219 		pxEventData->size -= iBytesCommitted;
220 		pxEventData->pvBlob = ((uint8_t*)pxEventData->pvBlob) + iBytesCommitted;
221 	}
222 
223 	RESET_EVENT_DATA(pxEventData);
224 
225 	TRACE_EXIT_CRITICAL_SECTION();
226 
227 	return TRC_SUCCESS;
228 }
229 
xTraceEventAddData(TraceEventHandle_t xEventHandle,void * pvData,uint32_t uiSize)230 traceResult xTraceEventAddData(TraceEventHandle_t xEventHandle, void* pvData, uint32_t uiSize)
231 {
232 	uint32_t i;
233 
234 	/* This should never fail */
235 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
236 
237 	/* This should never fail */
238 	TRC_ASSERT(xEventHandle != 0);
239 
240 	/* This should never fail */
241 	TRC_ASSERT(pvData != 0);
242 
243 	/* This should never fail */
244 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + uiSize <= ((TraceEventData_t*)xEventHandle)->size);
245 
246 	for (i = 0; i < uiSize; i++)
247 	{
248 		TRC_EVENT_ADD_8(xEventHandle, ((uint8_t*)pvData)[i]);
249 	}
250 
251 	return TRC_SUCCESS;
252 }
253 
254 #if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
255 
xTraceEventGetSize(void * pvAddress,uint32_t * puiSize)256 traceResult xTraceEventGetSize(void *pvAddress, uint32_t* puiSize)
257 {
258 	/* This should never fail */
259 	TRC_ASSERT(pvAddress != 0);
260 
261 	/* This should never fail */
262 	TRC_ASSERT(puiSize != 0);
263 
264 	/* This should never fail */
265 	TRC_ASSERT((sizeof(TraceBaseEvent_t) + (TRC_EVENT_GET_PARAM_COUNT(((TraceBaseEvent_t*)pvAddress)->EventID)) * sizeof(uint32_t)) <= TRC_MAX_BLOB_SIZE);
266 
267 	return TRC_EVENT_GET_SIZE(pvAddress, puiSize);
268 }
269 
xTraceEventGetRawData(TraceEventHandle_t xEventHandle,uint32_t uiOffset,uint32_t uiSize,void ** ppvData)270 traceResult xTraceEventGetRawData(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData)
271 {
272 	/* This should never fail */
273 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
274 
275 	/* This should never fail */
276 	TRC_ASSERT(xEventHandle != 0);
277 
278 	/* This should never fail */
279 	TRC_ASSERT(ppvData != 0);
280 
281 	/* This should never fail */
282 	TRC_ASSERT(uiOffset + uiSize <= ((TraceEventData_t*)xEventHandle)->size);
283 
284 	return TRC_EVENT_GET_RAW_DATA(xEventHandle, uiOffset, uiSize, ppvData);
285 }
286 
xTraceEventGetPayload(TraceEventHandle_t xEventHandle,uint32_t uiOffset,uint32_t uiSize,void ** ppvData)287 traceResult xTraceEventGetPayload(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData)
288 {
289 	/* This should never fail */
290 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
291 
292 	/* This should never fail */
293 	TRC_ASSERT(xEventHandle != 0);
294 
295 	/* This should never fail */
296 	TRC_ASSERT(ppvData != 0);
297 
298 	/* This should never fail */
299 	TRC_ASSERT(uiOffset + uiSize <= ((TraceEventData_t*)xEventHandle)->size);
300 
301 	return TRC_EVENT_GET_PAYLOAD(xEventHandle, uiOffset, uiSize, ppvData);
302 }
303 
xTraceEventPayloadRemaining(TraceEventHandle_t xEventHandle,uint32_t * puiValue)304 traceResult xTraceEventPayloadRemaining(TraceEventHandle_t xEventHandle, uint32_t* puiValue)
305 {
306 	/* This should never fail */
307 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
308 
309 	/* This should never fail */
310 	TRC_ASSERT(xEventHandle != 0);
311 
312 	/* This should never fail */
313 	TRC_ASSERT(puiValue != 0);
314 
315 	/* This should never fail */
316 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0);
317 
318 	return TRC_EVENT_PAYLOAD_REMAINING(xEventHandle, puiValue);
319 }
320 
xTraceEventPayloadUsed(TraceEventHandle_t xEventHandle,uint32_t * puiValue)321 traceResult xTraceEventPayloadUsed(TraceEventHandle_t xEventHandle, uint32_t* puiValue)
322 {
323 	/* This should never fail */
324 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
325 
326 	/* This should never fail */
327 	TRC_ASSERT(xEventHandle != 0);
328 
329 	/* This should never fail */
330 	TRC_ASSERT(puiValue != 0);
331 
332 	/* This should never fail */
333 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0);
334 
335 	return TRC_EVENT_PAYLOAD_USED(xEventHandle, puiValue);
336 }
337 
xTraceEventPayloadSize(TraceEventHandle_t xEventHandle,uint32_t * puiValue)338 traceResult xTraceEventPayloadSize(TraceEventHandle_t xEventHandle, uint32_t* puiValue)
339 {
340 	/* This should never fail */
341 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
342 
343 	/* This should never fail */
344 	TRC_ASSERT(xEventHandle != 0);
345 
346 	/* This should never fail */
347 	TRC_ASSERT(puiValue != 0);
348 
349 	/* This should never fail */
350 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0);
351 
352 	return TRC_EVENT_PAYLOAD_SIZE(xEventHandle, puiValue);
353 }
354 
xTraceEventAddPointer(TraceEventHandle_t xEventHandle,void * pvAddress)355 traceResult xTraceEventAddPointer(TraceEventHandle_t xEventHandle, void* pvAddress)
356 {
357 	/* This should never fail */
358 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
359 
360 	/* This should never fail */
361 	TRC_ASSERT(xEventHandle != 0);
362 
363 	/* This should never fail */
364 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(void*) <= ((TraceEventData_t*)xEventHandle)->size);
365 
366 	/* Make sure we are writing at void* aligned offset */
367 	/* This should never fail */
368 	TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(void*) - 1)) == 0);
369 
370 	return TRC_EVENT_ADD_POINTER(xEventHandle, pvAddress);
371 }
372 
xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle,TraceUnsignedBaseType_t uxValue)373 traceResult xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle, TraceUnsignedBaseType_t uxValue)
374 {
375 	/* This should never fail */
376 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
377 
378 	/* This should never fail */
379 	TRC_ASSERT(xEventHandle != 0);
380 
381 	/* This should never fail */
382 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(TraceUnsignedBaseType_t) <= ((TraceEventData_t*)xEventHandle)->size);
383 
384 	/* Make sure we are writing at TraceUnsignedBaseType_t aligned offset */
385 	/* This should never fail */
386 	TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(TraceUnsignedBaseType_t) - 1)) == 0);
387 
388 	return TRC_EVENT_ADD_UNSIGNED_BASE_TYPE(xEventHandle, uxValue);
389 }
390 
xTraceEventAdd32(TraceEventHandle_t xEventHandle,uint32_t value)391 traceResult xTraceEventAdd32(TraceEventHandle_t xEventHandle, uint32_t value)
392 {
393 	/* This should never fail */
394 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
395 
396 	/* This should never fail */
397 	TRC_ASSERT(xEventHandle != 0);
398 
399 	/* This should never fail */
400 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint32_t) <= ((TraceEventData_t*)xEventHandle)->size);
401 
402 	/* Make sure we are writing at 32-bit aligned offset */
403 	/* This should never fail */
404 	TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 3) == 0);
405 
406 	return TRC_EVENT_ADD_32(xEventHandle, value);
407 }
408 
xTraceEventAdd16(TraceEventHandle_t xEventHandle,uint16_t value)409 traceResult xTraceEventAdd16(TraceEventHandle_t xEventHandle, uint16_t value)
410 {
411 	/* This should never fail */
412 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
413 
414 	/* This should never fail */
415 	TRC_ASSERT(xEventHandle != 0);
416 
417 	/* This should never fail */
418 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint16_t) <= ((TraceEventData_t*)xEventHandle)->size);
419 
420 	/* Make sure we are writing at 16-bit aligned offset */
421 	/* This should never fail */
422 	TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 1) == 0);
423 
424 	return TRC_EVENT_ADD_16(xEventHandle, value);
425 }
426 
xTraceEventAdd8(TraceEventHandle_t xEventHandle,uint8_t value)427 traceResult xTraceEventAdd8(TraceEventHandle_t xEventHandle, uint8_t value)
428 {
429 	/* This should never fail */
430 	TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
431 
432 	/* This should never fail */
433 	TRC_ASSERT(xEventHandle != 0);
434 
435 	/* This should never fail */
436 	TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint8_t) <= ((TraceEventData_t*)xEventHandle)->size);
437 
438 	return TRC_EVENT_ADD_8(xEventHandle, value);
439 }
440 
441 #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
442 
443 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
444 
445 #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
446