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