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 void __rta_out_be64(struct program *program, bool is_ext,
504 __rta_out_be32(program, upper_32_bits(val));
505 __rta_out_be32(program, lower_32_bits(val));
507 __rta_out_be32(program, lower_32_bits(val));
511 static inline void __rta_out_le64(struct program *program, bool is_ext,
515 __rta_out_le32(program, lower_32_bits(val));
516 __rta_out_le32(program, upper_32_bits(val));
518 __rta_out_le32(program, lower_32_bits(val));
522 static inline unsigned int
523 rta_word(struct program *program, uint32_t val)
525 unsigned int start_pc = program->current_pc;
527 __rta_out32(program, val);
532 static inline unsigned int
533 rta_dword(struct program *program, uint64_t val)
535 unsigned int start_pc = program->current_pc;
537 __rta_out64(program, true, val);
542 static inline uint32_t
543 inline_flags(enum rta_data_type data_type)
550 case RTA_DATA_IMM_DMA:
551 return IMMED | DCOPY;
553 /* warn and default to RTA_DATA_PTR */
554 pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n");
559 static inline unsigned int
560 rta_copy_data(struct program *program, uint8_t *data, unsigned int length)
563 unsigned int start_pc = program->current_pc;
564 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
566 for (i = 0; i < length; i++)
568 program->current_pc += (length + 3) / 4;
573 #if defined(__EWL__) && defined(AIOP)
575 __rta_dma_data(void *ws_dst, uint64_t ext_address, uint16_t size)
576 { cdma_read(ws_dst, ext_address, size); }
579 __rta_dma_data(void *ws_dst __maybe_unused,
580 uint64_t ext_address __maybe_unused,
581 uint16_t size __maybe_unused)
582 { pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); }
583 #endif /* defined(__EWL__) && defined(AIOP) */
586 __rta_inline_data(struct program *program, uint64_t data,
587 uint32_t copy_data, uint32_t length)
590 __rta_out64(program, length > 4, data);
591 } else if (copy_data & COPY) {
592 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
595 for (i = 0; i < length; i++)
596 *tmp++ = ((uint8_t *)(uintptr_t)data)[i];
597 program->current_pc += ((length + 3) / 4);
598 } else if (copy_data & DCOPY) {
599 __rta_dma_data(&program->buffer[program->current_pc], data,
601 program->current_pc += ((length + 3) / 4);
605 static inline unsigned int
606 rta_desc_len(uint32_t *buffer)
608 if ((*buffer & CMD_MASK) == CMD_DESC_HDR)
609 return *buffer & HDR_DESCLEN_MASK;
611 return *buffer & HDR_DESCLEN_SHR_MASK;
614 static inline unsigned int
615 rta_desc_bytes(uint32_t *buffer)
617 return (unsigned int)(rta_desc_len(buffer) * CAAM_CMD_SZ);
621 * split_key_len - Compute MDHA split key length for a given algorithm
622 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* or
623 * OP_PCLID_DKP_* - MD5, SHA1, SHA224, SHA256, SHA384, SHA512.
625 * Return: MDHA split key length
627 static inline uint32_t
628 split_key_len(uint32_t hash)
630 /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
631 static const uint8_t mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
634 idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
636 return (uint32_t)(mdpadlen[idx] * 2);
640 * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
641 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
642 * SHA224, SHA384, SHA512.
644 * Return: MDHA split key pad length
646 static inline uint32_t
647 split_key_pad_len(uint32_t hash)
649 return ALIGN(split_key_len(hash), 16);
652 static inline unsigned int
653 rta_set_label(struct program *program)
655 return program->current_pc + program->start_pc;
659 rta_patch_move(struct program *program, int line, unsigned int new_ref)
662 bool bswap = program->bswap;
667 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
669 opcode &= (uint32_t)~MOVE_OFFSET_MASK;
670 opcode |= (new_ref << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
671 program->buffer[line] = bswap ? swab32(opcode) : opcode;
677 rta_patch_jmp(struct program *program, int line, unsigned int new_ref)
680 bool bswap = program->bswap;
685 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
687 opcode &= (uint32_t)~JUMP_OFFSET_MASK;
688 opcode |= (new_ref - (line + program->start_pc)) & JUMP_OFFSET_MASK;
689 program->buffer[line] = bswap ? swab32(opcode) : opcode;
695 rta_patch_header(struct program *program, int line, unsigned int new_ref)
698 bool bswap = program->bswap;
703 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
705 opcode &= (uint32_t)~HDR_START_IDX_MASK;
706 opcode |= (new_ref << HDR_START_IDX_SHIFT) & HDR_START_IDX_MASK;
707 program->buffer[line] = bswap ? swab32(opcode) : opcode;
713 rta_patch_load(struct program *program, int line, unsigned int new_ref)
716 bool bswap = program->bswap;
721 opcode = (bswap ? swab32(program->buffer[line]) :
722 program->buffer[line]) & (uint32_t)~LDST_OFFSET_MASK;
724 if (opcode & (LDST_SRCDST_WORD_DESCBUF | LDST_CLASS_DECO))
725 opcode |= (new_ref << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
727 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
730 program->buffer[line] = bswap ? swab32(opcode) : opcode;
736 rta_patch_store(struct program *program, int line, unsigned int new_ref)
739 bool bswap = program->bswap;
744 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
746 opcode &= (uint32_t)~LDST_OFFSET_MASK;
748 switch (opcode & LDST_SRCDST_MASK) {
749 case LDST_SRCDST_WORD_DESCBUF:
750 case LDST_SRCDST_WORD_DESCBUF_JOB:
751 case LDST_SRCDST_WORD_DESCBUF_SHARED:
752 case LDST_SRCDST_WORD_DESCBUF_JOB_WE:
753 case LDST_SRCDST_WORD_DESCBUF_SHARED_WE:
754 opcode |= ((new_ref) << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
757 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
761 program->buffer[line] = bswap ? swab32(opcode) : opcode;
767 rta_patch_raw(struct program *program, int line, unsigned int mask,
768 unsigned int new_val)
771 bool bswap = program->bswap;
776 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
778 opcode &= (uint32_t)~mask;
779 opcode |= new_val & mask;
780 program->buffer[line] = bswap ? swab32(opcode) : opcode;
786 __rta_map_opcode(uint32_t name, const uint32_t (*map_table)[2],
787 unsigned int num_of_entries, uint32_t *val)
791 for (i = 0; i < num_of_entries; i++)
792 if (map_table[i][0] == name) {
793 *val = map_table[i][1];
801 __rta_map_flags(uint32_t flags, const uint32_t (*flags_table)[2],
802 unsigned int num_of_entries, uint32_t *opcode)
806 for (i = 0; i < num_of_entries; i++) {
807 if (flags_table[i][0] & flags)
808 *opcode |= flags_table[i][1];
812 #endif /* __RTA_SEC_RUN_TIME_ASM_H__ */