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_JUMP_CMD_H__
8 #define __RTA_JUMP_CMD_H__
10 extern enum rta_sec_era rta_sec_era
;
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
}
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
}
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
}
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
)
58 uint32_t opcode
= CMD_JUMP
;
59 unsigned int start_pc
= program
->current_pc
;
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
));
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
));
79 * opcode |= JUMP_TYPE_LOCAL;
80 * JUMP_TYPE_LOCAL is 0
84 opcode
|= JUMP_TYPE_HALT
;
87 opcode
|= JUMP_TYPE_HALT_USER
;
90 opcode
|= JUMP_TYPE_NONLOCAL
;
93 opcode
|= JUMP_TYPE_GOSUB
;
96 opcode
|= JUMP_TYPE_RETURN
;
98 case (LOCAL_JUMP_INC
):
99 opcode
|= JUMP_TYPE_LOCAL_INC
;
101 case (LOCAL_JUMP_DEC
):
102 opcode
|= JUMP_TYPE_LOCAL_DEC
;
105 pr_err("JUMP: Invalid jump type. SEC Program Line: %d\n",
106 program
->current_pc
);
113 * opcode |= JUMP_TEST_ALL;
118 opcode
|= JUMP_TEST_INVALL
;
121 opcode
|= JUMP_TEST_ANY
;
124 opcode
|= JUMP_TEST_INVANY
;
127 pr_err("JUMP: test type not supported. SEC Program Line: %d\n",
128 program
->current_pc
);
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
);
139 ret
= __rta_map_opcode(src_dst
, jump_src_dst
,
140 ARRAY_SIZE(jump_src_dst
), &val
);
142 pr_err("JUMP_INCDEC: SRC_DST not supported. SEC PC: %d; Instr: %d\n",
144 program
->current_instruction
);
149 __rta_map_flags(test_condition
, jump_test_math_cond
,
150 ARRAY_SIZE(jump_test_math_cond
), &opcode
);
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
);
159 __rta_out32(program
, opcode
);
160 program
->current_instruction
++;
162 if (jump_type
== FAR_JUMP
)
163 __rta_out64(program
, program
->ps
, address
);
165 return (int)start_pc
;
168 program
->first_error_pc
= start_pc
;
169 program
->current_instruction
++;
173 #endif /* __RTA_JUMP_CMD_H__ */