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