1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
4 * Copyright 2016,2019 NXP
7 #ifndef __RTA_MATH_CMD_H__
8 #define __RTA_MATH_CMD_H__
10 extern enum rta_sec_era rta_sec_era;
12 static const uint32_t math_op1[][2] = {
13 /*1*/ { MATH0, MATH_SRC0_REG0 },
14 { MATH1, MATH_SRC0_REG1 },
15 { MATH2, MATH_SRC0_REG2 },
16 { MATH3, MATH_SRC0_REG3 },
17 { SEQINSZ, MATH_SRC0_SEQINLEN },
18 { SEQOUTSZ, MATH_SRC0_SEQOUTLEN },
19 { VSEQINSZ, MATH_SRC0_VARSEQINLEN },
20 { VSEQOUTSZ, MATH_SRC0_VARSEQOUTLEN },
21 { ZERO, MATH_SRC0_ZERO },
22 /*10*/ { NONE, 0 }, /* dummy value */
23 { DPOVRD, MATH_SRC0_DPOVRD },
24 { ONE, MATH_SRC0_ONE }
28 * Allowed MATH op1 sources for each SEC Era.
29 * Values represent the number of entries from math_op1[] that are supported.
31 static const unsigned int math_op1_sz[] = {10, 10, 12, 12, 12, 12,
34 static const uint32_t math_op2[][2] = {
35 /*1*/ { MATH0, MATH_SRC1_REG0 },
36 { MATH1, MATH_SRC1_REG1 },
37 { MATH2, MATH_SRC1_REG2 },
38 { MATH3, MATH_SRC1_REG3 },
39 { ABD, MATH_SRC1_INFIFO },
40 { OFIFO, MATH_SRC1_OUTFIFO },
41 { ONE, MATH_SRC1_ONE },
42 /*8*/ { NONE, 0 }, /* dummy value */
43 { JOBSRC, MATH_SRC1_JOBSOURCE },
44 { DPOVRD, MATH_SRC1_DPOVRD },
45 { VSEQINSZ, MATH_SRC1_VARSEQINLEN },
46 { VSEQOUTSZ, MATH_SRC1_VARSEQOUTLEN },
47 /*13*/ { ZERO, MATH_SRC1_ZERO }
51 * Allowed MATH op2 sources for each SEC Era.
52 * Values represent the number of entries from math_op2[] that are supported.
54 static const unsigned int math_op2_sz[] = {8, 9, 13, 13, 13, 13, 13, 13,
57 static const uint32_t math_result[][2] = {
58 /*1*/ { MATH0, MATH_DEST_REG0 },
59 { MATH1, MATH_DEST_REG1 },
60 { MATH2, MATH_DEST_REG2 },
61 { MATH3, MATH_DEST_REG3 },
62 { SEQINSZ, MATH_DEST_SEQINLEN },
63 { SEQOUTSZ, MATH_DEST_SEQOUTLEN },
64 { VSEQINSZ, MATH_DEST_VARSEQINLEN },
65 { VSEQOUTSZ, MATH_DEST_VARSEQOUTLEN },
66 /*9*/ { NONE, MATH_DEST_NONE },
67 { DPOVRD, MATH_DEST_DPOVRD }
71 * Allowed MATH result destinations for each SEC Era.
72 * Values represent the number of entries from math_result[] that are
75 static const unsigned int math_result_sz[] = {9, 9, 10, 10, 10, 10, 10, 10,
79 rta_math(struct program *program, uint64_t operand1,
80 uint32_t op, uint64_t operand2, uint32_t result,
81 int length, uint32_t options)
83 uint32_t opcode = CMD_MATH;
86 unsigned int start_pc = program->current_pc;
88 if (((op == MATH_FUN_BSWAP) && (rta_sec_era < RTA_SEC_ERA_4)) ||
89 ((op == MATH_FUN_ZBYT) && (rta_sec_era < RTA_SEC_ERA_2))) {
90 pr_err("MATH: operation not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
91 USER_SEC_ERA(rta_sec_era), program->current_pc,
92 program->current_instruction);
97 if (rta_sec_era < RTA_SEC_ERA_7) {
98 pr_err("MATH: operation not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
99 USER_SEC_ERA(rta_sec_era), program->current_pc,
100 program->current_instruction);
104 if ((options & IFB) ||
105 (!(options & IMMED) && !(options & IMMED2)) ||
106 ((options & IMMED) && (options & IMMED2))) {
107 pr_err("MATH: SWP - invalid configuration. SEC PC: %d; Instr: %d\n",
109 program->current_instruction);
115 * SHLD operation is different from others and we
116 * assume that we can have _NONE as first operand
117 * or _SEQINSZ as second operand
119 if ((op != MATH_FUN_SHLD) && ((operand1 == NONE) ||
120 (operand2 == SEQINSZ))) {
121 pr_err("MATH: Invalid operand. SEC PC: %d; Instr: %d\n",
122 program->current_pc, program->current_instruction);
127 * We first check if it is unary operation. In that
128 * case second operand must be _NONE
130 if (((op == MATH_FUN_ZBYT) || (op == MATH_FUN_BSWAP)) &&
131 (operand2 != NONE)) {
132 pr_err("MATH: Invalid operand2. SEC PC: %d; Instr: %d\n",
133 program->current_pc, program->current_instruction);
137 /* Write first operand field */
138 if (options & IMMED) {
139 opcode |= MATH_SRC0_IMM;
141 ret = __rta_map_opcode((uint32_t)operand1, math_op1,
142 math_op1_sz[rta_sec_era], &val);
144 pr_err("MATH: operand1 not supported. SEC PC: %d; Instr: %d\n",
146 program->current_instruction);
152 /* Write second operand field */
153 if (options & IMMED2) {
154 opcode |= MATH_SRC1_IMM;
156 ret = __rta_map_opcode((uint32_t)operand2, math_op2,
157 math_op2_sz[rta_sec_era], &val);
159 pr_err("MATH: operand2 not supported. SEC PC: %d; Instr: %d\n",
161 program->current_instruction);
167 /* Write result field */
168 ret = __rta_map_opcode(result, math_result, math_result_sz[rta_sec_era],
171 pr_err("MATH: result not supported. SEC PC: %d; Instr: %d\n",
172 program->current_pc, program->current_instruction);
178 * as we encode operations with their "real" values, we do not
179 * to translate but we do need to validate the value
182 /*Binary operators */
184 case (MATH_FUN_ADDC):
186 case (MATH_FUN_SUBB):
190 case (MATH_FUN_LSHIFT):
191 case (MATH_FUN_RSHIFT):
192 case (MATH_FUN_SHLD):
193 /* Unary operators */
194 case (MATH_FUN_ZBYT):
195 case (MATH_FUN_BSWAP):
199 pr_err("MATH: operator is not supported. SEC PC: %d; Instr: %d\n",
200 program->current_pc, program->current_instruction);
205 opcode |= (options & ~(IMMED | IMMED2));
210 opcode |= MATH_LEN_1BYTE;
213 opcode |= MATH_LEN_2BYTE;
216 opcode |= MATH_LEN_4BYTE;
219 opcode |= MATH_LEN_8BYTE;
222 pr_err("MATH: length is not supported. SEC PC: %d; Instr: %d\n",
223 program->current_pc, program->current_instruction);
228 __rta_out32(program, opcode);
229 program->current_instruction++;
231 /* Write immediate value */
232 if ((options & IMMED) && !(options & IMMED2)) {
233 __rta_out64(program, (length > 4) && !(options & IFB),
235 } else if ((options & IMMED2) && !(options & IMMED)) {
236 __rta_out64(program, (length > 4) && !(options & IFB),
238 } else if ((options & IMMED) && (options & IMMED2)) {
239 __rta_out32(program, lower_32_bits(operand1));
240 __rta_out32(program, lower_32_bits(operand2));
243 return (int)start_pc;
246 program->first_error_pc = start_pc;
247 program->current_instruction++;
252 rta_mathi(struct program *program, uint64_t operand,
253 uint32_t op, uint8_t imm, uint32_t result,
254 int length, uint32_t options)
256 uint32_t opcode = CMD_MATHI;
259 unsigned int start_pc = program->current_pc;
261 if (rta_sec_era < RTA_SEC_ERA_6) {
262 pr_err("MATHI: Command not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
263 USER_SEC_ERA(rta_sec_era), program->current_pc,
264 program->current_instruction);
268 if (((op == MATH_FUN_FBYT) && (options & SSEL))) {
269 pr_err("MATHI: Illegal combination - FBYT and SSEL. SEC PC: %d; Instr: %d\n",
270 program->current_pc, program->current_instruction);
274 if ((options & SWP) && (rta_sec_era < RTA_SEC_ERA_7)) {
275 pr_err("MATHI: SWP not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
276 USER_SEC_ERA(rta_sec_era), program->current_pc,
277 program->current_instruction);
281 /* Write first operand field */
282 if (!(options & SSEL))
283 ret = __rta_map_opcode((uint32_t)operand, math_op1,
284 math_op1_sz[rta_sec_era], &val);
286 ret = __rta_map_opcode((uint32_t)operand, math_op2,
287 math_op2_sz[rta_sec_era], &val);
289 pr_err("MATHI: operand not supported. SEC PC: %d; Instr: %d\n",
290 program->current_pc, program->current_instruction);
294 if (!(options & SSEL))
297 opcode |= (val << (MATHI_SRC1_SHIFT - MATH_SRC1_SHIFT));
299 /* Write second operand field */
300 opcode |= (imm << MATHI_IMM_SHIFT);
302 /* Write result field */
303 ret = __rta_map_opcode(result, math_result, math_result_sz[rta_sec_era],
306 pr_err("MATHI: result not supported. SEC PC: %d; Instr: %d\n",
307 program->current_pc, program->current_instruction);
310 opcode |= (val << (MATHI_DEST_SHIFT - MATH_DEST_SHIFT));
313 * as we encode operations with their "real" values, we do not have to
314 * translate but we do need to validate the value
318 case (MATH_FUN_ADDC):
320 case (MATH_FUN_SUBB):
324 case (MATH_FUN_LSHIFT):
325 case (MATH_FUN_RSHIFT):
326 case (MATH_FUN_FBYT):
330 pr_err("MATHI: operator not supported. SEC PC: %d; Instr: %d\n",
331 program->current_pc, program->current_instruction);
341 opcode |= MATH_LEN_1BYTE;
344 opcode |= MATH_LEN_2BYTE;
347 opcode |= MATH_LEN_4BYTE;
350 opcode |= MATH_LEN_8BYTE;
353 pr_err("MATHI: length %d not supported. SEC PC: %d; Instr: %d\n",
354 length, program->current_pc,
355 program->current_instruction);
360 __rta_out32(program, opcode);
361 program->current_instruction++;
363 return (int)start_pc;
366 program->first_error_pc = start_pc;
367 program->current_instruction++;
371 #endif /* __RTA_MATH_CMD_H__ */