1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * CSS definitions 4 * 5 * Copyright IBM Corp. 2020 6 * Author: Pierre Morel <pmorel@linux.ibm.com> 7 */ 8 9 #ifndef _S390X_CSS_H_ 10 #define _S390X_CSS_H_ 11 12 /* subchannel ID bit 16 must always be one */ 13 #define SCHID_ONE 0x00010000 14 15 #define CCW_F_CD 0x80 16 #define CCW_F_CC 0x40 17 #define CCW_F_SLI 0x20 18 #define CCW_F_SKP 0x10 19 #define CCW_F_PCI 0x08 20 #define CCW_F_IDA 0x04 21 #define CCW_F_S 0x02 22 #define CCW_F_MIDA 0x01 23 24 #define CCW_C_NOP 0x03 25 #define CCW_C_TIC 0x08 26 27 struct ccw1 { 28 uint8_t code; 29 uint8_t flags; 30 uint16_t count; 31 uint32_t data_address; 32 } __attribute__ ((aligned(8))); 33 34 #define ORB_CTRL_KEY 0xf0000000 35 #define ORB_CTRL_SPND 0x08000000 36 #define ORB_CTRL_STR 0x04000000 37 #define ORB_CTRL_MOD 0x02000000 38 #define ORB_CTRL_SYNC 0x01000000 39 #define ORB_CTRL_FMT 0x00800000 40 #define ORB_CTRL_PFCH 0x00400000 41 #define ORB_CTRL_ISIC 0x00200000 42 #define ORB_CTRL_ALCC 0x00100000 43 #define ORB_CTRL_SSIC 0x00080000 44 #define ORB_CTRL_CPTC 0x00040000 45 #define ORB_CTRL_C64 0x00020000 46 #define ORB_CTRL_I2K 0x00010000 47 #define ORB_CTRL_LPM 0x0000ff00 48 #define ORB_CTRL_ILS 0x00000080 49 #define ORB_CTRL_MIDAW 0x00000040 50 #define ORB_CTRL_ORBX 0x00000001 51 52 #define ORB_LPM_DFLT 0x00008000 53 54 struct orb { 55 uint32_t intparm; 56 uint32_t ctrl; 57 uint32_t cpa; 58 uint32_t prio; 59 uint32_t reserved[4]; 60 } __attribute__ ((aligned(4))); 61 62 struct scsw { 63 #define SCSW_SC_PENDING 0x00000001 64 #define SCSW_SC_SECONDARY 0x00000002 65 #define SCSW_SC_PRIMARY 0x00000004 66 #define SCSW_SC_INTERMEDIATE 0x00000008 67 #define SCSW_SC_ALERT 0x00000010 68 uint32_t ctrl; 69 uint32_t ccw_addr; 70 #define SCSW_DEVS_DEV_END 0x04 71 #define SCSW_DEVS_SCH_END 0x08 72 uint8_t dev_stat; 73 #define SCSW_SCHS_PCI 0x80 74 #define SCSW_SCHS_IL 0x40 75 uint8_t sch_stat; 76 uint16_t count; 77 }; 78 79 struct pmcw { 80 uint32_t intparm; 81 #define PMCW_DNV 0x0001 82 #define PMCW_ENABLE 0x0080 83 #define PMCW_MBUE 0x0010 84 #define PMCW_DCTME 0x0008 85 #define PMCW_ISC_MASK 0x3800 86 #define PMCW_ISC_SHIFT 11 87 uint16_t flags; 88 uint16_t devnum; 89 uint8_t lpm; 90 uint8_t pnom; 91 uint8_t lpum; 92 uint8_t pim; 93 uint16_t mbi; 94 uint8_t pom; 95 uint8_t pam; 96 uint8_t chpid[8]; 97 #define PMCW_MBF1 0x0004 98 uint32_t flags2; 99 }; 100 #define PMCW_CHANNEL_TYPE(pmcw) (pmcw->flags2 >> 21) 101 102 struct schib { 103 struct pmcw pmcw; 104 struct scsw scsw; 105 uint64_t mbo; 106 uint8_t md[4]; 107 } __attribute__ ((aligned(4))); 108 extern struct schib schib; 109 110 struct irb { 111 struct scsw scsw; 112 uint32_t esw[5]; 113 uint32_t ecw[8]; 114 uint32_t emw[8]; 115 } __attribute__ ((aligned(4))); 116 117 #define CCW_CMD_SENSE_ID 0xe4 118 #define CSS_SENSEID_COMMON_LEN 8 119 struct senseid { 120 /* common part */ 121 uint8_t reserved; /* always 0x'FF' */ 122 uint16_t cu_type; /* control unit type */ 123 uint8_t cu_model; /* control unit model */ 124 uint16_t dev_type; /* device type */ 125 uint8_t dev_model; /* device model */ 126 uint8_t unused; /* padding byte */ 127 uint8_t padding[256 - 8]; /* Extended part */ 128 } __attribute__ ((aligned(4))) __attribute__ ((packed)); 129 130 /* CSS low level access functions */ 131 132 static inline int ssch(unsigned long schid, struct orb *addr) 133 { 134 register long long reg1 asm("1") = schid; 135 int cc; 136 137 asm volatile( 138 " ssch 0(%2)\n" 139 " ipm %0\n" 140 " srl %0,28\n" 141 : "=d" (cc) 142 : "d" (reg1), "a" (addr), "m" (*addr) 143 : "cc", "memory"); 144 return cc; 145 } 146 147 static inline int stsch(unsigned long schid, struct schib *addr) 148 { 149 register unsigned long reg1 asm ("1") = schid; 150 int cc; 151 152 asm volatile( 153 " stsch 0(%3)\n" 154 " ipm %0\n" 155 " srl %0,28" 156 : "=d" (cc), "=m" (*addr) 157 : "d" (reg1), "a" (addr) 158 : "cc"); 159 return cc; 160 } 161 162 static inline int msch(unsigned long schid, struct schib *addr) 163 { 164 register unsigned long reg1 asm ("1") = schid; 165 int cc; 166 167 asm volatile( 168 " msch 0(%3)\n" 169 " ipm %0\n" 170 " srl %0,28" 171 : "=d" (cc) 172 : "d" (reg1), "m" (*addr), "a" (addr) 173 : "cc"); 174 return cc; 175 } 176 177 static inline int tsch(unsigned long schid, struct irb *addr) 178 { 179 register unsigned long reg1 asm ("1") = schid; 180 int cc; 181 182 asm volatile( 183 " tsch 0(%3)\n" 184 " ipm %0\n" 185 " srl %0,28" 186 : "=d" (cc), "=m" (*addr) 187 : "d" (reg1), "a" (addr) 188 : "cc"); 189 return cc; 190 } 191 192 static inline int hsch(unsigned long schid) 193 { 194 register unsigned long reg1 asm("1") = schid; 195 int cc; 196 197 asm volatile( 198 " hsch\n" 199 " ipm %0\n" 200 " srl %0,28" 201 : "=d" (cc) 202 : "d" (reg1) 203 : "cc"); 204 return cc; 205 } 206 207 static inline int xsch(unsigned long schid) 208 { 209 register unsigned long reg1 asm("1") = schid; 210 int cc; 211 212 asm volatile( 213 " xsch\n" 214 " ipm %0\n" 215 " srl %0,28" 216 : "=d" (cc) 217 : "d" (reg1) 218 : "cc"); 219 return cc; 220 } 221 222 static inline int csch(unsigned long schid) 223 { 224 register unsigned long reg1 asm("1") = schid; 225 int cc; 226 227 asm volatile( 228 " csch\n" 229 " ipm %0\n" 230 " srl %0,28" 231 : "=d" (cc) 232 : "d" (reg1) 233 : "cc"); 234 return cc; 235 } 236 237 static inline int rsch(unsigned long schid) 238 { 239 register unsigned long reg1 asm("1") = schid; 240 int cc; 241 242 asm volatile( 243 " rsch\n" 244 " ipm %0\n" 245 " srl %0,28" 246 : "=d" (cc) 247 : "d" (reg1) 248 : "cc"); 249 return cc; 250 } 251 252 static inline int rchp(unsigned long chpid) 253 { 254 register unsigned long reg1 asm("1") = chpid; 255 int cc; 256 257 asm volatile( 258 " rchp\n" 259 " ipm %0\n" 260 " srl %0,28" 261 : "=d" (cc) 262 : "d" (reg1) 263 : "cc"); 264 return cc; 265 } 266 267 static inline int stcrw(uint32_t *crw) 268 { 269 int cc; 270 271 asm volatile( 272 " stcrw %[crw]\n" 273 " ipm %[cc]\n" 274 " srl %[cc],28" 275 : [cc] "=d" (cc) 276 : [crw] "Q" (*crw) 277 : "cc", "memory"); 278 return cc; 279 } 280 281 /* Debug functions */ 282 char *dump_pmcw_flags(uint16_t f); 283 char *dump_scsw_flags(uint32_t f); 284 285 void dump_scsw(struct scsw *scsw); 286 void dump_irb(struct irb *irbp); 287 void dump_schib(struct schib *sch); 288 struct ccw1 *dump_ccw(struct ccw1 *cp); 289 void dump_irb(struct irb *irbp); 290 void dump_pmcw(struct pmcw *p); 291 void dump_orb(struct orb *op); 292 293 int css_enumerate(void); 294 #define MAX_ENABLE_RETRIES 5 295 296 #define IO_SCH_ISC 3 297 int css_enable(int schid, int isc); 298 bool css_enabled(int schid); 299 300 /* Library functions */ 301 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw); 302 struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags); 303 void css_irq_io(void); 304 int css_residual_count(unsigned int schid); 305 306 void enable_io_isc(uint8_t isc); 307 int wait_and_check_io_completion(int schid); 308 309 int css_find_installed_chpid(int sid, uint8_t *chpid_out); 310 int css_generate_crw(int sid); 311 312 /* 313 * CHSC definitions 314 */ 315 struct chsc_header { 316 uint16_t len; 317 uint16_t code; 318 }; 319 320 /* Store Channel Subsystem Characteristics */ 321 struct chsc_scsc { 322 struct chsc_header req; 323 uint16_t req_fmt; 324 uint8_t cssid; 325 uint8_t reserved[9]; 326 struct chsc_header res; 327 uint32_t res_fmt; 328 #define CSSC_EXTENDED_MEASUREMENT_BLOCK 48 329 uint64_t general_char[255]; 330 uint64_t chsc_char[254]; 331 }; 332 333 extern struct chsc_scsc *chsc_scsc; 334 #define CHSC_SCSC 0x0010 335 #define CHSC_SCSC_LEN 0x0010 336 337 bool get_chsc_scsc(void); 338 339 #define CSS_GENERAL_FEAT_BITLEN (255 * 64) 340 #define CSS_CHSC_FEAT_BITLEN (254 * 64) 341 342 #define CHSC_SCSC 0x0010 343 #define CHSC_SCSC_LEN 0x0010 344 345 #define CHSC_ERROR 0x0000 346 #define CHSC_RSP_OK 0x0001 347 #define CHSC_RSP_INVAL 0x0002 348 #define CHSC_RSP_REQERR 0x0003 349 #define CHSC_RSP_ENOCMD 0x0004 350 #define CHSC_RSP_NODATA 0x0005 351 #define CHSC_RSP_SUP31B 0x0006 352 #define CHSC_RSP_EFRMT 0x0007 353 #define CHSC_RSP_ECSSID 0x0008 354 #define CHSC_RSP_ERFRMT 0x0009 355 #define CHSC_RSP_ESSID 0x000A 356 #define CHSC_RSP_EBUSY 0x000B 357 #define CHSC_RSP_MAX 0x000B 358 359 static inline int _chsc(void *p) 360 { 361 int cc; 362 363 asm volatile(" .insn rre,0xb25f0000,%2,0\n" 364 " ipm %0\n" 365 " srl %0,28\n" 366 : "=d" (cc), "=m" (p) 367 : "d" (p), "m" (p) 368 : "cc"); 369 370 return cc; 371 } 372 373 bool chsc(void *p, uint16_t code, uint16_t len); 374 375 #include <bitops.h> 376 #define css_test_general_feature(bit) test_bit_inv(bit, chsc_scsc->general_char) 377 #define css_test_chsc_feature(bit) test_bit_inv(bit, chsc_scsc->chsc_char) 378 379 #define SCHM_DCTM 1 /* activate Device Connection TiMe */ 380 #define SCHM_MBU 2 /* activate Measurement Block Update */ 381 382 static inline void schm(void *mbo, unsigned int flags) 383 { 384 register void *__gpr2 asm("2") = mbo; 385 register long __gpr1 asm("1") = flags; 386 387 asm("schm" : : "d" (__gpr2), "d" (__gpr1)); 388 } 389 390 bool css_enable_mb(int sid, uint64_t mb, uint16_t mbi, uint16_t flg, bool fmt1); 391 bool css_disable_mb(int schid); 392 393 struct measurement_block_format0 { 394 uint16_t ssch_rsch_count; 395 uint16_t sample_count; 396 uint32_t device_connect_time; 397 uint32_t function_pending_time; 398 uint32_t device_disconnect_time; 399 uint32_t cu_queuing_time; 400 uint32_t device_active_only_time; 401 uint32_t device_busy_time; 402 uint32_t initial_cmd_resp_time; 403 }; 404 405 struct measurement_block_format1 { 406 uint32_t ssch_rsch_count; 407 uint32_t sample_count; 408 uint32_t device_connect_time; 409 uint32_t function_pending_time; 410 uint32_t device_disconnect_time; 411 uint32_t cu_queuing_time; 412 uint32_t device_active_only_time; 413 uint32_t device_busy_time; 414 uint32_t initial_cmd_resp_time; 415 uint32_t irq_delay_time; 416 uint32_t irq_prio_delay_time; 417 }; 418 419 #endif 420