2 * Copyright 2008-2016 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: BSD-3-Clause or GPL-2.0+
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 */
14 #include "hw/compat.h"
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
38 MAX_SEC_ERA = RTA_SEC_ERA_8
42 * DEFAULT_SEC_ERA - the default value for the SEC era in case the user provides
43 * an unsupported value.
45 #define DEFAULT_SEC_ERA MAX_SEC_ERA
48 * USER_SEC_ERA - translates the SEC Era from internal to user representation.
49 * @sec_era: SEC Era in internal (library) representation
51 #define USER_SEC_ERA(sec_era) (sec_era + 1)
54 * INTL_SEC_ERA - translates the SEC Era from user representation to internal.
55 * @sec_era: SEC Era in user representation
57 #define INTL_SEC_ERA(sec_era) (sec_era - 1)
60 * enum rta_jump_type - Types of action taken by JUMP command
61 * @LOCAL_JUMP: conditional jump to an offset within the descriptor buffer
62 * @FAR_JUMP: conditional jump to a location outside the descriptor buffer,
63 * indicated by the POINTER field after the JUMP command.
64 * @HALT: conditional halt - stop the execution of the current descriptor and
65 * writes PKHA / Math condition bits as status / error code.
66 * @HALT_STATUS: conditional halt with user-specified status - stop the
67 * execution of the current descriptor and writes the value of
68 * "LOCAL OFFSET" JUMP field as status / error code.
69 * @GOSUB: conditional subroutine call - similar to @LOCAL_JUMP, but also saves
70 * return address in the Return Address register; subroutine calls
72 * @RETURN: conditional subroutine return - similar to @LOCAL_JUMP, but the
73 * offset is taken from the Return Address register.
74 * @LOCAL_JUMP_INC: similar to @LOCAL_JUMP, but increment the register specified
75 * in "SRC_DST" JUMP field before evaluating the jump
77 * @LOCAL_JUMP_DEC: similar to @LOCAL_JUMP, but decrement the register specified
78 * in "SRC_DST" JUMP field before evaluating the jump
93 * enum rta_jump_cond - How test conditions are evaluated by JUMP command
94 * @ALL_TRUE: perform action if ALL selected conditions are true
95 * @ALL_FALSE: perform action if ALL selected conditions are false
96 * @ANY_TRUE: perform action if ANY of the selected conditions is true
97 * @ANY_FALSE: perform action if ANY of the selected conditions is false
107 * enum rta_share_type - Types of sharing for JOB_HDR and SHR_HDR commands
108 * @SHR_NEVER: nothing is shared; descriptors can execute in parallel (i.e. no
109 * dependencies are allowed between them).
110 * @SHR_WAIT: shared descriptor and keys are shared once the descriptor sets
111 * "OK to share" in DECO Control Register (DCTRL).
112 * @SHR_SERIAL: shared descriptor and keys are shared once the descriptor has
114 * @SHR_ALWAYS: shared descriptor is shared anytime after the descriptor is
116 * @SHR_DEFER: valid only for JOB_HDR; sharing type is the one specified
117 * in the shared descriptor associated with the job descriptor.
119 enum rta_share_type {
128 * enum rta_data_type - Indicates how is the data provided and how to include it
130 * @RTA_DATA_PTR: Data is in memory and accessed by reference; data address is a
131 * physical (bus) address.
132 * @RTA_DATA_IMM: Data is inlined in descriptor and accessed as immediate data;
133 * data address is a virtual address.
134 * @RTA_DATA_IMM_DMA: (AIOP only) Data is inlined in descriptor and accessed as
135 * immediate data; data address is a physical (bus) address
136 * in external memory and CDMA is programmed to transfer the
137 * data into descriptor buffer being built in Workspace Area.
145 /* Registers definitions */
206 /* Pseudo registers */
257 #define FLUSH1 BIT(0)
267 #define FLUSH2 BIT(10)
268 #define CLASS1 BIT(11)
269 #define CLASS2 BIT(12)
273 * DCOPY - (AIOP only) command param is pointer to external memory
275 * CDMA must be used to transfer the key via DMA into Workspace Area.
276 * Valid only in combination with IMMED flag.
278 #define DCOPY BIT(30)
280 #define COPY BIT(31) /* command param is pointer (not immediate)
281 * valid only in combination when IMMED
284 #define __COPY_MASK (COPY | DCOPY)
286 /* SEQ IN/OUT PTR Command specific flags */
296 #define ENC BIT(14) /* Encrypted Key */
297 #define EKT BIT(15) /* AES CCM Encryption (default is
298 * AES ECB Encryption)
300 #define TK BIT(16) /* Trusted Descriptor Key (default is
301 * Job Descriptor Key)
303 #define NWB BIT(17) /* No Write Back Key */
304 #define PTS BIT(18) /* Plaintext Store */
306 /* HEADER Command specific flags */
317 /* Extended HEADER specific flags */
319 #define DSEL_MASK 0x00000007 /* DECO Select */
322 /* JUMP Command specific flags */
329 #define MATH_Z BIT(25)
330 #define MATH_N BIT(26)
331 #define MATH_NV BIT(27)
332 #define MATH_C BIT(28)
334 #define PK_GCD_1 BIT(30)
335 #define PK_PRIME BIT(31)
340 /* NFIFOADD specific flags */
341 #define PAD_ZERO BIT(16)
342 #define PAD_NONZERO BIT(17)
343 #define PAD_INCREMENT BIT(18)
344 #define PAD_RANDOM BIT(19)
345 #define PAD_ZERO_N1 BIT(20)
346 #define PAD_NONZERO_0 BIT(21)
347 #define PAD_N1 BIT(23)
348 #define PAD_NONZERO_N BIT(24)
355 /* MOVE Command specific flags */
356 #define WAITCOMP BIT(16)
357 #define SIZE_WORD BIT(17)
358 #define SIZE_BYTE BIT(18)
359 #define SIZE_DWORD BIT(19)
361 /* MATH command specific flags */
365 #define SSEL MATH_SSEL
367 #define IMMED2 BIT(31)
370 * struct program - descriptor buffer management structure
371 * @current_pc: current offset in descriptor
372 * @current_instruction: current instruction in descriptor
373 * @first_error_pc: offset of the first error in descriptor
374 * @start_pc: start offset in descriptor buffer
375 * @buffer: buffer carrying descriptor
376 * @shrhdr: shared descriptor header
377 * @jobhdr: job descriptor header
378 * @ps: pointer fields size; if ps is true, pointers will be 36bits in
379 * length; if ps is false, pointers will be 32bits in length
380 * @bswap: if true, perform byte swap on a 4-byte boundary
383 unsigned int current_pc;
384 unsigned int current_instruction;
385 unsigned int first_error_pc;
386 unsigned int start_pc;
395 rta_program_cntxt_init(struct program *program,
396 uint32_t *buffer, unsigned int offset)
398 program->current_pc = 0;
399 program->current_instruction = 0;
400 program->first_error_pc = 0;
401 program->start_pc = offset;
402 program->buffer = buffer;
403 program->shrhdr = NULL;
404 program->jobhdr = NULL;
406 program->bswap = false;
410 rta_program_finalize(struct program *program)
412 /* Descriptor is usually not allowed to go beyond 64 words size */
413 if (program->current_pc > MAX_CAAM_DESCSIZE)
414 pr_warn("Descriptor Size exceeded max limit of 64 words\n");
416 /* Descriptor is erroneous */
417 if (program->first_error_pc) {
418 pr_err("Descriptor creation error\n");
422 /* Update descriptor length in shared and job descriptor headers */
423 if (program->shrhdr != NULL)
424 *program->shrhdr |= program->bswap ?
425 swab32(program->current_pc) :
427 else if (program->jobhdr != NULL)
428 *program->jobhdr |= program->bswap ?
429 swab32(program->current_pc) :
432 return (int)program->current_pc;
435 static inline unsigned int
436 rta_program_set_36bit_addr(struct program *program)
439 return program->current_pc;
442 static inline unsigned int
443 rta_program_set_bswap(struct program *program)
445 program->bswap = true;
446 return program->current_pc;
450 __rta_out32(struct program *program, uint32_t val)
452 program->buffer[program->current_pc] = program->bswap ?
454 program->current_pc++;
458 __rta_out_be32(struct program *program, uint32_t val)
460 program->buffer[program->current_pc] = cpu_to_be32(val);
461 program->current_pc++;
465 __rta_out_le32(struct program *program, uint32_t val)
467 program->buffer[program->current_pc] = cpu_to_le32(val);
468 program->current_pc++;
472 __rta_out64(struct program *program, bool is_ext, uint64_t val)
476 * Since we are guaranteed only a 4-byte alignment in the
477 * descriptor buffer, we have to do 2 x 32-bit (word) writes.
478 * For the order of the 2 words to be correct, we need to
479 * take into account the endianness of the CPU.
481 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
482 __rta_out32(program, program->bswap ? lower_32_bits(val) :
485 __rta_out32(program, program->bswap ? upper_32_bits(val) :
488 __rta_out32(program, program->bswap ? upper_32_bits(val) :
491 __rta_out32(program, program->bswap ? lower_32_bits(val) :
495 __rta_out32(program, lower_32_bits(val));
499 static inline unsigned int
500 rta_word(struct program *program, uint32_t val)
502 unsigned int start_pc = program->current_pc;
504 __rta_out32(program, val);
509 static inline unsigned int
510 rta_dword(struct program *program, uint64_t val)
512 unsigned int start_pc = program->current_pc;
514 __rta_out64(program, true, val);
519 static inline uint32_t
520 inline_flags(enum rta_data_type data_type)
527 case RTA_DATA_IMM_DMA:
528 return IMMED | DCOPY;
530 /* warn and default to RTA_DATA_PTR */
531 pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n");
536 static inline unsigned int
537 rta_copy_data(struct program *program, uint8_t *data, unsigned int length)
540 unsigned int start_pc = program->current_pc;
541 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
543 for (i = 0; i < length; i++)
545 program->current_pc += (length + 3) / 4;
550 #if defined(__EWL__) && defined(AIOP)
552 __rta_dma_data(void *ws_dst, uint64_t ext_address, uint16_t size)
553 { cdma_read(ws_dst, ext_address, size); }
556 __rta_dma_data(void *ws_dst __maybe_unused,
557 uint64_t ext_address __maybe_unused,
558 uint16_t size __maybe_unused)
559 { pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); }
560 #endif /* defined(__EWL__) && defined(AIOP) */
563 __rta_inline_data(struct program *program, uint64_t data,
564 uint32_t copy_data, uint32_t length)
567 __rta_out64(program, length > 4, data);
568 } else if (copy_data & COPY) {
569 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
572 for (i = 0; i < length; i++)
573 *tmp++ = ((uint8_t *)(uintptr_t)data)[i];
574 program->current_pc += ((length + 3) / 4);
575 } else if (copy_data & DCOPY) {
576 __rta_dma_data(&program->buffer[program->current_pc], data,
578 program->current_pc += ((length + 3) / 4);
582 static inline unsigned int
583 rta_desc_len(uint32_t *buffer)
585 if ((*buffer & CMD_MASK) == CMD_DESC_HDR)
586 return *buffer & HDR_DESCLEN_MASK;
588 return *buffer & HDR_DESCLEN_SHR_MASK;
591 static inline unsigned int
592 rta_desc_bytes(uint32_t *buffer)
594 return (unsigned int)(rta_desc_len(buffer) * CAAM_CMD_SZ);
598 * split_key_len - Compute MDHA split key length for a given algorithm
599 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* or
600 * OP_PCLID_DKP_* - MD5, SHA1, SHA224, SHA256, SHA384, SHA512.
602 * Return: MDHA split key length
604 static inline uint32_t
605 split_key_len(uint32_t hash)
607 /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
608 static const uint8_t mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
611 idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
613 return (uint32_t)(mdpadlen[idx] * 2);
617 * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
618 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
619 * SHA224, SHA384, SHA512.
621 * Return: MDHA split key pad length
623 static inline uint32_t
624 split_key_pad_len(uint32_t hash)
626 return ALIGN(split_key_len(hash), 16);
629 static inline unsigned int
630 rta_set_label(struct program *program)
632 return program->current_pc + program->start_pc;
636 rta_patch_move(struct program *program, int line, unsigned int new_ref)
639 bool bswap = program->bswap;
644 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
646 opcode &= (uint32_t)~MOVE_OFFSET_MASK;
647 opcode |= (new_ref << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
648 program->buffer[line] = bswap ? swab32(opcode) : opcode;
654 rta_patch_jmp(struct program *program, int line, unsigned int new_ref)
657 bool bswap = program->bswap;
662 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
664 opcode &= (uint32_t)~JUMP_OFFSET_MASK;
665 opcode |= (new_ref - (line + program->start_pc)) & JUMP_OFFSET_MASK;
666 program->buffer[line] = bswap ? swab32(opcode) : opcode;
672 rta_patch_header(struct program *program, int line, unsigned int new_ref)
675 bool bswap = program->bswap;
680 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
682 opcode &= (uint32_t)~HDR_START_IDX_MASK;
683 opcode |= (new_ref << HDR_START_IDX_SHIFT) & HDR_START_IDX_MASK;
684 program->buffer[line] = bswap ? swab32(opcode) : opcode;
690 rta_patch_load(struct program *program, int line, unsigned int new_ref)
693 bool bswap = program->bswap;
698 opcode = (bswap ? swab32(program->buffer[line]) :
699 program->buffer[line]) & (uint32_t)~LDST_OFFSET_MASK;
701 if (opcode & (LDST_SRCDST_WORD_DESCBUF | LDST_CLASS_DECO))
702 opcode |= (new_ref << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
704 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
707 program->buffer[line] = bswap ? swab32(opcode) : opcode;
713 rta_patch_store(struct program *program, int line, unsigned int new_ref)
716 bool bswap = program->bswap;
721 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
723 opcode &= (uint32_t)~LDST_OFFSET_MASK;
725 switch (opcode & LDST_SRCDST_MASK) {
726 case LDST_SRCDST_WORD_DESCBUF:
727 case LDST_SRCDST_WORD_DESCBUF_JOB:
728 case LDST_SRCDST_WORD_DESCBUF_SHARED:
729 case LDST_SRCDST_WORD_DESCBUF_JOB_WE:
730 case LDST_SRCDST_WORD_DESCBUF_SHARED_WE:
731 opcode |= ((new_ref) << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
734 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
738 program->buffer[line] = bswap ? swab32(opcode) : opcode;
744 rta_patch_raw(struct program *program, int line, unsigned int mask,
745 unsigned int new_val)
748 bool bswap = program->bswap;
753 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
755 opcode &= (uint32_t)~mask;
756 opcode |= new_val & mask;
757 program->buffer[line] = bswap ? swab32(opcode) : opcode;
763 __rta_map_opcode(uint32_t name, const uint32_t (*map_table)[2],
764 unsigned int num_of_entries, uint32_t *val)
768 for (i = 0; i < num_of_entries; i++)
769 if (map_table[i][0] == name) {
770 *val = map_table[i][1];
778 __rta_map_flags(uint32_t flags, const uint32_t (*flags_table)[2],
779 unsigned int num_of_entries, uint32_t *opcode)
783 for (i = 0; i < num_of_entries; i++) {
784 if (flags_table[i][0] & flags)
785 *opcode |= flags_table[i][1];
789 #endif /* __RTA_SEC_RUN_TIME_ASM_H__ */