blob: d3ce3c607eaf08ce91f52b34da0db1dc7697eddb [file] [log] [blame]
developer02e65912023-08-17 16:33:10 +08001/* eip202_rd_format.c
2 *
3 * EIP-202 Ring Control Driver Library
4 * Result Descriptor Internal interface
5 *
6 * This module contains the EIP-202 Result Descriptor specific functionality
7 */
8
9/* -------------------------------------------------------------------------- */
10/* */
11/* Module : ddk197 */
12/* Version : 5.6.1 */
13/* Configuration : DDK-197-GPL */
14/* */
15/* Date : 2022-Dec-16 */
16/* */
17/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
18/* */
19/* This program is free software: you can redistribute it and/or modify */
20/* it under the terms of the GNU General Public License as published by */
21/* the Free Software Foundation, either version 2 of the License, or */
22/* any later version. */
23/* */
24/* This program is distributed in the hope that it will be useful, */
25/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
26/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
27/* GNU General Public License for more details. */
28/* */
29/* You should have received a copy of the GNU General Public License */
30/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
31/* -------------------------------------------------------------------------- */
32
33/*----------------------------------------------------------------------------
34 * This module implements (provides) the following interface(s):
35 */
36
37#include "eip202_rd_format.h"
38
39// Descriptor I/O Driver Library API implementation
40#include "eip202_rdr.h" // EIP202_ARM_CommandDescriptor_t
41
42
43/*----------------------------------------------------------------------------
44 * This module uses (requires) the following interface(s):
45 */
46
47// Default configuration
48#include "c_eip202_ring.h"
49
50// EIP-202 Ring Control Driver Library Internal interfaces
51#include "eip202_ring_internal.h"
52
53// Driver Framework Basic Definitions API
54#include "basic_defs.h" // bool, uint32_t, uint8_t
55
56// Driver Framework DMA Resource API
57#include "dmares_types.h" // DMAResource_Handle_t
58#include "dmares_rw.h" // DMAResource_Write/Read
59
60// Standard IOToken API
61#include "iotoken.h"
62
63
64/*----------------------------------------------------------------------------
65 * Definitions and macros
66 */
67
68
69/*----------------------------------------------------------------------------
70 * Local variables
71 */
72
73
74/*----------------------------------------------------------------------------
75 * EIP202_RD_Make_ControlWord
76 */
77uint32_t
78EIP202_RD_Make_ControlWord(
79 const uint8_t ExpectedResultWordCount,
80 const uint32_t PrepSegmentByteCount,
81 const bool fFirstSegment,
82 const bool fLastSegment)
83{
84 uint32_t Value = 0;
85
86 if(fFirstSegment)
87 Value |= BIT_23;
88
89 if(fLastSegment)
90 Value |= BIT_22;
91
92 Value |= ((((uint32_t)ExpectedResultWordCount) & MASK_8_BITS) << 24);
93 Value |= ((((uint32_t)PrepSegmentByteCount) & MASK_20_BITS));
94
95 return Value;
96}
97
98
99/*----------------------------------------------------------------------------
100 * EIP202_Prepared_Write
101 */
102void
103EIP202_Prepared_Write(
104 DMAResource_Handle_t Handle,
105 const unsigned int WordOffset,
106 const EIP202_ARM_PreparedDescriptor_t * const Descr_p)
107{
108#ifdef EIP202_64BIT_DEVICE
109 // Write Control Word
110 DMAResource_Write32(Handle, WordOffset, Descr_p->PrepControlWord);
111
112 // Do not support lengths greater than 20 bit.
113 DMAResource_Write32(Handle, WordOffset + 1, 0);
114
115 // Write Destination Packet Data address
116 DMAResource_Write32(Handle, WordOffset + 2, Descr_p->DstPacketAddr.Addr);
117 DMAResource_Write32(Handle, WordOffset + 3, Descr_p->DstPacketAddr.UpperAddr);
118
119#else
120 // Write Control Word
121 DMAResource_Write32(Handle, WordOffset, Descr_p->PrepControlWord);
122
123 // Write Destination Packet Data address
124 DMAResource_Write32(Handle, WordOffset + 1, Descr_p->DstPacketAddr.Addr);
125#endif
126
127 return;
128}
129
130
131/*----------------------------------------------------------------------------
132 * EIP202_ReadDescriptor
133 */
134void
135EIP202_ReadDescriptor(
136 EIP202_ARM_ResultDescriptor_t * const Descr_p,
137 const DMAResource_Handle_t Handle,
138 const unsigned int WordOffset,
139 const unsigned int DscrOffsWordCount,
140 const unsigned int TokenOffsWordCount,
141 bool * const fLastSegment,
142 bool * const fFirstSegment)
143{
144 unsigned int OutTokenWordOffset;
145
146#ifdef EIP202_64BIT_DEVICE
147 // Word 0 - Control Word
148 Descr_p->ProcControlWord = DMAResource_Read32(Handle, WordOffset);
149
150 // Word 1 - extended length, not read.
151
152 // Word 2 & 3 - Destination Packet Data Buffer Address
153 Descr_p->DstPacketAddr.Addr = DMAResource_Read32(Handle, WordOffset + 2);
154 Descr_p->DstPacketAddr.UpperAddr = DMAResource_Read32(Handle, WordOffset + 3);
155
156 OutTokenWordOffset = WordOffset + TokenOffsWordCount;
157#else // EIP202_64BIT_DEVICE
158 // Word 0 - Control Word
159 Descr_p->ProcControlWord = DMAResource_Read32(Handle, WordOffset);
160
161 // Word 1 - Destination Packet Data Buffer Address
162 Descr_p->DstPacketAddr.Addr = DMAResource_Read32(Handle, WordOffset + 1);
163
164 OutTokenWordOffset = WordOffset + 2;
165#endif // !EIP202_64BIT_DEVICE
166
167 if (Descr_p->Token_p == NULL)
168 {
169 *fLastSegment = false;
170 *fFirstSegment = false;
171 return; // Fatal error
172 }
173
174 // Read token data
175 {
176 unsigned int i;
177
178#ifdef EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
179 for (i = 0; i < IOToken_OutWordCount_Get(); i++)
180 if (i != (unsigned int)IOToken_OutMarkOffset_Get())
181 Descr_p->Token_p[i] = DMAResource_Read32(
182 Handle,
183 OutTokenWordOffset + i);
184#else
185 for (i = 0; i < IOToken_OutWordCount_Get(); i++)
186 Descr_p->Token_p[i] = DMAResource_Read32(
187 Handle,
188 OutTokenWordOffset + i);
189#endif
190 }
191
192 // Check if this descriptor is for the last segment
193 if((Descr_p->ProcControlWord & BIT_22) != 0)
194 *fLastSegment = true; // Processed packet
195 else
196 *fLastSegment = false;
197
198 // Check if this descriptor is for the first segment
199 if((Descr_p->ProcControlWord & BIT_23) != 0)
200 *fFirstSegment = true; // New packet descriptor chain detected
201 else
202 *fFirstSegment = false;
203
204 IDENTIFIER_NOT_USED(DscrOffsWordCount);
205
206 return;
207}
208
209
210/*----------------------------------------------------------------------------
211 * EIP202_ClearDescriptor
212 */
213void
214EIP202_ClearDescriptor(
215 EIP202_ARM_ResultDescriptor_t * const Descr_p,
216 const DMAResource_Handle_t Handle,
217 const unsigned int WordOffset,
218 const unsigned int TokenOffsWordCount,
219 const unsigned int DscrWordCount)
220{
221 IDENTIFIER_NOT_USED(Descr_p);
222
223#if defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
224
225 DMAResource_Write32(Handle, WordOffset + DscrWordCount - 1, 0);
226 IDENTIFIER_NOT_USED(TokenOffsWordCount);
227
228#elif defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS)
229
230 IDENTIFIER_NOT_USED(DscrWordCount);
231
232 DMAResource_Write32(Handle,
233 WordOffset + TokenOffsWordCount +
234 IOToken_OutMarkOffset_Get(),
235 0);
236#else
237 IDENTIFIER_NOT_USED(Handle);
238 IDENTIFIER_NOT_USED(WordOffset);
239 IDENTIFIER_NOT_USED(DscrWordCount);
240 IDENTIFIER_NOT_USED(TokenOffsWordCount);
241#endif // !EIP202_RDR_OWNERSHIP_WORD_ENABLE
242}
243
244
245/*----------------------------------------------------------------------------
246 * EIP202_RD_Read_ControlWord
247 */
248void
249EIP202_RD_Read_ControlWord(
250 const uint32_t ControlWord,
251 uint32_t * TokenData_p,
252 EIP202_RDR_Result_Control_t * const RDControl_p,
253 EIP202_RDR_Result_Token_t * const ResToken_p)
254{
255 RDControl_p->ProcSegmentByteCount = (ControlWord & MASK_20_BITS);
256 RDControl_p->ProcResultWordCount = ((ControlWord >> 24) & MASK_8_BITS);
257
258 // Fill in EIP202_RDR_Result_Control_t
259 if((ControlWord & BIT_20) != 0)
260 RDControl_p->fDscrOverflow = true;
261 else
262 RDControl_p->fDscrOverflow = false;
263
264 if((ControlWord & BIT_21) != 0)
265 RDControl_p->fBufferOverflow = true;
266 else
267 RDControl_p->fBufferOverflow = false;
268
269 if((ControlWord & BIT_22) != 0)
270 RDControl_p->fLastSegment = true;
271 else
272 RDControl_p->fLastSegment = false;
273
274 if((ControlWord & BIT_23) != 0)
275 RDControl_p->fFirstSegment = true;
276 else
277 RDControl_p->fFirstSegment = false;
278
279 IDENTIFIER_NOT_USED(TokenData_p);
280 IDENTIFIER_NOT_USED(ResToken_p);
281}
282
283
284/*----------------------------------------------------------------------------
285 * EIP202_RD_Read_BypassData
286 */
287void
288EIP202_RD_Read_BypassData(
289 const uint32_t * BypassData_p,
290 const uint8_t BypassWordCount,
291 EIP202_RDR_BypassData_t * const BD_p)
292{
293 if (BypassWordCount == 1)
294 {
295 BD_p->Fail.ErrorFlags = BypassData_p[0] & MASK_2_BITS;
296 }
297 else if (BypassWordCount == 2)
298 {
299 BD_p->Pass.TOS_TC = BypassData_p[0] & MASK_8_BITS;
300 BD_p->Pass.fDF = ((BypassData_p[0] & BIT_8) != 0);
301 BD_p->Pass.NextHeaderOffset = (BypassData_p[0] >> 8) & MASK_16_BITS;
302 BD_p->Pass.HdrProcCtxRef = BypassData_p[1];
303 }
304 else
305 {
306 IDENTIFIER_NOT_USED(BypassData_p);
307 IDENTIFIER_NOT_USED(BypassWordCount);
308 IDENTIFIER_NOT_USED(BD_p);
309 }
310}
311
312
313/* end of file eip202_rd_format.c */