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