]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/dpdk/drivers/common/dpaax/caamflib/rta/move_cmd.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / drivers / common / dpaax / caamflib / rta / move_cmd.h
CommitLineData
11fdf7f2
TL
1/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2 *
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
f67539c2 4 * Copyright 2016,2019 NXP
11fdf7f2
TL
5 */
6
7#ifndef __RTA_MOVE_CMD_H__
8#define __RTA_MOVE_CMD_H__
9
10#define MOVE_SET_AUX_SRC 0x01
11#define MOVE_SET_AUX_DST 0x02
12#define MOVE_SET_AUX_LS 0x03
13#define MOVE_SET_LEN_16b 0x04
14
15#define MOVE_SET_AUX_MATH 0x10
16#define MOVE_SET_AUX_MATH_SRC (MOVE_SET_AUX_SRC | MOVE_SET_AUX_MATH)
17#define MOVE_SET_AUX_MATH_DST (MOVE_SET_AUX_DST | MOVE_SET_AUX_MATH)
18
19#define MASK_16b 0xFF
20
21/* MOVE command type */
22#define __MOVE 1
23#define __MOVEB 2
24#define __MOVEDW 3
25
26extern enum rta_sec_era rta_sec_era;
27
28static const uint32_t move_src_table[][2] = {
29/*1*/ { CONTEXT1, MOVE_SRC_CLASS1CTX },
30 { CONTEXT2, MOVE_SRC_CLASS2CTX },
31 { OFIFO, MOVE_SRC_OUTFIFO },
32 { DESCBUF, MOVE_SRC_DESCBUF },
33 { MATH0, MOVE_SRC_MATH0 },
34 { MATH1, MOVE_SRC_MATH1 },
35 { MATH2, MOVE_SRC_MATH2 },
36 { MATH3, MOVE_SRC_MATH3 },
37/*9*/ { IFIFOABD, MOVE_SRC_INFIFO },
38 { IFIFOAB1, MOVE_SRC_INFIFO_CL | MOVE_AUX_LS },
39 { IFIFOAB2, MOVE_SRC_INFIFO_CL },
40/*12*/ { ABD, MOVE_SRC_INFIFO_NO_NFIFO },
41 { AB1, MOVE_SRC_INFIFO_NO_NFIFO | MOVE_AUX_LS },
42 { AB2, MOVE_SRC_INFIFO_NO_NFIFO | MOVE_AUX_MS }
43};
44
45/* Allowed MOVE / MOVE_LEN sources for each SEC Era.
46 * Values represent the number of entries from move_src_table[] that are
47 * supported.
48 */
f67539c2
TL
49static const unsigned int move_src_table_sz[] = {9, 11, 14, 14, 14, 14, 14, 14,
50 14, 14};
11fdf7f2
TL
51
52static const uint32_t move_dst_table[][2] = {
53/*1*/ { CONTEXT1, MOVE_DEST_CLASS1CTX },
54 { CONTEXT2, MOVE_DEST_CLASS2CTX },
55 { OFIFO, MOVE_DEST_OUTFIFO },
56 { DESCBUF, MOVE_DEST_DESCBUF },
57 { MATH0, MOVE_DEST_MATH0 },
58 { MATH1, MOVE_DEST_MATH1 },
59 { MATH2, MOVE_DEST_MATH2 },
60 { MATH3, MOVE_DEST_MATH3 },
61 { IFIFOAB1, MOVE_DEST_CLASS1INFIFO },
62 { IFIFOAB2, MOVE_DEST_CLASS2INFIFO },
63 { PKA, MOVE_DEST_PK_A },
64 { KEY1, MOVE_DEST_CLASS1KEY },
65 { KEY2, MOVE_DEST_CLASS2KEY },
66/*14*/ { IFIFO, MOVE_DEST_INFIFO },
67/*15*/ { ALTSOURCE, MOVE_DEST_ALTSOURCE}
68};
69
70/* Allowed MOVE / MOVE_LEN destinations for each SEC Era.
71 * Values represent the number of entries from move_dst_table[] that are
72 * supported.
73 */
74static const
f67539c2 75unsigned int move_dst_table_sz[] = {13, 14, 14, 15, 15, 15, 15, 15, 15, 15};
11fdf7f2
TL
76
77static inline int
78set_move_offset(struct program *program __maybe_unused,
79 uint64_t src, uint16_t src_offset,
80 uint64_t dst, uint16_t dst_offset,
81 uint16_t *offset, uint16_t *opt);
82
83static inline int
84math_offset(uint16_t offset);
85
86static inline int
87rta_move(struct program *program, int cmd_type, uint64_t src,
88 uint16_t src_offset, uint64_t dst,
89 uint16_t dst_offset, uint32_t length, uint32_t flags)
90{
91 uint32_t opcode = 0;
92 uint16_t offset = 0, opt = 0;
93 uint32_t val = 0;
94 int ret = -EINVAL;
95 bool is_move_len_cmd = false;
96 unsigned int start_pc = program->current_pc;
97
98 if ((rta_sec_era < RTA_SEC_ERA_7) && (cmd_type != __MOVE)) {
99 pr_err("MOVE: MOVEB / MOVEDW not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
100 USER_SEC_ERA(rta_sec_era), program->current_pc,
101 program->current_instruction);
102 goto err;
103 }
104
105 /* write command type */
106 if (cmd_type == __MOVEB) {
107 opcode = CMD_MOVEB;
108 } else if (cmd_type == __MOVEDW) {
109 opcode = CMD_MOVEDW;
110 } else if (!(flags & IMMED)) {
111 if (rta_sec_era < RTA_SEC_ERA_3) {
112 pr_err("MOVE: MOVE_LEN not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
113 USER_SEC_ERA(rta_sec_era), program->current_pc,
114 program->current_instruction);
115 goto err;
116 }
117
118 if ((length != MATH0) && (length != MATH1) &&
119 (length != MATH2) && (length != MATH3)) {
120 pr_err("MOVE: MOVE_LEN length must be MATH[0-3]. SEC PC: %d; Instr: %d\n",
121 program->current_pc,
122 program->current_instruction);
123 goto err;
124 }
125
126 opcode = CMD_MOVE_LEN;
127 is_move_len_cmd = true;
128 } else {
129 opcode = CMD_MOVE;
130 }
131
132 /* write offset first, to check for invalid combinations or incorrect
133 * offset values sooner; decide which offset should be here
134 * (src or dst)
135 */
136 ret = set_move_offset(program, src, src_offset, dst, dst_offset,
137 &offset, &opt);
138 if (ret < 0)
139 goto err;
140
141 opcode |= (offset << MOVE_OFFSET_SHIFT) & MOVE_OFFSET_MASK;
142
143 /* set AUX field if required */
144 if (opt == MOVE_SET_AUX_SRC) {
145 opcode |= ((src_offset / 16) << MOVE_AUX_SHIFT) & MOVE_AUX_MASK;
146 } else if (opt == MOVE_SET_AUX_DST) {
147 opcode |= ((dst_offset / 16) << MOVE_AUX_SHIFT) & MOVE_AUX_MASK;
148 } else if (opt == MOVE_SET_AUX_LS) {
149 opcode |= MOVE_AUX_LS;
150 } else if (opt & MOVE_SET_AUX_MATH) {
151 if (opt & MOVE_SET_AUX_SRC)
152 offset = src_offset;
153 else
154 offset = dst_offset;
155
156 if (rta_sec_era < RTA_SEC_ERA_6) {
157 if (offset)
158 pr_debug("MOVE: Offset not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
159 USER_SEC_ERA(rta_sec_era),
160 program->current_pc,
161 program->current_instruction);
162 /* nothing to do for offset = 0 */
163 } else {
164 ret = math_offset(offset);
165 if (ret < 0) {
166 pr_err("MOVE: Invalid offset in MATH register. SEC PC: %d; Instr: %d\n",
167 program->current_pc,
168 program->current_instruction);
169 goto err;
170 }
171
172 opcode |= (uint32_t)ret;
173 }
174 }
175
176 /* write source field */
177 ret = __rta_map_opcode((uint32_t)src, move_src_table,
178 move_src_table_sz[rta_sec_era], &val);
179 if (ret < 0) {
180 pr_err("MOVE: Invalid SRC. SEC PC: %d; Instr: %d\n",
181 program->current_pc, program->current_instruction);
182 goto err;
183 }
184 opcode |= val;
185
186 /* write destination field */
187 ret = __rta_map_opcode((uint32_t)dst, move_dst_table,
188 move_dst_table_sz[rta_sec_era], &val);
189 if (ret < 0) {
190 pr_err("MOVE: Invalid DST. SEC PC: %d; Instr: %d\n",
191 program->current_pc, program->current_instruction);
192 goto err;
193 }
194 opcode |= val;
195
196 /* write flags */
197 if (flags & (FLUSH1 | FLUSH2))
198 opcode |= MOVE_AUX_MS;
199 if (flags & (LAST2 | LAST1))
200 opcode |= MOVE_AUX_LS;
201 if (flags & WAITCOMP)
202 opcode |= MOVE_WAITCOMP;
203
204 if (!is_move_len_cmd) {
205 /* write length */
206 if (opt == MOVE_SET_LEN_16b)
207 opcode |= (length & (MOVE_OFFSET_MASK | MOVE_LEN_MASK));
208 else
209 opcode |= (length & MOVE_LEN_MASK);
210 } else {
211 /* write mrsel */
212 switch (length) {
213 case (MATH0):
214 /*
215 * opcode |= MOVELEN_MRSEL_MATH0;
216 * MOVELEN_MRSEL_MATH0 is 0
217 */
218 break;
219 case (MATH1):
220 opcode |= MOVELEN_MRSEL_MATH1;
221 break;
222 case (MATH2):
223 opcode |= MOVELEN_MRSEL_MATH2;
224 break;
225 case (MATH3):
226 opcode |= MOVELEN_MRSEL_MATH3;
227 break;
228 }
229
230 /* write size */
231 if (rta_sec_era >= RTA_SEC_ERA_7) {
232 if (flags & SIZE_WORD)
233 opcode |= MOVELEN_SIZE_WORD;
234 else if (flags & SIZE_BYTE)
235 opcode |= MOVELEN_SIZE_BYTE;
236 else if (flags & SIZE_DWORD)
237 opcode |= MOVELEN_SIZE_DWORD;
238 }
239 }
240
241 __rta_out32(program, opcode);
242 program->current_instruction++;
243
244 return (int)start_pc;
245
246 err:
247 program->first_error_pc = start_pc;
248 program->current_instruction++;
249 return ret;
250}
251
252static inline int
253set_move_offset(struct program *program __maybe_unused,
254 uint64_t src, uint16_t src_offset,
255 uint64_t dst, uint16_t dst_offset,
256 uint16_t *offset, uint16_t *opt)
257{
258 switch (src) {
259 case (CONTEXT1):
260 case (CONTEXT2):
261 if (dst == DESCBUF) {
262 *opt = MOVE_SET_AUX_SRC;
263 *offset = dst_offset;
264 } else if ((dst == KEY1) || (dst == KEY2)) {
265 if ((src_offset) && (dst_offset)) {
266 pr_err("MOVE: Bad offset. SEC PC: %d; Instr: %d\n",
267 program->current_pc,
268 program->current_instruction);
269 goto err;
270 }
271 if (dst_offset) {
272 *opt = MOVE_SET_AUX_LS;
273 *offset = dst_offset;
274 } else {
275 *offset = src_offset;
276 }
277 } else {
278 if ((dst == MATH0) || (dst == MATH1) ||
279 (dst == MATH2) || (dst == MATH3)) {
280 *opt = MOVE_SET_AUX_MATH_DST;
281 } else if (((dst == OFIFO) || (dst == ALTSOURCE)) &&
282 (src_offset % 4)) {
283 pr_err("MOVE: Bad offset alignment. SEC PC: %d; Instr: %d\n",
284 program->current_pc,
285 program->current_instruction);
286 goto err;
287 }
288
289 *offset = src_offset;
290 }
291 break;
292
293 case (OFIFO):
294 if (dst == OFIFO) {
295 pr_err("MOVE: Invalid DST. SEC PC: %d; Instr: %d\n",
296 program->current_pc,
297 program->current_instruction);
298 goto err;
299 }
300 if (((dst == IFIFOAB1) || (dst == IFIFOAB2) ||
301 (dst == IFIFO) || (dst == PKA)) &&
302 (src_offset || dst_offset)) {
303 pr_err("MOVE: Offset should be zero. SEC PC: %d; Instr: %d\n",
304 program->current_pc,
305 program->current_instruction);
306 goto err;
307 }
308 *offset = dst_offset;
309 break;
310
311 case (DESCBUF):
312 if ((dst == CONTEXT1) || (dst == CONTEXT2)) {
313 *opt = MOVE_SET_AUX_DST;
314 } else if ((dst == MATH0) || (dst == MATH1) ||
315 (dst == MATH2) || (dst == MATH3)) {
316 *opt = MOVE_SET_AUX_MATH_DST;
317 } else if (dst == DESCBUF) {
318 pr_err("MOVE: Invalid DST. SEC PC: %d; Instr: %d\n",
319 program->current_pc,
320 program->current_instruction);
321 goto err;
322 } else if (((dst == OFIFO) || (dst == ALTSOURCE)) &&
323 (src_offset % 4)) {
324 pr_err("MOVE: Invalid offset alignment. SEC PC: %d; Instr %d\n",
325 program->current_pc,
326 program->current_instruction);
327 goto err;
328 }
329
330 *offset = src_offset;
331 break;
332
333 case (MATH0):
334 case (MATH1):
335 case (MATH2):
336 case (MATH3):
337 if ((dst == OFIFO) || (dst == ALTSOURCE)) {
338 if (src_offset % 4) {
339 pr_err("MOVE: Bad offset alignment. SEC PC: %d; Instr: %d\n",
340 program->current_pc,
341 program->current_instruction);
342 goto err;
343 }
344 *offset = src_offset;
345 } else if ((dst == IFIFOAB1) || (dst == IFIFOAB2) ||
346 (dst == IFIFO) || (dst == PKA)) {
347 *offset = src_offset;
348 } else {
349 *offset = dst_offset;
350
351 /*
352 * This condition is basically the negation of:
353 * dst in { CONTEXT[1-2], MATH[0-3] }
354 */
355 if ((dst != KEY1) && (dst != KEY2))
356 *opt = MOVE_SET_AUX_MATH_SRC;
357 }
358 break;
359
360 case (IFIFOABD):
361 case (IFIFOAB1):
362 case (IFIFOAB2):
363 case (ABD):
364 case (AB1):
365 case (AB2):
366 if ((dst == IFIFOAB1) || (dst == IFIFOAB2) ||
367 (dst == IFIFO) || (dst == PKA) || (dst == ALTSOURCE)) {
368 pr_err("MOVE: Bad DST. SEC PC: %d; Instr: %d\n",
369 program->current_pc,
370 program->current_instruction);
371 goto err;
372 } else {
373 if (dst == OFIFO) {
374 *opt = MOVE_SET_LEN_16b;
375 } else {
376 if (dst_offset % 4) {
377 pr_err("MOVE: Bad offset alignment. SEC PC: %d; Instr: %d\n",
378 program->current_pc,
379 program->current_instruction);
380 goto err;
381 }
382 *offset = dst_offset;
383 }
384 }
385 break;
386 default:
387 break;
388 }
389
390 return 0;
391 err:
392 return -EINVAL;
393}
394
395static inline int
396math_offset(uint16_t offset)
397{
398 switch (offset) {
399 case 0:
400 return 0;
401 case 4:
402 return MOVE_AUX_LS;
403 case 6:
404 return MOVE_AUX_MS;
405 case 7:
406 return MOVE_AUX_LS | MOVE_AUX_MS;
407 }
408
409 return -EINVAL;
410}
411
412#endif /* __RTA_MOVE_CMD_H__ */