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   */
24  typedef 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   */
42  struct 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   */
58  union 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   */
ap_instructions_available(void)71  static 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 */
91  struct 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   */
ap_tapq(ap_qid_t qid,struct ap_tapq_hwinfo * info)135  static 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   */
ap_test_queue(ap_qid_t qid,int tbit,struct ap_tapq_hwinfo * info)163  static 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   */
ap_rapq(ap_qid_t qid,int fbit)178  static 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   */
ap_zapq(ap_qid_t qid,int fbit)203  static 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   */
225  struct ap_config_info {
226  	union {
227  		unsigned int flags;
228  		struct {
229  			unsigned int apsc	 : 1;	/* S bit */
230  			unsigned int apxa	 : 1;	/* N bit */
231  			unsigned int qact	 : 1;	/* C bit */
232  			unsigned int rc8a	 : 1;	/* R bit */
233  			unsigned int		 : 4;
234  			unsigned int apsb	 : 1;	/* B bit */
235  			unsigned int		 : 23;
236  		};
237  	};
238  	unsigned char na;		/* max # of APs - 1 */
239  	unsigned char nd;		/* max # of Domains - 1 */
240  	unsigned char _reserved0[10];
241  	unsigned int apm[8];		/* AP ID mask */
242  	unsigned int aqm[8];		/* AP (usage) queue mask */
243  	unsigned int adm[8];		/* AP (control) domain mask */
244  	unsigned char _reserved1[16];
245  } __aligned(8);
246  
247  /**
248   * ap_qci(): Get AP configuration data
249   *
250   * Returns 0 on success, or -EOPNOTSUPP.
251   */
ap_qci(struct ap_config_info * config)252  static inline int ap_qci(struct ap_config_info *config)
253  {
254  	unsigned long reg0 = 4UL << 24;  /* fc 4UL is QCI */
255  	unsigned long reg1 = -EOPNOTSUPP;
256  	struct ap_config_info *reg2 = config;
257  
258  	asm volatile(
259  		"	lgr	0,%[reg0]\n"		/* QCI fc into gr0 */
260  		"	lgr	2,%[reg2]\n"		/* ptr to config into gr2 */
261  		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(QCI) */
262  		"0:	la	%[reg1],0\n"		/* good case, QCI fc available */
263  		"1:\n"
264  		EX_TABLE(0b, 1b)
265  		: [reg1] "+&d" (reg1)
266  		: [reg0] "d" (reg0), [reg2] "d" (reg2)
267  		: "cc", "memory", "0", "2");
268  
269  	return reg1;
270  }
271  
272  /*
273   * struct ap_qirq_ctrl - convenient struct for easy invocation
274   * of the ap_aqic() function. This struct is passed as GR1
275   * parameter to the PQAP(AQIC) instruction. For details please
276   * see the AR documentation.
277   */
278  union ap_qirq_ctrl {
279  	unsigned long value;
280  	struct {
281  		unsigned int	   : 8;
282  		unsigned int zone  : 8;	/* zone info */
283  		unsigned int ir	   : 1;	/* ir flag: enable (1) or disable (0) irq */
284  		unsigned int	   : 4;
285  		unsigned int gisc  : 3;	/* guest isc field */
286  		unsigned int	   : 6;
287  		unsigned int gf	   : 2;	/* gisa format */
288  		unsigned int	   : 1;
289  		unsigned int gisa  : 27;	/* gisa origin */
290  		unsigned int	   : 1;
291  		unsigned int isc   : 3;	/* irq sub class */
292  	};
293  };
294  
295  /**
296   * ap_aqic(): Control interruption for a specific AP.
297   * @qid: The AP queue number
298   * @qirqctrl: struct ap_qirq_ctrl (64 bit value)
299   * @pa_ind: Physical address of the notification indicator byte
300   *
301   * Returns AP queue status.
302   */
ap_aqic(ap_qid_t qid,union ap_qirq_ctrl qirqctrl,phys_addr_t pa_ind)303  static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
304  					     union ap_qirq_ctrl qirqctrl,
305  					     phys_addr_t pa_ind)
306  {
307  	unsigned long reg0 = qid | (3UL << 24);  /* fc 3UL is AQIC */
308  	union ap_queue_status_reg reg1;
309  	unsigned long reg2 = pa_ind;
310  
311  	reg1.value = qirqctrl.value;
312  
313  	asm volatile(
314  		"	lgr	0,%[reg0]\n"		/* qid param into gr0 */
315  		"	lgr	1,%[reg1]\n"		/* irq ctrl into gr1 */
316  		"	lgr	2,%[reg2]\n"		/* ni addr into gr2 */
317  		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(AQIC) */
318  		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
319  		: [reg1] "+&d" (reg1.value)
320  		: [reg0] "d" (reg0), [reg2] "d" (reg2)
321  		: "cc", "memory", "0", "1", "2");
322  
323  	return reg1.status;
324  }
325  
326  /*
327   * union ap_qact_ap_info - used together with the
328   * ap_aqic() function to provide a convenient way
329   * to handle the ap info needed by the qact function.
330   */
331  union ap_qact_ap_info {
332  	unsigned long val;
333  	struct {
334  		unsigned int	  : 3;
335  		unsigned int mode : 3;
336  		unsigned int	  : 26;
337  		unsigned int cat  : 8;
338  		unsigned int	  : 8;
339  		unsigned char ver[2];
340  	};
341  };
342  
343  /**
344   * ap_qact(): Query AP compatibility type.
345   * @qid: The AP queue number
346   * @apinfo: On input the info about the AP queue. On output the
347   *	    alternate AP queue info provided by the qact function
348   *	    in GR2 is stored in.
349   *
350   * Returns AP queue status. Check response_code field for failures.
351   */
ap_qact(ap_qid_t qid,int ifbit,union ap_qact_ap_info * apinfo)352  static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
353  					     union ap_qact_ap_info *apinfo)
354  {
355  	unsigned long reg0 = qid | (5UL << 24) | ((ifbit & 0x01) << 22);
356  	union ap_queue_status_reg reg1;
357  	unsigned long reg2;
358  
359  	reg1.value = apinfo->val;
360  
361  	asm volatile(
362  		"	lgr	0,%[reg0]\n"		/* qid param into gr0 */
363  		"	lgr	1,%[reg1]\n"		/* qact in info into gr1 */
364  		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(QACT) */
365  		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
366  		"	lgr	%[reg2],2\n"		/* qact out info into reg2 */
367  		: [reg1] "+&d" (reg1.value), [reg2] "=&d" (reg2)
368  		: [reg0] "d" (reg0)
369  		: "cc", "0", "1", "2");
370  	apinfo->val = reg2;
371  	return reg1.status;
372  }
373  
374  /*
375   * ap_bapq(): SE bind AP queue.
376   * @qid: The AP queue number
377   *
378   * Returns AP queue status structure.
379   *
380   * Invoking this function in a non-SE environment
381   * may case a specification exception.
382   */
ap_bapq(ap_qid_t qid)383  static inline struct ap_queue_status ap_bapq(ap_qid_t qid)
384  {
385  	unsigned long reg0 = qid | (7UL << 24);  /* fc 7 is BAPQ */
386  	union ap_queue_status_reg reg1;
387  
388  	asm volatile(
389  		"	lgr	0,%[reg0]\n"		/* qid arg into gr0 */
390  		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(BAPQ) */
391  		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
392  		: [reg1] "=&d" (reg1.value)
393  		: [reg0] "d" (reg0)
394  		: "cc", "0", "1");
395  
396  	return reg1.status;
397  }
398  
399  /*
400   * ap_aapq(): SE associate AP queue.
401   * @qid: The AP queue number
402   * @sec_idx: The secret index
403   *
404   * Returns AP queue status structure.
405   *
406   * Invoking this function in a non-SE environment
407   * may case a specification exception.
408   */
ap_aapq(ap_qid_t qid,unsigned int sec_idx)409  static inline struct ap_queue_status ap_aapq(ap_qid_t qid, unsigned int sec_idx)
410  {
411  	unsigned long reg0 = qid | (8UL << 24);  /* fc 8 is AAPQ */
412  	unsigned long reg2 = sec_idx;
413  	union ap_queue_status_reg reg1;
414  
415  	asm volatile(
416  		"	lgr	0,%[reg0]\n"		/* qid arg into gr0 */
417  		"	lgr	2,%[reg2]\n"		/* secret index into gr2 */
418  		"	.insn	rre,0xb2af0000,0,0\n"	/* PQAP(AAPQ) */
419  		"	lgr	%[reg1],1\n"		/* gr1 (status) into reg1 */
420  		: [reg1] "=&d" (reg1.value)
421  		: [reg0] "d" (reg0), [reg2] "d" (reg2)
422  		: "cc", "0", "1", "2");
423  
424  	return reg1.status;
425  }
426  
427  /**
428   * ap_nqap(): Send message to adjunct processor queue.
429   * @qid: The AP queue number
430   * @psmid: The program supplied message identifier
431   * @msg: The message text
432   * @length: The message length
433   *
434   * Returns AP queue status structure.
435   * Condition code 1 on NQAP can't happen because the L bit is 1.
436   * Condition code 2 on NQAP also means the send is incomplete,
437   * because a segment boundary was reached. The NQAP is repeated.
438   */
ap_nqap(ap_qid_t qid,unsigned long long psmid,void * msg,size_t length)439  static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
440  					     unsigned long long psmid,
441  					     void *msg, size_t length)
442  {
443  	unsigned long reg0 = qid | 0x40000000UL;  /* 0x4... is last msg part */
444  	union register_pair nqap_r1, nqap_r2;
445  	union ap_queue_status_reg reg1;
446  
447  	nqap_r1.even = (unsigned int)(psmid >> 32);
448  	nqap_r1.odd  = psmid & 0xffffffff;
449  	nqap_r2.even = (unsigned long)msg;
450  	nqap_r2.odd  = (unsigned long)length;
451  
452  	asm volatile (
453  		"	lgr	0,%[reg0]\n"  /* qid param in gr0 */
454  		"0:	.insn	rre,0xb2ad0000,%[nqap_r1],%[nqap_r2]\n"
455  		"	brc	2,0b\n"       /* handle partial completion */
456  		"	lgr	%[reg1],1\n"  /* gr1 (status) into reg1 */
457  		: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1.value),
458  		  [nqap_r2] "+&d" (nqap_r2.pair)
459  		: [nqap_r1] "d" (nqap_r1.pair)
460  		: "cc", "memory", "0", "1");
461  	return reg1.status;
462  }
463  
464  /**
465   * ap_dqap(): Receive message from adjunct processor queue.
466   * @qid: The AP queue number
467   * @psmid: Pointer to program supplied message identifier
468   * @msg: Pointer to message buffer
469   * @msglen: Message buffer size
470   * @length: Pointer to length of actually written bytes
471   * @reslength: Residual length on return
472   * @resgr0: input: gr0 value (only used if != 0), output: residual gr0 content
473   *
474   * Returns AP queue status structure.
475   * Condition code 1 on DQAP means the receive has taken place
476   * but only partially.	The response is incomplete, hence the
477   * DQAP is repeated.
478   * Condition code 2 on DQAP also means the receive is incomplete,
479   * this time because a segment boundary was reached. Again, the
480   * DQAP is repeated.
481   * Note that gpr2 is used by the DQAP instruction to keep track of
482   * any 'residual' length, in case the instruction gets interrupted.
483   * Hence it gets zeroed before the instruction.
484   * If the message does not fit into the buffer, this function will
485   * return with a truncated message and the reply in the firmware queue
486   * is not removed. This is indicated to the caller with an
487   * ap_queue_status response_code value of all bits on (0xFF) and (if
488   * the reslength ptr is given) the remaining length is stored in
489   * *reslength and (if the resgr0 ptr is given) the updated gr0 value
490   * for further processing of this msg entry is stored in *resgr0. The
491   * caller needs to detect this situation and should invoke ap_dqap
492   * with a valid resgr0 ptr and a value in there != 0 to indicate that
493   * *resgr0 is to be used instead of qid to further process this entry.
494   */
ap_dqap(ap_qid_t qid,unsigned long * psmid,void * msg,size_t msglen,size_t * length,size_t * reslength,unsigned long * resgr0)495  static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
496  					     unsigned long *psmid,
497  					     void *msg, size_t msglen,
498  					     size_t *length,
499  					     size_t *reslength,
500  					     unsigned long *resgr0)
501  {
502  	unsigned long reg0 = resgr0 && *resgr0 ? *resgr0 : qid | 0x80000000UL;
503  	union ap_queue_status_reg reg1;
504  	unsigned long reg2;
505  	union register_pair rp1, rp2;
506  
507  	rp1.even = 0UL;
508  	rp1.odd  = 0UL;
509  	rp2.even = (unsigned long)msg;
510  	rp2.odd  = (unsigned long)msglen;
511  
512  	asm volatile(
513  		"	lgr	0,%[reg0]\n"   /* qid param into gr0 */
514  		"	lghi	2,0\n"	       /* 0 into gr2 (res length) */
515  		"0:	ltgr	%N[rp2],%N[rp2]\n" /* check buf len */
516  		"	jz	2f\n"	       /* go out if buf len is 0 */
517  		"1:	.insn	rre,0xb2ae0000,%[rp1],%[rp2]\n"
518  		"	brc	6,0b\n"        /* handle partial complete */
519  		"2:	lgr	%[reg0],0\n"   /* gr0 (qid + info) into reg0 */
520  		"	lgr	%[reg1],1\n"   /* gr1 (status) into reg1 */
521  		"	lgr	%[reg2],2\n"   /* gr2 (res length) into reg2 */
522  		: [reg0] "+&d" (reg0), [reg1] "=&d" (reg1.value),
523  		  [reg2] "=&d" (reg2), [rp1] "+&d" (rp1.pair),
524  		  [rp2] "+&d" (rp2.pair)
525  		:
526  		: "cc", "memory", "0", "1", "2");
527  
528  	if (reslength)
529  		*reslength = reg2;
530  	if (reg2 != 0 && rp2.odd == 0) {
531  		/*
532  		 * Partially complete, status in gr1 is not set.
533  		 * Signal the caller that this dqap is only partially received
534  		 * with a special status response code 0xFF and *resgr0 updated
535  		 */
536  		reg1.status.response_code = 0xFF;
537  		if (resgr0)
538  			*resgr0 = reg0;
539  	} else {
540  		*psmid = (rp1.even << 32) + rp1.odd;
541  		if (resgr0)
542  			*resgr0 = 0;
543  	}
544  
545  	/* update *length with the nr of bytes stored into the msg buffer */
546  	if (length)
547  		*length = msglen - rp2.odd;
548  
549  	return reg1.status;
550  }
551  
552  #endif /* _ASM_S390_AP_H_ */
553