1
2
3
4
5
6
7#ifndef __RTA_LOAD_CMD_H__
8#define __RTA_LOAD_CMD_H__
9
10extern enum rta_sec_era rta_sec_era;
11
12
13static const uint32_t load_len_mask_allowed[] = {
14 0x000000ee,
15 0x000000fe,
16 0x000000fe,
17 0x000000fe,
18 0x000000fe,
19 0x000000fe,
20 0x000000fe,
21 0x000000fe,
22 0x000000fe,
23 0x000000fe
24};
25
26static const uint32_t load_off_mask_allowed[] = {
27 0x0000000f,
28 0x000000ff,
29 0x000000ff,
30 0x000000ff,
31 0x000000ff,
32 0x000000ff,
33 0x000000ff,
34 0x000000ff,
35 0x000000ff,
36 0x000000ff
37};
38
39#define IMM_MUST 0
40#define IMM_CAN 1
41#define IMM_NO 2
42#define IMM_DSNM 3
43
44enum e_lenoff {
45 LENOF_03,
46 LENOF_4,
47 LENOF_48,
48 LENOF_448,
49 LENOF_18,
50 LENOF_32,
51 LENOF_24,
52 LENOF_16,
53 LENOF_8,
54 LENOF_128,
55 LENOF_256,
56 DSNM
57};
58
59struct load_map {
60 uint32_t dst;
61 uint32_t dst_opcode;
62 enum e_lenoff len_off;
63 uint8_t imm_src;
64
65};
66
67static const struct load_map load_dst[] = {
68 { KEY1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
69 LENOF_4, IMM_MUST },
70 { KEY2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
71 LENOF_4, IMM_MUST },
72 { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG,
73 LENOF_448, IMM_MUST },
74 { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG,
75 LENOF_448, IMM_MUST },
76 { ICV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
77 LENOF_4, IMM_MUST },
78 { ICV2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
79 LENOF_4, IMM_MUST },
80 { CCTRL, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CHACTRL,
81 LENOF_4, IMM_MUST },
82 { DCTRL, LDST_CLASS_DECO | LDST_IMM | LDST_SRCDST_WORD_DECOCTRL,
83 DSNM, IMM_DSNM },
84 { ICTRL, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_IRQCTRL,
85 LENOF_4, IMM_MUST },
86 { DPOVRD, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_PCLOVRD,
87 LENOF_4, IMM_MUST },
88 { CLRW, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CLRW,
89 LENOF_4, IMM_MUST },
90 { AAD1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ,
91 LENOF_4, IMM_MUST },
92 { IV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ,
93 LENOF_4, IMM_MUST },
94 { ALTDS1, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ALTDS_CLASS1,
95 LENOF_448, IMM_MUST },
96 { PKASZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ,
97 LENOF_4, IMM_MUST, },
98 { PKBSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ,
99 LENOF_4, IMM_MUST },
100 { PKNSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ,
101 LENOF_4, IMM_MUST },
102 { PKESZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ,
103 LENOF_4, IMM_MUST },
104 { NFIFO, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_INFO_FIFO,
105 LENOF_48, IMM_MUST },
106 { IFIFO, LDST_SRCDST_BYTE_INFIFO, LENOF_18, IMM_MUST },
107 { OFIFO, LDST_SRCDST_BYTE_OUTFIFO, LENOF_18, IMM_MUST },
108 { MATH0, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0,
109 LENOF_32, IMM_CAN },
110 { MATH1, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1,
111 LENOF_24, IMM_CAN },
112 { MATH2, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2,
113 LENOF_16, IMM_CAN },
114 { MATH3, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3,
115 LENOF_8, IMM_CAN },
116 { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT,
117 LENOF_128, IMM_CAN },
118 { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT,
119 LENOF_128, IMM_CAN },
120 { KEY1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_KEY,
121 LENOF_32, IMM_CAN },
122 { KEY2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY,
123 LENOF_32, IMM_CAN },
124 { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF,
125 LENOF_256, IMM_NO },
126 { DPID, LDST_CLASS_DECO | LDST_SRCDST_WORD_PID,
127 LENOF_448, IMM_MUST },
128 { IDFNS, LDST_SRCDST_WORD_IFNSR, LENOF_18, IMM_MUST },
129 { ODFNS, LDST_SRCDST_WORD_OFNSR, LENOF_18, IMM_MUST },
130 { ALTSOURCE, LDST_SRCDST_BYTE_ALTSOURCE, LENOF_18, IMM_MUST },
131 { NFIFO_SZL, LDST_SRCDST_WORD_INFO_FIFO_SZL, LENOF_48, IMM_MUST },
132 { NFIFO_SZM, LDST_SRCDST_WORD_INFO_FIFO_SZM, LENOF_03, IMM_MUST },
133 { NFIFO_L, LDST_SRCDST_WORD_INFO_FIFO_L, LENOF_48, IMM_MUST },
134 { NFIFO_M, LDST_SRCDST_WORD_INFO_FIFO_M, LENOF_03, IMM_MUST },
135 { SZL, LDST_SRCDST_WORD_SZL, LENOF_48, IMM_MUST },
136 { SZM, LDST_SRCDST_WORD_SZM, LENOF_03, IMM_MUST }
137};
138
139
140
141
142
143static const unsigned int load_dst_sz[] = { 31, 34, 34, 40, 40,
144 40, 40, 40, 40, 40};
145
146static inline int
147load_check_len_offset(int pos, uint32_t length, uint32_t offset)
148{
149 if ((load_dst[pos].dst == DCTRL) &&
150 ((length & ~load_len_mask_allowed[rta_sec_era]) ||
151 (offset & ~load_off_mask_allowed[rta_sec_era])))
152 goto err;
153
154 switch (load_dst[pos].len_off) {
155 case (LENOF_03):
156 if ((length > 3) || (offset))
157 goto err;
158 break;
159 case (LENOF_4):
160 if ((length != 4) || (offset != 0))
161 goto err;
162 break;
163 case (LENOF_48):
164 if (!(((length == 4) && (offset == 0)) ||
165 ((length == 8) && (offset == 0))))
166 goto err;
167 break;
168 case (LENOF_448):
169 if (!(((length == 4) && (offset == 0)) ||
170 ((length == 4) && (offset == 4)) ||
171 ((length == 8) && (offset == 0))))
172 goto err;
173 break;
174 case (LENOF_18):
175 if ((length < 1) || (length > 8) || (offset != 0))
176 goto err;
177 break;
178 case (LENOF_32):
179 if ((length > 32) || (offset > 32) || ((offset + length) > 32))
180 goto err;
181 break;
182 case (LENOF_24):
183 if ((length > 24) || (offset > 24) || ((offset + length) > 24))
184 goto err;
185 break;
186 case (LENOF_16):
187 if ((length > 16) || (offset > 16) || ((offset + length) > 16))
188 goto err;
189 break;
190 case (LENOF_8):
191 if ((length > 8) || (offset > 8) || ((offset + length) > 8))
192 goto err;
193 break;
194 case (LENOF_128):
195 if ((length > 128) || (offset > 128) ||
196 ((offset + length) > 128))
197 goto err;
198 break;
199 case (LENOF_256):
200 if ((length < 1) || (length > 256) || ((length + offset) > 256))
201 goto err;
202 break;
203 case (DSNM):
204 break;
205 default:
206 goto err;
207 }
208
209 return 0;
210err:
211 return -EINVAL;
212}
213
214static inline int
215rta_load(struct program *program, uint64_t src, uint64_t dst,
216 uint32_t offset, uint32_t length, uint32_t flags)
217{
218 uint32_t opcode = 0;
219 int pos = -1, ret = -EINVAL;
220 unsigned int start_pc = program->current_pc, i;
221
222 if (flags & SEQ)
223 opcode = CMD_SEQ_LOAD;
224 else
225 opcode = CMD_LOAD;
226
227 if ((length & 0xffffff00) || (offset & 0xffffff00)) {
228 pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
229 goto err;
230 }
231
232 if (flags & SGF)
233 opcode |= LDST_SGF;
234 if (flags & VLF)
235 opcode |= LDST_VLF;
236
237
238 for (i = 0; i < load_dst_sz[rta_sec_era]; i++)
239 if (dst == load_dst[i].dst) {
240 pos = (int)i;
241 break;
242 }
243 if (-1 == pos) {
244 pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
245 program->current_pc);
246 goto err;
247 }
248
249 if (flags & IMMED) {
250 if (load_dst[pos].imm_src == IMM_NO) {
251 pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
252 program->current_pc);
253 goto err;
254 }
255 opcode |= LDST_IMM;
256 } else if (load_dst[pos].imm_src == IMM_MUST) {
257 pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
258 program->current_pc);
259 goto err;
260 }
261
262 ret = load_check_len_offset(pos, length, offset);
263 if (ret < 0) {
264 pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
265 program->current_pc);
266 goto err;
267 }
268
269 opcode |= load_dst[pos].dst_opcode;
270
271
272 if (dst == DESCBUF) {
273 opcode |= (length >> 2);
274 opcode |= ((offset >> 2) << LDST_OFFSET_SHIFT);
275 } else {
276 opcode |= length;
277 opcode |= (offset << LDST_OFFSET_SHIFT);
278 }
279
280 __rta_out32(program, opcode);
281 program->current_instruction++;
282
283
284 if (dst == DCTRL)
285 return (int)start_pc;
286
287
288
289
290
291
292
293 if (flags & IMMED)
294 __rta_inline_data(program, src, flags & __COPY_MASK, length);
295 else if (!(flags & SEQ))
296 __rta_out64(program, program->ps, src);
297
298 return (int)start_pc;
299
300 err:
301 program->first_error_pc = start_pc;
302 program->current_instruction++;
303 return ret;
304}
305
306#endif
307