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