1 /* Copyright 2015 IBM Corp.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 * implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <skiboot.h>
18 #include <chip.h>
19 #include <xscom.h>
20 #include <io.h>
21 #include <cpu.h>
22 #include <nx.h>
23
24 /* Configuration settings */
25 #define CFG_SYM_FC_ENABLE (0) /* disable all sym functions */
26 #define CFG_SYM_ENABLE (0) /* disable sym engines */
27 #define CFG_ASYM_FC_ENABLE (0) /* disable all asym functions */
28 #define CFG_ASYM_ENABLE (0) /* disable asym engines */
29 #define CFG_CRB_IQ_SYM (0) /* don't use any extra input queues */
30 #define CFG_CRB_IQ_ASYM (0) /* don't use any extra input queues */
31 #define AES_SHA_MAX_RR (1) /* valid range: 1-8 */
32 #define AES_SHA_CSB_WR NX_DMA_CSB_WR_PDMA
33 #define AES_SHA_COMPLETION_MODE NX_DMA_COMPLETION_MODE_PDMA
34 #define AES_SHA_CPB_WR NX_DMA_CPB_WR_DMA_NOPAD
35 #define AES_SHA_OUTPUT_DATA_WR NX_DMA_OUTPUT_DATA_WR_DMA
36 #define AMF_MAX_RR (1) /* valid range: 1-8 */
37 #define AMF_CSB_WR NX_DMA_CSB_WR_PDMA
38 #define AMF_COMPLETION_MODE NX_DMA_COMPLETION_MODE_PDMA
39 #define AMF_CPB_WR (0) /* CPB WR not done with AMF */
40 #define AMF_OUTPUT_DATA_WR NX_DMA_OUTPUT_DATA_WR_DMA
41 #define EE_CH7 (0) /* disable engine AMF 3(P8) */
42 #define EE_CH6 (0) /* disable engine AMF 2(P8) */
43 #define EE_CH5 (0) /* disable engine AMF 1(P8) */
44 #define EE_CH4 (0) /* disable engine SYM AMF 0(P8) */
45 #define EE_CH3 (0) /* disable engine SYM 1 */
46 #define EE_CH2 (0) /* disable engine SYM 0 */
47
nx_cfg_sym(u32 gcid,u64 xcfg)48 static int nx_cfg_sym(u32 gcid, u64 xcfg)
49 {
50 u64 cfg, ci, ct;
51 int rc, instance = gcid + 1;
52
53 BUILD_ASSERT(MAX_CHIPS < NX_SYM_CFG_CI_MAX);
54
55 rc = xscom_read(gcid, xcfg, &cfg);
56 if (rc) {
57 prerror("NX%d: ERROR: XSCOM SYM config read failure %d\n",
58 gcid, rc);
59 return rc;
60 }
61
62 ct = GETFIELD(NX_SYM_CFG_CT, cfg);
63 if (!ct)
64 prlog(PR_INFO, "NX%d: SYM CT set to %u\n", gcid, NX_CT_SYM);
65 else if (ct == NX_CT_SYM)
66 prlog(PR_INFO, "NX%d: SYM CT already set to %u\n",
67 gcid, NX_CT_SYM);
68 else
69 prlog(PR_INFO, "NX%d: SYM CT already set to %u, "
70 "changing to %u\n", gcid, (unsigned int)ct, NX_CT_SYM);
71 ct = NX_CT_SYM;
72 cfg = SETFIELD(NX_SYM_CFG_CT, cfg, ct);
73
74 /* Coprocessor Instance must be shifted left.
75 * See hw doc Section 5.5.1.
76 */
77 ci = GETFIELD(NX_SYM_CFG_CI, cfg) >> NX_SYM_CFG_CI_LSHIFT;
78 if (!ci)
79 prlog(PR_INFO, "NX%d: SYM CI set to %d\n", gcid, instance);
80 else if (ci == instance)
81 prlog(PR_INFO, "NX%d: SYM CI already set to %u\n", gcid,
82 (unsigned int)ci);
83 else
84 prlog(PR_INFO, "NX%d: SYM CI already set to %u, "
85 "changing to %d\n", gcid, (unsigned int)ci, instance);
86 ci = instance;
87 cfg = SETFIELD(NX_SYM_CFG_CI, cfg, ci << NX_SYM_CFG_CI_LSHIFT);
88
89 cfg = SETFIELD(NX_SYM_CFG_FC_ENABLE, cfg, CFG_SYM_FC_ENABLE);
90
91 cfg = SETFIELD(NX_SYM_CFG_ENABLE, cfg, CFG_SYM_ENABLE);
92
93 rc = xscom_write(gcid, xcfg, cfg);
94 if (rc)
95 prerror("NX%d: ERROR: SYM CT %u CI %u config failure %d\n",
96 gcid, (unsigned int)ct, (unsigned int)ci, rc);
97 else
98 prlog(PR_DEBUG, "NX%d: SYM Config 0x%016lx\n",
99 gcid, (unsigned long)cfg);
100
101 return rc;
102 }
103
nx_cfg_asym(u32 gcid,u64 xcfg)104 static int nx_cfg_asym(u32 gcid, u64 xcfg)
105 {
106 u64 cfg, ci, ct;
107 int rc, instance = gcid + 1;
108
109 BUILD_ASSERT(MAX_CHIPS < NX_ASYM_CFG_CI_MAX);
110
111 rc = xscom_read(gcid, xcfg, &cfg);
112 if (rc) {
113 prerror("NX%d: ERROR: XSCOM ASYM config read failure %d\n",
114 gcid, rc);
115 return rc;
116 }
117
118 ct = GETFIELD(NX_ASYM_CFG_CT, cfg);
119 if (!ct)
120 prlog(PR_INFO, "NX%d: ASYM CT set to %u\n",
121 gcid, NX_CT_ASYM);
122 else if (ct == NX_CT_ASYM)
123 prlog(PR_INFO, "NX%d: ASYM CT already set to %u\n",
124 gcid, NX_CT_ASYM);
125 else
126 prlog(PR_INFO, "NX%d: ASYM CT already set to %u, "
127 "changing to %u\n", gcid, (unsigned int)ct, NX_CT_ASYM);
128 ct = NX_CT_ASYM;
129 cfg = SETFIELD(NX_ASYM_CFG_CT, cfg, ct);
130
131 /* Coprocessor Instance must be shifted left.
132 * See hw doc Section 5.5.1.
133 */
134 ci = GETFIELD(NX_ASYM_CFG_CI, cfg) >> NX_ASYM_CFG_CI_LSHIFT;
135 if (!ci)
136 prlog(PR_INFO, "NX%d: ASYM CI set to %d\n", gcid, instance);
137 else if (ci == instance)
138 prlog(PR_INFO, "NX%d: ASYM CI already set to %u\n", gcid,
139 (unsigned int)ci);
140 else
141 prlog(PR_INFO, "NX%d: ASYM CI already set to %u, "
142 "changing to %d\n", gcid, (unsigned int)ci, instance);
143 ci = instance;
144 cfg = SETFIELD(NX_ASYM_CFG_CI, cfg, ci << NX_ASYM_CFG_CI_LSHIFT);
145
146 cfg = SETFIELD(NX_ASYM_CFG_FC_ENABLE, cfg, CFG_ASYM_FC_ENABLE);
147
148 cfg = SETFIELD(NX_ASYM_CFG_ENABLE, cfg, CFG_ASYM_ENABLE);
149
150 rc = xscom_write(gcid, xcfg, cfg);
151 if (rc)
152 prerror("NX%d: ERROR: ASYM CT %u CI %u config failure %d\n",
153 gcid, (unsigned int)ct, (unsigned int)ci, rc);
154 else
155 prlog(PR_DEBUG, "NX%d: ASYM Config 0x%016lx\n",
156 gcid, (unsigned long)cfg);
157
158 return rc;
159 }
160
nx_cfg_dma(u32 gcid,u64 xcfg)161 static int nx_cfg_dma(u32 gcid, u64 xcfg)
162 {
163 u64 cfg;
164 int rc;
165
166 rc = xscom_read(gcid, xcfg, &cfg);
167 if (rc) {
168 prerror("NX%d: ERROR: XSCOM DMA config read failure %d\n",
169 gcid, rc);
170 return rc;
171 }
172
173 cfg = SETFIELD(NX_DMA_CFG_AES_SHA_MAX_RR, cfg,
174 AES_SHA_MAX_RR);
175 cfg = SETFIELD(NX_DMA_CFG_AES_SHA_CSB_WR, cfg,
176 AES_SHA_CSB_WR);
177 cfg = SETFIELD(NX_DMA_CFG_AES_SHA_COMPLETION_MODE, cfg,
178 AES_SHA_COMPLETION_MODE);
179 cfg = SETFIELD(NX_DMA_CFG_AES_SHA_CPB_WR, cfg,
180 AES_SHA_CPB_WR);
181 cfg = SETFIELD(NX_DMA_CFG_AES_SHA_OUTPUT_DATA_WR, cfg,
182 AES_SHA_OUTPUT_DATA_WR);
183
184 cfg = SETFIELD(NX_DMA_CFG_AMF_MAX_RR, cfg,
185 AMF_MAX_RR);
186 cfg = SETFIELD(NX_DMA_CFG_AMF_CSB_WR, cfg,
187 AMF_CSB_WR);
188 cfg = SETFIELD(NX_DMA_CFG_AMF_COMPLETION_MODE, cfg,
189 AMF_COMPLETION_MODE);
190 cfg = SETFIELD(NX_DMA_CFG_AMF_CPB_WR, cfg,
191 AMF_CPB_WR);
192 cfg = SETFIELD(NX_DMA_CFG_AMF_OUTPUT_DATA_WR, cfg,
193 AMF_OUTPUT_DATA_WR);
194
195 rc = xscom_write(gcid, xcfg, cfg);
196 if (rc)
197 prerror("NX%d: ERROR: DMA config failure %d\n", gcid, rc);
198 else
199 prlog(PR_DEBUG, "NX%d: DMA 0x%016lx\n", gcid,
200 (unsigned long)cfg);
201
202 return rc;
203 }
204
nx_cfg_iq(u32 gcid,u64 xcfg)205 static int nx_cfg_iq(u32 gcid, u64 xcfg)
206 {
207 u64 cfg;
208 int rc;
209
210 rc = xscom_read(gcid, xcfg, &cfg);
211 if (rc) {
212 prerror("NX%d: ERROR: XSCOM CRB IQ config read failure %d\n",
213 gcid, rc);
214 return rc;
215 }
216
217 cfg = SETFIELD(NX_CRB_IQ_SYM, cfg, CFG_CRB_IQ_SYM);
218 cfg = SETFIELD(NX_CRB_IQ_ASYM, cfg, CFG_CRB_IQ_ASYM);
219
220 rc = xscom_write(gcid, xcfg, cfg);
221 if (rc)
222 prerror("NX%d: ERROR: CRB Input Queue failure %d\n", gcid, rc);
223 else
224 prlog(PR_DEBUG, "NX%d: CRB Input Queue 0x%016lx\n",
225 gcid, (unsigned long)cfg);
226
227 return rc;
228 }
229
nx_cfg_ee(u32 gcid,u64 xcfg)230 static int nx_cfg_ee(u32 gcid, u64 xcfg)
231 {
232 u64 cfg;
233 int rc;
234
235 rc = xscom_read(gcid, xcfg, &cfg);
236 if (rc) {
237 prerror("NX%d: ERROR: XSCOM EE config read failure %d\n",
238 gcid, rc);
239 return rc;
240 }
241
242 cfg = SETFIELD(NX_EE_CFG_CH7, cfg, EE_CH7);
243 cfg = SETFIELD(NX_EE_CFG_CH6, cfg, EE_CH6);
244 cfg = SETFIELD(NX_EE_CFG_CH5, cfg, EE_CH5);
245 cfg = SETFIELD(NX_EE_CFG_CH4, cfg, EE_CH4);
246 cfg = SETFIELD(NX_EE_CFG_CH3, cfg, EE_CH3);
247 cfg = SETFIELD(NX_EE_CFG_CH2, cfg, EE_CH2);
248
249 rc = xscom_write(gcid, xcfg, cfg);
250 if (rc)
251 prerror("NX%d: ERROR: Engine Enable failure %d\n", gcid, rc);
252 else
253 prlog(PR_DEBUG, "NX%d: Engine Enable 0x%016lx\n",
254 gcid, (unsigned long)cfg);
255
256 return rc;
257 }
258
nx_create_crypto_node(struct dt_node * node)259 void nx_create_crypto_node(struct dt_node *node)
260 {
261 u32 gcid;
262 u32 pb_base;
263 u64 cfg_dma, cfg_sym, cfg_asym, cfg_iq, cfg_ee;
264 int rc;
265
266 gcid = dt_get_chip_id(node);
267 pb_base = dt_get_address(node, 0, NULL);
268
269 prlog(PR_INFO, "NX%d: Crypto at 0x%x\n", gcid, pb_base);
270
271 if (dt_node_is_compatible(node, "ibm,power8-nx")) {
272 cfg_dma = pb_base + NX_P8_DMA_CFG;
273 cfg_sym = pb_base + NX_P8_SYM_CFG;
274 cfg_asym = pb_base + NX_P8_ASYM_CFG;
275 cfg_iq = pb_base + NX_P8_CRB_IQ;
276 cfg_ee = pb_base + NX_P8_EE_CFG;
277 } else if (dt_node_is_compatible(node, "ibm,power9-nx")) {
278 prlog(PR_INFO, "NX%d: POWER9 nx-crypto not yet supported\n",
279 gcid);
280 return;
281 } else {
282 prerror("NX%d: ERROR: Unknown NX type!\n", gcid);
283 return;
284 }
285
286 rc = nx_cfg_dma(gcid, cfg_dma);
287 if (rc)
288 return;
289
290 rc = nx_cfg_sym(gcid, cfg_sym);
291 if (rc)
292 return;
293
294 rc = nx_cfg_asym(gcid, cfg_asym);
295 if (rc)
296 return;
297
298 rc = nx_cfg_iq(gcid, cfg_iq);
299 if (rc)
300 return;
301
302 rc = nx_cfg_ee(gcid, cfg_ee);
303 if (rc)
304 return;
305
306 prlog(PR_INFO, "NX%d: Crypto Coprocessors Disabled (not supported)\n", gcid);
307 }
308