1*c0ded849SHemant Agrawal /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2*c0ded849SHemant Agrawal *
3*c0ded849SHemant Agrawal * Copyright 2008-2016 Freescale Semiconductor Inc.
4*c0ded849SHemant Agrawal * Copyright 2016,2019 NXP
5*c0ded849SHemant Agrawal */
6*c0ded849SHemant Agrawal
7*c0ded849SHemant Agrawal #ifndef __RTA_LOAD_CMD_H__
8*c0ded849SHemant Agrawal #define __RTA_LOAD_CMD_H__
9*c0ded849SHemant Agrawal
10*c0ded849SHemant Agrawal extern enum rta_sec_era rta_sec_era;
11*c0ded849SHemant Agrawal
12*c0ded849SHemant Agrawal /* Allowed length and offset masks for each SEC Era in case DST = DCTRL */
13*c0ded849SHemant Agrawal static const uint32_t load_len_mask_allowed[] = {
14*c0ded849SHemant Agrawal 0x000000ee,
15*c0ded849SHemant Agrawal 0x000000fe,
16*c0ded849SHemant Agrawal 0x000000fe,
17*c0ded849SHemant Agrawal 0x000000fe,
18*c0ded849SHemant Agrawal 0x000000fe,
19*c0ded849SHemant Agrawal 0x000000fe,
20*c0ded849SHemant Agrawal 0x000000fe,
21*c0ded849SHemant Agrawal 0x000000fe,
22*c0ded849SHemant Agrawal 0x000000fe,
23*c0ded849SHemant Agrawal 0x000000fe
24*c0ded849SHemant Agrawal };
25*c0ded849SHemant Agrawal
26*c0ded849SHemant Agrawal static const uint32_t load_off_mask_allowed[] = {
27*c0ded849SHemant Agrawal 0x0000000f,
28*c0ded849SHemant Agrawal 0x000000ff,
29*c0ded849SHemant Agrawal 0x000000ff,
30*c0ded849SHemant Agrawal 0x000000ff,
31*c0ded849SHemant Agrawal 0x000000ff,
32*c0ded849SHemant Agrawal 0x000000ff,
33*c0ded849SHemant Agrawal 0x000000ff,
34*c0ded849SHemant Agrawal 0x000000ff,
35*c0ded849SHemant Agrawal 0x000000ff,
36*c0ded849SHemant Agrawal 0x000000ff
37*c0ded849SHemant Agrawal };
38*c0ded849SHemant Agrawal
39*c0ded849SHemant Agrawal #define IMM_MUST 0
40*c0ded849SHemant Agrawal #define IMM_CAN 1
41*c0ded849SHemant Agrawal #define IMM_NO 2
42*c0ded849SHemant Agrawal #define IMM_DSNM 3 /* it doesn't matter the src type */
43*c0ded849SHemant Agrawal
44*c0ded849SHemant Agrawal enum e_lenoff {
45*c0ded849SHemant Agrawal LENOF_03,
46*c0ded849SHemant Agrawal LENOF_4,
47*c0ded849SHemant Agrawal LENOF_48,
48*c0ded849SHemant Agrawal LENOF_448,
49*c0ded849SHemant Agrawal LENOF_18,
50*c0ded849SHemant Agrawal LENOF_32,
51*c0ded849SHemant Agrawal LENOF_24,
52*c0ded849SHemant Agrawal LENOF_16,
53*c0ded849SHemant Agrawal LENOF_8,
54*c0ded849SHemant Agrawal LENOF_128,
55*c0ded849SHemant Agrawal LENOF_256,
56*c0ded849SHemant Agrawal DSNM /* it doesn't matter the length/offset values */
57*c0ded849SHemant Agrawal };
58*c0ded849SHemant Agrawal
59*c0ded849SHemant Agrawal struct load_map {
60*c0ded849SHemant Agrawal uint32_t dst;
61*c0ded849SHemant Agrawal uint32_t dst_opcode;
62*c0ded849SHemant Agrawal enum e_lenoff len_off;
63*c0ded849SHemant Agrawal uint8_t imm_src;
64*c0ded849SHemant Agrawal
65*c0ded849SHemant Agrawal };
66*c0ded849SHemant Agrawal
67*c0ded849SHemant Agrawal static const struct load_map load_dst[] = {
68*c0ded849SHemant Agrawal /*1*/ { KEY1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
69*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
70*c0ded849SHemant Agrawal { KEY2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
71*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
72*c0ded849SHemant Agrawal { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG,
73*c0ded849SHemant Agrawal LENOF_448, IMM_MUST },
74*c0ded849SHemant Agrawal { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG,
75*c0ded849SHemant Agrawal LENOF_448, IMM_MUST },
76*c0ded849SHemant Agrawal { ICV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
77*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
78*c0ded849SHemant Agrawal { ICV2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
79*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
80*c0ded849SHemant Agrawal { CCTRL, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CHACTRL,
81*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
82*c0ded849SHemant Agrawal { DCTRL, LDST_CLASS_DECO | LDST_IMM | LDST_SRCDST_WORD_DECOCTRL,
83*c0ded849SHemant Agrawal DSNM, IMM_DSNM },
84*c0ded849SHemant Agrawal { ICTRL, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_IRQCTRL,
85*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
86*c0ded849SHemant Agrawal { DPOVRD, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_PCLOVRD,
87*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
88*c0ded849SHemant Agrawal { CLRW, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CLRW,
89*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
90*c0ded849SHemant Agrawal { AAD1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ,
91*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
92*c0ded849SHemant Agrawal { IV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ,
93*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
94*c0ded849SHemant Agrawal { ALTDS1, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ALTDS_CLASS1,
95*c0ded849SHemant Agrawal LENOF_448, IMM_MUST },
96*c0ded849SHemant Agrawal { PKASZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ,
97*c0ded849SHemant Agrawal LENOF_4, IMM_MUST, },
98*c0ded849SHemant Agrawal { PKBSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ,
99*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
100*c0ded849SHemant Agrawal { PKNSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ,
101*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
102*c0ded849SHemant Agrawal { PKESZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ,
103*c0ded849SHemant Agrawal LENOF_4, IMM_MUST },
104*c0ded849SHemant Agrawal { NFIFO, LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_INFO_FIFO,
105*c0ded849SHemant Agrawal LENOF_48, IMM_MUST },
106*c0ded849SHemant Agrawal { IFIFO, LDST_SRCDST_BYTE_INFIFO, LENOF_18, IMM_MUST },
107*c0ded849SHemant Agrawal { OFIFO, LDST_SRCDST_BYTE_OUTFIFO, LENOF_18, IMM_MUST },
108*c0ded849SHemant Agrawal { MATH0, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0,
109*c0ded849SHemant Agrawal LENOF_32, IMM_CAN },
110*c0ded849SHemant Agrawal { MATH1, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1,
111*c0ded849SHemant Agrawal LENOF_24, IMM_CAN },
112*c0ded849SHemant Agrawal { MATH2, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2,
113*c0ded849SHemant Agrawal LENOF_16, IMM_CAN },
114*c0ded849SHemant Agrawal { MATH3, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3,
115*c0ded849SHemant Agrawal LENOF_8, IMM_CAN },
116*c0ded849SHemant Agrawal { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT,
117*c0ded849SHemant Agrawal LENOF_128, IMM_CAN },
118*c0ded849SHemant Agrawal { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT,
119*c0ded849SHemant Agrawal LENOF_128, IMM_CAN },
120*c0ded849SHemant Agrawal { KEY1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_KEY,
121*c0ded849SHemant Agrawal LENOF_32, IMM_CAN },
122*c0ded849SHemant Agrawal { KEY2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY,
123*c0ded849SHemant Agrawal LENOF_32, IMM_CAN },
124*c0ded849SHemant Agrawal { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF,
125*c0ded849SHemant Agrawal LENOF_256, IMM_NO },
126*c0ded849SHemant Agrawal { DPID, LDST_CLASS_DECO | LDST_SRCDST_WORD_PID,
127*c0ded849SHemant Agrawal LENOF_448, IMM_MUST },
128*c0ded849SHemant Agrawal /*32*/ { IDFNS, LDST_SRCDST_WORD_IFNSR, LENOF_18, IMM_MUST },
129*c0ded849SHemant Agrawal { ODFNS, LDST_SRCDST_WORD_OFNSR, LENOF_18, IMM_MUST },
130*c0ded849SHemant Agrawal { ALTSOURCE, LDST_SRCDST_BYTE_ALTSOURCE, LENOF_18, IMM_MUST },
131*c0ded849SHemant Agrawal /*35*/ { NFIFO_SZL, LDST_SRCDST_WORD_INFO_FIFO_SZL, LENOF_48, IMM_MUST },
132*c0ded849SHemant Agrawal { NFIFO_SZM, LDST_SRCDST_WORD_INFO_FIFO_SZM, LENOF_03, IMM_MUST },
133*c0ded849SHemant Agrawal { NFIFO_L, LDST_SRCDST_WORD_INFO_FIFO_L, LENOF_48, IMM_MUST },
134*c0ded849SHemant Agrawal { NFIFO_M, LDST_SRCDST_WORD_INFO_FIFO_M, LENOF_03, IMM_MUST },
135*c0ded849SHemant Agrawal { SZL, LDST_SRCDST_WORD_SZL, LENOF_48, IMM_MUST },
136*c0ded849SHemant Agrawal /*40*/ { SZM, LDST_SRCDST_WORD_SZM, LENOF_03, IMM_MUST }
137*c0ded849SHemant Agrawal };
138*c0ded849SHemant Agrawal
139*c0ded849SHemant Agrawal /*
140*c0ded849SHemant Agrawal * Allowed LOAD destinations for each SEC Era.
141*c0ded849SHemant Agrawal * Values represent the number of entries from load_dst[] that are supported.
142*c0ded849SHemant Agrawal */
143*c0ded849SHemant Agrawal static const unsigned int load_dst_sz[] = { 31, 34, 34, 40, 40,
144*c0ded849SHemant Agrawal 40, 40, 40, 40, 40};
145*c0ded849SHemant Agrawal
146*c0ded849SHemant Agrawal static inline int
load_check_len_offset(int pos,uint32_t length,uint32_t offset)147*c0ded849SHemant Agrawal load_check_len_offset(int pos, uint32_t length, uint32_t offset)
148*c0ded849SHemant Agrawal {
149*c0ded849SHemant Agrawal if ((load_dst[pos].dst == DCTRL) &&
150*c0ded849SHemant Agrawal ((length & ~load_len_mask_allowed[rta_sec_era]) ||
151*c0ded849SHemant Agrawal (offset & ~load_off_mask_allowed[rta_sec_era])))
152*c0ded849SHemant Agrawal goto err;
153*c0ded849SHemant Agrawal
154*c0ded849SHemant Agrawal switch (load_dst[pos].len_off) {
155*c0ded849SHemant Agrawal case (LENOF_03):
156*c0ded849SHemant Agrawal if ((length > 3) || (offset))
157*c0ded849SHemant Agrawal goto err;
158*c0ded849SHemant Agrawal break;
159*c0ded849SHemant Agrawal case (LENOF_4):
160*c0ded849SHemant Agrawal if ((length != 4) || (offset != 0))
161*c0ded849SHemant Agrawal goto err;
162*c0ded849SHemant Agrawal break;
163*c0ded849SHemant Agrawal case (LENOF_48):
164*c0ded849SHemant Agrawal if (!(((length == 4) && (offset == 0)) ||
165*c0ded849SHemant Agrawal ((length == 8) && (offset == 0))))
166*c0ded849SHemant Agrawal goto err;
167*c0ded849SHemant Agrawal break;
168*c0ded849SHemant Agrawal case (LENOF_448):
169*c0ded849SHemant Agrawal if (!(((length == 4) && (offset == 0)) ||
170*c0ded849SHemant Agrawal ((length == 4) && (offset == 4)) ||
171*c0ded849SHemant Agrawal ((length == 8) && (offset == 0))))
172*c0ded849SHemant Agrawal goto err;
173*c0ded849SHemant Agrawal break;
174*c0ded849SHemant Agrawal case (LENOF_18):
175*c0ded849SHemant Agrawal if ((length < 1) || (length > 8) || (offset != 0))
176*c0ded849SHemant Agrawal goto err;
177*c0ded849SHemant Agrawal break;
178*c0ded849SHemant Agrawal case (LENOF_32):
179*c0ded849SHemant Agrawal if ((length > 32) || (offset > 32) || ((offset + length) > 32))
180*c0ded849SHemant Agrawal goto err;
181*c0ded849SHemant Agrawal break;
182*c0ded849SHemant Agrawal case (LENOF_24):
183*c0ded849SHemant Agrawal if ((length > 24) || (offset > 24) || ((offset + length) > 24))
184*c0ded849SHemant Agrawal goto err;
185*c0ded849SHemant Agrawal break;
186*c0ded849SHemant Agrawal case (LENOF_16):
187*c0ded849SHemant Agrawal if ((length > 16) || (offset > 16) || ((offset + length) > 16))
188*c0ded849SHemant Agrawal goto err;
189*c0ded849SHemant Agrawal break;
190*c0ded849SHemant Agrawal case (LENOF_8):
191*c0ded849SHemant Agrawal if ((length > 8) || (offset > 8) || ((offset + length) > 8))
192*c0ded849SHemant Agrawal goto err;
193*c0ded849SHemant Agrawal break;
194*c0ded849SHemant Agrawal case (LENOF_128):
195*c0ded849SHemant Agrawal if ((length > 128) || (offset > 128) ||
196*c0ded849SHemant Agrawal ((offset + length) > 128))
197*c0ded849SHemant Agrawal goto err;
198*c0ded849SHemant Agrawal break;
199*c0ded849SHemant Agrawal case (LENOF_256):
200*c0ded849SHemant Agrawal if ((length < 1) || (length > 256) || ((length + offset) > 256))
201*c0ded849SHemant Agrawal goto err;
202*c0ded849SHemant Agrawal break;
203*c0ded849SHemant Agrawal case (DSNM):
204*c0ded849SHemant Agrawal break;
205*c0ded849SHemant Agrawal default:
206*c0ded849SHemant Agrawal goto err;
207*c0ded849SHemant Agrawal }
208*c0ded849SHemant Agrawal
209*c0ded849SHemant Agrawal return 0;
210*c0ded849SHemant Agrawal err:
211*c0ded849SHemant Agrawal return -EINVAL;
212*c0ded849SHemant Agrawal }
213*c0ded849SHemant Agrawal
214*c0ded849SHemant Agrawal static inline int
rta_load(struct program * program,uint64_t src,uint64_t dst,uint32_t offset,uint32_t length,uint32_t flags)215*c0ded849SHemant Agrawal rta_load(struct program *program, uint64_t src, uint64_t dst,
216*c0ded849SHemant Agrawal uint32_t offset, uint32_t length, uint32_t flags)
217*c0ded849SHemant Agrawal {
218*c0ded849SHemant Agrawal uint32_t opcode = 0;
219*c0ded849SHemant Agrawal int pos = -1, ret = -EINVAL;
220*c0ded849SHemant Agrawal unsigned int start_pc = program->current_pc, i;
221*c0ded849SHemant Agrawal
222*c0ded849SHemant Agrawal if (flags & SEQ)
223*c0ded849SHemant Agrawal opcode = CMD_SEQ_LOAD;
224*c0ded849SHemant Agrawal else
225*c0ded849SHemant Agrawal opcode = CMD_LOAD;
226*c0ded849SHemant Agrawal
227*c0ded849SHemant Agrawal if ((length & 0xffffff00) || (offset & 0xffffff00)) {
228*c0ded849SHemant Agrawal pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
229*c0ded849SHemant Agrawal goto err;
230*c0ded849SHemant Agrawal }
231*c0ded849SHemant Agrawal
232*c0ded849SHemant Agrawal if (flags & SGF)
233*c0ded849SHemant Agrawal opcode |= LDST_SGF;
234*c0ded849SHemant Agrawal if (flags & VLF)
235*c0ded849SHemant Agrawal opcode |= LDST_VLF;
236*c0ded849SHemant Agrawal
237*c0ded849SHemant Agrawal /* check load destination, length and offset and source type */
238*c0ded849SHemant Agrawal for (i = 0; i < load_dst_sz[rta_sec_era]; i++)
239*c0ded849SHemant Agrawal if (dst == load_dst[i].dst) {
240*c0ded849SHemant Agrawal pos = (int)i;
241*c0ded849SHemant Agrawal break;
242*c0ded849SHemant Agrawal }
243*c0ded849SHemant Agrawal if (-1 == pos) {
244*c0ded849SHemant Agrawal pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
245*c0ded849SHemant Agrawal program->current_pc);
246*c0ded849SHemant Agrawal goto err;
247*c0ded849SHemant Agrawal }
248*c0ded849SHemant Agrawal
249*c0ded849SHemant Agrawal if (flags & IMMED) {
250*c0ded849SHemant Agrawal if (load_dst[pos].imm_src == IMM_NO) {
251*c0ded849SHemant Agrawal pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
252*c0ded849SHemant Agrawal program->current_pc);
253*c0ded849SHemant Agrawal goto err;
254*c0ded849SHemant Agrawal }
255*c0ded849SHemant Agrawal opcode |= LDST_IMM;
256*c0ded849SHemant Agrawal } else if (load_dst[pos].imm_src == IMM_MUST) {
257*c0ded849SHemant Agrawal pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
258*c0ded849SHemant Agrawal program->current_pc);
259*c0ded849SHemant Agrawal goto err;
260*c0ded849SHemant Agrawal }
261*c0ded849SHemant Agrawal
262*c0ded849SHemant Agrawal ret = load_check_len_offset(pos, length, offset);
263*c0ded849SHemant Agrawal if (ret < 0) {
264*c0ded849SHemant Agrawal pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
265*c0ded849SHemant Agrawal program->current_pc);
266*c0ded849SHemant Agrawal goto err;
267*c0ded849SHemant Agrawal }
268*c0ded849SHemant Agrawal
269*c0ded849SHemant Agrawal opcode |= load_dst[pos].dst_opcode;
270*c0ded849SHemant Agrawal
271*c0ded849SHemant Agrawal /* DESC BUFFER: length / offset values are specified in 4-byte words */
272*c0ded849SHemant Agrawal if (dst == DESCBUF) {
273*c0ded849SHemant Agrawal opcode |= (length >> 2);
274*c0ded849SHemant Agrawal opcode |= ((offset >> 2) << LDST_OFFSET_SHIFT);
275*c0ded849SHemant Agrawal } else {
276*c0ded849SHemant Agrawal opcode |= length;
277*c0ded849SHemant Agrawal opcode |= (offset << LDST_OFFSET_SHIFT);
278*c0ded849SHemant Agrawal }
279*c0ded849SHemant Agrawal
280*c0ded849SHemant Agrawal __rta_out32(program, opcode);
281*c0ded849SHemant Agrawal program->current_instruction++;
282*c0ded849SHemant Agrawal
283*c0ded849SHemant Agrawal /* DECO CONTROL: skip writing pointer of imm data */
284*c0ded849SHemant Agrawal if (dst == DCTRL)
285*c0ded849SHemant Agrawal return (int)start_pc;
286*c0ded849SHemant Agrawal
287*c0ded849SHemant Agrawal /*
288*c0ded849SHemant Agrawal * For data copy, 3 possible ways to specify how to copy data:
289*c0ded849SHemant Agrawal * - IMMED & !COPY: copy data directly from src( max 8 bytes)
290*c0ded849SHemant Agrawal * - IMMED & COPY: copy data imm from the location specified by user
291*c0ded849SHemant Agrawal * - !IMMED and is not SEQ cmd: copy the address
292*c0ded849SHemant Agrawal */
293*c0ded849SHemant Agrawal if (flags & IMMED)
294*c0ded849SHemant Agrawal __rta_inline_data(program, src, flags & __COPY_MASK, length);
295*c0ded849SHemant Agrawal else if (!(flags & SEQ))
296*c0ded849SHemant Agrawal __rta_out64(program, program->ps, src);
297*c0ded849SHemant Agrawal
298*c0ded849SHemant Agrawal return (int)start_pc;
299*c0ded849SHemant Agrawal
300*c0ded849SHemant Agrawal err:
301*c0ded849SHemant Agrawal program->first_error_pc = start_pc;
302*c0ded849SHemant Agrawal program->current_instruction++;
303*c0ded849SHemant Agrawal return ret;
304*c0ded849SHemant Agrawal }
305*c0ded849SHemant Agrawal
306*c0ded849SHemant Agrawal #endif /* __RTA_LOAD_CMD_H__*/
307