1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.9.2
3 * Copyright 2023 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The interface for the multi-core event buffer.
9 */
10 
11 #include <trcRecorder.h>
12 
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1) && (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
14 
xTraceMultiCoreEventBufferInitialize(TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer,uint32_t uiOptions,uint8_t * puiBuffer,uint32_t uiSize)15 traceResult xTraceMultiCoreEventBufferInitialize(TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, uint32_t uiOptions,
16 	uint8_t* puiBuffer, uint32_t uiSize)
17 {
18 	uint32_t i;
19 	uint32_t uiBufferSizePerCore;
20 
21 	/* This should never fail */
22 	TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
23 
24 	/* This should never fail */
25 	TRC_ASSERT(puiBuffer != (void*)0);
26 
27 	uiBufferSizePerCore = ((uiSize / (uint32_t)(TRC_CFG_CORE_COUNT)) / sizeof(TraceUnsignedBaseType_t)) * sizeof(TraceUnsignedBaseType_t); /* BaseType aligned */
28 
29 	/* This should never fail */
30 	TRC_ASSERT(uiBufferSizePerCore != 0u);
31 
32 	for (i = 0u; i < (uint32_t)(TRC_CFG_CORE_COUNT); i++)
33 	{
34 		/* Set the event buffer pointers to point into the allocated space we have been given, this ensures
35 		 * a flat memory layout necessary for usage in streaming snaphot. */
36 		pxTraceMultiCoreEventBuffer->xEventBuffer[i] = (TraceEventBuffer_t*)(&puiBuffer[i * uiBufferSizePerCore]); /*cstat !MISRAC2004-11.4 !MISRAC2012-Rule-11.3 Suppress conversion between pointer types checks*/ /*cstat !MISRAC2004-17.4_b We need to access a spcific point in the buffer*/
37 
38 		/* Initialize the event buffer structure with its memory buffer placed following its own structure data. */
39 		/* We need to check this */
40 		if (xTraceEventBufferInitialize(pxTraceMultiCoreEventBuffer->xEventBuffer[i], uiOptions,
41 			&puiBuffer[(i * uiBufferSizePerCore) + sizeof(TraceEventBuffer_t)], /*cstat !MISRAC2004-17.4_b We need to access a specific point in the buffer*/
42 			uiBufferSizePerCore - sizeof(TraceEventBuffer_t)) == TRC_FAIL)
43 		{
44 			return TRC_FAIL;
45 		}
46 	}
47 
48 	return TRC_SUCCESS;
49 }
50 
51 #if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
52 /*cstat !MISRAC2012-Rule-5.1 Yes, these are long names*/
xTraceMultiCoreEventBufferAlloc(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer,uint32_t uiSize,void ** ppvData)53 traceResult xTraceMultiCoreEventBufferAlloc(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer, uint32_t uiSize,
54 	void **ppvData)
55 {
56 	/* This should never fail */
57 	TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
58 
59 	TRC_ASSERT((TRC_CFG_GET_CURRENT_CORE()) < (TRC_CFG_CORE_COUNT));
60 
61 	return xTraceEventBufferAlloc(pxTraceMultiCoreEventBuffer->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], uiSize, ppvData);
62 }
63 
64 /*cstat !MISRAC2012-Rule-5.1 Yes, these are long names*/
xTraceMultiCoreEventBufferAllocCommit(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer,void * pvData,uint32_t uiSize,int32_t * piBytesWritten)65 traceResult xTraceMultiCoreEventBufferAllocCommit(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer, void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
66 {
67 	/* This should never fail */
68 	TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
69 
70 	TRC_ASSERT((TRC_CFG_GET_CURRENT_CORE()) < (TRC_CFG_CORE_COUNT));
71 
72 	return xTraceEventBufferAllocCommit(pxTraceMultiCoreEventBuffer->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], pvData, uiSize, piBytesWritten);
73 }
74 
xTraceMultiCoreEventBufferPush(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer,void * pvData,uint32_t uiSize,int32_t * piBytesWritten)75 traceResult xTraceMultiCoreEventBufferPush(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer,
76 	void* pvData, uint32_t uiSize, int32_t* piBytesWritten)
77 {
78 	/* This should never fail */
79 	TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
80 
81 	TRC_ASSERT((TRC_CFG_GET_CURRENT_CORE()) < (TRC_CFG_CORE_COUNT));
82 
83 	return xTraceEventBufferPush(pxTraceMultiCoreEventBuffer->xEventBuffer[TRC_CFG_GET_CURRENT_CORE()], pvData, uiSize, piBytesWritten);
84 }
85 
86 #endif
87 
88 /*cstat !MISRAC2012-Rule-5.1 Yes, these are long names*/
xTraceMultiCoreEventBufferTransferAll(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer,int32_t * piBytesWritten)89 traceResult xTraceMultiCoreEventBufferTransferAll(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, int32_t* piBytesWritten)
90 {
91 	int32_t iBytesWritten = 0;
92 	uint32_t uiCoreId;
93 
94 	/* This should never fail */
95 	TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
96 
97 	/* This should never fail */
98 	TRC_ASSERT(piBytesWritten != (void*)0);
99 
100 	*piBytesWritten = 0;
101 
102 	for (uiCoreId = 0u; uiCoreId < (uint32_t)(TRC_CFG_CORE_COUNT); uiCoreId++)
103 	{
104 		/* We need to check this */
105 		if (xTraceEventBufferTransferAll(pxTraceMultiCoreEventBuffer->xEventBuffer[uiCoreId], &iBytesWritten) == TRC_FAIL)
106 		{
107 			return TRC_FAIL;
108 		}
109 
110 		*piBytesWritten += iBytesWritten;
111 	}
112 
113 	return TRC_SUCCESS;
114 }
115 
116 /*cstat !MISRAC2012-Rule-5.1 Yes, these are long names*/
xTraceMultiCoreEventBufferTransferChunk(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer,uint32_t uiChunkSize,int32_t * piBytesWritten)117 traceResult xTraceMultiCoreEventBufferTransferChunk(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer, uint32_t uiChunkSize, int32_t* piBytesWritten)
118 {
119 	int32_t iBytesWritten = 0;
120 	uint32_t uiCoreId;
121 
122 	/* This should never fail */
123 	TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
124 
125 	/* This should never fail */
126 	TRC_ASSERT(piBytesWritten != (void*)0);
127 
128 	*piBytesWritten = 0;
129 
130 	for (uiCoreId = 0u; uiCoreId < (uint32_t)(TRC_CFG_CORE_COUNT); uiCoreId++)
131 	{
132 		/* We need to check this */
133 		if (xTraceEventBufferTransferChunk(pxTraceMultiCoreEventBuffer->xEventBuffer[uiCoreId], uiChunkSize, &iBytesWritten) == TRC_FAIL)
134 		{
135 			return TRC_FAIL;
136 		}
137 
138 		*piBytesWritten += iBytesWritten;
139 	}
140 
141 	return TRC_SUCCESS;
142 }
143 
xTraceMultiCoreEventBufferClear(const TraceMultiCoreEventBuffer_t * const pxTraceMultiCoreEventBuffer)144 traceResult xTraceMultiCoreEventBufferClear(const TraceMultiCoreEventBuffer_t* const pxTraceMultiCoreEventBuffer)
145 {
146 	uint32_t uiCoreId;
147 
148 	/* This should never fail */
149 	TRC_ASSERT(pxTraceMultiCoreEventBuffer != (void*)0);
150 
151 	for (uiCoreId = 0u; uiCoreId < (uint32_t)(TRC_CFG_CORE_COUNT); uiCoreId++)
152 	{
153 		/* This should never fail */
154 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventBufferClear(pxTraceMultiCoreEventBuffer->xEventBuffer[uiCoreId]) == TRC_SUCCESS);
155 	}
156 
157 	return TRC_SUCCESS;
158 }
159 
160 #endif
161