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