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 /* Debug functions */ 270 char *dump_pmcw_flags(uint16_t f); 271 char *dump_scsw_flags(uint32_t f); 272 273 void dump_scsw(struct scsw *scsw); 274 void dump_irb(struct irb *irbp); 275 void dump_schib(struct schib *sch); 276 struct ccw1 *dump_ccw(struct ccw1 *cp); 277 void dump_irb(struct irb *irbp); 278 void dump_pmcw(struct pmcw *p); 279 void dump_orb(struct orb *op); 280 281 int css_enumerate(void); 282 #define MAX_ENABLE_RETRIES 5 283 284 #define IO_SCH_ISC 3 285 int css_enable(int schid, int isc); 286 bool css_enabled(int schid); 287 288 /* Library functions */ 289 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw); 290 struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags); 291 void css_irq_io(void); 292 int css_residual_count(unsigned int schid); 293 294 void enable_io_isc(uint8_t isc); 295 int wait_and_check_io_completion(int schid); 296 297 /* 298 * CHSC definitions 299 */ 300 struct chsc_header { 301 uint16_t len; 302 uint16_t code; 303 }; 304 305 /* Store Channel Subsystem Characteristics */ 306 struct chsc_scsc { 307 struct chsc_header req; 308 uint16_t req_fmt; 309 uint8_t cssid; 310 uint8_t reserved[9]; 311 struct chsc_header res; 312 uint32_t res_fmt; 313 #define CSSC_EXTENDED_MEASUREMENT_BLOCK 48 314 uint64_t general_char[255]; 315 uint64_t chsc_char[254]; 316 }; 317 318 extern struct chsc_scsc *chsc_scsc; 319 #define CHSC_SCSC 0x0010 320 #define CHSC_SCSC_LEN 0x0010 321 322 bool get_chsc_scsc(void); 323 324 #define CSS_GENERAL_FEAT_BITLEN (255 * 64) 325 #define CSS_CHSC_FEAT_BITLEN (254 * 64) 326 327 #define CHSC_SCSC 0x0010 328 #define CHSC_SCSC_LEN 0x0010 329 330 #define CHSC_ERROR 0x0000 331 #define CHSC_RSP_OK 0x0001 332 #define CHSC_RSP_INVAL 0x0002 333 #define CHSC_RSP_REQERR 0x0003 334 #define CHSC_RSP_ENOCMD 0x0004 335 #define CHSC_RSP_NODATA 0x0005 336 #define CHSC_RSP_SUP31B 0x0006 337 #define CHSC_RSP_EFRMT 0x0007 338 #define CHSC_RSP_ECSSID 0x0008 339 #define CHSC_RSP_ERFRMT 0x0009 340 #define CHSC_RSP_ESSID 0x000A 341 #define CHSC_RSP_EBUSY 0x000B 342 #define CHSC_RSP_MAX 0x000B 343 344 static inline int _chsc(void *p) 345 { 346 int cc; 347 348 asm volatile(" .insn rre,0xb25f0000,%2,0\n" 349 " ipm %0\n" 350 " srl %0,28\n" 351 : "=d" (cc), "=m" (p) 352 : "d" (p), "m" (p) 353 : "cc"); 354 355 return cc; 356 } 357 358 bool chsc(void *p, uint16_t code, uint16_t len); 359 360 #include <bitops.h> 361 #define css_test_general_feature(bit) test_bit_inv(bit, chsc_scsc->general_char) 362 #define css_test_chsc_feature(bit) test_bit_inv(bit, chsc_scsc->chsc_char) 363 364 #define SCHM_DCTM 1 /* activate Device Connection TiMe */ 365 #define SCHM_MBU 2 /* activate Measurement Block Update */ 366 367 static inline void schm(void *mbo, unsigned int flags) 368 { 369 register void *__gpr2 asm("2") = mbo; 370 register long __gpr1 asm("1") = flags; 371 372 asm("schm" : : "d" (__gpr2), "d" (__gpr1)); 373 } 374 375 bool css_enable_mb(int sid, uint64_t mb, uint16_t mbi, uint16_t flg, bool fmt1); 376 bool css_disable_mb(int schid); 377 378 struct measurement_block_format0 { 379 uint16_t ssch_rsch_count; 380 uint16_t sample_count; 381 uint32_t device_connect_time; 382 uint32_t function_pending_time; 383 uint32_t device_disconnect_time; 384 uint32_t cu_queuing_time; 385 uint32_t device_active_only_time; 386 uint32_t device_busy_time; 387 uint32_t initial_cmd_resp_time; 388 }; 389 390 struct measurement_block_format1 { 391 uint32_t ssch_rsch_count; 392 uint32_t sample_count; 393 uint32_t device_connect_time; 394 uint32_t function_pending_time; 395 uint32_t device_disconnect_time; 396 uint32_t cu_queuing_time; 397 uint32_t device_active_only_time; 398 uint32_t device_busy_time; 399 uint32_t initial_cmd_resp_time; 400 uint32_t irq_delay_time; 401 uint32_t irq_prio_delay_time; 402 }; 403 404 #endif 405