root/arch/s390/include/asm/ap.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ap_instructions_available
  2. ap_tapq
  3. ap_test_queue
  4. ap_rapq
  5. ap_zapq
  6. ap_qci
  7. ap_aqic
  8. ap_qact
  9. ap_nqap
  10. ap_dqap
  11. ap_bus_cfg_chg

   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 /**
  16  * The ap_qid_t identifier of an ap queue.
  17  * If the AP facilities test (APFT) facility is available,
  18  * card and queue index are 8 bit values, otherwise
  19  * card index is 6 bit and queue index a 4 bit value.
  20  */
  21 typedef unsigned int ap_qid_t;
  22 
  23 #define AP_MKQID(_card, _queue) (((_card) & 0xff) << 8 | ((_queue) & 0xff))
  24 #define AP_QID_CARD(_qid) (((_qid) >> 8) & 0xff)
  25 #define AP_QID_QUEUE(_qid) ((_qid) & 0xff)
  26 
  27 /**
  28  * struct ap_queue_status - Holds the AP queue status.
  29  * @queue_empty: Shows if queue is empty
  30  * @replies_waiting: Waiting replies
  31  * @queue_full: Is 1 if the queue is full
  32  * @irq_enabled: Shows if interrupts are enabled for the AP
  33  * @response_code: Holds the 8 bit response code
  34  *
  35  * The ap queue status word is returned by all three AP functions
  36  * (PQAP, NQAP and DQAP).  There's a set of flags in the first
  37  * byte, followed by a 1 byte response code.
  38  */
  39 struct ap_queue_status {
  40         unsigned int queue_empty        : 1;
  41         unsigned int replies_waiting    : 1;
  42         unsigned int queue_full         : 1;
  43         unsigned int _pad1              : 4;
  44         unsigned int irq_enabled        : 1;
  45         unsigned int response_code      : 8;
  46         unsigned int _pad2              : 16;
  47 };
  48 
  49 /**
  50  * ap_intructions_available() - Test if AP instructions are available.
  51  *
  52  * Returns true if the AP instructions are installed, otherwise false.
  53  */
  54 static inline bool ap_instructions_available(void)
  55 {
  56         register unsigned long reg0 asm ("0") = AP_MKQID(0, 0);
  57         register unsigned long reg1 asm ("1") = 0;
  58         register unsigned long reg2 asm ("2") = 0;
  59 
  60         asm volatile(
  61                 "   .long 0xb2af0000\n"         /* PQAP(TAPQ) */
  62                 "0: la    %0,1\n"
  63                 "1:\n"
  64                 EX_TABLE(0b, 1b)
  65                 : "+d" (reg1), "+d" (reg2)
  66                 : "d" (reg0)
  67                 : "cc");
  68         return reg1 != 0;
  69 }
  70 
  71 /**
  72  * ap_tapq(): Test adjunct processor queue.
  73  * @qid: The AP queue number
  74  * @info: Pointer to queue descriptor
  75  *
  76  * Returns AP queue status structure.
  77  */
  78 static inline struct ap_queue_status ap_tapq(ap_qid_t qid, unsigned long *info)
  79 {
  80         register unsigned long reg0 asm ("0") = qid;
  81         register struct ap_queue_status reg1 asm ("1");
  82         register unsigned long reg2 asm ("2");
  83 
  84         asm volatile(".long 0xb2af0000"         /* PQAP(TAPQ) */
  85                      : "=d" (reg1), "=d" (reg2)
  86                      : "d" (reg0)
  87                      : "cc");
  88         if (info)
  89                 *info = reg2;
  90         return reg1;
  91 }
  92 
  93 /**
  94  * ap_test_queue(): Test adjunct processor queue.
  95  * @qid: The AP queue number
  96  * @tbit: Test facilities bit
  97  * @info: Pointer to queue descriptor
  98  *
  99  * Returns AP queue status structure.
 100  */
 101 static inline struct ap_queue_status ap_test_queue(ap_qid_t qid,
 102                                                    int tbit,
 103                                                    unsigned long *info)
 104 {
 105         if (tbit)
 106                 qid |= 1UL << 23; /* set T bit*/
 107         return ap_tapq(qid, info);
 108 }
 109 
 110 /**
 111  * ap_pqap_rapq(): Reset adjunct processor queue.
 112  * @qid: The AP queue number
 113  *
 114  * Returns AP queue status structure.
 115  */
 116 static inline struct ap_queue_status ap_rapq(ap_qid_t qid)
 117 {
 118         register unsigned long reg0 asm ("0") = qid | (1UL << 24);
 119         register struct ap_queue_status reg1 asm ("1");
 120 
 121         asm volatile(
 122                 ".long 0xb2af0000"              /* PQAP(RAPQ) */
 123                 : "=d" (reg1)
 124                 : "d" (reg0)
 125                 : "cc");
 126         return reg1;
 127 }
 128 
 129 /**
 130  * ap_pqap_zapq(): Reset and zeroize adjunct processor queue.
 131  * @qid: The AP queue number
 132  *
 133  * Returns AP queue status structure.
 134  */
 135 static inline struct ap_queue_status ap_zapq(ap_qid_t qid)
 136 {
 137         register unsigned long reg0 asm ("0") = qid | (2UL << 24);
 138         register struct ap_queue_status reg1 asm ("1");
 139 
 140         asm volatile(
 141                 ".long 0xb2af0000"              /* PQAP(ZAPQ) */
 142                 : "=d" (reg1)
 143                 : "d" (reg0)
 144                 : "cc");
 145         return reg1;
 146 }
 147 
 148 /**
 149  * struct ap_config_info - convenience struct for AP crypto
 150  * config info as returned by the ap_qci() function.
 151  */
 152 struct ap_config_info {
 153         unsigned int apsc        : 1;   /* S bit */
 154         unsigned int apxa        : 1;   /* N bit */
 155         unsigned int qact        : 1;   /* C bit */
 156         unsigned int rc8a        : 1;   /* R bit */
 157         unsigned char _reserved1 : 4;
 158         unsigned char _reserved2[3];
 159         unsigned char Na;               /* max # of APs - 1 */
 160         unsigned char Nd;               /* max # of Domains - 1 */
 161         unsigned char _reserved3[10];
 162         unsigned int apm[8];            /* AP ID mask */
 163         unsigned int aqm[8];            /* AP (usage) queue mask */
 164         unsigned int adm[8];            /* AP (control) domain mask */
 165         unsigned char _reserved4[16];
 166 } __aligned(8);
 167 
 168 /**
 169  * ap_qci(): Get AP configuration data
 170  *
 171  * Returns 0 on success, or -EOPNOTSUPP.
 172  */
 173 static inline int ap_qci(struct ap_config_info *config)
 174 {
 175         register unsigned long reg0 asm ("0") = 4UL << 24;
 176         register unsigned long reg1 asm ("1") = -EOPNOTSUPP;
 177         register struct ap_config_info *reg2 asm ("2") = config;
 178 
 179         asm volatile(
 180                 ".long 0xb2af0000\n"            /* PQAP(QCI) */
 181                 "0: la    %0,0\n"
 182                 "1:\n"
 183                 EX_TABLE(0b, 1b)
 184                 : "+d" (reg1)
 185                 : "d" (reg0), "d" (reg2)
 186                 : "cc", "memory");
 187 
 188         return reg1;
 189 }
 190 
 191 /*
 192  * struct ap_qirq_ctrl - convenient struct for easy invocation
 193  * of the ap_aqic() function. This struct is passed as GR1
 194  * parameter to the PQAP(AQIC) instruction. For details please
 195  * see the AR documentation.
 196  */
 197 struct ap_qirq_ctrl {
 198         unsigned int _res1 : 8;
 199         unsigned int zone  : 8; /* zone info */
 200         unsigned int ir    : 1; /* ir flag: enable (1) or disable (0) irq */
 201         unsigned int _res2 : 4;
 202         unsigned int gisc  : 3; /* guest isc field */
 203         unsigned int _res3 : 6;
 204         unsigned int gf    : 2; /* gisa format */
 205         unsigned int _res4 : 1;
 206         unsigned int gisa  : 27;        /* gisa origin */
 207         unsigned int _res5 : 1;
 208         unsigned int isc   : 3; /* irq sub class */
 209 };
 210 
 211 /**
 212  * ap_aqic(): Control interruption for a specific AP.
 213  * @qid: The AP queue number
 214  * @qirqctrl: struct ap_qirq_ctrl (64 bit value)
 215  * @ind: The notification indicator byte
 216  *
 217  * Returns AP queue status.
 218  */
 219 static inline struct ap_queue_status ap_aqic(ap_qid_t qid,
 220                                              struct ap_qirq_ctrl qirqctrl,
 221                                              void *ind)
 222 {
 223         register unsigned long reg0 asm ("0") = qid | (3UL << 24);
 224         register union {
 225                 unsigned long value;
 226                 struct ap_qirq_ctrl qirqctrl;
 227                 struct ap_queue_status status;
 228         } reg1 asm ("1");
 229         register void *reg2 asm ("2") = ind;
 230 
 231         reg1.qirqctrl = qirqctrl;
 232 
 233         asm volatile(
 234                 ".long 0xb2af0000"              /* PQAP(AQIC) */
 235                 : "+d" (reg1)
 236                 : "d" (reg0), "d" (reg2)
 237                 : "cc");
 238 
 239         return reg1.status;
 240 }
 241 
 242 /*
 243  * union ap_qact_ap_info - used together with the
 244  * ap_aqic() function to provide a convenient way
 245  * to handle the ap info needed by the qact function.
 246  */
 247 union ap_qact_ap_info {
 248         unsigned long val;
 249         struct {
 250                 unsigned int      : 3;
 251                 unsigned int mode : 3;
 252                 unsigned int      : 26;
 253                 unsigned int cat  : 8;
 254                 unsigned int      : 8;
 255                 unsigned char ver[2];
 256         };
 257 };
 258 
 259 /**
 260  * ap_qact(): Query AP combatibility type.
 261  * @qid: The AP queue number
 262  * @apinfo: On input the info about the AP queue. On output the
 263  *          alternate AP queue info provided by the qact function
 264  *          in GR2 is stored in.
 265  *
 266  * Returns AP queue status. Check response_code field for failures.
 267  */
 268 static inline struct ap_queue_status ap_qact(ap_qid_t qid, int ifbit,
 269                                              union ap_qact_ap_info *apinfo)
 270 {
 271         register unsigned long reg0 asm ("0") = qid | (5UL << 24)
 272                 | ((ifbit & 0x01) << 22);
 273         register union {
 274                 unsigned long value;
 275                 struct ap_queue_status status;
 276         } reg1 asm ("1");
 277         register unsigned long reg2 asm ("2");
 278 
 279         reg1.value = apinfo->val;
 280 
 281         asm volatile(
 282                 ".long 0xb2af0000"              /* PQAP(QACT) */
 283                 : "+d" (reg1), "=d" (reg2)
 284                 : "d" (reg0)
 285                 : "cc");
 286         apinfo->val = reg2;
 287         return reg1.status;
 288 }
 289 
 290 /**
 291  * ap_nqap(): Send message to adjunct processor queue.
 292  * @qid: The AP queue number
 293  * @psmid: The program supplied message identifier
 294  * @msg: The message text
 295  * @length: The message length
 296  *
 297  * Returns AP queue status structure.
 298  * Condition code 1 on NQAP can't happen because the L bit is 1.
 299  * Condition code 2 on NQAP also means the send is incomplete,
 300  * because a segment boundary was reached. The NQAP is repeated.
 301  */
 302 static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
 303                                              unsigned long long psmid,
 304                                              void *msg, size_t length)
 305 {
 306         register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
 307         register struct ap_queue_status reg1 asm ("1");
 308         register unsigned long reg2 asm ("2") = (unsigned long) msg;
 309         register unsigned long reg3 asm ("3") = (unsigned long) length;
 310         register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
 311         register unsigned long reg5 asm ("5") = psmid & 0xffffffff;
 312 
 313         asm volatile (
 314                 "0: .long 0xb2ad0042\n"         /* NQAP */
 315                 "   brc   2,0b"
 316                 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
 317                 : "d" (reg4), "d" (reg5)
 318                 : "cc", "memory");
 319         return reg1;
 320 }
 321 
 322 /**
 323  * ap_dqap(): Receive message from adjunct processor queue.
 324  * @qid: The AP queue number
 325  * @psmid: Pointer to program supplied message identifier
 326  * @msg: The message text
 327  * @length: The message length
 328  *
 329  * Returns AP queue status structure.
 330  * Condition code 1 on DQAP means the receive has taken place
 331  * but only partially.  The response is incomplete, hence the
 332  * DQAP is repeated.
 333  * Condition code 2 on DQAP also means the receive is incomplete,
 334  * this time because a segment boundary was reached. Again, the
 335  * DQAP is repeated.
 336  * Note that gpr2 is used by the DQAP instruction to keep track of
 337  * any 'residual' length, in case the instruction gets interrupted.
 338  * Hence it gets zeroed before the instruction.
 339  */
 340 static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
 341                                              unsigned long long *psmid,
 342                                              void *msg, size_t length)
 343 {
 344         register unsigned long reg0 asm("0") = qid | 0x80000000UL;
 345         register struct ap_queue_status reg1 asm ("1");
 346         register unsigned long reg2 asm("2") = 0UL;
 347         register unsigned long reg4 asm("4") = (unsigned long) msg;
 348         register unsigned long reg5 asm("5") = (unsigned long) length;
 349         register unsigned long reg6 asm("6") = 0UL;
 350         register unsigned long reg7 asm("7") = 0UL;
 351 
 352 
 353         asm volatile(
 354                 "0: .long 0xb2ae0064\n"         /* DQAP */
 355                 "   brc   6,0b\n"
 356                 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
 357                   "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7)
 358                 : : "cc", "memory");
 359         *psmid = (((unsigned long long) reg6) << 32) + reg7;
 360         return reg1;
 361 }
 362 
 363 /*
 364  * Interface to tell the AP bus code that a configuration
 365  * change has happened. The bus code should at least do
 366  * an ap bus resource rescan.
 367  */
 368 #if IS_ENABLED(CONFIG_ZCRYPT)
 369 void ap_bus_cfg_chg(void);
 370 #else
 371 static inline void ap_bus_cfg_chg(void){};
 372 #endif
 373 
 374 #endif /* _ASM_S390_AP_H_ */

/* [<][>][^][v][top][bottom][index][help] */