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_SEC_RUN_TIME_ASM_H__
8 : : #define __RTA_SEC_RUN_TIME_ASM_H__
9 : :
10 : : #include "desc.h"
11 : :
12 : : /* hw/compat.h is not delivered in kernel */
13 : : #ifndef __KERNEL__
14 : : #include "compat.h"
15 : : #endif
16 : :
17 : : /**
18 : : * enum rta_sec_era - SEC HW block revisions supported by the RTA library
19 : : * @RTA_SEC_ERA_1: SEC Era 1
20 : : * @RTA_SEC_ERA_2: SEC Era 2
21 : : * @RTA_SEC_ERA_3: SEC Era 3
22 : : * @RTA_SEC_ERA_4: SEC Era 4
23 : : * @RTA_SEC_ERA_5: SEC Era 5
24 : : * @RTA_SEC_ERA_6: SEC Era 6
25 : : * @RTA_SEC_ERA_7: SEC Era 7
26 : : * @RTA_SEC_ERA_8: SEC Era 8
27 : : * @MAX_SEC_ERA: maximum SEC HW block revision supported by RTA library
28 : : */
29 : : enum rta_sec_era {
30 : : RTA_SEC_ERA_1,
31 : : RTA_SEC_ERA_2,
32 : : RTA_SEC_ERA_3,
33 : : RTA_SEC_ERA_4,
34 : : RTA_SEC_ERA_5,
35 : : RTA_SEC_ERA_6,
36 : : RTA_SEC_ERA_7,
37 : : RTA_SEC_ERA_8,
38 : : RTA_SEC_ERA_9,
39 : : RTA_SEC_ERA_10,
40 : : MAX_SEC_ERA = RTA_SEC_ERA_10
41 : : };
42 : :
43 : : /**
44 : : * DEFAULT_SEC_ERA - the default value for the SEC era in case the user provides
45 : : * an unsupported value.
46 : : */
47 : : #define DEFAULT_SEC_ERA MAX_SEC_ERA
48 : :
49 : : /**
50 : : * USER_SEC_ERA - translates the SEC Era from internal to user representation.
51 : : * @sec_era: SEC Era in internal (library) representation
52 : : */
53 : : #define USER_SEC_ERA(sec_era) (sec_era + 1)
54 : :
55 : : /**
56 : : * INTL_SEC_ERA - translates the SEC Era from user representation to internal.
57 : : * @sec_era: SEC Era in user representation
58 : : */
59 : : #define INTL_SEC_ERA(sec_era) (sec_era - 1)
60 : :
61 : : /**
62 : : * enum rta_jump_type - Types of action taken by JUMP command
63 : : * @LOCAL_JUMP: conditional jump to an offset within the descriptor buffer
64 : : * @FAR_JUMP: conditional jump to a location outside the descriptor buffer,
65 : : * indicated by the POINTER field after the JUMP command.
66 : : * @HALT: conditional halt - stop the execution of the current descriptor and
67 : : * writes PKHA / Math condition bits as status / error code.
68 : : * @HALT_STATUS: conditional halt with user-specified status - stop the
69 : : * execution of the current descriptor and writes the value of
70 : : * "LOCAL OFFSET" JUMP field as status / error code.
71 : : * @GOSUB: conditional subroutine call - similar to @LOCAL_JUMP, but also saves
72 : : * return address in the Return Address register; subroutine calls
73 : : * cannot be nested.
74 : : * @RETURN: conditional subroutine return - similar to @LOCAL_JUMP, but the
75 : : * offset is taken from the Return Address register.
76 : : * @LOCAL_JUMP_INC: similar to @LOCAL_JUMP, but increment the register specified
77 : : * in "SRC_DST" JUMP field before evaluating the jump
78 : : * condition.
79 : : * @LOCAL_JUMP_DEC: similar to @LOCAL_JUMP, but decrement the register specified
80 : : * in "SRC_DST" JUMP field before evaluating the jump
81 : : * condition.
82 : : */
83 : : enum rta_jump_type {
84 : : LOCAL_JUMP,
85 : : FAR_JUMP,
86 : : HALT,
87 : : HALT_STATUS,
88 : : GOSUB,
89 : : RETURN,
90 : : LOCAL_JUMP_INC,
91 : : LOCAL_JUMP_DEC
92 : : };
93 : :
94 : : /**
95 : : * enum rta_jump_cond - How test conditions are evaluated by JUMP command
96 : : * @ALL_TRUE: perform action if ALL selected conditions are true
97 : : * @ALL_FALSE: perform action if ALL selected conditions are false
98 : : * @ANY_TRUE: perform action if ANY of the selected conditions is true
99 : : * @ANY_FALSE: perform action if ANY of the selected conditions is false
100 : : */
101 : : enum rta_jump_cond {
102 : : ALL_TRUE,
103 : : ALL_FALSE,
104 : : ANY_TRUE,
105 : : ANY_FALSE
106 : : };
107 : :
108 : : /**
109 : : * enum rta_share_type - Types of sharing for JOB_HDR and SHR_HDR commands
110 : : * @SHR_NEVER: nothing is shared; descriptors can execute in parallel (i.e. no
111 : : * dependencies are allowed between them).
112 : : * @SHR_WAIT: shared descriptor and keys are shared once the descriptor sets
113 : : * "OK to share" in DECO Control Register (DCTRL).
114 : : * @SHR_SERIAL: shared descriptor and keys are shared once the descriptor has
115 : : * completed.
116 : : * @SHR_ALWAYS: shared descriptor is shared anytime after the descriptor is
117 : : * loaded.
118 : : * @SHR_DEFER: valid only for JOB_HDR; sharing type is the one specified
119 : : * in the shared descriptor associated with the job descriptor.
120 : : */
121 : : enum rta_share_type {
122 : : SHR_NEVER,
123 : : SHR_WAIT,
124 : : SHR_SERIAL,
125 : : SHR_ALWAYS,
126 : : SHR_DEFER
127 : : };
128 : :
129 : : /**
130 : : * enum rta_data_type - Indicates how is the data provided and how to include it
131 : : * in the descriptor.
132 : : * @RTA_DATA_PTR: Data is in memory and accessed by reference; data address is a
133 : : * physical (bus) address.
134 : : * @RTA_DATA_IMM: Data is inlined in descriptor and accessed as immediate data;
135 : : * data address is a virtual address.
136 : : * @RTA_DATA_IMM_DMA: (AIOP only) Data is inlined in descriptor and accessed as
137 : : * immediate data; data address is a physical (bus) address
138 : : * in external memory and CDMA is programmed to transfer the
139 : : * data into descriptor buffer being built in Workspace Area.
140 : : */
141 : : enum rta_data_type {
142 : : RTA_DATA_PTR = 1,
143 : : RTA_DATA_IMM,
144 : : RTA_DATA_IMM_DMA
145 : : };
146 : :
147 : : /* Registers definitions */
148 : : enum rta_regs {
149 : : /* CCB Registers */
150 : : CONTEXT1 = 1,
151 : : CONTEXT2,
152 : : KEY1,
153 : : KEY2,
154 : : KEY1SZ,
155 : : KEY2SZ,
156 : : ICV1SZ,
157 : : ICV2SZ,
158 : : DATA1SZ,
159 : : DATA2SZ,
160 : : ALTDS1,
161 : : IV1SZ,
162 : : AAD1SZ,
163 : : MODE1,
164 : : MODE2,
165 : : CCTRL,
166 : : DCTRL,
167 : : ICTRL,
168 : : CLRW,
169 : : CSTAT,
170 : : IFIFO,
171 : : NFIFO,
172 : : OFIFO,
173 : : PKASZ,
174 : : PKBSZ,
175 : : PKNSZ,
176 : : PKESZ,
177 : : /* DECO Registers */
178 : : MATH0,
179 : : MATH1,
180 : : MATH2,
181 : : MATH3,
182 : : DESCBUF,
183 : : JOBDESCBUF,
184 : : SHAREDESCBUF,
185 : : DPOVRD,
186 : : DJQDA,
187 : : DSTAT,
188 : : DPID,
189 : : DJQCTRL,
190 : : ALTSOURCE,
191 : : SEQINSZ,
192 : : SEQOUTSZ,
193 : : VSEQINSZ,
194 : : VSEQOUTSZ,
195 : : /* PKHA Registers */
196 : : PKA,
197 : : PKN,
198 : : PKA0,
199 : : PKA1,
200 : : PKA2,
201 : : PKA3,
202 : : PKB,
203 : : PKB0,
204 : : PKB1,
205 : : PKB2,
206 : : PKB3,
207 : : PKE,
208 : : /* Pseudo registers */
209 : : AB1,
210 : : AB2,
211 : : ABD,
212 : : IFIFOABD,
213 : : IFIFOAB1,
214 : : IFIFOAB2,
215 : : AFHA_SBOX,
216 : : MDHA_SPLIT_KEY,
217 : : JOBSRC,
218 : : ZERO,
219 : : ONE,
220 : : AAD1,
221 : : IV1,
222 : : IV2,
223 : : MSG1,
224 : : MSG2,
225 : : MSG,
226 : : MSG_CKSUM,
227 : : MSGOUTSNOOP,
228 : : MSGINSNOOP,
229 : : ICV1,
230 : : ICV2,
231 : : SKIP,
232 : : NONE,
233 : : RNGOFIFO,
234 : : RNG,
235 : : IDFNS,
236 : : ODFNS,
237 : : NFIFOSZ,
238 : : SZ,
239 : : PAD,
240 : : SAD1,
241 : : AAD2,
242 : : BIT_DATA,
243 : : NFIFO_SZL,
244 : : NFIFO_SZM,
245 : : NFIFO_L,
246 : : NFIFO_M,
247 : : SZL,
248 : : SZM,
249 : : JOBDESCBUF_EFF,
250 : : SHAREDESCBUF_EFF,
251 : : METADATA,
252 : : GTR,
253 : : STR,
254 : : OFIFO_SYNC,
255 : : MSGOUTSNOOP_ALT
256 : : };
257 : :
258 : : /* Command flags */
259 : : #define FLUSH1 BIT(0)
260 : : #define LAST1 BIT(1)
261 : : #define LAST2 BIT(2)
262 : : #define IMMED BIT(3)
263 : : #define SGF BIT(4)
264 : : #define VLF BIT(5)
265 : : #define EXT BIT(6)
266 : : #define CONT BIT(7)
267 : : #define SEQ BIT(8)
268 : : #define AIDF BIT(9)
269 : : #define FLUSH2 BIT(10)
270 : : #define CLASS1 BIT(11)
271 : : #define CLASS2 BIT(12)
272 : : #define BOTH BIT(13)
273 : :
274 : : /**
275 : : * DCOPY - (AIOP only) command param is pointer to external memory
276 : : *
277 : : * CDMA must be used to transfer the key via DMA into Workspace Area.
278 : : * Valid only in combination with IMMED flag.
279 : : */
280 : : #define DCOPY BIT(30)
281 : :
282 : : #define COPY BIT(31) /* command param is pointer (not immediate)
283 : : * valid only in combination when IMMED
284 : : */
285 : :
286 : : #define __COPY_MASK (COPY | DCOPY)
287 : :
288 : : /* SEQ IN/OUT PTR Command specific flags */
289 : : #define RBS BIT(16)
290 : : #define INL BIT(17)
291 : : #define PRE BIT(18)
292 : : #define RTO BIT(19)
293 : : #define RJD BIT(20)
294 : : #define SOP BIT(21)
295 : : #define RST BIT(22)
296 : : #define EWS BIT(23)
297 : :
298 : : #define ENC BIT(14) /* Encrypted Key */
299 : : #define EKT BIT(15) /* AES CCM Encryption (default is
300 : : * AES ECB Encryption)
301 : : */
302 : : #define TK BIT(16) /* Trusted Descriptor Key (default is
303 : : * Job Descriptor Key)
304 : : */
305 : : #define NWB BIT(17) /* No Write Back Key */
306 : : #define PTS BIT(18) /* Plaintext Store */
307 : :
308 : : /* HEADER Command specific flags */
309 : : #define RIF BIT(16)
310 : : #define DNR BIT(17)
311 : : #define CIF BIT(18)
312 : : #define PD BIT(19)
313 : : #define RSMS BIT(20)
314 : : #define TD BIT(21)
315 : : #define MTD BIT(22)
316 : : #define REO BIT(23)
317 : : #define SHR BIT(24)
318 : : #define SC BIT(25)
319 : : /* Extended HEADER specific flags */
320 : : #define DSV BIT(7)
321 : : #define DSEL_MASK 0x00000007 /* DECO Select */
322 : : #define FTD BIT(8)
323 : :
324 : : /* JUMP Command specific flags */
325 : : #define NIFP BIT(20)
326 : : #define NIP BIT(21)
327 : : #define NOP BIT(22)
328 : : #define NCP BIT(23)
329 : : #define CALM BIT(24)
330 : :
331 : : #define MATH_Z BIT(25)
332 : : #define MATH_N BIT(26)
333 : : #define MATH_NV BIT(27)
334 : : #define MATH_C BIT(28)
335 : : #define PK_0 BIT(29)
336 : : #define PK_GCD_1 BIT(30)
337 : : #define PK_PRIME BIT(31)
338 : : #define SELF BIT(0)
339 : : #define SHRD BIT(1)
340 : : #define JQP BIT(2)
341 : :
342 : : /* NFIFOADD specific flags */
343 : : #define PAD_ZERO BIT(16)
344 : : #define PAD_NONZERO BIT(17)
345 : : #define PAD_INCREMENT BIT(18)
346 : : #define PAD_RANDOM BIT(19)
347 : : #define PAD_ZERO_N1 BIT(20)
348 : : #define PAD_NONZERO_0 BIT(21)
349 : : #define PAD_N1 BIT(23)
350 : : #define PAD_NONZERO_N BIT(24)
351 : : #define OC BIT(25)
352 : : #define BM BIT(26)
353 : : #define PR BIT(27)
354 : : #define PS BIT(28)
355 : : #define BP BIT(29)
356 : :
357 : : /* MOVE Command specific flags */
358 : : #define WAITCOMP BIT(16)
359 : : #define SIZE_WORD BIT(17)
360 : : #define SIZE_BYTE BIT(18)
361 : : #define SIZE_DWORD BIT(19)
362 : :
363 : : /* MATH command specific flags */
364 : : #define IFB MATH_IFB
365 : : #define NFU MATH_NFU
366 : : #define STL MATH_STL
367 : : #define SSEL MATH_SSEL
368 : : #define SWP MATH_SWP
369 : : #define IMMED2 BIT(31)
370 : :
371 : : /**
372 : : * struct program - descriptor buffer management structure
373 : : * @current_pc: current offset in descriptor
374 : : * @current_instruction: current instruction in descriptor
375 : : * @first_error_pc: offset of the first error in descriptor
376 : : * @start_pc: start offset in descriptor buffer
377 : : * @buffer: buffer carrying descriptor
378 : : * @shrhdr: shared descriptor header
379 : : * @jobhdr: job descriptor header
380 : : * @ps: pointer fields size; if ps is true, pointers will be 36bits in
381 : : * length; if ps is false, pointers will be 32bits in length
382 : : * @bswap: if true, perform byte swap on a 4-byte boundary
383 : : */
384 : : struct program {
385 : : unsigned int current_pc;
386 : : unsigned int current_instruction;
387 : : unsigned int first_error_pc;
388 : : unsigned int start_pc;
389 : : uint32_t *buffer;
390 : : uint32_t *shrhdr;
391 : : uint32_t *jobhdr;
392 : : bool ps;
393 : : bool bswap;
394 : : };
395 : :
396 : : static inline void
397 : : rta_program_cntxt_init(struct program *program,
398 : : uint32_t *buffer, unsigned int offset)
399 : : {
400 : 0 : program->current_pc = 0;
401 : 0 : program->current_instruction = 0;
402 : 0 : program->first_error_pc = 0;
403 : 0 : program->start_pc = offset;
404 : 0 : program->buffer = buffer;
405 : 0 : program->shrhdr = NULL;
406 : 0 : program->jobhdr = NULL;
407 : 0 : program->ps = false;
408 [ # # # # : 0 : program->bswap = false;
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
409 : : }
410 : :
411 : : static inline int
412 : 0 : rta_program_finalize(struct program *program)
413 : : {
414 : : /* Descriptor is usually not allowed to go beyond 64 words size */
415 : 0 : if (program->current_pc > MAX_CAAM_DESCSIZE)
416 : : pr_debug("Descriptor Size exceeded max limit of 64 words");
417 : :
418 : : /* Descriptor is erroneous */
419 [ # # ]: 0 : if (program->first_error_pc) {
420 : 0 : pr_err("Descriptor creation error\n");
421 : 0 : return -EINVAL;
422 : : }
423 : :
424 : : /* Update descriptor length in shared and job descriptor headers */
425 [ # # ]: 0 : if (program->shrhdr != NULL)
426 : 0 : *program->shrhdr |= program->bswap ?
427 [ # # # # ]: 0 : swab32(program->current_pc) :
428 : : program->current_pc;
429 [ # # ]: 0 : else if (program->jobhdr != NULL)
430 : 0 : *program->jobhdr |= program->bswap ?
431 [ # # # # ]: 0 : swab32(program->current_pc) :
432 : : program->current_pc;
433 : :
434 : 0 : return (int)program->current_pc;
435 : : }
436 : :
437 : : static inline unsigned int
438 : : rta_program_set_36bit_addr(struct program *program)
439 : : {
440 : 0 : program->ps = true;
441 : 0 : return program->current_pc;
442 : : }
443 : :
444 : : static inline unsigned int
445 : : rta_program_set_bswap(struct program *program)
446 : : {
447 : 0 : program->bswap = true;
448 : 0 : return program->current_pc;
449 : : }
450 : :
451 : : static inline void
452 : 0 : __rta_out32(struct program *program, uint32_t val)
453 : : {
454 : 0 : program->buffer[program->current_pc] = program->bswap ?
455 [ # # # # ]: 0 : swab32(val) : val;
456 : 0 : program->current_pc++;
457 : 0 : }
458 : :
459 : : static inline void
460 : 0 : __rta_out_be32(struct program *program, uint32_t val)
461 : : {
462 [ # # ]: 0 : program->buffer[program->current_pc] = cpu_to_be32(val);
463 : 0 : program->current_pc++;
464 : 0 : }
465 : :
466 : : static inline void
467 : : __rta_out_le32(struct program *program, uint32_t val)
468 : : {
469 : : program->buffer[program->current_pc] = cpu_to_le32(val);
470 : : program->current_pc++;
471 : : }
472 : :
473 : : static inline void
474 : 0 : __rta_out64(struct program *program, bool is_ext, uint64_t val)
475 : : {
476 [ # # ]: 0 : if (is_ext) {
477 : : /*
478 : : * Since we are guaranteed only a 4-byte alignment in the
479 : : * descriptor buffer, we have to do 2 x 32-bit (word) writes.
480 : : * For the order of the 2 words to be correct, we need to
481 : : * take into account the endianness of the CPU.
482 : : */
483 : : #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
484 : : __rta_out32(program, program->bswap ? lower_32_bits(val) :
485 : : upper_32_bits(val));
486 : :
487 : : __rta_out32(program, program->bswap ? upper_32_bits(val) :
488 : : lower_32_bits(val));
489 : : #else
490 [ # # ]: 0 : __rta_out32(program, program->bswap ? upper_32_bits(val) :
491 : : lower_32_bits(val));
492 : :
493 [ # # ]: 0 : __rta_out32(program, program->bswap ? lower_32_bits(val) :
494 : 0 : upper_32_bits(val));
495 : : #endif
496 : : } else {
497 : 0 : __rta_out32(program, lower_32_bits(val));
498 : : }
499 : 0 : }
500 : :
501 : : static inline void __rta_out_be64(struct program *program, bool is_ext,
502 : : uint64_t val)
503 : : {
504 : : if (is_ext) {
505 : : __rta_out_be32(program, upper_32_bits(val));
506 : : __rta_out_be32(program, lower_32_bits(val));
507 : : } else {
508 : : __rta_out_be32(program, lower_32_bits(val));
509 : : }
510 : : }
511 : :
512 : : static inline void __rta_out_le64(struct program *program, bool is_ext,
513 : : uint64_t val)
514 : : {
515 : : if (is_ext) {
516 : : __rta_out_le32(program, lower_32_bits(val));
517 : : __rta_out_le32(program, upper_32_bits(val));
518 : : } else {
519 : : __rta_out_le32(program, lower_32_bits(val));
520 : : }
521 : : }
522 : :
523 : : static inline unsigned int
524 : : rta_word(struct program *program, uint32_t val)
525 : : {
526 : : unsigned int start_pc = program->current_pc;
527 : :
528 : 0 : __rta_out32(program, val);
529 : :
530 : 0 : return start_pc;
531 : : }
532 : :
533 : : static inline unsigned int
534 : : rta_dword(struct program *program, uint64_t val)
535 : : {
536 : : unsigned int start_pc = program->current_pc;
537 : :
538 : : __rta_out64(program, true, val);
539 : :
540 : : return start_pc;
541 : : }
542 : :
543 : : static inline uint32_t
544 [ # # ]: 0 : inline_flags(enum rta_data_type data_type)
545 : : {
546 : : switch (data_type) {
547 : : case RTA_DATA_PTR:
548 : : return 0;
549 : : case RTA_DATA_IMM:
550 : : return IMMED | COPY;
551 : : case RTA_DATA_IMM_DMA:
552 : : return IMMED | DCOPY;
553 : 0 : default:
554 : : /* warn and default to RTA_DATA_PTR */
555 : 0 : pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n");
556 : 0 : return 0;
557 : : }
558 : : }
559 : :
560 : : static inline unsigned int
561 : : rta_copy_data(struct program *program, uint8_t *data, unsigned int length)
562 : : {
563 : : unsigned int i;
564 : 0 : unsigned int start_pc = program->current_pc;
565 : 0 : uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
566 : :
567 [ # # # # : 0 : for (i = 0; i < length; i++)
# # # # #
# # # # #
# # # # #
# # # ]
568 : 0 : *tmp++ = data[i];
569 : 0 : program->current_pc += (length + 3) / 4;
570 : :
571 : 0 : return start_pc;
572 : : }
573 : :
574 : : #if defined(__EWL__) && defined(AIOP)
575 : : static inline void
576 : : __rta_dma_data(void *ws_dst, uint64_t ext_address, uint16_t size)
577 : : { cdma_read(ws_dst, ext_address, size); }
578 : : #else
579 : : static inline void
580 : 0 : __rta_dma_data(void *ws_dst __maybe_unused,
581 : : uint64_t ext_address __maybe_unused,
582 : : uint16_t size __maybe_unused)
583 : 0 : { pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); }
584 : : #endif /* defined(__EWL__) && defined(AIOP) */
585 : :
586 : : static inline void
587 : 0 : __rta_inline_data(struct program *program, uint64_t data,
588 : : uint32_t copy_data, uint32_t length)
589 : : {
590 [ # # ]: 0 : if (!copy_data) {
591 : 0 : __rta_out64(program, length > 4, data);
592 [ # # ]: 0 : } else if (copy_data & COPY) {
593 : 0 : uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
594 : : uint32_t i;
595 : :
596 [ # # ]: 0 : for (i = 0; i < length; i++)
597 : 0 : *tmp++ = ((uint8_t *)(uintptr_t)data)[i];
598 : 0 : program->current_pc += ((length + 3) / 4);
599 [ # # ]: 0 : } else if (copy_data & DCOPY) {
600 : 0 : __rta_dma_data(&program->buffer[program->current_pc], data,
601 : : (uint16_t)length);
602 : 0 : program->current_pc += ((length + 3) / 4);
603 : : }
604 : 0 : }
605 : :
606 : : static inline unsigned int
607 : : rta_desc_len(uint32_t *buffer)
608 : : {
609 : : if ((*buffer & CMD_MASK) == CMD_DESC_HDR) {
610 : : return *buffer & HDR_DESCLEN_MASK;
611 : : } else {
612 : : if (rta_sec_era >= RTA_SEC_ERA_10)
613 : : return *buffer & HDR_DESCLEN_SHR_MASK_ERA10;
614 : : else
615 : : return *buffer & HDR_DESCLEN_SHR_MASK;
616 : : }
617 : : }
618 : :
619 : : static inline unsigned int
620 : : rta_desc_bytes(uint32_t *buffer)
621 : : {
622 : : return (unsigned int)(rta_desc_len(buffer) * CAAM_CMD_SZ);
623 : : }
624 : :
625 : : /**
626 : : * split_key_len - Compute MDHA split key length for a given algorithm
627 : : * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* or
628 : : * OP_PCLID_DKP_* - MD5, SHA1, SHA224, SHA256, SHA384, SHA512.
629 : : *
630 : : * Return: MDHA split key length
631 : : */
632 : : static inline uint32_t
633 : : split_key_len(uint32_t hash)
634 : : {
635 : : /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
636 : : static const uint8_t mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
637 : : uint32_t idx;
638 : :
639 : 0 : idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
640 : :
641 : 0 : return (uint32_t)(mdpadlen[idx] * 2);
642 : : }
643 : :
644 : : /**
645 : : * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
646 : : * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
647 : : * SHA224, SHA384, SHA512.
648 : : *
649 : : * Return: MDHA split key pad length
650 : : */
651 : : static inline uint32_t
652 : : split_key_pad_len(uint32_t hash)
653 : : {
654 : : return ALIGN(split_key_len(hash), 16);
655 : : }
656 : :
657 : : static inline unsigned int
658 : : rta_set_label(struct program *program)
659 : : {
660 [ # # # # : 0 : return program->current_pc + program->start_pc;
# # # # #
# ]
661 : : }
662 : :
663 : : static inline int
664 : 0 : rta_patch_move(struct program *program, int line, unsigned int new_ref)
665 : : {
666 : : uint32_t opcode;
667 : 0 : bool bswap = program->bswap;
668 : :
669 [ # # ]: 0 : if (line < 0)
670 : : return -EINVAL;
671 : :
672 [ # # # # ]: 0 : opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
673 : :
674 : 0 : opcode &= (uint32_t)~MOVE_OFFSET_MASK;
675 : 0 : opcode |= (new_ref << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
676 [ # # # # ]: 0 : program->buffer[line] = bswap ? swab32(opcode) : opcode;
677 : :
678 : 0 : return 0;
679 : : }
680 : :
681 : : static inline int
682 : 0 : rta_patch_jmp(struct program *program, int line, unsigned int new_ref)
683 : : {
684 : : uint32_t opcode;
685 : 0 : bool bswap = program->bswap;
686 : :
687 [ # # ]: 0 : if (line < 0)
688 : : return -EINVAL;
689 : :
690 [ # # # # ]: 0 : opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
691 : :
692 : 0 : opcode &= (uint32_t)~JUMP_OFFSET_MASK;
693 : 0 : opcode |= (new_ref - (line + program->start_pc)) & JUMP_OFFSET_MASK;
694 [ # # # # ]: 0 : program->buffer[line] = bswap ? swab32(opcode) : opcode;
695 : :
696 : 0 : return 0;
697 : : }
698 : :
699 : : static inline int
700 : 0 : rta_patch_header(struct program *program, int line, unsigned int new_ref)
701 : : {
702 : : uint32_t opcode;
703 : 0 : bool bswap = program->bswap;
704 : :
705 [ # # ]: 0 : if (line < 0)
706 : : return -EINVAL;
707 : :
708 [ # # # # ]: 0 : opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
709 [ # # ]: 0 : if (rta_sec_era >= RTA_SEC_ERA_10) {
710 : 0 : opcode &= (uint32_t)~HDR_START_IDX_MASK_ERA10;
711 : 0 : opcode |= (new_ref << HDR_START_IDX_SHIFT) &
712 : : HDR_START_IDX_MASK_ERA10;
713 : : } else {
714 : 0 : opcode &= (uint32_t)~HDR_START_IDX_MASK;
715 : 0 : opcode |= (new_ref << HDR_START_IDX_SHIFT) & HDR_START_IDX_MASK;
716 : : }
717 : :
718 [ # # # # ]: 0 : program->buffer[line] = bswap ? swab32(opcode) : opcode;
719 : :
720 : 0 : return 0;
721 : : }
722 : :
723 : : static inline int
724 : : rta_patch_load(struct program *program, int line, unsigned int new_ref)
725 : : {
726 : : uint32_t opcode;
727 : : bool bswap = program->bswap;
728 : :
729 : : if (line < 0)
730 : : return -EINVAL;
731 : :
732 : : opcode = (bswap ? swab32(program->buffer[line]) :
733 : : program->buffer[line]) & (uint32_t)~LDST_OFFSET_MASK;
734 : :
735 : : if (opcode & (LDST_SRCDST_WORD_DESCBUF | LDST_CLASS_DECO))
736 : : opcode |= (new_ref << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
737 : : else
738 : : opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
739 : : LDST_OFFSET_MASK;
740 : :
741 : : program->buffer[line] = bswap ? swab32(opcode) : opcode;
742 : :
743 : : return 0;
744 : : }
745 : :
746 : : static inline int
747 : : rta_patch_store(struct program *program, int line, unsigned int new_ref)
748 : : {
749 : : uint32_t opcode;
750 : : bool bswap = program->bswap;
751 : :
752 : : if (line < 0)
753 : : return -EINVAL;
754 : :
755 : : opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
756 : :
757 : : opcode &= (uint32_t)~LDST_OFFSET_MASK;
758 : :
759 : : switch (opcode & LDST_SRCDST_MASK) {
760 : : case LDST_SRCDST_WORD_DESCBUF:
761 : : case LDST_SRCDST_WORD_DESCBUF_JOB:
762 : : case LDST_SRCDST_WORD_DESCBUF_SHARED:
763 : : case LDST_SRCDST_WORD_DESCBUF_JOB_WE:
764 : : case LDST_SRCDST_WORD_DESCBUF_SHARED_WE:
765 : : opcode |= ((new_ref) << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
766 : : break;
767 : : default:
768 : : opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
769 : : LDST_OFFSET_MASK;
770 : : }
771 : :
772 : : program->buffer[line] = bswap ? swab32(opcode) : opcode;
773 : :
774 : : return 0;
775 : : }
776 : :
777 : : static inline int
778 : : rta_patch_raw(struct program *program, int line, unsigned int mask,
779 : : unsigned int new_val)
780 : : {
781 : : uint32_t opcode;
782 : : bool bswap = program->bswap;
783 : :
784 : : if (line < 0)
785 : : return -EINVAL;
786 : :
787 : : opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
788 : :
789 : : opcode &= (uint32_t)~mask;
790 : : opcode |= new_val & mask;
791 : : program->buffer[line] = bswap ? swab32(opcode) : opcode;
792 : :
793 : : return 0;
794 : : }
795 : :
796 : : static inline int
797 : : __rta_map_opcode(uint32_t name, const uint32_t (*map_table)[2],
798 : : unsigned int num_of_entries, uint32_t *val)
799 : : {
800 : : unsigned int i;
801 : :
802 [ # # # # : 0 : for (i = 0; i < num_of_entries; i++)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
803 [ # # # # : 0 : if (map_table[i][0] == name) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
804 [ # # # # : 0 : *val = map_table[i][1];
# # # # #
# # # ]
805 : 0 : return 0;
806 : : }
807 : :
808 : : return -EINVAL;
809 : : }
810 : :
811 : : static inline void
812 : : __rta_map_flags(uint32_t flags, const uint32_t (*flags_table)[2],
813 : : unsigned int num_of_entries, uint32_t *opcode)
814 : : {
815 : : unsigned int i;
816 : :
817 [ # # # # : 0 : for (i = 0; i < num_of_entries; i++) {
# # # # ]
818 [ # # # # : 0 : if (flags_table[i][0] & flags)
# # # # ]
819 : 0 : *opcode |= flags_table[i][1];
820 : : }
821 : : }
822 : :
823 : : #endif /* __RTA_SEC_RUN_TIME_ASM_H__ */
|