2 * Copyright 2008-2016 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: BSD-3-Clause or GPL-2.0+
7 #ifndef __RTA_LOAD_CMD_H__
8 #define __RTA_LOAD_CMD_H__
10 extern enum rta_sec_era rta_sec_era;
12 /* Allowed length and offset masks for each SEC Era in case DST = DCTRL */
13 static const uint32_t load_len_mask_allowed[] = {
24 static const uint32_t load_off_mask_allowed[] = {
38 #define IMM_DSNM 3 /* it doesn't matter the src type */
52 DSNM /* it doesn't matter the length/offset values */
58 enum e_lenoff len_off;
63 static const struct load_map load_dst[] = {
64 /*1*/ { KEY1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
66 { KEY2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
68 { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG,
69 LENOF_448, IMM_MUST },
70 { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG,
71 LENOF_448, IMM_MUST },
72 { ICV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
74 { ICV2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
76 { CCTRL, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CHACTRL,
78 { DCTRL, LDST_CLASS_DECO | LDST_IMM | LDST_SRCDST_WORD_DECOCTRL,
80 { ICTRL, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_IRQCTRL,
82 { DPOVRD, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_PCLOVRD,
84 { CLRW, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CLRW,
86 { AAD1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ,
88 { IV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ,
90 { ALTDS1, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ALTDS_CLASS1,
91 LENOF_448, IMM_MUST },
92 { PKASZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ,
94 { PKBSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ,
96 { PKNSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ,
98 { PKESZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ,
100 { NFIFO, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_INFO_FIFO,
101 LENOF_48, IMM_MUST },
102 { IFIFO, LDST_SRCDST_BYTE_INFIFO, LENOF_18, IMM_MUST },
103 { OFIFO, LDST_SRCDST_BYTE_OUTFIFO, LENOF_18, IMM_MUST },
104 { MATH0, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0,
106 { MATH1, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1,
108 { MATH2, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2,
110 { MATH3, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3,
112 { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT,
113 LENOF_128, IMM_CAN },
114 { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT,
115 LENOF_128, IMM_CAN },
116 { KEY1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_KEY,
118 { KEY2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY,
120 { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF,
122 { DPID, LDST_CLASS_DECO | LDST_SRCDST_WORD_PID,
123 LENOF_448, IMM_MUST },
124 /*32*/ { IDFNS, LDST_SRCDST_WORD_IFNSR, LENOF_18, IMM_MUST },
125 { ODFNS, LDST_SRCDST_WORD_OFNSR, LENOF_18, IMM_MUST },
126 { ALTSOURCE, LDST_SRCDST_BYTE_ALTSOURCE, LENOF_18, IMM_MUST },
127 /*35*/ { NFIFO_SZL, LDST_SRCDST_WORD_INFO_FIFO_SZL, LENOF_48, IMM_MUST },
128 { NFIFO_SZM, LDST_SRCDST_WORD_INFO_FIFO_SZM, LENOF_03, IMM_MUST },
129 { NFIFO_L, LDST_SRCDST_WORD_INFO_FIFO_L, LENOF_48, IMM_MUST },
130 { NFIFO_M, LDST_SRCDST_WORD_INFO_FIFO_M, LENOF_03, IMM_MUST },
131 { SZL, LDST_SRCDST_WORD_SZL, LENOF_48, IMM_MUST },
132 /*40*/ { SZM, LDST_SRCDST_WORD_SZM, LENOF_03, IMM_MUST }
136 * Allowed LOAD destinations for each SEC Era.
137 * Values represent the number of entries from load_dst[] that are supported.
139 static const unsigned int load_dst_sz[] = { 31, 34, 34, 40, 40, 40, 40, 40 };
142 load_check_len_offset(int pos, uint32_t length, uint32_t offset)
144 if ((load_dst[pos].dst == DCTRL) &&
145 ((length & ~load_len_mask_allowed[rta_sec_era]) ||
146 (offset & ~load_off_mask_allowed[rta_sec_era])))
149 switch (load_dst[pos].len_off) {
151 if ((length > 3) || (offset))
155 if ((length != 4) || (offset != 0))
159 if (!(((length == 4) && (offset == 0)) ||
160 ((length == 8) && (offset == 0))))
164 if (!(((length == 4) && (offset == 0)) ||
165 ((length == 4) && (offset == 4)) ||
166 ((length == 8) && (offset == 0))))
170 if ((length < 1) || (length > 8) || (offset != 0))
174 if ((length > 32) || (offset > 32) || ((offset + length) > 32))
178 if ((length > 24) || (offset > 24) || ((offset + length) > 24))
182 if ((length > 16) || (offset > 16) || ((offset + length) > 16))
186 if ((length > 8) || (offset > 8) || ((offset + length) > 8))
190 if ((length > 128) || (offset > 128) ||
191 ((offset + length) > 128))
195 if ((length < 1) || (length > 256) || ((length + offset) > 256))
210 rta_load(struct program *program, uint64_t src, uint64_t dst,
211 uint32_t offset, uint32_t length, uint32_t flags)
214 int pos = -1, ret = -EINVAL;
215 unsigned int start_pc = program->current_pc, i;
218 opcode = CMD_SEQ_LOAD;
222 if ((length & 0xffffff00) || (offset & 0xffffff00)) {
223 pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
232 /* check load destination, length and offset and source type */
233 for (i = 0; i < load_dst_sz[rta_sec_era]; i++)
234 if (dst == load_dst[i].dst) {
239 pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
240 program->current_pc);
245 if (load_dst[pos].imm_src == IMM_NO) {
246 pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
247 program->current_pc);
251 } else if (load_dst[pos].imm_src == IMM_MUST) {
252 pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
253 program->current_pc);
257 ret = load_check_len_offset(pos, length, offset);
259 pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
260 program->current_pc);
264 opcode |= load_dst[pos].dst_opcode;
266 /* DESC BUFFER: length / offset values are specified in 4-byte words */
267 if (dst == DESCBUF) {
268 opcode |= (length >> 2);
269 opcode |= ((offset >> 2) << LDST_OFFSET_SHIFT);
272 opcode |= (offset << LDST_OFFSET_SHIFT);
275 __rta_out32(program, opcode);
276 program->current_instruction++;
278 /* DECO CONTROL: skip writing pointer of imm data */
280 return (int)start_pc;
283 * For data copy, 3 possible ways to specify how to copy data:
284 * - IMMED & !COPY: copy data directly from src( max 8 bytes)
285 * - IMMED & COPY: copy data imm from the location specified by user
286 * - !IMMED and is not SEQ cmd: copy the address
289 __rta_inline_data(program, src, flags & __COPY_MASK, length);
290 else if (!(flags & SEQ))
291 __rta_out64(program, program->ps, src);
293 return (int)start_pc;
296 program->first_error_pc = start_pc;
297 program->current_instruction++;
301 #endif /* __RTA_LOAD_CMD_H__*/