1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
8 #ifndef __RTA_JUMP_CMD_H__
9 #define __RTA_JUMP_CMD_H__
11 extern enum rta_sec_era rta_sec_era
;
13 static const uint32_t jump_test_cond
[][2] = {
14 { NIFP
, JUMP_COND_NIFP
},
15 { NIP
, JUMP_COND_NIP
},
16 { NOP
, JUMP_COND_NOP
},
17 { NCP
, JUMP_COND_NCP
},
18 { CALM
, JUMP_COND_CALM
},
19 { SELF
, JUMP_COND_SELF
},
20 { SHRD
, JUMP_COND_SHRD
},
21 { JQP
, JUMP_COND_JQP
},
22 { MATH_Z
, JUMP_COND_MATH_Z
},
23 { MATH_N
, JUMP_COND_MATH_N
},
24 { MATH_NV
, JUMP_COND_MATH_NV
},
25 { MATH_C
, JUMP_COND_MATH_C
},
26 { PK_0
, JUMP_COND_PK_0
},
27 { PK_GCD_1
, JUMP_COND_PK_GCD_1
},
28 { PK_PRIME
, JUMP_COND_PK_PRIME
},
29 { CLASS1
, JUMP_CLASS_CLASS1
},
30 { CLASS2
, JUMP_CLASS_CLASS2
},
31 { BOTH
, JUMP_CLASS_BOTH
}
34 static const uint32_t jump_test_math_cond
[][2] = {
35 { MATH_Z
, JUMP_COND_MATH_Z
},
36 { MATH_N
, JUMP_COND_MATH_N
},
37 { MATH_NV
, JUMP_COND_MATH_NV
},
38 { MATH_C
, JUMP_COND_MATH_C
}
41 static const uint32_t jump_src_dst
[][2] = {
42 { MATH0
, JUMP_SRC_DST_MATH0
},
43 { MATH1
, JUMP_SRC_DST_MATH1
},
44 { MATH2
, JUMP_SRC_DST_MATH2
},
45 { MATH3
, JUMP_SRC_DST_MATH3
},
46 { DPOVRD
, JUMP_SRC_DST_DPOVRD
},
47 { SEQINSZ
, JUMP_SRC_DST_SEQINLEN
},
48 { SEQOUTSZ
, JUMP_SRC_DST_SEQOUTLEN
},
49 { VSEQINSZ
, JUMP_SRC_DST_VARSEQINLEN
},
50 { VSEQOUTSZ
, JUMP_SRC_DST_VARSEQOUTLEN
}
54 rta_jump(struct program
*program
, uint64_t address
,
55 enum rta_jump_type jump_type
,
56 enum rta_jump_cond test_type
,
57 uint32_t test_condition
, uint32_t src_dst
)
59 uint32_t opcode
= CMD_JUMP
;
60 unsigned int start_pc
= program
->current_pc
;
63 if (((jump_type
== GOSUB
) || (jump_type
== RETURN
)) &&
64 (rta_sec_era
< RTA_SEC_ERA_4
)) {
65 pr_err("JUMP: Jump type not supported by SEC Era %d\n",
66 USER_SEC_ERA(rta_sec_era
));
70 if (((jump_type
== LOCAL_JUMP_INC
) || (jump_type
== LOCAL_JUMP_DEC
)) &&
71 (rta_sec_era
<= RTA_SEC_ERA_5
)) {
72 pr_err("JUMP_INCDEC: Jump type not supported by SEC Era %d\n",
73 USER_SEC_ERA(rta_sec_era
));
80 * opcode |= JUMP_TYPE_LOCAL;
81 * JUMP_TYPE_LOCAL is 0
85 opcode
|= JUMP_TYPE_HALT
;
88 opcode
|= JUMP_TYPE_HALT_USER
;
91 opcode
|= JUMP_TYPE_NONLOCAL
;
94 opcode
|= JUMP_TYPE_GOSUB
;
97 opcode
|= JUMP_TYPE_RETURN
;
99 case (LOCAL_JUMP_INC
):
100 opcode
|= JUMP_TYPE_LOCAL_INC
;
102 case (LOCAL_JUMP_DEC
):
103 opcode
|= JUMP_TYPE_LOCAL_DEC
;
106 pr_err("JUMP: Invalid jump type. SEC Program Line: %d\n",
107 program
->current_pc
);
114 * opcode |= JUMP_TEST_ALL;
119 opcode
|= JUMP_TEST_INVALL
;
122 opcode
|= JUMP_TEST_ANY
;
125 opcode
|= JUMP_TEST_INVANY
;
128 pr_err("JUMP: test type not supported. SEC Program Line: %d\n",
129 program
->current_pc
);
133 /* write test condition field */
134 if ((jump_type
!= LOCAL_JUMP_INC
) && (jump_type
!= LOCAL_JUMP_DEC
)) {
135 __rta_map_flags(test_condition
, jump_test_cond
,
136 ARRAY_SIZE(jump_test_cond
), &opcode
);
140 ret
= __rta_map_opcode(src_dst
, jump_src_dst
,
141 ARRAY_SIZE(jump_src_dst
), &val
);
143 pr_err("JUMP_INCDEC: SRC_DST not supported. SEC PC: %d; Instr: %d\n",
145 program
->current_instruction
);
150 __rta_map_flags(test_condition
, jump_test_math_cond
,
151 ARRAY_SIZE(jump_test_math_cond
), &opcode
);
154 /* write local offset field for local jumps and user-defined halt */
155 if ((jump_type
== LOCAL_JUMP
) || (jump_type
== LOCAL_JUMP_INC
) ||
156 (jump_type
== LOCAL_JUMP_DEC
) || (jump_type
== GOSUB
) ||
157 (jump_type
== HALT_STATUS
))
158 opcode
|= (uint32_t)(address
& JUMP_OFFSET_MASK
);
160 __rta_out32(program
, opcode
);
161 program
->current_instruction
++;
163 if (jump_type
== FAR_JUMP
)
164 __rta_out64(program
, program
->ps
, address
);
166 return (int)start_pc
;
169 program
->first_error_pc
= start_pc
;
170 program
->current_instruction
++;
174 #endif /* __RTA_JUMP_CMD_H__ */