1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
8 #ifndef __RTA_LOAD_CMD_H__
9 #define __RTA_LOAD_CMD_H__
11 extern enum rta_sec_era rta_sec_era
;
13 /* Allowed length and offset masks for each SEC Era in case DST = DCTRL */
14 static const uint32_t load_len_mask_allowed
[] = {
25 static const uint32_t load_off_mask_allowed
[] = {
39 #define IMM_DSNM 3 /* it doesn't matter the src type */
53 DSNM
/* it doesn't matter the length/offset values */
59 enum e_lenoff len_off
;
64 static const struct load_map load_dst
[] = {
65 /*1*/ { KEY1SZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_KEYSZ_REG
,
67 { KEY2SZ
, LDST_CLASS_2_CCB
| LDST_SRCDST_WORD_KEYSZ_REG
,
69 { DATA1SZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_DATASZ_REG
,
70 LENOF_448
, IMM_MUST
},
71 { DATA2SZ
, LDST_CLASS_2_CCB
| LDST_SRCDST_WORD_DATASZ_REG
,
72 LENOF_448
, IMM_MUST
},
73 { ICV1SZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_ICVSZ_REG
,
75 { ICV2SZ
, LDST_CLASS_2_CCB
| LDST_SRCDST_WORD_ICVSZ_REG
,
77 { CCTRL
, LDST_CLASS_IND_CCB
| LDST_SRCDST_WORD_CHACTRL
,
79 { DCTRL
, LDST_CLASS_DECO
| LDST_IMM
| LDST_SRCDST_WORD_DECOCTRL
,
81 { ICTRL
, LDST_CLASS_IND_CCB
| LDST_SRCDST_WORD_IRQCTRL
,
83 { DPOVRD
, LDST_CLASS_DECO
| LDST_SRCDST_WORD_DECO_PCLOVRD
,
85 { CLRW
, LDST_CLASS_IND_CCB
| LDST_SRCDST_WORD_CLRW
,
87 { AAD1SZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_DECO_AAD_SZ
,
89 { IV1SZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_CLASS1_IV_SZ
,
91 { ALTDS1
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_ALTDS_CLASS1
,
92 LENOF_448
, IMM_MUST
},
93 { PKASZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_PKHA_A_SZ
,
95 { PKBSZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_PKHA_B_SZ
,
97 { PKNSZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_PKHA_N_SZ
,
99 { PKESZ
, LDST_CLASS_1_CCB
| LDST_SRCDST_WORD_PKHA_E_SZ
,
101 { NFIFO
, LDST_CLASS_IND_CCB
| LDST_SRCDST_WORD_INFO_FIFO
,
102 LENOF_48
, IMM_MUST
},
103 { IFIFO
, LDST_SRCDST_BYTE_INFIFO
, LENOF_18
, IMM_MUST
},
104 { OFIFO
, LDST_SRCDST_BYTE_OUTFIFO
, LENOF_18
, IMM_MUST
},
105 { MATH0
, LDST_CLASS_DECO
| LDST_SRCDST_WORD_DECO_MATH0
,
107 { MATH1
, LDST_CLASS_DECO
| LDST_SRCDST_WORD_DECO_MATH1
,
109 { MATH2
, LDST_CLASS_DECO
| LDST_SRCDST_WORD_DECO_MATH2
,
111 { MATH3
, LDST_CLASS_DECO
| LDST_SRCDST_WORD_DECO_MATH3
,
113 { CONTEXT1
, LDST_CLASS_1_CCB
| LDST_SRCDST_BYTE_CONTEXT
,
114 LENOF_128
, IMM_CAN
},
115 { CONTEXT2
, LDST_CLASS_2_CCB
| LDST_SRCDST_BYTE_CONTEXT
,
116 LENOF_128
, IMM_CAN
},
117 { KEY1
, LDST_CLASS_1_CCB
| LDST_SRCDST_BYTE_KEY
,
119 { KEY2
, LDST_CLASS_2_CCB
| LDST_SRCDST_BYTE_KEY
,
121 { DESCBUF
, LDST_CLASS_DECO
| LDST_SRCDST_WORD_DESCBUF
,
123 { DPID
, LDST_CLASS_DECO
| LDST_SRCDST_WORD_PID
,
124 LENOF_448
, IMM_MUST
},
125 /*32*/ { IDFNS
, LDST_SRCDST_WORD_IFNSR
, LENOF_18
, IMM_MUST
},
126 { ODFNS
, LDST_SRCDST_WORD_OFNSR
, LENOF_18
, IMM_MUST
},
127 { ALTSOURCE
, LDST_SRCDST_BYTE_ALTSOURCE
, LENOF_18
, IMM_MUST
},
128 /*35*/ { NFIFO_SZL
, LDST_SRCDST_WORD_INFO_FIFO_SZL
, LENOF_48
, IMM_MUST
},
129 { NFIFO_SZM
, LDST_SRCDST_WORD_INFO_FIFO_SZM
, LENOF_03
, IMM_MUST
},
130 { NFIFO_L
, LDST_SRCDST_WORD_INFO_FIFO_L
, LENOF_48
, IMM_MUST
},
131 { NFIFO_M
, LDST_SRCDST_WORD_INFO_FIFO_M
, LENOF_03
, IMM_MUST
},
132 { SZL
, LDST_SRCDST_WORD_SZL
, LENOF_48
, IMM_MUST
},
133 /*40*/ { SZM
, LDST_SRCDST_WORD_SZM
, LENOF_03
, IMM_MUST
}
137 * Allowed LOAD destinations for each SEC Era.
138 * Values represent the number of entries from load_dst[] that are supported.
140 static const unsigned int load_dst_sz
[] = { 31, 34, 34, 40, 40, 40, 40, 40 };
143 load_check_len_offset(int pos
, uint32_t length
, uint32_t offset
)
145 if ((load_dst
[pos
].dst
== DCTRL
) &&
146 ((length
& ~load_len_mask_allowed
[rta_sec_era
]) ||
147 (offset
& ~load_off_mask_allowed
[rta_sec_era
])))
150 switch (load_dst
[pos
].len_off
) {
152 if ((length
> 3) || (offset
))
156 if ((length
!= 4) || (offset
!= 0))
160 if (!(((length
== 4) && (offset
== 0)) ||
161 ((length
== 8) && (offset
== 0))))
165 if (!(((length
== 4) && (offset
== 0)) ||
166 ((length
== 4) && (offset
== 4)) ||
167 ((length
== 8) && (offset
== 0))))
171 if ((length
< 1) || (length
> 8) || (offset
!= 0))
175 if ((length
> 32) || (offset
> 32) || ((offset
+ length
) > 32))
179 if ((length
> 24) || (offset
> 24) || ((offset
+ length
) > 24))
183 if ((length
> 16) || (offset
> 16) || ((offset
+ length
) > 16))
187 if ((length
> 8) || (offset
> 8) || ((offset
+ length
) > 8))
191 if ((length
> 128) || (offset
> 128) ||
192 ((offset
+ length
) > 128))
196 if ((length
< 1) || (length
> 256) || ((length
+ offset
) > 256))
211 rta_load(struct program
*program
, uint64_t src
, uint64_t dst
,
212 uint32_t offset
, uint32_t length
, uint32_t flags
)
215 int pos
= -1, ret
= -EINVAL
;
216 unsigned int start_pc
= program
->current_pc
, i
;
219 opcode
= CMD_SEQ_LOAD
;
223 if ((length
& 0xffffff00) || (offset
& 0xffffff00)) {
224 pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
233 /* check load destination, length and offset and source type */
234 for (i
= 0; i
< load_dst_sz
[rta_sec_era
]; i
++)
235 if (dst
== load_dst
[i
].dst
) {
240 pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
241 program
->current_pc
);
246 if (load_dst
[pos
].imm_src
== IMM_NO
) {
247 pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
248 program
->current_pc
);
252 } else if (load_dst
[pos
].imm_src
== IMM_MUST
) {
253 pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
254 program
->current_pc
);
258 ret
= load_check_len_offset(pos
, length
, offset
);
260 pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
261 program
->current_pc
);
265 opcode
|= load_dst
[pos
].dst_opcode
;
267 /* DESC BUFFER: length / offset values are specified in 4-byte words */
268 if (dst
== DESCBUF
) {
269 opcode
|= (length
>> 2);
270 opcode
|= ((offset
>> 2) << LDST_OFFSET_SHIFT
);
273 opcode
|= (offset
<< LDST_OFFSET_SHIFT
);
276 __rta_out32(program
, opcode
);
277 program
->current_instruction
++;
279 /* DECO CONTROL: skip writing pointer of imm data */
281 return (int)start_pc
;
284 * For data copy, 3 possible ways to specify how to copy data:
285 * - IMMED & !COPY: copy data directly from src( max 8 bytes)
286 * - IMMED & COPY: copy data imm from the location specified by user
287 * - !IMMED and is not SEQ cmd: copy the address
290 __rta_inline_data(program
, src
, flags
& __COPY_MASK
, length
);
291 else if (!(flags
& SEQ
))
292 __rta_out64(program
, program
->ps
, src
);
294 return (int)start_pc
;
297 program
->first_error_pc
= start_pc
;
298 program
->current_instruction
++;
302 #endif /* __RTA_LOAD_CMD_H__*/