1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
4 * Copyright 2016,2019 NXP
7 #ifndef __RTA_SEC_RUN_TIME_ASM_H__
8 #define __RTA_SEC_RUN_TIME_ASM_H__
12 /* hw/compat.h is not delivered in kernel */
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
40 MAX_SEC_ERA = RTA_SEC_ERA_10
44 * DEFAULT_SEC_ERA - the default value for the SEC era in case the user provides
45 * an unsupported value.
47 #define DEFAULT_SEC_ERA MAX_SEC_ERA
50 * USER_SEC_ERA - translates the SEC Era from internal to user representation.
51 * @sec_era: SEC Era in internal (library) representation
53 #define USER_SEC_ERA(sec_era) (sec_era + 1)
56 * INTL_SEC_ERA - translates the SEC Era from user representation to internal.
57 * @sec_era: SEC Era in user representation
59 #define INTL_SEC_ERA(sec_era) (sec_era - 1)
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
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
79 * @LOCAL_JUMP_DEC: similar to @LOCAL_JUMP, but decrement the register specified
80 * in "SRC_DST" JUMP field before evaluating the jump
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
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
116 * @SHR_ALWAYS: shared descriptor is shared anytime after the descriptor is
118 * @SHR_DEFER: valid only for JOB_HDR; sharing type is the one specified
119 * in the shared descriptor associated with the job descriptor.
121 enum rta_share_type {
130 * enum rta_data_type - Indicates how is the data provided and how to include it
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.
147 /* Registers definitions */
208 /* Pseudo registers */
259 #define FLUSH1 BIT(0)
269 #define FLUSH2 BIT(10)
270 #define CLASS1 BIT(11)
271 #define CLASS2 BIT(12)
275 * DCOPY - (AIOP only) command param is pointer to external memory
277 * CDMA must be used to transfer the key via DMA into Workspace Area.
278 * Valid only in combination with IMMED flag.
280 #define DCOPY BIT(30)
282 #define COPY BIT(31) /* command param is pointer (not immediate)
283 * valid only in combination when IMMED
286 #define __COPY_MASK (COPY | DCOPY)
288 /* SEQ IN/OUT PTR Command specific flags */
298 #define ENC BIT(14) /* Encrypted Key */
299 #define EKT BIT(15) /* AES CCM Encryption (default is
300 * AES ECB Encryption)
302 #define TK BIT(16) /* Trusted Descriptor Key (default is
303 * Job Descriptor Key)
305 #define NWB BIT(17) /* No Write Back Key */
306 #define PTS BIT(18) /* Plaintext Store */
308 /* HEADER Command specific flags */
319 /* Extended HEADER specific flags */
321 #define DSEL_MASK 0x00000007 /* DECO Select */
324 /* JUMP Command specific flags */
331 #define MATH_Z BIT(25)
332 #define MATH_N BIT(26)
333 #define MATH_NV BIT(27)
334 #define MATH_C BIT(28)
336 #define PK_GCD_1 BIT(30)
337 #define PK_PRIME BIT(31)
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)
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)
363 /* MATH command specific flags */
367 #define SSEL MATH_SSEL
369 #define IMMED2 BIT(31)
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
385 unsigned int current_pc;
386 unsigned int current_instruction;
387 unsigned int first_error_pc;
388 unsigned int start_pc;
397 rta_program_cntxt_init(struct program *program,
398 uint32_t *buffer, unsigned int offset)
400 program->current_pc = 0;
401 program->current_instruction = 0;
402 program->first_error_pc = 0;
403 program->start_pc = offset;
404 program->buffer = buffer;
405 program->shrhdr = NULL;
406 program->jobhdr = NULL;
408 program->bswap = false;
412 rta_program_finalize(struct program *program)
414 /* Descriptor is usually not allowed to go beyond 64 words size */
415 if (program->current_pc > MAX_CAAM_DESCSIZE)
416 pr_warn("Descriptor Size exceeded max limit of 64 words\n");
418 /* Descriptor is erroneous */
419 if (program->first_error_pc) {
420 pr_err("Descriptor creation error\n");
424 /* Update descriptor length in shared and job descriptor headers */
425 if (program->shrhdr != NULL)
426 *program->shrhdr |= program->bswap ?
427 swab32(program->current_pc) :
429 else if (program->jobhdr != NULL)
430 *program->jobhdr |= program->bswap ?
431 swab32(program->current_pc) :
434 return (int)program->current_pc;
437 static inline unsigned int
438 rta_program_set_36bit_addr(struct program *program)
441 return program->current_pc;
444 static inline unsigned int
445 rta_program_set_bswap(struct program *program)
447 program->bswap = true;
448 return program->current_pc;
452 __rta_out32(struct program *program, uint32_t val)
454 program->buffer[program->current_pc] = program->bswap ?
456 program->current_pc++;
460 __rta_out_be32(struct program *program, uint32_t val)
462 program->buffer[program->current_pc] = cpu_to_be32(val);
463 program->current_pc++;
467 __rta_out_le32(struct program *program, uint32_t val)
469 program->buffer[program->current_pc] = cpu_to_le32(val);
470 program->current_pc++;
474 __rta_out64(struct program *program, bool is_ext, uint64_t val)
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.
483 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
484 __rta_out32(program, program->bswap ? lower_32_bits(val) :
487 __rta_out32(program, program->bswap ? upper_32_bits(val) :
490 __rta_out32(program, program->bswap ? upper_32_bits(val) :
493 __rta_out32(program, program->bswap ? lower_32_bits(val) :
497 __rta_out32(program, lower_32_bits(val));
501 static inline void __rta_out_be64(struct program *program, bool is_ext,
505 __rta_out_be32(program, upper_32_bits(val));
506 __rta_out_be32(program, lower_32_bits(val));
508 __rta_out_be32(program, lower_32_bits(val));
512 static inline void __rta_out_le64(struct program *program, bool is_ext,
516 __rta_out_le32(program, lower_32_bits(val));
517 __rta_out_le32(program, upper_32_bits(val));
519 __rta_out_le32(program, lower_32_bits(val));
523 static inline unsigned int
524 rta_word(struct program *program, uint32_t val)
526 unsigned int start_pc = program->current_pc;
528 __rta_out32(program, val);
533 static inline unsigned int
534 rta_dword(struct program *program, uint64_t val)
536 unsigned int start_pc = program->current_pc;
538 __rta_out64(program, true, val);
543 static inline uint32_t
544 inline_flags(enum rta_data_type data_type)
551 case RTA_DATA_IMM_DMA:
552 return IMMED | DCOPY;
554 /* warn and default to RTA_DATA_PTR */
555 pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n");
560 static inline unsigned int
561 rta_copy_data(struct program *program, uint8_t *data, unsigned int length)
564 unsigned int start_pc = program->current_pc;
565 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
567 for (i = 0; i < length; i++)
569 program->current_pc += (length + 3) / 4;
574 #if defined(__EWL__) && defined(AIOP)
576 __rta_dma_data(void *ws_dst, uint64_t ext_address, uint16_t size)
577 { cdma_read(ws_dst, ext_address, size); }
580 __rta_dma_data(void *ws_dst __maybe_unused,
581 uint64_t ext_address __maybe_unused,
582 uint16_t size __maybe_unused)
583 { pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); }
584 #endif /* defined(__EWL__) && defined(AIOP) */
587 __rta_inline_data(struct program *program, uint64_t data,
588 uint32_t copy_data, uint32_t length)
591 __rta_out64(program, length > 4, data);
592 } else if (copy_data & COPY) {
593 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
596 for (i = 0; i < length; i++)
597 *tmp++ = ((uint8_t *)(uintptr_t)data)[i];
598 program->current_pc += ((length + 3) / 4);
599 } else if (copy_data & DCOPY) {
600 __rta_dma_data(&program->buffer[program->current_pc], data,
602 program->current_pc += ((length + 3) / 4);
606 static inline unsigned int
607 rta_desc_len(uint32_t *buffer)
609 if ((*buffer & CMD_MASK) == CMD_DESC_HDR) {
610 return *buffer & HDR_DESCLEN_MASK;
612 if (rta_sec_era >= RTA_SEC_ERA_10)
613 return *buffer & HDR_DESCLEN_SHR_MASK_ERA10;
615 return *buffer & HDR_DESCLEN_SHR_MASK;
619 static inline unsigned int
620 rta_desc_bytes(uint32_t *buffer)
622 return (unsigned int)(rta_desc_len(buffer) * CAAM_CMD_SZ);
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.
630 * Return: MDHA split key length
632 static inline uint32_t
633 split_key_len(uint32_t hash)
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 };
639 idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
641 return (uint32_t)(mdpadlen[idx] * 2);
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.
649 * Return: MDHA split key pad length
651 static inline uint32_t
652 split_key_pad_len(uint32_t hash)
654 return ALIGN(split_key_len(hash), 16);
657 static inline unsigned int
658 rta_set_label(struct program *program)
660 return program->current_pc + program->start_pc;
664 rta_patch_move(struct program *program, int line, unsigned int new_ref)
667 bool bswap = program->bswap;
672 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
674 opcode &= (uint32_t)~MOVE_OFFSET_MASK;
675 opcode |= (new_ref << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
676 program->buffer[line] = bswap ? swab32(opcode) : opcode;
682 rta_patch_jmp(struct program *program, int line, unsigned int new_ref)
685 bool bswap = program->bswap;
690 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
692 opcode &= (uint32_t)~JUMP_OFFSET_MASK;
693 opcode |= (new_ref - (line + program->start_pc)) & JUMP_OFFSET_MASK;
694 program->buffer[line] = bswap ? swab32(opcode) : opcode;
700 rta_patch_header(struct program *program, int line, unsigned int new_ref)
703 bool bswap = program->bswap;
708 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
709 if (rta_sec_era >= RTA_SEC_ERA_10) {
710 opcode &= (uint32_t)~HDR_START_IDX_MASK_ERA10;
711 opcode |= (new_ref << HDR_START_IDX_SHIFT) &
712 HDR_START_IDX_MASK_ERA10;
714 opcode &= (uint32_t)~HDR_START_IDX_MASK;
715 opcode |= (new_ref << HDR_START_IDX_SHIFT) & HDR_START_IDX_MASK;
718 program->buffer[line] = bswap ? swab32(opcode) : opcode;
724 rta_patch_load(struct program *program, int line, unsigned int new_ref)
727 bool bswap = program->bswap;
732 opcode = (bswap ? swab32(program->buffer[line]) :
733 program->buffer[line]) & (uint32_t)~LDST_OFFSET_MASK;
735 if (opcode & (LDST_SRCDST_WORD_DESCBUF | LDST_CLASS_DECO))
736 opcode |= (new_ref << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
738 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
741 program->buffer[line] = bswap ? swab32(opcode) : opcode;
747 rta_patch_store(struct program *program, int line, unsigned int new_ref)
750 bool bswap = program->bswap;
755 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
757 opcode &= (uint32_t)~LDST_OFFSET_MASK;
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;
768 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
772 program->buffer[line] = bswap ? swab32(opcode) : opcode;
778 rta_patch_raw(struct program *program, int line, unsigned int mask,
779 unsigned int new_val)
782 bool bswap = program->bswap;
787 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
789 opcode &= (uint32_t)~mask;
790 opcode |= new_val & mask;
791 program->buffer[line] = bswap ? swab32(opcode) : opcode;
797 __rta_map_opcode(uint32_t name, const uint32_t (*map_table)[2],
798 unsigned int num_of_entries, uint32_t *val)
802 for (i = 0; i < num_of_entries; i++)
803 if (map_table[i][0] == name) {
804 *val = map_table[i][1];
812 __rta_map_flags(uint32_t flags, const uint32_t (*flags_table)[2],
813 unsigned int num_of_entries, uint32_t *opcode)
817 for (i = 0; i < num_of_entries; i++) {
818 if (flags_table[i][0] & flags)
819 *opcode |= flags_table[i][1];
823 #endif /* __RTA_SEC_RUN_TIME_ASM_H__ */