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