1fee1bbd26109b9f4994f2d89613e4b4338337cf
[dpdk.git] / drivers / crypto / dpaa2_sec / hw / rta / store_cmd.h
1 /*
2  * Copyright 2008-2016 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause or GPL-2.0+
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
60 static inline int
61 rta_store(struct program *program, uint64_t src,
62           uint16_t offset, uint64_t dst, uint32_t length,
63           uint32_t flags)
64 {
65         uint32_t opcode = 0, val;
66         int ret = -EINVAL;
67         unsigned int start_pc = program->current_pc;
68
69         if (flags & SEQ)
70                 opcode = CMD_SEQ_STORE;
71         else
72                 opcode = CMD_STORE;
73
74         /* parameters check */
75         if ((flags & IMMED) && (flags & SGF)) {
76                 pr_err("STORE: Invalid flag. SEC PC: %d; Instr: %d\n",
77                        program->current_pc, program->current_instruction);
78                 goto err;
79         }
80         if ((flags & IMMED) && (offset != 0)) {
81                 pr_err("STORE: Invalid flag. SEC PC: %d; Instr: %d\n",
82                        program->current_pc, program->current_instruction);
83                 goto err;
84         }
85
86         if ((flags & SEQ) && ((src == JOBDESCBUF) || (src == SHAREDESCBUF) ||
87                               (src == JOBDESCBUF_EFF) ||
88                               (src == SHAREDESCBUF_EFF))) {
89                 pr_err("STORE: Invalid SRC type. SEC PC: %d; Instr: %d\n",
90                        program->current_pc, program->current_instruction);
91                 goto err;
92         }
93
94         if (flags & IMMED)
95                 opcode |= LDST_IMM;
96
97         if ((flags & SGF) || (flags & VLF))
98                 opcode |= LDST_VLF;
99
100         /*
101          * source for data to be stored can be specified as:
102          *    - register location; set in src field[9-15];
103          *    - if IMMED flag is set, data is set in value field [0-31];
104          *      user can give this value as actual value or pointer to data
105          */
106         if (!(flags & IMMED)) {
107                 ret = __rta_map_opcode((uint32_t)src, store_src_table,
108                                        store_src_table_sz[rta_sec_era], &val);
109                 if (ret < 0) {
110                         pr_err("STORE: Invalid source. SEC PC: %d; Instr: %d\n",
111                                program->current_pc,
112                                program->current_instruction);
113                         goto err;
114                 }
115                 opcode |= val;
116         }
117
118         /* DESC BUFFER: length / offset values are specified in 4-byte words */
119         if ((src == DESCBUF) || (src == JOBDESCBUF) || (src == SHAREDESCBUF) ||
120             (src == JOBDESCBUF_EFF) || (src == SHAREDESCBUF_EFF)) {
121                 opcode |= (length >> 2);
122                 opcode |= (uint32_t)((offset >> 2) << LDST_OFFSET_SHIFT);
123         } else {
124                 opcode |= length;
125                 opcode |= (uint32_t)(offset << LDST_OFFSET_SHIFT);
126         }
127
128         __rta_out32(program, opcode);
129         program->current_instruction++;
130
131         if ((src == JOBDESCBUF) || (src == SHAREDESCBUF) ||
132             (src == JOBDESCBUF_EFF) || (src == SHAREDESCBUF_EFF))
133                 return (int)start_pc;
134
135         /* for STORE, a pointer to where the data will be stored if needed */
136         if (!(flags & SEQ))
137                 __rta_out64(program, program->ps, dst);
138
139         /* for IMMED data, place the data here */
140         if (flags & IMMED)
141                 __rta_inline_data(program, src, flags & __COPY_MASK, length);
142
143         return (int)start_pc;
144
145  err:
146         program->first_error_pc = start_pc;
147         program->current_instruction++;
148         return ret;
149 }
150
151 #endif /* __RTA_STORE_CMD_H__ */