1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
8 #ifndef __RTA_SEC_RUN_TIME_ASM_H__
9 #define __RTA_SEC_RUN_TIME_ASM_H__
13 /* hw/compat.h is not delivered in kernel */
15 #include "hw/compat.h"
19 * enum rta_sec_era - SEC HW block revisions supported by the RTA library
20 * @RTA_SEC_ERA_1: SEC Era 1
21 * @RTA_SEC_ERA_2: SEC Era 2
22 * @RTA_SEC_ERA_3: SEC Era 3
23 * @RTA_SEC_ERA_4: SEC Era 4
24 * @RTA_SEC_ERA_5: SEC Era 5
25 * @RTA_SEC_ERA_6: SEC Era 6
26 * @RTA_SEC_ERA_7: SEC Era 7
27 * @RTA_SEC_ERA_8: SEC Era 8
28 * @MAX_SEC_ERA: maximum SEC HW block revision supported by RTA library
39 MAX_SEC_ERA
= RTA_SEC_ERA_8
43 * DEFAULT_SEC_ERA - the default value for the SEC era in case the user provides
44 * an unsupported value.
46 #define DEFAULT_SEC_ERA MAX_SEC_ERA
49 * USER_SEC_ERA - translates the SEC Era from internal to user representation.
50 * @sec_era: SEC Era in internal (library) representation
52 #define USER_SEC_ERA(sec_era) (sec_era + 1)
55 * INTL_SEC_ERA - translates the SEC Era from user representation to internal.
56 * @sec_era: SEC Era in user representation
58 #define INTL_SEC_ERA(sec_era) (sec_era - 1)
61 * enum rta_jump_type - Types of action taken by JUMP command
62 * @LOCAL_JUMP: conditional jump to an offset within the descriptor buffer
63 * @FAR_JUMP: conditional jump to a location outside the descriptor buffer,
64 * indicated by the POINTER field after the JUMP command.
65 * @HALT: conditional halt - stop the execution of the current descriptor and
66 * writes PKHA / Math condition bits as status / error code.
67 * @HALT_STATUS: conditional halt with user-specified status - stop the
68 * execution of the current descriptor and writes the value of
69 * "LOCAL OFFSET" JUMP field as status / error code.
70 * @GOSUB: conditional subroutine call - similar to @LOCAL_JUMP, but also saves
71 * return address in the Return Address register; subroutine calls
73 * @RETURN: conditional subroutine return - similar to @LOCAL_JUMP, but the
74 * offset is taken from the Return Address register.
75 * @LOCAL_JUMP_INC: similar to @LOCAL_JUMP, but increment the register specified
76 * in "SRC_DST" JUMP field before evaluating the jump
78 * @LOCAL_JUMP_DEC: similar to @LOCAL_JUMP, but decrement the register specified
79 * in "SRC_DST" JUMP field before evaluating the jump
94 * enum rta_jump_cond - How test conditions are evaluated by JUMP command
95 * @ALL_TRUE: perform action if ALL selected conditions are true
96 * @ALL_FALSE: perform action if ALL selected conditions are false
97 * @ANY_TRUE: perform action if ANY of the selected conditions is true
98 * @ANY_FALSE: perform action if ANY of the selected conditions is false
108 * enum rta_share_type - Types of sharing for JOB_HDR and SHR_HDR commands
109 * @SHR_NEVER: nothing is shared; descriptors can execute in parallel (i.e. no
110 * dependencies are allowed between them).
111 * @SHR_WAIT: shared descriptor and keys are shared once the descriptor sets
112 * "OK to share" in DECO Control Register (DCTRL).
113 * @SHR_SERIAL: shared descriptor and keys are shared once the descriptor has
115 * @SHR_ALWAYS: shared descriptor is shared anytime after the descriptor is
117 * @SHR_DEFER: valid only for JOB_HDR; sharing type is the one specified
118 * in the shared descriptor associated with the job descriptor.
120 enum rta_share_type
{
129 * enum rta_data_type - Indicates how is the data provided and how to include it
131 * @RTA_DATA_PTR: Data is in memory and accessed by reference; data address is a
132 * physical (bus) address.
133 * @RTA_DATA_IMM: Data is inlined in descriptor and accessed as immediate data;
134 * data address is a virtual address.
135 * @RTA_DATA_IMM_DMA: (AIOP only) Data is inlined in descriptor and accessed as
136 * immediate data; data address is a physical (bus) address
137 * in external memory and CDMA is programmed to transfer the
138 * data into descriptor buffer being built in Workspace Area.
146 /* Registers definitions */
207 /* Pseudo registers */
258 #define FLUSH1 BIT(0)
268 #define FLUSH2 BIT(10)
269 #define CLASS1 BIT(11)
270 #define CLASS2 BIT(12)
274 * DCOPY - (AIOP only) command param is pointer to external memory
276 * CDMA must be used to transfer the key via DMA into Workspace Area.
277 * Valid only in combination with IMMED flag.
279 #define DCOPY BIT(30)
281 #define COPY BIT(31) /* command param is pointer (not immediate)
282 * valid only in combination when IMMED
285 #define __COPY_MASK (COPY | DCOPY)
287 /* SEQ IN/OUT PTR Command specific flags */
297 #define ENC BIT(14) /* Encrypted Key */
298 #define EKT BIT(15) /* AES CCM Encryption (default is
299 * AES ECB Encryption)
301 #define TK BIT(16) /* Trusted Descriptor Key (default is
302 * Job Descriptor Key)
304 #define NWB BIT(17) /* No Write Back Key */
305 #define PTS BIT(18) /* Plaintext Store */
307 /* HEADER Command specific flags */
318 /* Extended HEADER specific flags */
320 #define DSEL_MASK 0x00000007 /* DECO Select */
323 /* JUMP Command specific flags */
330 #define MATH_Z BIT(25)
331 #define MATH_N BIT(26)
332 #define MATH_NV BIT(27)
333 #define MATH_C BIT(28)
335 #define PK_GCD_1 BIT(30)
336 #define PK_PRIME BIT(31)
341 /* NFIFOADD specific flags */
342 #define PAD_ZERO BIT(16)
343 #define PAD_NONZERO BIT(17)
344 #define PAD_INCREMENT BIT(18)
345 #define PAD_RANDOM BIT(19)
346 #define PAD_ZERO_N1 BIT(20)
347 #define PAD_NONZERO_0 BIT(21)
348 #define PAD_N1 BIT(23)
349 #define PAD_NONZERO_N BIT(24)
356 /* MOVE Command specific flags */
357 #define WAITCOMP BIT(16)
358 #define SIZE_WORD BIT(17)
359 #define SIZE_BYTE BIT(18)
360 #define SIZE_DWORD BIT(19)
362 /* MATH command specific flags */
366 #define SSEL MATH_SSEL
368 #define IMMED2 BIT(31)
371 * struct program - descriptor buffer management structure
372 * @current_pc: current offset in descriptor
373 * @current_instruction: current instruction in descriptor
374 * @first_error_pc: offset of the first error in descriptor
375 * @start_pc: start offset in descriptor buffer
376 * @buffer: buffer carrying descriptor
377 * @shrhdr: shared descriptor header
378 * @jobhdr: job descriptor header
379 * @ps: pointer fields size; if ps is true, pointers will be 36bits in
380 * length; if ps is false, pointers will be 32bits in length
381 * @bswap: if true, perform byte swap on a 4-byte boundary
384 unsigned int current_pc
;
385 unsigned int current_instruction
;
386 unsigned int first_error_pc
;
387 unsigned int start_pc
;
396 rta_program_cntxt_init(struct program
*program
,
397 uint32_t *buffer
, unsigned int offset
)
399 program
->current_pc
= 0;
400 program
->current_instruction
= 0;
401 program
->first_error_pc
= 0;
402 program
->start_pc
= offset
;
403 program
->buffer
= buffer
;
404 program
->shrhdr
= NULL
;
405 program
->jobhdr
= NULL
;
407 program
->bswap
= false;
411 rta_program_finalize(struct program
*program
)
413 /* Descriptor is usually not allowed to go beyond 64 words size */
414 if (program
->current_pc
> MAX_CAAM_DESCSIZE
)
415 pr_warn("Descriptor Size exceeded max limit of 64 words\n");
417 /* Descriptor is erroneous */
418 if (program
->first_error_pc
) {
419 pr_err("Descriptor creation error\n");
423 /* Update descriptor length in shared and job descriptor headers */
424 if (program
->shrhdr
!= NULL
)
425 *program
->shrhdr
|= program
->bswap
?
426 swab32(program
->current_pc
) :
428 else if (program
->jobhdr
!= NULL
)
429 *program
->jobhdr
|= program
->bswap
?
430 swab32(program
->current_pc
) :
433 return (int)program
->current_pc
;
436 static inline unsigned int
437 rta_program_set_36bit_addr(struct program
*program
)
440 return program
->current_pc
;
443 static inline unsigned int
444 rta_program_set_bswap(struct program
*program
)
446 program
->bswap
= true;
447 return program
->current_pc
;
451 __rta_out32(struct program
*program
, uint32_t val
)
453 program
->buffer
[program
->current_pc
] = program
->bswap
?
455 program
->current_pc
++;
459 __rta_out_be32(struct program
*program
, uint32_t val
)
461 program
->buffer
[program
->current_pc
] = cpu_to_be32(val
);
462 program
->current_pc
++;
466 __rta_out_le32(struct program
*program
, uint32_t val
)
468 program
->buffer
[program
->current_pc
] = cpu_to_le32(val
);
469 program
->current_pc
++;
473 __rta_out64(struct program
*program
, bool is_ext
, uint64_t val
)
477 * Since we are guaranteed only a 4-byte alignment in the
478 * descriptor buffer, we have to do 2 x 32-bit (word) writes.
479 * For the order of the 2 words to be correct, we need to
480 * take into account the endianness of the CPU.
482 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
483 __rta_out32(program
, program
->bswap
? lower_32_bits(val
) :
486 __rta_out32(program
, program
->bswap
? upper_32_bits(val
) :
489 __rta_out32(program
, program
->bswap
? upper_32_bits(val
) :
492 __rta_out32(program
, program
->bswap
? lower_32_bits(val
) :
496 __rta_out32(program
, lower_32_bits(val
));
500 static inline unsigned int
501 rta_word(struct program
*program
, uint32_t val
)
503 unsigned int start_pc
= program
->current_pc
;
505 __rta_out32(program
, val
);
510 static inline unsigned int
511 rta_dword(struct program
*program
, uint64_t val
)
513 unsigned int start_pc
= program
->current_pc
;
515 __rta_out64(program
, true, val
);
520 static inline uint32_t
521 inline_flags(enum rta_data_type data_type
)
528 case RTA_DATA_IMM_DMA
:
529 return IMMED
| DCOPY
;
531 /* warn and default to RTA_DATA_PTR */
532 pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n");
537 static inline unsigned int
538 rta_copy_data(struct program
*program
, uint8_t *data
, unsigned int length
)
541 unsigned int start_pc
= program
->current_pc
;
542 uint8_t *tmp
= (uint8_t *)&program
->buffer
[program
->current_pc
];
544 for (i
= 0; i
< length
; i
++)
546 program
->current_pc
+= (length
+ 3) / 4;
551 #if defined(__EWL__) && defined(AIOP)
553 __rta_dma_data(void *ws_dst
, uint64_t ext_address
, uint16_t size
)
554 { cdma_read(ws_dst
, ext_address
, size
); }
557 __rta_dma_data(void *ws_dst __maybe_unused
,
558 uint64_t ext_address __maybe_unused
,
559 uint16_t size __maybe_unused
)
560 { pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); }
561 #endif /* defined(__EWL__) && defined(AIOP) */
564 __rta_inline_data(struct program
*program
, uint64_t data
,
565 uint32_t copy_data
, uint32_t length
)
568 __rta_out64(program
, length
> 4, data
);
569 } else if (copy_data
& COPY
) {
570 uint8_t *tmp
= (uint8_t *)&program
->buffer
[program
->current_pc
];
573 for (i
= 0; i
< length
; i
++)
574 *tmp
++ = ((uint8_t *)(uintptr_t)data
)[i
];
575 program
->current_pc
+= ((length
+ 3) / 4);
576 } else if (copy_data
& DCOPY
) {
577 __rta_dma_data(&program
->buffer
[program
->current_pc
], data
,
579 program
->current_pc
+= ((length
+ 3) / 4);
583 static inline unsigned int
584 rta_desc_len(uint32_t *buffer
)
586 if ((*buffer
& CMD_MASK
) == CMD_DESC_HDR
)
587 return *buffer
& HDR_DESCLEN_MASK
;
589 return *buffer
& HDR_DESCLEN_SHR_MASK
;
592 static inline unsigned int
593 rta_desc_bytes(uint32_t *buffer
)
595 return (unsigned int)(rta_desc_len(buffer
) * CAAM_CMD_SZ
);
599 * split_key_len - Compute MDHA split key length for a given algorithm
600 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* or
601 * OP_PCLID_DKP_* - MD5, SHA1, SHA224, SHA256, SHA384, SHA512.
603 * Return: MDHA split key length
605 static inline uint32_t
606 split_key_len(uint32_t hash
)
608 /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
609 static const uint8_t mdpadlen
[] = { 16, 20, 32, 32, 64, 64 };
612 idx
= (hash
& OP_ALG_ALGSEL_SUBMASK
) >> OP_ALG_ALGSEL_SHIFT
;
614 return (uint32_t)(mdpadlen
[idx
] * 2);
618 * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
619 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
620 * SHA224, SHA384, SHA512.
622 * Return: MDHA split key pad length
624 static inline uint32_t
625 split_key_pad_len(uint32_t hash
)
627 return ALIGN(split_key_len(hash
), 16);
630 static inline unsigned int
631 rta_set_label(struct program
*program
)
633 return program
->current_pc
+ program
->start_pc
;
637 rta_patch_move(struct program
*program
, int line
, unsigned int new_ref
)
640 bool bswap
= program
->bswap
;
645 opcode
= bswap
? swab32(program
->buffer
[line
]) : program
->buffer
[line
];
647 opcode
&= (uint32_t)~MOVE_OFFSET_MASK
;
648 opcode
|= (new_ref
<< (MOVE_OFFSET_SHIFT
+ 2)) & MOVE_OFFSET_MASK
;
649 program
->buffer
[line
] = bswap
? swab32(opcode
) : opcode
;
655 rta_patch_jmp(struct program
*program
, int line
, unsigned int new_ref
)
658 bool bswap
= program
->bswap
;
663 opcode
= bswap
? swab32(program
->buffer
[line
]) : program
->buffer
[line
];
665 opcode
&= (uint32_t)~JUMP_OFFSET_MASK
;
666 opcode
|= (new_ref
- (line
+ program
->start_pc
)) & JUMP_OFFSET_MASK
;
667 program
->buffer
[line
] = bswap
? swab32(opcode
) : opcode
;
673 rta_patch_header(struct program
*program
, int line
, unsigned int new_ref
)
676 bool bswap
= program
->bswap
;
681 opcode
= bswap
? swab32(program
->buffer
[line
]) : program
->buffer
[line
];
683 opcode
&= (uint32_t)~HDR_START_IDX_MASK
;
684 opcode
|= (new_ref
<< HDR_START_IDX_SHIFT
) & HDR_START_IDX_MASK
;
685 program
->buffer
[line
] = bswap
? swab32(opcode
) : opcode
;
691 rta_patch_load(struct program
*program
, int line
, unsigned int new_ref
)
694 bool bswap
= program
->bswap
;
699 opcode
= (bswap
? swab32(program
->buffer
[line
]) :
700 program
->buffer
[line
]) & (uint32_t)~LDST_OFFSET_MASK
;
702 if (opcode
& (LDST_SRCDST_WORD_DESCBUF
| LDST_CLASS_DECO
))
703 opcode
|= (new_ref
<< LDST_OFFSET_SHIFT
) & LDST_OFFSET_MASK
;
705 opcode
|= (new_ref
<< (LDST_OFFSET_SHIFT
+ 2)) &
708 program
->buffer
[line
] = bswap
? swab32(opcode
) : opcode
;
714 rta_patch_store(struct program
*program
, int line
, unsigned int new_ref
)
717 bool bswap
= program
->bswap
;
722 opcode
= bswap
? swab32(program
->buffer
[line
]) : program
->buffer
[line
];
724 opcode
&= (uint32_t)~LDST_OFFSET_MASK
;
726 switch (opcode
& LDST_SRCDST_MASK
) {
727 case LDST_SRCDST_WORD_DESCBUF
:
728 case LDST_SRCDST_WORD_DESCBUF_JOB
:
729 case LDST_SRCDST_WORD_DESCBUF_SHARED
:
730 case LDST_SRCDST_WORD_DESCBUF_JOB_WE
:
731 case LDST_SRCDST_WORD_DESCBUF_SHARED_WE
:
732 opcode
|= ((new_ref
) << LDST_OFFSET_SHIFT
) & LDST_OFFSET_MASK
;
735 opcode
|= (new_ref
<< (LDST_OFFSET_SHIFT
+ 2)) &
739 program
->buffer
[line
] = bswap
? swab32(opcode
) : opcode
;
745 rta_patch_raw(struct program
*program
, int line
, unsigned int mask
,
746 unsigned int new_val
)
749 bool bswap
= program
->bswap
;
754 opcode
= bswap
? swab32(program
->buffer
[line
]) : program
->buffer
[line
];
756 opcode
&= (uint32_t)~mask
;
757 opcode
|= new_val
& mask
;
758 program
->buffer
[line
] = bswap
? swab32(opcode
) : opcode
;
764 __rta_map_opcode(uint32_t name
, const uint32_t (*map_table
)[2],
765 unsigned int num_of_entries
, uint32_t *val
)
769 for (i
= 0; i
< num_of_entries
; i
++)
770 if (map_table
[i
][0] == name
) {
771 *val
= map_table
[i
][1];
779 __rta_map_flags(uint32_t flags
, const uint32_t (*flags_table
)[2],
780 unsigned int num_of_entries
, uint32_t *opcode
)
784 for (i
= 0; i
< num_of_entries
; i
++) {
785 if (flags_table
[i
][0] & flags
)
786 *opcode
|= flags_table
[i
][1];
790 #endif /* __RTA_SEC_RUN_TIME_ASM_H__ */