1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 * 3 * Copyright 2008-2016 Freescale Semiconductor Inc. 4 * Copyright 2016,2019 NXP 5 */ 6 7 #ifndef __RTA_STORE_CMD_H__ 8 #define __RTA_STORE_CMD_H__ 9 10 extern enum rta_sec_era rta_sec_era; 11 12 static const uint32_t store_src_table[][2] = { 13 /*1*/ { KEY1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG }, 14 { KEY2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG }, 15 { DJQDA, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_JQDAR }, 16 { MODE1, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_MODE_REG }, 17 { MODE2, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_MODE_REG }, 18 { DJQCTRL, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_JQCTRL }, 19 { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG }, 20 { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG }, 21 { DSTAT, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_STAT }, 22 { ICV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG }, 23 { ICV2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG }, 24 { DPID, LDST_CLASS_DECO | LDST_SRCDST_WORD_PID }, 25 { CCTRL, LDST_SRCDST_WORD_CHACTRL }, 26 { ICTRL, LDST_SRCDST_WORD_IRQCTRL }, 27 { CLRW, LDST_SRCDST_WORD_CLRW }, 28 { MATH0, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0 }, 29 { CSTAT, LDST_SRCDST_WORD_STAT }, 30 { MATH1, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1 }, 31 { MATH2, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2 }, 32 { AAD1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ }, 33 { MATH3, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3 }, 34 { IV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ }, 35 { PKASZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ }, 36 { PKBSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ }, 37 { PKESZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ }, 38 { PKNSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ }, 39 { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT }, 40 { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT }, 41 { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF }, 42 /*30*/ { JOBDESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF_JOB }, 43 { SHAREDESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF_SHARED }, 44 /*32*/ { JOBDESCBUF_EFF, LDST_CLASS_DECO | 45 LDST_SRCDST_WORD_DESCBUF_JOB_WE }, 46 { SHAREDESCBUF_EFF, LDST_CLASS_DECO | 47 LDST_SRCDST_WORD_DESCBUF_SHARED_WE }, 48 /*34*/ { GTR, LDST_CLASS_DECO | LDST_SRCDST_WORD_GTR }, 49 { STR, LDST_CLASS_DECO | LDST_SRCDST_WORD_STR } 50 }; 51 52 /* 53 * Allowed STORE sources for each SEC ERA. 54 * Values represent the number of entries from source_src_table[] that are 55 * supported. 56 */ 57 static const unsigned int store_src_table_sz[] = {29, 31, 33, 33, 58 33, 33, 35, 35, 59 35, 35}; 60 61 static inline int 62 rta_store(struct program *program, uint64_t src, 63 uint16_t offset, uint64_t dst, uint32_t length, 64 uint32_t flags) 65 { 66 uint32_t opcode = 0, val; 67 int ret = -EINVAL; 68 unsigned int start_pc = program->current_pc; 69 70 if (flags & SEQ) 71 opcode = CMD_SEQ_STORE; 72 else 73 opcode = CMD_STORE; 74 75 /* parameters check */ 76 if ((flags & IMMED) && (flags & SGF)) { 77 pr_err("STORE: Invalid flag. SEC PC: %d; Instr: %d\n", 78 program->current_pc, program->current_instruction); 79 goto err; 80 } 81 if ((flags & IMMED) && (offset != 0)) { 82 pr_err("STORE: Invalid flag. SEC PC: %d; Instr: %d\n", 83 program->current_pc, program->current_instruction); 84 goto err; 85 } 86 87 if ((flags & SEQ) && ((src == JOBDESCBUF) || (src == SHAREDESCBUF) || 88 (src == JOBDESCBUF_EFF) || 89 (src == SHAREDESCBUF_EFF))) { 90 pr_err("STORE: Invalid SRC type. SEC PC: %d; Instr: %d\n", 91 program->current_pc, program->current_instruction); 92 goto err; 93 } 94 95 if (flags & IMMED) 96 opcode |= LDST_IMM; 97 98 if ((flags & SGF) || (flags & VLF)) 99 opcode |= LDST_VLF; 100 101 /* 102 * source for data to be stored can be specified as: 103 * - register location; set in src field[9-15]; 104 * - if IMMED flag is set, data is set in value field [0-31]; 105 * user can give this value as actual value or pointer to data 106 */ 107 if (!(flags & IMMED)) { 108 ret = __rta_map_opcode((uint32_t)src, store_src_table, 109 store_src_table_sz[rta_sec_era], &val); 110 if (ret < 0) { 111 pr_err("STORE: Invalid source. SEC PC: %d; Instr: %d\n", 112 program->current_pc, 113 program->current_instruction); 114 goto err; 115 } 116 opcode |= val; 117 } 118 119 /* DESC BUFFER: length / offset values are specified in 4-byte words */ 120 if ((src == DESCBUF) || (src == JOBDESCBUF) || (src == SHAREDESCBUF) || 121 (src == JOBDESCBUF_EFF) || (src == SHAREDESCBUF_EFF)) { 122 opcode |= (length >> 2); 123 opcode |= (uint32_t)((offset >> 2) << LDST_OFFSET_SHIFT); 124 } else { 125 opcode |= length; 126 opcode |= (uint32_t)(offset << LDST_OFFSET_SHIFT); 127 } 128 129 __rta_out32(program, opcode); 130 program->current_instruction++; 131 132 if ((src == JOBDESCBUF) || (src == SHAREDESCBUF) || 133 (src == JOBDESCBUF_EFF) || (src == SHAREDESCBUF_EFF)) 134 return (int)start_pc; 135 136 /* for STORE, a pointer to where the data will be stored if needed */ 137 if (!(flags & SEQ)) 138 __rta_out64(program, program->ps, dst); 139 140 /* for IMMED data, place the data here */ 141 if (flags & IMMED) 142 __rta_inline_data(program, src, flags & __COPY_MASK, length); 143 144 return (int)start_pc; 145 146 err: 147 program->first_error_pc = start_pc; 148 program->current_instruction++; 149 return ret; 150 } 151 152 #endif /* __RTA_STORE_CMD_H__ */ 153