1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Adjunct processor (AP) interfaces
4 *
5 * Copyright IBM Corp. 2017
6 *
7 * Author(s): Tony Krowiak <akrowia@linux.vnet.ibm.com>
8 *	      Martin Schwidefsky <schwidefsky@de.ibm.com>
9 *	      Harald Freudenberger <freude@de.ibm.com>
10 */
11
12#ifndef _ASM_S390_AP_H_
13#define _ASM_S390_AP_H_
14
15#include <linux/io.h>
16#include <asm/asm-extable.h>
17
18/**
19 * The ap_qid_t identifier of an ap queue.
20 * If the AP facilities test (APFT) facility is available,
21 * card and queue index are 8 bit values, otherwise
22 * card index is 6 bit and queue index a 4 bit value.
23 */
24typedef unsigned int ap_qid_t;
25
26#define AP_MKQID(_card, _queue) (((_card) & 0xff) << 8 | ((_queue) & 0xff))
27#define AP_QID_CARD(_qid) (((_qid) >> 8) & 0xff)
28#define AP_QID_QUEUE(_qid) ((_qid) & 0xff)
29
30/**
31 * struct ap_queue_status - Holds the AP queue status.
32 * @queue_empty: Shows if queue is empty
33 * @replies_waiting: Waiting replies
34 * @queue_full: Is 1 if the queue is full
35 * @irq_enabled: Shows if interrupts are enabled for the AP
36 * @response_code: Holds the 8 bit response code
37 *
38 * The ap queue status word is returned by all three AP functions
39 * (PQAP, NQAP and DQAP).  There's a set of flags in the first
40 * byte, followed by a 1 byte response code.
41 */
42struct ap_queue_status {
43	unsigned int queue_empty	: 1;
44	unsigned int replies_waiting	: 1;
45	unsigned int queue_full		: 1;
46	unsigned int			: 3;
47	unsigned int async		: 1;
48	unsigned int irq_enabled	: 1;
49	unsigned int response_code	: 8;
50	unsigned int			: 16;
51};
52
53/*
54 * AP queue status reg union to access the reg1
55 * register with the lower 32 bits comprising the
56 * ap queue status.
57 */
58union ap_queue_status_reg {
59	unsigned long value;
60	struct {
61		u32 _pad;
62		struct ap_queue_status status;
63	};
64};
65
66/**
67 * ap_intructions_available() - Test if AP instructions are available.
68 *
69 * Returns true if the AP instructions are installed, otherwise false.
70 */
71static inline bool ap_instructions_available(void)
72{
73	unsigned long reg0 = AP_MKQID(0, 0);
74	unsigned long reg1 = 0;
75
76	asm volatile(
77		"	lgr	0,%[reg0]\n"		/* qid into gr0 */
78		"	lghi	1,0\n"			/* 0 into gr1 */
79		"	lghi	2,0\n"			/* 0 into gr2 */
80		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(TAPQ) */
81		"0:	la	%[reg1],1\n"		/* 1 into reg1 */
82		"1:\n"
83		EX_TABLE(0b, 1b)
84		: [reg1] "+&d" (reg1)
85		: [reg0] "d" (reg0)
86		: "cc", "0", "1", "2");
87	return reg1 != 0;
88}
89
90/* TAPQ register GR2 response struct */
91struct ap_tapq_hwinfo {
92	union {
93		unsigned long value;
94		struct {
95			unsigned int fac    : 32; /* facility bits */
96			unsigned int apinfo : 32; /* ap type, ... */
97		};
98		struct {
99			unsigned int apsc  :  1; /* APSC */
100			unsigned int mex4k :  1; /* AP4KM */
101			unsigned int crt4k :  1; /* AP4KC */
102			unsigned int cca   :  1; /* D */
103			unsigned int accel :  1; /* A */
104			unsigned int ep11  :  1; /* X */
105			unsigned int apxa  :  1; /* APXA */
106			unsigned int	   :  1;
107			unsigned int class :  8;
108			unsigned int bs	   :  2; /* SE bind/assoc */
109			unsigned int	   : 14;
110			unsigned int at	   :  8; /* ap type */
111			unsigned int nd	   :  8; /* nr of domains */
112			unsigned int	   :  4;
113			unsigned int ml	   :  4; /* apxl ml */
114			unsigned int	   :  4;
115			unsigned int qd	   :  4; /* queue depth */
116		};
117	};
118};
119
120/*
121 * Convenience defines to be used with the bs field from struct ap_tapq_gr2
122 */
123#define AP_BS_Q_USABLE		      0
124#define AP_BS_Q_USABLE_NO_SECURE_KEY  1
125#define AP_BS_Q_AVAIL_FOR_BINDING     2
126#define AP_BS_Q_UNUSABLE	      3
127
128/**
129 * ap_tapq(): Test adjunct processor queue.
130 * @qid: The AP queue number
131 * @info: Pointer to tapq hwinfo struct
132 *
133 * Returns AP queue status structure.
134 */
135static inline struct ap_queue_status ap_tapq(ap_qid_t qid,
136					     struct ap_tapq_hwinfo *info)
137{
138	union ap_queue_status_reg reg1;
139	unsigned long reg2;
140
141	asm volatile(
142		"	lgr	0,%[qid]\n"		/* qid into gr0 */
143		"	lghi	2,0\n"			/* 0 into gr2 */
144		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(TAPQ) */
145		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
146		"	lgr	%[reg2],2\n"		/* gr2 into reg2 */
147		: [reg1] "=&d" (reg1.value), [reg2] "=&d" (reg2)
148		: [qid] "d" (qid)
149		: "cc", "0", "1", "2");
150	if (info)
151		info->value = reg2;
152	return reg1.status;
153}
154
155/**
156 * ap_test_queue(): Test adjunct processor queue.
157 * @qid: The AP queue number
158 * @tbit: Test facilities bit
159 * @info: Ptr to tapq gr2 struct
160 *
161 * Returns AP queue status structure.
162 */
163static inline struct ap_queue_status ap_test_queue(ap_qid_t qid, int tbit,
164						   struct ap_tapq_hwinfo *info)
165{
166	if (tbit)
167		qid |= 1UL << 23; /* set T bit*/
168	return ap_tapq(qid, info);
169}
170
171/**
172 * ap_pqap_rapq(): Reset adjunct processor queue.
173 * @qid: The AP queue number
174 * @fbit: if != 0 set F bit
175 *
176 * Returns AP queue status structure.
177 */
178static inline struct ap_queue_status ap_rapq(ap_qid_t qid, int fbit)
179{
180	unsigned long reg0 = qid | (1UL << 24);  /* fc 1UL is RAPQ */
181	union ap_queue_status_reg reg1;
182
183	if (fbit)
184		reg0 |= 1UL << 22;
185
186	asm volatile(
187		"	lgr	0,%[reg0]\n"		/* qid arg into gr0 */
188		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(RAPQ) */
189		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
190		: [reg1] "=&d" (reg1.value)
191		: [reg0] "d" (reg0)
192		: "cc", "0", "1");
193	return reg1.status;
194}
195
196/**
197 * ap_pqap_zapq(): Reset and zeroize adjunct processor queue.
198 * @qid: The AP queue number
199 * @fbit: if != 0 set F bit
200 *
201 * Returns AP queue status structure.
202 */
203static inline struct ap_queue_status ap_zapq(ap_qid_t qid, int fbit)
204{
205	unsigned long reg0 = qid | (2UL << 24);  /* fc 2UL is ZAPQ */
206	union ap_queue_status_reg reg1;
207
208	if (fbit)
209		reg0 |= 1UL << 22;
210
211	asm volatile(
212		"	lgr	0,%[reg0]\n"		/* qid arg into gr0 */
213		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(ZAPQ) */
214		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
215		: [reg1] "=&d" (reg1.value)
216		: [reg0] "d" (reg0)
217		: "cc", "0", "1");
218	return reg1.status;
219}
220
221/**
222 * struct ap_config_info - convenience struct for AP crypto
223 * config info as returned by the ap_qci() function.
224 */
225struct ap_config_info {
226	unsigned int apsc	 : 1;	/* S bit */
227	unsigned int apxa	 : 1;	/* N bit */
228	unsigned int qact	 : 1;	/* C bit */
229	unsigned int rc8a	 : 1;	/* R bit */
230	unsigned int		 : 4;
231	unsigned int apsb	 : 1;	/* B bit */
232	unsigned int		 : 23;
233	unsigned char na;		/* max # of APs - 1 */
234	unsigned char nd;		/* max # of Domains - 1 */
235	unsigned char _reserved0[10];
236	unsigned int apm[8];		/* AP ID mask */
237	unsigned int aqm[8];		/* AP (usage) queue mask */
238	unsigned int adm[8];		/* AP (control) domain mask */
239	unsigned char _reserved1[16];
240} __aligned(8);
241
242/**
243 * ap_qci(): Get AP configuration data
244 *
245 * Returns 0 on success, or -EOPNOTSUPP.
246 */
247static inline int ap_qci(struct ap_config_info *config)
248{
249	unsigned long reg0 = 4UL << 24;  /* fc 4UL is QCI */
250	unsigned long reg1 = -EOPNOTSUPP;
251	struct ap_config_info *reg2 = config;
252
253	asm volatile(
254		"	lgr	0,%[reg0]\n"		/* QCI fc into gr0 */
255		"	lgr	2,%[reg2]\n"		/* ptr to config into gr2 */
256		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(QCI) */
257		"0:	la	%[reg1],0\n"		/* good case, QCI fc available */
258		"1:\n"
259		EX_TABLE(0b, 1b)
260		: [reg1] "+&d" (reg1)
261		: [reg0] "d" (reg0), [reg2] "d" (reg2)
262		: "cc", "memory", "0", "2");
263
264	return reg1;
265}
266
267/*
268 * struct ap_qirq_ctrl - convenient struct for easy invocation
269 * of the ap_aqic() function. This struct is passed as GR1
270 * parameter to the PQAP(AQIC) instruction. For details please
271 * see the AR documentation.
272 */
273union ap_qirq_ctrl {
274	unsigned long value;
275	struct {
276		unsigned int	   : 8;
277		unsigned int zone  : 8;	/* zone info */
278		unsigned int ir	   : 1;	/* ir flag: enable (1) or disable (0) irq */
279		unsigned int	   : 4;
280		unsigned int gisc  : 3;	/* guest isc field */
281		unsigned int	   : 6;
282		unsigned int gf	   : 2;	/* gisa format */
283		unsigned int	   : 1;
284		unsigned int gisa  : 27;	/* gisa origin */
285		unsigned int	   : 1;
286		unsigned int isc   : 3;	/* irq sub class */
287	};
288};
289
290/**
291 * ap_aqic(): Control interruption for a specific AP.
292 * @qid: The AP queue number
293 * @qirqctrl: struct ap_qirq_ctrl (64 bit value)
294 * @pa_ind: Physical address of the notification indicator byte
295 *
296 * Returns AP queue status.
297 */
298static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
299					     union ap_qirq_ctrl qirqctrl,
300					     phys_addr_t pa_ind)
301{
302	unsigned long reg0 = qid | (3UL << 24);  /* fc 3UL is AQIC */
303	union ap_queue_status_reg reg1;
304	unsigned long reg2 = pa_ind;
305
306	reg1.value = qirqctrl.value;
307
308	asm volatile(
309		"	lgr	0,%[reg0]\n"		/* qid param into gr0 */
310		"	lgr	1,%[reg1]\n"		/* irq ctrl into gr1 */
311		"	lgr	2,%[reg2]\n"		/* ni addr into gr2 */
312		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(AQIC) */
313		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
314		: [reg1] "+&d" (reg1.value)
315		: [reg0] "d" (reg0), [reg2] "d" (reg2)
316		: "cc", "memory", "0", "1", "2");
317
318	return reg1.status;
319}
320
321/*
322 * union ap_qact_ap_info - used together with the
323 * ap_aqic() function to provide a convenient way
324 * to handle the ap info needed by the qact function.
325 */
326union ap_qact_ap_info {
327	unsigned long val;
328	struct {
329		unsigned int	  : 3;
330		unsigned int mode : 3;
331		unsigned int	  : 26;
332		unsigned int cat  : 8;
333		unsigned int	  : 8;
334		unsigned char ver[2];
335	};
336};
337
338/**
339 * ap_qact(): Query AP compatibility type.
340 * @qid: The AP queue number
341 * @apinfo: On input the info about the AP queue. On output the
342 *	    alternate AP queue info provided by the qact function
343 *	    in GR2 is stored in.
344 *
345 * Returns AP queue status. Check response_code field for failures.
346 */
347static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
348					     union ap_qact_ap_info *apinfo)
349{
350	unsigned long reg0 = qid | (5UL << 24) | ((ifbit & 0x01) << 22);
351	union ap_queue_status_reg reg1;
352	unsigned long reg2;
353
354	reg1.value = apinfo->val;
355
356	asm volatile(
357		"	lgr	0,%[reg0]\n"		/* qid param into gr0 */
358		"	lgr	1,%[reg1]\n"		/* qact in info into gr1 */
359		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(QACT) */
360		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
361		"	lgr	%[reg2],2\n"		/* qact out info into reg2 */
362		: [reg1] "+&d" (reg1.value), [reg2] "=&d" (reg2)
363		: [reg0] "d" (reg0)
364		: "cc", "0", "1", "2");
365	apinfo->val = reg2;
366	return reg1.status;
367}
368
369/*
370 * ap_bapq(): SE bind AP queue.
371 * @qid: The AP queue number
372 *
373 * Returns AP queue status structure.
374 *
375 * Invoking this function in a non-SE environment
376 * may case a specification exception.
377 */
378static inline struct ap_queue_status ap_bapq(ap_qid_t qid)
379{
380	unsigned long reg0 = qid | (7UL << 24);  /* fc 7 is BAPQ */
381	union ap_queue_status_reg reg1;
382
383	asm volatile(
384		"	lgr	0,%[reg0]\n"		/* qid arg into gr0 */
385		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(BAPQ) */
386		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
387		: [reg1] "=&d" (reg1.value)
388		: [reg0] "d" (reg0)
389		: "cc", "0", "1");
390
391	return reg1.status;
392}
393
394/*
395 * ap_aapq(): SE associate AP queue.
396 * @qid: The AP queue number
397 * @sec_idx: The secret index
398 *
399 * Returns AP queue status structure.
400 *
401 * Invoking this function in a non-SE environment
402 * may case a specification exception.
403 */
404static inline struct ap_queue_status ap_aapq(ap_qid_t qid, unsigned int sec_idx)
405{
406	unsigned long reg0 = qid | (8UL << 24);  /* fc 8 is AAPQ */
407	unsigned long reg2 = sec_idx;
408	union ap_queue_status_reg reg1;
409
410	asm volatile(
411		"	lgr	0,%[reg0]\n"		/* qid arg into gr0 */
412		"	lgr	2,%[reg2]\n"		/* secret index into gr2 */
413		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(AAPQ) */
414		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
415		: [reg1] "=&d" (reg1.value)
416		: [reg0] "d" (reg0), [reg2] "d" (reg2)
417		: "cc", "0", "1", "2");
418
419	return reg1.status;
420}
421
422/**
423 * ap_nqap(): Send message to adjunct processor queue.
424 * @qid: The AP queue number
425 * @psmid: The program supplied message identifier
426 * @msg: The message text
427 * @length: The message length
428 *
429 * Returns AP queue status structure.
430 * Condition code 1 on NQAP can't happen because the L bit is 1.
431 * Condition code 2 on NQAP also means the send is incomplete,
432 * because a segment boundary was reached. The NQAP is repeated.
433 */
434static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
435					     unsigned long long psmid,
436					     void *msg, size_t length)
437{
438	unsigned long reg0 = qid | 0x40000000UL;  /* 0x4... is last msg part */
439	union register_pair nqap_r1, nqap_r2;
440	union ap_queue_status_reg reg1;
441
442	nqap_r1.even = (unsigned int)(psmid >> 32);
443	nqap_r1.odd  = psmid & 0xffffffff;
444	nqap_r2.even = (unsigned long)msg;
445	nqap_r2.odd  = (unsigned long)length;
446
447	asm volatile (
448		"	lgr	0,%[reg0]\n"  /* qid param in gr0 */
449		"0:	.insn	rre,0xb2ad0000,%[nqap_r1],%[nqap_r2]\n"
450		"	brc	2,0b\n"       /* handle partial completion */
451		"	lgr	%[reg1],1\n"  /* gr1 (status) into reg1 */
452		: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1.value),
453		  [nqap_r2] "+&d" (nqap_r2.pair)
454		: [nqap_r1] "d" (nqap_r1.pair)
455		: "cc", "memory", "0", "1");
456	return reg1.status;
457}
458
459/**
460 * ap_dqap(): Receive message from adjunct processor queue.
461 * @qid: The AP queue number
462 * @psmid: Pointer to program supplied message identifier
463 * @msg: Pointer to message buffer
464 * @msglen: Message buffer size
465 * @length: Pointer to length of actually written bytes
466 * @reslength: Residual length on return
467 * @resgr0: input: gr0 value (only used if != 0), output: residual gr0 content
468 *
469 * Returns AP queue status structure.
470 * Condition code 1 on DQAP means the receive has taken place
471 * but only partially.	The response is incomplete, hence the
472 * DQAP is repeated.
473 * Condition code 2 on DQAP also means the receive is incomplete,
474 * this time because a segment boundary was reached. Again, the
475 * DQAP is repeated.
476 * Note that gpr2 is used by the DQAP instruction to keep track of
477 * any 'residual' length, in case the instruction gets interrupted.
478 * Hence it gets zeroed before the instruction.
479 * If the message does not fit into the buffer, this function will
480 * return with a truncated message and the reply in the firmware queue
481 * is not removed. This is indicated to the caller with an
482 * ap_queue_status response_code value of all bits on (0xFF) and (if
483 * the reslength ptr is given) the remaining length is stored in
484 * *reslength and (if the resgr0 ptr is given) the updated gr0 value
485 * for further processing of this msg entry is stored in *resgr0. The
486 * caller needs to detect this situation and should invoke ap_dqap
487 * with a valid resgr0 ptr and a value in there != 0 to indicate that
488 * *resgr0 is to be used instead of qid to further process this entry.
489 */
490static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
491					     unsigned long *psmid,
492					     void *msg, size_t msglen,
493					     size_t *length,
494					     size_t *reslength,
495					     unsigned long *resgr0)
496{
497	unsigned long reg0 = resgr0 && *resgr0 ? *resgr0 : qid | 0x80000000UL;
498	union ap_queue_status_reg reg1;
499	unsigned long reg2;
500	union register_pair rp1, rp2;
501
502	rp1.even = 0UL;
503	rp1.odd  = 0UL;
504	rp2.even = (unsigned long)msg;
505	rp2.odd  = (unsigned long)msglen;
506
507	asm volatile(
508		"	lgr	0,%[reg0]\n"   /* qid param into gr0 */
509		"	lghi	2,0\n"	       /* 0 into gr2 (res length) */
510		"0:	ltgr	%N[rp2],%N[rp2]\n" /* check buf len */
511		"	jz	2f\n"	       /* go out if buf len is 0 */
512		"1:	.insn	rre,0xb2ae0000,%[rp1],%[rp2]\n"
513		"	brc	6,0b\n"        /* handle partial complete */
514		"2:	lgr	%[reg0],0\n"   /* gr0 (qid + info) into reg0 */
515		"	lgr	%[reg1],1\n"   /* gr1 (status) into reg1 */
516		"	lgr	%[reg2],2\n"   /* gr2 (res length) into reg2 */
517		: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1.value),
518		  [reg2] "=&d" (reg2), [rp1] "+&d" (rp1.pair),
519		  [rp2] "+&d" (rp2.pair)
520		:
521		: "cc", "memory", "0", "1", "2");
522
523	if (reslength)
524		*reslength = reg2;
525	if (reg2 != 0 && rp2.odd == 0) {
526		/*
527		 * Partially complete, status in gr1 is not set.
528		 * Signal the caller that this dqap is only partially received
529		 * with a special status response code 0xFF and *resgr0 updated
530		 */
531		reg1.status.response_code = 0xFF;
532		if (resgr0)
533			*resgr0 = reg0;
534	} else {
535		*psmid = (rp1.even << 32) + rp1.odd;
536		if (resgr0)
537			*resgr0 = 0;
538	}
539
540	/* update *length with the nr of bytes stored into the msg buffer */
541	if (length)
542		*length = msglen - rp2.odd;
543
544	return reg1.status;
545}
546
547/*
548 * Interface to tell the AP bus code that a configuration
549 * change has happened. The bus code should at least do
550 * an ap bus resource rescan.
551 */
552#if IS_ENABLED(CONFIG_ZCRYPT)
553void ap_bus_cfg_chg(void);
554#else
555static inline void ap_bus_cfg_chg(void){}
556#endif
557
558#endif /* _ASM_S390_AP_H_ */
559