2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
7 * Copyright 2008-2016 Freescale Semiconductor Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * * Neither the name of the above-listed copyright holders nor the
18 * names of any contributors may be used to endorse or promote products
19 * derived from this software without specific prior written permission.
23 * ALTERNATIVELY, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") as published by the Free Software
25 * Foundation, either version 2 of that License or (at your option) any
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
41 #ifndef __RTA_SEC_RUN_TIME_ASM_H__
42 #define __RTA_SEC_RUN_TIME_ASM_H__
46 /* hw/compat.h is not delivered in kernel */
48 #include "hw/compat.h"
52 * enum rta_sec_era - SEC HW block revisions supported by the RTA library
53 * @RTA_SEC_ERA_1: SEC Era 1
54 * @RTA_SEC_ERA_2: SEC Era 2
55 * @RTA_SEC_ERA_3: SEC Era 3
56 * @RTA_SEC_ERA_4: SEC Era 4
57 * @RTA_SEC_ERA_5: SEC Era 5
58 * @RTA_SEC_ERA_6: SEC Era 6
59 * @RTA_SEC_ERA_7: SEC Era 7
60 * @RTA_SEC_ERA_8: SEC Era 8
61 * @MAX_SEC_ERA: maximum SEC HW block revision supported by RTA library
72 MAX_SEC_ERA = RTA_SEC_ERA_8
76 * DEFAULT_SEC_ERA - the default value for the SEC era in case the user provides
77 * an unsupported value.
79 #define DEFAULT_SEC_ERA MAX_SEC_ERA
82 * USER_SEC_ERA - translates the SEC Era from internal to user representation.
83 * @sec_era: SEC Era in internal (library) representation
85 #define USER_SEC_ERA(sec_era) (sec_era + 1)
88 * INTL_SEC_ERA - translates the SEC Era from user representation to internal.
89 * @sec_era: SEC Era in user representation
91 #define INTL_SEC_ERA(sec_era) (sec_era - 1)
94 * enum rta_jump_type - Types of action taken by JUMP command
95 * @LOCAL_JUMP: conditional jump to an offset within the descriptor buffer
96 * @FAR_JUMP: conditional jump to a location outside the descriptor buffer,
97 * indicated by the POINTER field after the JUMP command.
98 * @HALT: conditional halt - stop the execution of the current descriptor and
99 * writes PKHA / Math condition bits as status / error code.
100 * @HALT_STATUS: conditional halt with user-specified status - stop the
101 * execution of the current descriptor and writes the value of
102 * "LOCAL OFFSET" JUMP field as status / error code.
103 * @GOSUB: conditional subroutine call - similar to @LOCAL_JUMP, but also saves
104 * return address in the Return Address register; subroutine calls
106 * @RETURN: conditional subroutine return - similar to @LOCAL_JUMP, but the
107 * offset is taken from the Return Address register.
108 * @LOCAL_JUMP_INC: similar to @LOCAL_JUMP, but increment the register specified
109 * in "SRC_DST" JUMP field before evaluating the jump
111 * @LOCAL_JUMP_DEC: similar to @LOCAL_JUMP, but decrement the register specified
112 * in "SRC_DST" JUMP field before evaluating the jump
127 * enum rta_jump_cond - How test conditions are evaluated by JUMP command
128 * @ALL_TRUE: perform action if ALL selected conditions are true
129 * @ALL_FALSE: perform action if ALL selected conditions are false
130 * @ANY_TRUE: perform action if ANY of the selected conditions is true
131 * @ANY_FALSE: perform action if ANY of the selected conditions is false
141 * enum rta_share_type - Types of sharing for JOB_HDR and SHR_HDR commands
142 * @SHR_NEVER: nothing is shared; descriptors can execute in parallel (i.e. no
143 * dependencies are allowed between them).
144 * @SHR_WAIT: shared descriptor and keys are shared once the descriptor sets
145 * "OK to share" in DECO Control Register (DCTRL).
146 * @SHR_SERIAL: shared descriptor and keys are shared once the descriptor has
148 * @SHR_ALWAYS: shared descriptor is shared anytime after the descriptor is
150 * @SHR_DEFER: valid only for JOB_HDR; sharing type is the one specified
151 * in the shared descriptor associated with the job descriptor.
153 enum rta_share_type {
162 * enum rta_data_type - Indicates how is the data provided and how to include it
164 * @RTA_DATA_PTR: Data is in memory and accessed by reference; data address is a
165 * physical (bus) address.
166 * @RTA_DATA_IMM: Data is inlined in descriptor and accessed as immediate data;
167 * data address is a virtual address.
168 * @RTA_DATA_IMM_DMA: (AIOP only) Data is inlined in descriptor and accessed as
169 * immediate data; data address is a physical (bus) address
170 * in external memory and CDMA is programmed to transfer the
171 * data into descriptor buffer being built in Workspace Area.
179 /* Registers definitions */
240 /* Pseudo registers */
291 #define FLUSH1 BIT(0)
301 #define FLUSH2 BIT(10)
302 #define CLASS1 BIT(11)
303 #define CLASS2 BIT(12)
307 * DCOPY - (AIOP only) command param is pointer to external memory
309 * CDMA must be used to transfer the key via DMA into Workspace Area.
310 * Valid only in combination with IMMED flag.
312 #define DCOPY BIT(30)
314 #define COPY BIT(31) /* command param is pointer (not immediate)
315 * valid only in combination when IMMED
318 #define __COPY_MASK (COPY | DCOPY)
320 /* SEQ IN/OUT PTR Command specific flags */
330 #define ENC BIT(14) /* Encrypted Key */
331 #define EKT BIT(15) /* AES CCM Encryption (default is
332 * AES ECB Encryption)
334 #define TK BIT(16) /* Trusted Descriptor Key (default is
335 * Job Descriptor Key)
337 #define NWB BIT(17) /* No Write Back Key */
338 #define PTS BIT(18) /* Plaintext Store */
340 /* HEADER Command specific flags */
351 /* Extended HEADER specific flags */
353 #define DSEL_MASK 0x00000007 /* DECO Select */
356 /* JUMP Command specific flags */
363 #define MATH_Z BIT(25)
364 #define MATH_N BIT(26)
365 #define MATH_NV BIT(27)
366 #define MATH_C BIT(28)
368 #define PK_GCD_1 BIT(30)
369 #define PK_PRIME BIT(31)
374 /* NFIFOADD specific flags */
375 #define PAD_ZERO BIT(16)
376 #define PAD_NONZERO BIT(17)
377 #define PAD_INCREMENT BIT(18)
378 #define PAD_RANDOM BIT(19)
379 #define PAD_ZERO_N1 BIT(20)
380 #define PAD_NONZERO_0 BIT(21)
381 #define PAD_N1 BIT(23)
382 #define PAD_NONZERO_N BIT(24)
389 /* MOVE Command specific flags */
390 #define WAITCOMP BIT(16)
391 #define SIZE_WORD BIT(17)
392 #define SIZE_BYTE BIT(18)
393 #define SIZE_DWORD BIT(19)
395 /* MATH command specific flags */
399 #define SSEL MATH_SSEL
401 #define IMMED2 BIT(31)
404 * struct program - descriptor buffer management structure
405 * @current_pc: current offset in descriptor
406 * @current_instruction: current instruction in descriptor
407 * @first_error_pc: offset of the first error in descriptor
408 * @start_pc: start offset in descriptor buffer
409 * @buffer: buffer carrying descriptor
410 * @shrhdr: shared descriptor header
411 * @jobhdr: job descriptor header
412 * @ps: pointer fields size; if ps is true, pointers will be 36bits in
413 * length; if ps is false, pointers will be 32bits in length
414 * @bswap: if true, perform byte swap on a 4-byte boundary
417 unsigned int current_pc;
418 unsigned int current_instruction;
419 unsigned int first_error_pc;
420 unsigned int start_pc;
429 rta_program_cntxt_init(struct program *program,
430 uint32_t *buffer, unsigned int offset)
432 program->current_pc = 0;
433 program->current_instruction = 0;
434 program->first_error_pc = 0;
435 program->start_pc = offset;
436 program->buffer = buffer;
437 program->shrhdr = NULL;
438 program->jobhdr = NULL;
440 program->bswap = false;
444 rta_program_finalize(struct program *program)
446 /* Descriptor is usually not allowed to go beyond 64 words size */
447 if (program->current_pc > MAX_CAAM_DESCSIZE)
448 pr_warn("Descriptor Size exceeded max limit of 64 words\n");
450 /* Descriptor is erroneous */
451 if (program->first_error_pc) {
452 pr_err("Descriptor creation error\n");
456 /* Update descriptor length in shared and job descriptor headers */
457 if (program->shrhdr != NULL)
458 *program->shrhdr |= program->bswap ?
459 swab32(program->current_pc) :
461 else if (program->jobhdr != NULL)
462 *program->jobhdr |= program->bswap ?
463 swab32(program->current_pc) :
466 return (int)program->current_pc;
469 static inline unsigned int
470 rta_program_set_36bit_addr(struct program *program)
473 return program->current_pc;
476 static inline unsigned int
477 rta_program_set_bswap(struct program *program)
479 program->bswap = true;
480 return program->current_pc;
484 __rta_out32(struct program *program, uint32_t val)
486 program->buffer[program->current_pc] = program->bswap ?
488 program->current_pc++;
492 __rta_out_be32(struct program *program, uint32_t val)
494 program->buffer[program->current_pc] = cpu_to_be32(val);
495 program->current_pc++;
499 __rta_out_le32(struct program *program, uint32_t val)
501 program->buffer[program->current_pc] = cpu_to_le32(val);
502 program->current_pc++;
506 __rta_out64(struct program *program, bool is_ext, uint64_t val)
510 * Since we are guaranteed only a 4-byte alignment in the
511 * descriptor buffer, we have to do 2 x 32-bit (word) writes.
512 * For the order of the 2 words to be correct, we need to
513 * take into account the endianness of the CPU.
515 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
516 __rta_out32(program, program->bswap ? lower_32_bits(val) :
519 __rta_out32(program, program->bswap ? upper_32_bits(val) :
522 __rta_out32(program, program->bswap ? upper_32_bits(val) :
525 __rta_out32(program, program->bswap ? lower_32_bits(val) :
529 __rta_out32(program, lower_32_bits(val));
533 static inline unsigned int
534 rta_word(struct program *program, uint32_t val)
536 unsigned int start_pc = program->current_pc;
538 __rta_out32(program, val);
543 static inline unsigned int
544 rta_dword(struct program *program, uint64_t val)
546 unsigned int start_pc = program->current_pc;
548 __rta_out64(program, true, val);
553 static inline uint32_t
554 inline_flags(enum rta_data_type data_type)
561 case RTA_DATA_IMM_DMA:
562 return IMMED | DCOPY;
564 /* warn and default to RTA_DATA_PTR */
565 pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n");
570 static inline unsigned int
571 rta_copy_data(struct program *program, uint8_t *data, unsigned int length)
574 unsigned int start_pc = program->current_pc;
575 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
577 for (i = 0; i < length; i++)
579 program->current_pc += (length + 3) / 4;
584 #if defined(__EWL__) && defined(AIOP)
586 __rta_dma_data(void *ws_dst, uint64_t ext_address, uint16_t size)
587 { cdma_read(ws_dst, ext_address, size); }
590 __rta_dma_data(void *ws_dst __maybe_unused,
591 uint64_t ext_address __maybe_unused,
592 uint16_t size __maybe_unused)
593 { pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); }
594 #endif /* defined(__EWL__) && defined(AIOP) */
597 __rta_inline_data(struct program *program, uint64_t data,
598 uint32_t copy_data, uint32_t length)
601 __rta_out64(program, length > 4, data);
602 } else if (copy_data & COPY) {
603 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
606 for (i = 0; i < length; i++)
607 *tmp++ = ((uint8_t *)(uintptr_t)data)[i];
608 program->current_pc += ((length + 3) / 4);
609 } else if (copy_data & DCOPY) {
610 __rta_dma_data(&program->buffer[program->current_pc], data,
612 program->current_pc += ((length + 3) / 4);
616 static inline unsigned int
617 rta_desc_len(uint32_t *buffer)
619 if ((*buffer & CMD_MASK) == CMD_DESC_HDR)
620 return *buffer & HDR_DESCLEN_MASK;
622 return *buffer & HDR_DESCLEN_SHR_MASK;
625 static inline unsigned int
626 rta_desc_bytes(uint32_t *buffer)
628 return (unsigned int)(rta_desc_len(buffer) * CAAM_CMD_SZ);
632 * split_key_len - Compute MDHA split key length for a given algorithm
633 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* or
634 * OP_PCLID_DKP_* - MD5, SHA1, SHA224, SHA256, SHA384, SHA512.
636 * Return: MDHA split key length
638 static inline uint32_t
639 split_key_len(uint32_t hash)
641 /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
642 static const uint8_t mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
645 idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
647 return (uint32_t)(mdpadlen[idx] * 2);
651 * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
652 * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
653 * SHA224, SHA384, SHA512.
655 * Return: MDHA split key pad length
657 static inline uint32_t
658 split_key_pad_len(uint32_t hash)
660 return ALIGN(split_key_len(hash), 16);
663 static inline unsigned int
664 rta_set_label(struct program *program)
666 return program->current_pc + program->start_pc;
670 rta_patch_move(struct program *program, int line, unsigned int new_ref)
673 bool bswap = program->bswap;
678 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
680 opcode &= (uint32_t)~MOVE_OFFSET_MASK;
681 opcode |= (new_ref << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
682 program->buffer[line] = bswap ? swab32(opcode) : opcode;
688 rta_patch_jmp(struct program *program, int line, unsigned int new_ref)
691 bool bswap = program->bswap;
696 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
698 opcode &= (uint32_t)~JUMP_OFFSET_MASK;
699 opcode |= (new_ref - (line + program->start_pc)) & JUMP_OFFSET_MASK;
700 program->buffer[line] = bswap ? swab32(opcode) : opcode;
706 rta_patch_header(struct program *program, int line, unsigned int new_ref)
709 bool bswap = program->bswap;
714 opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
716 opcode &= (uint32_t)~HDR_START_IDX_MASK;
717 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__ */