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