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