1 /*
2  * Percepio DFM v2.1.0
3  * Copyright 2023 Percepio AB
4  * www.percepio.com
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * DFM Retained Memory
9  */
10 
11 #include <dfm.h>
12 
13 #if (defined(DFM_CFG_ENABLED) && (DFM_CFG_ENABLED >= 1)) && (defined(DFM_CFG_RETAINED_MEMORY) && (DFM_CFG_RETAINED_MEMORY >= 1))
14 
15 #include <dfmRetainedMemoryPort.h>
16 
17 #define DFM_RETAINED_MEMORY_TYPE_ALERT 0x341562AB
18 #define DFM_RETAINED_MEMORY_TYPE_PAYLOAD 0xE78BAC01
19 
20 static DfmRetainedMemoryData_t* pxRetainedMemoryData;
21 
22 typedef struct DfmRetainedMemoryMetaData
23 {
24 	uint32_t ulType;
25 	uint32_t ulSize;
26 } DfmRetainedMemoryMetaData_t;
27 
28 static DfmResult_t prvRetainedMemoryWrite(uint32_t ulType, DfmEntryHandle_t xEntryHandle);
29 static DfmResult_t prvRetainedMemoryRead(uint32_t ulType, void* pvBuffer, uint32_t ulBufferSize);
30 
prvRetainedMemoryWrite(uint32_t ulType,DfmEntryHandle_t xEntryHandle)31 static DfmResult_t prvRetainedMemoryWrite(uint32_t ulType, DfmEntryHandle_t xEntryHandle)
32 {
33 	DfmRetainedMemoryMetaData_t xRetainedMemoryMetaData;
34 
35 	if (pxRetainedMemoryData == (void*) 0)
36 	{
37 		return DFM_FAIL;
38 	}
39 
40 	if (pxRetainedMemoryData->ulInitialized == 0)
41 	{
42 		return DFM_FAIL;
43 	}
44 
45 	if (xEntryHandle == 0)
46 	{
47 		return DFM_FAIL;
48 	}
49 
50 	xRetainedMemoryMetaData.ulType = ulType;
51 	if (xDfmEntryGetSize(xEntryHandle, &xRetainedMemoryMetaData.ulSize) == DFM_FAIL)
52 	{
53 		return DFM_FAIL;
54 	}
55 
56 	if (xRetainedMemoryMetaData.ulSize == 0)
57 	{
58 		return DFM_FAIL;
59 	}
60 
61 	/* Write the meta data */
62 	if (xDfmRetainedMemoryPortWrite((uint8_t*)&xRetainedMemoryMetaData, sizeof(DfmRetainedMemoryMetaData_t), pxRetainedMemoryData->ulWriteOffset) == DFM_FAIL)
63 	{
64 		return DFM_FAIL;
65 	}
66 
67 	pxRetainedMemoryData->ulWriteOffset += sizeof(DfmRetainedMemoryMetaData_t);
68 
69 	/* Write the data */
70 	if (xDfmRetainedMemoryPortWrite((uint8_t*)xEntryHandle, xRetainedMemoryMetaData.ulSize, pxRetainedMemoryData->ulWriteOffset) == DFM_FAIL)
71 	{
72 		return DFM_FAIL;
73 	}
74 
75 	pxRetainedMemoryData->ulWriteOffset += xRetainedMemoryMetaData.ulSize;
76 
77 	return DFM_SUCCESS;
78 }
79 
prvRetainedMemoryRead(uint32_t ulType,void * pvBuffer,uint32_t ulBufferSize)80 static DfmResult_t prvRetainedMemoryRead(uint32_t ulType, void* pvBuffer, uint32_t ulBufferSize)
81 {
82 	DfmRetainedMemoryMetaData_t xRetainedMemoryMetaData;
83 
84 	/* Read the metadata */
85 	if (xDfmRetainedMemoryPortRead(&xRetainedMemoryMetaData, sizeof(DfmRetainedMemoryMetaData_t), pxRetainedMemoryData->ulReadOffset) == DFM_FAIL)
86 	{
87 		return DFM_FAIL;
88 	}
89 
90 	if (xRetainedMemoryMetaData.ulType != ulType)
91 	{
92 		return DFM_FAIL;
93 	}
94 
95 	if (xRetainedMemoryMetaData.ulSize <= 0)
96 	{
97 		return DFM_FAIL;
98 	}
99 
100 	if (xRetainedMemoryMetaData.ulSize > ulBufferSize)
101 	{
102 		return DFM_FAIL;
103 	}
104 
105 	pxRetainedMemoryData->ulReadOffset += sizeof(DfmRetainedMemoryMetaData_t);
106 
107 	/* Read the data */
108 	if (xDfmRetainedMemoryPortRead(pvBuffer, xRetainedMemoryMetaData.ulSize, pxRetainedMemoryData->ulReadOffset) != 0)
109 	{
110 		return DFM_FAIL;
111 	}
112 
113 	pxRetainedMemoryData->ulReadOffset += xRetainedMemoryMetaData.ulSize;
114 
115 	return DFM_SUCCESS;
116 }
117 
xDfmRetainedMemoryInitialize(DfmRetainedMemoryData_t * pxBuffer)118 DfmResult_t xDfmRetainedMemoryInitialize(DfmRetainedMemoryData_t *pxBuffer)
119 {
120 	pxRetainedMemoryData = pxBuffer;
121 
122 	pxRetainedMemoryData->ulWriteOffset = 0;
123 	pxRetainedMemoryData->ulReadOffset = 0;
124 
125 	if (xDfmRetainedMemoryPortInitialize(&pxRetainedMemoryData->xRetainedMemoryPortData) == DFM_FAIL)
126 	{
127 		return DFM_FAIL;
128 	}
129 
130 	pxRetainedMemoryData->ulInitialized = 1;
131 
132 	return DFM_SUCCESS;
133 }
134 
xDfmRetainedMemoryWriteAlert(DfmEntryHandle_t xEntryHandle)135 DfmResult_t xDfmRetainedMemoryWriteAlert(DfmEntryHandle_t xEntryHandle)
136 {
137 	pxRetainedMemoryData->ulWriteOffset = 0;
138 	pxRetainedMemoryData->ulReadOffset = 0;
139 
140 	if (xDfmRetainedMemoryPortClear() == DFM_FAIL)
141 	{
142 		return DFM_FAIL;
143 	}
144 
145 	return prvRetainedMemoryWrite(DFM_RETAINED_MEMORY_TYPE_ALERT, xEntryHandle);
146 }
147 
xDfmRetainedMemoryReadAlert(void * pvBuffer,uint32_t ulBufferSize)148 DfmResult_t xDfmRetainedMemoryReadAlert(void* pvBuffer, uint32_t ulBufferSize)
149 {
150 	pxRetainedMemoryData->ulWriteOffset = 0;
151 	pxRetainedMemoryData->ulReadOffset = 0;
152 
153 	/* We only check this on Read Alert since Read Payload will not be called if there is no Alert */
154 	if (xDfmRetainedMemoryPortHasData() == 0)
155 	{
156 		return DFM_FAIL;
157 	}
158 
159 	return prvRetainedMemoryRead(DFM_RETAINED_MEMORY_TYPE_ALERT, pvBuffer, ulBufferSize);
160 }
161 
xDfmRetainedMemoryWritePayloadChunk(DfmEntryHandle_t xEntryHandle)162 DfmResult_t xDfmRetainedMemoryWritePayloadChunk(DfmEntryHandle_t xEntryHandle)
163 {
164 	return prvRetainedMemoryWrite(DFM_RETAINED_MEMORY_TYPE_PAYLOAD, xEntryHandle);
165 }
166 
xDfmRetainedMemoryReadPayloadChunk(char * szSessionId,uint32_t ulAlertId,void * pvBuffer,uint32_t ulBufferSize)167 DfmResult_t xDfmRetainedMemoryReadPayloadChunk(char* szSessionId, uint32_t ulAlertId, void* pvBuffer, uint32_t ulBufferSize)
168 {
169 	(void)szSessionId;
170 	(void)ulAlertId;
171 
172 	return prvRetainedMemoryRead(DFM_RETAINED_MEMORY_TYPE_PAYLOAD, pvBuffer, ulBufferSize);
173 }
174 
xDfmRetainedMemoryClear(void)175 DfmResult_t xDfmRetainedMemoryClear(void)
176 {
177 	return xDfmRetainedMemoryPortClear();
178 }
179 
180 #endif
181