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