xref: /dpdk/drivers/common/dpaax/caamflib/rta/jump_cmd.h (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016,2019 NXP
5  */
6 
7 #ifndef __RTA_JUMP_CMD_H__
8 #define __RTA_JUMP_CMD_H__
9 
10 extern enum rta_sec_era rta_sec_era;
11 
12 static const uint32_t jump_test_cond[][2] = {
13 	{ NIFP,     JUMP_COND_NIFP },
14 	{ NIP,      JUMP_COND_NIP },
15 	{ NOP,      JUMP_COND_NOP },
16 	{ NCP,      JUMP_COND_NCP },
17 	{ CALM,     JUMP_COND_CALM },
18 	{ SELF,     JUMP_COND_SELF },
19 	{ SHRD,     JUMP_COND_SHRD },
20 	{ JQP,      JUMP_COND_JQP },
21 	{ MATH_Z,   JUMP_COND_MATH_Z },
22 	{ MATH_N,   JUMP_COND_MATH_N },
23 	{ MATH_NV,  JUMP_COND_MATH_NV },
24 	{ MATH_C,   JUMP_COND_MATH_C },
25 	{ PK_0,     JUMP_COND_PK_0 },
26 	{ PK_GCD_1, JUMP_COND_PK_GCD_1 },
27 	{ PK_PRIME, JUMP_COND_PK_PRIME },
28 	{ CLASS1,   JUMP_CLASS_CLASS1 },
29 	{ CLASS2,   JUMP_CLASS_CLASS2 },
30 	{ BOTH,     JUMP_CLASS_BOTH }
31 };
32 
33 static const uint32_t jump_test_math_cond[][2] = {
34 	{ MATH_Z,   JUMP_COND_MATH_Z },
35 	{ MATH_N,   JUMP_COND_MATH_N },
36 	{ MATH_NV,  JUMP_COND_MATH_NV },
37 	{ MATH_C,   JUMP_COND_MATH_C }
38 };
39 
40 static const uint32_t jump_src_dst[][2] = {
41 	{ MATH0,     JUMP_SRC_DST_MATH0 },
42 	{ MATH1,     JUMP_SRC_DST_MATH1 },
43 	{ MATH2,     JUMP_SRC_DST_MATH2 },
44 	{ MATH3,     JUMP_SRC_DST_MATH3 },
45 	{ DPOVRD,    JUMP_SRC_DST_DPOVRD },
46 	{ SEQINSZ,   JUMP_SRC_DST_SEQINLEN },
47 	{ SEQOUTSZ,  JUMP_SRC_DST_SEQOUTLEN },
48 	{ VSEQINSZ,  JUMP_SRC_DST_VARSEQINLEN },
49 	{ VSEQOUTSZ, JUMP_SRC_DST_VARSEQOUTLEN }
50 };
51 
52 static inline int
53 rta_jump(struct program *program, uint64_t address,
54 	 enum rta_jump_type jump_type,
55 	 enum rta_jump_cond test_type,
56 	 uint32_t test_condition, uint32_t src_dst)
57 {
58 	uint32_t opcode = CMD_JUMP;
59 	unsigned int start_pc = program->current_pc;
60 	int ret = -EINVAL;
61 
62 	if (((jump_type == GOSUB) || (jump_type == RETURN)) &&
63 	    (rta_sec_era < RTA_SEC_ERA_4)) {
64 		pr_err("JUMP: Jump type not supported by SEC Era %d\n",
65 		       USER_SEC_ERA(rta_sec_era));
66 		goto err;
67 	}
68 
69 	if (((jump_type == LOCAL_JUMP_INC) || (jump_type == LOCAL_JUMP_DEC)) &&
70 	    (rta_sec_era <= RTA_SEC_ERA_5)) {
71 		pr_err("JUMP_INCDEC: Jump type not supported by SEC Era %d\n",
72 		       USER_SEC_ERA(rta_sec_era));
73 		goto err;
74 	}
75 
76 	switch (jump_type) {
77 	case (LOCAL_JUMP):
78 		/*
79 		 * opcode |= JUMP_TYPE_LOCAL;
80 		 * JUMP_TYPE_LOCAL is 0
81 		 */
82 		break;
83 	case (HALT):
84 		opcode |= JUMP_TYPE_HALT;
85 		break;
86 	case (HALT_STATUS):
87 		opcode |= JUMP_TYPE_HALT_USER;
88 		break;
89 	case (FAR_JUMP):
90 		opcode |= JUMP_TYPE_NONLOCAL;
91 		break;
92 	case (GOSUB):
93 		opcode |= JUMP_TYPE_GOSUB;
94 		break;
95 	case (RETURN):
96 		opcode |= JUMP_TYPE_RETURN;
97 		break;
98 	case (LOCAL_JUMP_INC):
99 		opcode |= JUMP_TYPE_LOCAL_INC;
100 		break;
101 	case (LOCAL_JUMP_DEC):
102 		opcode |= JUMP_TYPE_LOCAL_DEC;
103 		break;
104 	default:
105 		pr_err("JUMP: Invalid jump type. SEC Program Line: %d\n",
106 		       program->current_pc);
107 		goto err;
108 	}
109 
110 	switch (test_type) {
111 	case (ALL_TRUE):
112 		/*
113 		 * opcode |= JUMP_TEST_ALL;
114 		 * JUMP_TEST_ALL is 0
115 		 */
116 		break;
117 	case (ALL_FALSE):
118 		opcode |= JUMP_TEST_INVALL;
119 		break;
120 	case (ANY_TRUE):
121 		opcode |= JUMP_TEST_ANY;
122 		break;
123 	case (ANY_FALSE):
124 		opcode |= JUMP_TEST_INVANY;
125 		break;
126 	default:
127 		pr_err("JUMP: test type not supported. SEC Program Line: %d\n",
128 		       program->current_pc);
129 		goto err;
130 	}
131 
132 	/* write test condition field */
133 	if ((jump_type != LOCAL_JUMP_INC) && (jump_type != LOCAL_JUMP_DEC)) {
134 		__rta_map_flags(test_condition, jump_test_cond,
135 				ARRAY_SIZE(jump_test_cond), &opcode);
136 	} else {
137 		uint32_t val = 0;
138 
139 		ret = __rta_map_opcode(src_dst, jump_src_dst,
140 				       ARRAY_SIZE(jump_src_dst), &val);
141 		if (ret < 0) {
142 			pr_err("JUMP_INCDEC: SRC_DST not supported. SEC PC: %d; Instr: %d\n",
143 			       program->current_pc,
144 			       program->current_instruction);
145 			goto err;
146 		}
147 		opcode |= val;
148 
149 		__rta_map_flags(test_condition, jump_test_math_cond,
150 				ARRAY_SIZE(jump_test_math_cond), &opcode);
151 	}
152 
153 	/* write local offset field for local jumps and user-defined halt */
154 	if ((jump_type == LOCAL_JUMP) || (jump_type == LOCAL_JUMP_INC) ||
155 	    (jump_type == LOCAL_JUMP_DEC) || (jump_type == GOSUB) ||
156 	    (jump_type == HALT_STATUS))
157 		opcode |= (uint32_t)(address & JUMP_OFFSET_MASK);
158 
159 	__rta_out32(program, opcode);
160 	program->current_instruction++;
161 
162 	if (jump_type == FAR_JUMP)
163 		__rta_out64(program, program->ps, address);
164 
165 	return (int)start_pc;
166 
167  err:
168 	program->first_error_pc = start_pc;
169 	program->current_instruction++;
170 	return ret;
171 }
172 
173 #endif /* __RTA_JUMP_CMD_H__ */
174