Branch data Line data Source code
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_FIFO_LOAD_STORE_CMD_H__
8 : : #define __RTA_FIFO_LOAD_STORE_CMD_H__
9 : :
10 : : extern enum rta_sec_era rta_sec_era;
11 : :
12 : : static const uint32_t fifo_load_table[][2] = {
13 : : /*1*/ { PKA0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A0 },
14 : : { PKA1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A1 },
15 : : { PKA2, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A2 },
16 : : { PKA3, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A3 },
17 : : { PKB0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B0 },
18 : : { PKB1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B1 },
19 : : { PKB2, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B2 },
20 : : { PKB3, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B3 },
21 : : { PKA, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A },
22 : : { PKB, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B },
23 : : { PKN, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_N },
24 : : { SKIP, FIFOLD_CLASS_SKIP },
25 : : { MSG1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG },
26 : : { MSG2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG },
27 : : { MSGOUTSNOOP, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG1OUT2 },
28 : : { MSGINSNOOP, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG },
29 : : { IV1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_IV },
30 : : { IV2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_IV },
31 : : { AAD1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_AAD },
32 : : { ICV1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_ICV },
33 : : { ICV2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_ICV },
34 : : { BIT_DATA, FIFOLD_TYPE_BITDATA },
35 : : /*23*/ { IFIFO, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_NOINFOFIFO }
36 : : };
37 : :
38 : : /*
39 : : * Allowed FIFO_LOAD input data types for each SEC Era.
40 : : * Values represent the number of entries from fifo_load_table[] that are
41 : : * supported.
42 : : */
43 : : static const unsigned int fifo_load_table_sz[] = {22, 22, 23, 23,
44 : : 23, 23, 23, 23,
45 : : 23, 23};
46 : :
47 : : static inline int
48 : 0 : rta_fifo_load(struct program *program, uint32_t src,
49 : : uint64_t loc, uint32_t length, uint32_t flags)
50 : : {
51 : : uint32_t opcode = 0;
52 : : uint32_t ext_length = 0, val = 0;
53 : : int ret = -EINVAL;
54 : : bool is_seq_cmd = false;
55 : 0 : unsigned int start_pc = program->current_pc;
56 : :
57 : : /* write command type field */
58 [ # # ]: 0 : if (flags & SEQ) {
59 : : opcode = CMD_SEQ_FIFO_LOAD;
60 : : is_seq_cmd = true;
61 : : } else {
62 : : opcode = CMD_FIFO_LOAD;
63 : : }
64 : :
65 : : /* Parameters checking */
66 : : if (is_seq_cmd) {
67 [ # # ]: 0 : if ((flags & IMMED) || (flags & SGF)) {
68 : 0 : pr_err("SEQ FIFO LOAD: Invalid command\n");
69 : 0 : goto err;
70 : : }
71 [ # # # # : 0 : if ((flags & VLF) && ((flags & EXT) || (length >> 16))) {
# # ]
72 : 0 : pr_err("SEQ FIFO LOAD: Invalid usage of VLF\n");
73 : 0 : goto err;
74 : : }
75 : : } else {
76 [ # # ]: 0 : if (src == SKIP) {
77 : 0 : pr_err("FIFO LOAD: Invalid src\n");
78 : 0 : goto err;
79 : : }
80 [ # # ]: 0 : if ((flags & AIDF) || (flags & VLF)) {
81 : 0 : pr_err("FIFO LOAD: Invalid command\n");
82 : 0 : goto err;
83 : : }
84 [ # # ]: 0 : if ((flags & IMMED) && (flags & SGF)) {
85 : 0 : pr_err("FIFO LOAD: Invalid usage of SGF and IMM\n");
86 : 0 : goto err;
87 : : }
88 [ # # # # : 0 : if ((flags & IMMED) && ((flags & EXT) || (length >> 16))) {
# # ]
89 : 0 : pr_err("FIFO LOAD: Invalid usage of EXT and IMM\n");
90 : 0 : goto err;
91 : : }
92 : : }
93 : :
94 : : /* write input data type field */
95 : 0 : ret = __rta_map_opcode(src, fifo_load_table,
96 : 0 : fifo_load_table_sz[rta_sec_era], &val);
97 : : if (ret < 0) {
98 : 0 : pr_err("FIFO LOAD: Source value is not supported. SEC Program Line: %d\n",
99 : : program->current_pc);
100 : 0 : goto err;
101 : : }
102 : 0 : opcode |= val;
103 : :
104 [ # # ]: 0 : if (flags & CLASS1)
105 : 0 : opcode |= FIFOLD_CLASS_CLASS1;
106 [ # # ]: 0 : if (flags & CLASS2)
107 : 0 : opcode |= FIFOLD_CLASS_CLASS2;
108 [ # # ]: 0 : if (flags & BOTH)
109 : 0 : opcode |= FIFOLD_CLASS_BOTH;
110 : :
111 : : /* write fields: SGF|VLF, IMM, [LC1, LC2, F1] */
112 [ # # ]: 0 : if (flags & FLUSH1)
113 : 0 : opcode |= FIFOLD_TYPE_FLUSH1;
114 [ # # ]: 0 : if (flags & LAST1)
115 : 0 : opcode |= FIFOLD_TYPE_LAST1;
116 [ # # ]: 0 : if (flags & LAST2)
117 : 0 : opcode |= FIFOLD_TYPE_LAST2;
118 [ # # ]: 0 : if (!is_seq_cmd) {
119 [ # # ]: 0 : if (flags & SGF)
120 : 0 : opcode |= FIFOLDST_SGF;
121 [ # # ]: 0 : if (flags & IMMED)
122 : 0 : opcode |= FIFOLD_IMM;
123 : : } else {
124 [ # # ]: 0 : if (flags & VLF)
125 : 0 : opcode |= FIFOLDST_VLF;
126 [ # # ]: 0 : if (flags & AIDF)
127 : 0 : opcode |= FIFOLD_AIDF;
128 : : }
129 : :
130 : : /*
131 : : * Verify if extended length is required. In case of BITDATA, calculate
132 : : * number of full bytes and additional valid bits.
133 : : */
134 [ # # # # ]: 0 : if ((flags & EXT) || (length >> 16)) {
135 : 0 : opcode |= FIFOLDST_EXT;
136 [ # # ]: 0 : if (src == BIT_DATA) {
137 : 0 : ext_length = (length / 8);
138 : 0 : length = (length % 8);
139 : : } else {
140 : : ext_length = length;
141 : : length = 0;
142 : : }
143 : : }
144 : 0 : opcode |= (uint16_t) length;
145 : :
146 : 0 : __rta_out32(program, opcode);
147 : 0 : program->current_instruction++;
148 : :
149 : : /* write pointer or immediate data field */
150 [ # # ]: 0 : if (flags & IMMED)
151 : 0 : __rta_inline_data(program, loc, flags & __COPY_MASK, length);
152 [ # # ]: 0 : else if (!is_seq_cmd)
153 : 0 : __rta_out64(program, program->ps, loc);
154 : :
155 : : /* write extended length field */
156 [ # # ]: 0 : if (opcode & FIFOLDST_EXT)
157 : 0 : __rta_out32(program, ext_length);
158 : :
159 : 0 : return (int)start_pc;
160 : :
161 : 0 : err:
162 : 0 : program->first_error_pc = start_pc;
163 : 0 : program->current_instruction++;
164 : 0 : return ret;
165 : : }
166 : :
167 : : static const uint32_t fifo_store_table[][2] = {
168 : : /*1*/ { PKA0, FIFOST_TYPE_PKHA_A0 },
169 : : { PKA1, FIFOST_TYPE_PKHA_A1 },
170 : : { PKA2, FIFOST_TYPE_PKHA_A2 },
171 : : { PKA3, FIFOST_TYPE_PKHA_A3 },
172 : : { PKB0, FIFOST_TYPE_PKHA_B0 },
173 : : { PKB1, FIFOST_TYPE_PKHA_B1 },
174 : : { PKB2, FIFOST_TYPE_PKHA_B2 },
175 : : { PKB3, FIFOST_TYPE_PKHA_B3 },
176 : : { PKA, FIFOST_TYPE_PKHA_A },
177 : : { PKB, FIFOST_TYPE_PKHA_B },
178 : : { PKN, FIFOST_TYPE_PKHA_N },
179 : : { PKE, FIFOST_TYPE_PKHA_E_JKEK },
180 : : { RNG, FIFOST_TYPE_RNGSTORE },
181 : : { RNGOFIFO, FIFOST_TYPE_RNGFIFO },
182 : : { AFHA_SBOX, FIFOST_TYPE_AF_SBOX_JKEK },
183 : : { MDHA_SPLIT_KEY, FIFOST_CLASS_CLASS2KEY | FIFOST_TYPE_SPLIT_KEK },
184 : : { MSG, FIFOST_TYPE_MESSAGE_DATA },
185 : : { KEY1, FIFOST_CLASS_CLASS1KEY | FIFOST_TYPE_KEY_KEK },
186 : : { KEY2, FIFOST_CLASS_CLASS2KEY | FIFOST_TYPE_KEY_KEK },
187 : : { OFIFO, FIFOST_TYPE_OUTFIFO_KEK},
188 : : { SKIP, FIFOST_TYPE_SKIP },
189 : : /*22*/ { METADATA, FIFOST_TYPE_METADATA},
190 : : { MSG_CKSUM, FIFOST_TYPE_MESSAGE_DATA2 }
191 : : };
192 : :
193 : : /*
194 : : * Allowed FIFO_STORE output data types for each SEC Era.
195 : : * Values represent the number of entries from fifo_store_table[] that are
196 : : * supported.
197 : : */
198 : : static const unsigned int fifo_store_table_sz[] = {21, 21, 21, 21,
199 : : 22, 22, 22, 23,
200 : : 23, 23};
201 : :
202 : : static inline int
203 : 0 : rta_fifo_store(struct program *program, uint32_t src,
204 : : uint32_t encrypt_flags, uint64_t dst,
205 : : uint32_t length, uint32_t flags)
206 : : {
207 : : uint32_t opcode = 0;
208 : : uint32_t val = 0;
209 : : int ret = -EINVAL;
210 : : bool is_seq_cmd = false;
211 : 0 : unsigned int start_pc = program->current_pc;
212 : :
213 : : /* write command type field */
214 [ # # ]: 0 : if (flags & SEQ) {
215 : : opcode = CMD_SEQ_FIFO_STORE;
216 : : is_seq_cmd = true;
217 : : } else {
218 : : opcode = CMD_FIFO_STORE;
219 : : }
220 : :
221 : : /* Parameter checking */
222 : : if (is_seq_cmd) {
223 [ # # # # : 0 : if ((flags & VLF) && ((length >> 16) || (flags & EXT))) {
# # ]
224 : 0 : pr_err("SEQ FIFO STORE: Invalid usage of VLF\n");
225 : 0 : goto err;
226 : : }
227 [ # # ]: 0 : if (dst) {
228 : 0 : pr_err("SEQ FIFO STORE: Invalid command\n");
229 : 0 : goto err;
230 : : }
231 [ # # # # ]: 0 : if ((src == METADATA) && (flags & (CONT | EXT))) {
232 : 0 : pr_err("SEQ FIFO STORE: Invalid flags\n");
233 : 0 : goto err;
234 : : }
235 : : } else {
236 [ # # # # : 0 : if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) ||
# # # # ]
237 : : (src == METADATA)) {
238 : 0 : pr_err("FIFO STORE: Invalid destination\n");
239 : 0 : goto err;
240 : : }
241 : : }
242 : :
243 : : /* write output data type field */
244 : 0 : ret = __rta_map_opcode(src, fifo_store_table,
245 : 0 : fifo_store_table_sz[rta_sec_era], &val);
246 : : if (ret < 0) {
247 : 0 : pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n",
248 : : program->current_pc);
249 : 0 : goto err;
250 : : }
251 : 0 : opcode |= val;
252 : :
253 [ # # ]: 0 : if (encrypt_flags & TK)
254 : 0 : opcode |= (0x1 << FIFOST_TYPE_SHIFT);
255 [ # # ]: 0 : if (encrypt_flags & EKT) {
256 : : opcode |= (0x10 << FIFOST_TYPE_SHIFT);
257 : 0 : opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT);
258 : : }
259 : :
260 : : /* write flags fields */
261 [ # # ]: 0 : if (flags & CONT)
262 : 0 : opcode |= FIFOST_CONT;
263 [ # # # # ]: 0 : if ((flags & VLF) && (is_seq_cmd))
264 : 0 : opcode |= FIFOLDST_VLF;
265 [ # # # # ]: 0 : if ((flags & SGF) && (!is_seq_cmd))
266 : 0 : opcode |= FIFOLDST_SGF;
267 [ # # ]: 0 : if (flags & CLASS1)
268 : 0 : opcode |= FIFOST_CLASS_CLASS1KEY;
269 [ # # ]: 0 : if (flags & CLASS2)
270 : 0 : opcode |= FIFOST_CLASS_CLASS2KEY;
271 [ # # ]: 0 : if (flags & BOTH)
272 : 0 : opcode |= FIFOST_CLASS_BOTH;
273 : :
274 : : /* Verify if extended length is required */
275 [ # # # # ]: 0 : if ((length >> 16) || (flags & EXT))
276 : 0 : opcode |= FIFOLDST_EXT;
277 : : else
278 : 0 : opcode |= (uint16_t) length;
279 : :
280 : 0 : __rta_out32(program, opcode);
281 : 0 : program->current_instruction++;
282 : :
283 : : /* write pointer field */
284 [ # # ]: 0 : if ((!is_seq_cmd) && (dst))
285 : 0 : __rta_out64(program, program->ps, dst);
286 : :
287 : : /* write extended length field */
288 [ # # ]: 0 : if (opcode & FIFOLDST_EXT)
289 : 0 : __rta_out32(program, length);
290 : :
291 : 0 : return (int)start_pc;
292 : :
293 : 0 : err:
294 : 0 : program->first_error_pc = start_pc;
295 : 0 : program->current_instruction++;
296 : 0 : return ret;
297 : : }
298 : :
299 : : #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */
|