]>
Commit | Line | Data |
---|---|---|
9f95a23c | 1 | /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) |
11fdf7f2 TL |
2 | * |
3 | * Copyright 2008-2016 Freescale Semiconductor Inc. | |
9f95a23c | 4 | * Copyright 2016 NXP |
11fdf7f2 | 5 | * |
11fdf7f2 TL |
6 | */ |
7 | ||
8 | #ifndef __RTA_STORE_CMD_H__ | |
9 | #define __RTA_STORE_CMD_H__ | |
10 | ||
11 | extern enum rta_sec_era rta_sec_era; | |
12 | ||
13 | static const uint32_t store_src_table[][2] = { | |
14 | /*1*/ { KEY1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG }, | |
15 | { KEY2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG }, | |
16 | { DJQDA, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_JQDAR }, | |
17 | { MODE1, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_MODE_REG }, | |
18 | { MODE2, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_MODE_REG }, | |
19 | { DJQCTRL, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_JQCTRL }, | |
20 | { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG }, | |
21 | { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG }, | |
22 | { DSTAT, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_STAT }, | |
23 | { ICV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG }, | |
24 | { ICV2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG }, | |
25 | { DPID, LDST_CLASS_DECO | LDST_SRCDST_WORD_PID }, | |
26 | { CCTRL, LDST_SRCDST_WORD_CHACTRL }, | |
27 | { ICTRL, LDST_SRCDST_WORD_IRQCTRL }, | |
28 | { CLRW, LDST_SRCDST_WORD_CLRW }, | |
29 | { MATH0, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0 }, | |
30 | { CSTAT, LDST_SRCDST_WORD_STAT }, | |
31 | { MATH1, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1 }, | |
32 | { MATH2, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2 }, | |
33 | { AAD1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ }, | |
34 | { MATH3, LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3 }, | |
35 | { IV1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ }, | |
36 | { PKASZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ }, | |
37 | { PKBSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ }, | |
38 | { PKESZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ }, | |
39 | { PKNSZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ }, | |
40 | { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT }, | |
41 | { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT }, | |
42 | { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF }, | |
43 | /*30*/ { JOBDESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF_JOB }, | |
44 | { SHAREDESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF_SHARED }, | |
45 | /*32*/ { JOBDESCBUF_EFF, LDST_CLASS_DECO | | |
46 | LDST_SRCDST_WORD_DESCBUF_JOB_WE }, | |
47 | { SHAREDESCBUF_EFF, LDST_CLASS_DECO | | |
48 | LDST_SRCDST_WORD_DESCBUF_SHARED_WE }, | |
49 | /*34*/ { GTR, LDST_CLASS_DECO | LDST_SRCDST_WORD_GTR }, | |
50 | { STR, LDST_CLASS_DECO | LDST_SRCDST_WORD_STR } | |
51 | }; | |
52 | ||
53 | /* | |
54 | * Allowed STORE sources for each SEC ERA. | |
55 | * Values represent the number of entries from source_src_table[] that are | |
56 | * supported. | |
57 | */ | |
58 | static const unsigned int store_src_table_sz[] = {29, 31, 33, 33, | |
59 | 33, 33, 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__ */ |