1 /* 2 * CSS definitions 3 * 4 * Copyright IBM, Corp. 2020 5 * Author: Pierre Morel <pmorel@linux.ibm.com> 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2. 9 */ 10 11 #ifndef CSS_H 12 #define CSS_H 13 14 #define lowcore_ptr ((struct lowcore *)0x0) 15 16 /* subchannel ID bit 16 must always be one */ 17 #define SCHID_ONE 0x00010000 18 19 #define CCW_F_CD 0x80 20 #define CCW_F_CC 0x40 21 #define CCW_F_SLI 0x20 22 #define CCW_F_SKP 0x10 23 #define CCW_F_PCI 0x08 24 #define CCW_F_IDA 0x04 25 #define CCW_F_S 0x02 26 #define CCW_F_MIDA 0x01 27 28 #define CCW_C_NOP 0x03 29 #define CCW_C_TIC 0x08 30 31 struct ccw1 { 32 uint8_t code; 33 uint8_t flags; 34 uint16_t count; 35 uint32_t data_address; 36 } __attribute__ ((aligned(8))); 37 38 #define ORB_CTRL_KEY 0xf0000000 39 #define ORB_CTRL_SPND 0x08000000 40 #define ORB_CTRL_STR 0x04000000 41 #define ORB_CTRL_MOD 0x02000000 42 #define ORB_CTRL_SYNC 0x01000000 43 #define ORB_CTRL_FMT 0x00800000 44 #define ORB_CTRL_PFCH 0x00400000 45 #define ORB_CTRL_ISIC 0x00200000 46 #define ORB_CTRL_ALCC 0x00100000 47 #define ORB_CTRL_SSIC 0x00080000 48 #define ORB_CTRL_CPTC 0x00040000 49 #define ORB_CTRL_C64 0x00020000 50 #define ORB_CTRL_I2K 0x00010000 51 #define ORB_CTRL_LPM 0x0000ff00 52 #define ORB_CTRL_ILS 0x00000080 53 #define ORB_CTRL_MIDAW 0x00000040 54 #define ORB_CTRL_ORBX 0x00000001 55 56 #define ORB_LPM_DFLT 0x00008000 57 58 struct orb { 59 uint32_t intparm; 60 uint32_t ctrl; 61 uint32_t cpa; 62 uint32_t prio; 63 uint32_t reserved[4]; 64 } __attribute__ ((aligned(4))); 65 66 struct scsw { 67 #define SCSW_SC_PENDING 0x00000001 68 #define SCSW_SC_SECONDARY 0x00000002 69 #define SCSW_SC_PRIMARY 0x00000004 70 #define SCSW_SC_INTERMEDIATE 0x00000008 71 #define SCSW_SC_ALERT 0x00000010 72 uint32_t ctrl; 73 uint32_t ccw_addr; 74 #define SCSW_DEVS_DEV_END 0x04 75 #define SCSW_DEVS_SCH_END 0x08 76 uint8_t dev_stat; 77 #define SCSW_SCHS_PCI 0x80 78 #define SCSW_SCHS_IL 0x40 79 uint8_t sch_stat; 80 uint16_t count; 81 }; 82 83 struct pmcw { 84 uint32_t intparm; 85 #define PMCW_DNV 0x0001 86 #define PMCW_ENABLE 0x0080 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 uint32_t flags2; 100 }; 101 #define PMCW_CHANNEL_TYPE(pmcw) (pmcw->flags2 >> 21) 102 103 struct schib { 104 struct pmcw pmcw; 105 struct scsw scsw; 106 uint8_t md[12]; 107 } __attribute__ ((aligned(4))); 108 109 struct irb { 110 struct scsw scsw; 111 uint32_t esw[5]; 112 uint32_t ecw[8]; 113 uint32_t emw[8]; 114 } __attribute__ ((aligned(4))); 115 116 #define CCW_CMD_SENSE_ID 0xe4 117 #define CSS_SENSEID_COMMON_LEN 8 118 struct senseid { 119 /* common part */ 120 uint8_t reserved; /* always 0x'FF' */ 121 uint16_t cu_type; /* control unit type */ 122 uint8_t cu_model; /* control unit model */ 123 uint16_t dev_type; /* device type */ 124 uint8_t dev_model; /* device model */ 125 uint8_t unused; /* padding byte */ 126 uint8_t padding[256 - 8]; /* Extended part */ 127 } __attribute__ ((aligned(4))) __attribute__ ((packed)); 128 129 /* CSS low level access functions */ 130 131 static inline int ssch(unsigned long schid, struct orb *addr) 132 { 133 register long long reg1 asm("1") = schid; 134 int cc; 135 136 asm volatile( 137 " ssch 0(%2)\n" 138 " ipm %0\n" 139 " srl %0,28\n" 140 : "=d" (cc) 141 : "d" (reg1), "a" (addr), "m" (*addr) 142 : "cc", "memory"); 143 return cc; 144 } 145 146 static inline int stsch(unsigned long schid, struct schib *addr) 147 { 148 register unsigned long reg1 asm ("1") = schid; 149 int cc; 150 151 asm volatile( 152 " stsch 0(%3)\n" 153 " ipm %0\n" 154 " srl %0,28" 155 : "=d" (cc), "=m" (*addr) 156 : "d" (reg1), "a" (addr) 157 : "cc"); 158 return cc; 159 } 160 161 static inline int msch(unsigned long schid, struct schib *addr) 162 { 163 register unsigned long reg1 asm ("1") = schid; 164 int cc; 165 166 asm volatile( 167 " msch 0(%3)\n" 168 " ipm %0\n" 169 " srl %0,28" 170 : "=d" (cc) 171 : "d" (reg1), "m" (*addr), "a" (addr) 172 : "cc"); 173 return cc; 174 } 175 176 static inline int tsch(unsigned long schid, struct irb *addr) 177 { 178 register unsigned long reg1 asm ("1") = schid; 179 int cc; 180 181 asm volatile( 182 " tsch 0(%3)\n" 183 " ipm %0\n" 184 " srl %0,28" 185 : "=d" (cc), "=m" (*addr) 186 : "d" (reg1), "a" (addr) 187 : "cc"); 188 return cc; 189 } 190 191 static inline int hsch(unsigned long schid) 192 { 193 register unsigned long reg1 asm("1") = schid; 194 int cc; 195 196 asm volatile( 197 " hsch\n" 198 " ipm %0\n" 199 " srl %0,28" 200 : "=d" (cc) 201 : "d" (reg1) 202 : "cc"); 203 return cc; 204 } 205 206 static inline int xsch(unsigned long schid) 207 { 208 register unsigned long reg1 asm("1") = schid; 209 int cc; 210 211 asm volatile( 212 " xsch\n" 213 " ipm %0\n" 214 " srl %0,28" 215 : "=d" (cc) 216 : "d" (reg1) 217 : "cc"); 218 return cc; 219 } 220 221 static inline int csch(unsigned long schid) 222 { 223 register unsigned long reg1 asm("1") = schid; 224 int cc; 225 226 asm volatile( 227 " csch\n" 228 " ipm %0\n" 229 " srl %0,28" 230 : "=d" (cc) 231 : "d" (reg1) 232 : "cc"); 233 return cc; 234 } 235 236 static inline int rsch(unsigned long schid) 237 { 238 register unsigned long reg1 asm("1") = schid; 239 int cc; 240 241 asm volatile( 242 " rsch\n" 243 " ipm %0\n" 244 " srl %0,28" 245 : "=d" (cc) 246 : "d" (reg1) 247 : "cc"); 248 return cc; 249 } 250 251 static inline int rchp(unsigned long chpid) 252 { 253 register unsigned long reg1 asm("1") = chpid; 254 int cc; 255 256 asm volatile( 257 " rchp\n" 258 " ipm %0\n" 259 " srl %0,28" 260 : "=d" (cc) 261 : "d" (reg1) 262 : "cc"); 263 return cc; 264 } 265 266 /* Debug functions */ 267 char *dump_pmcw_flags(uint16_t f); 268 char *dump_scsw_flags(uint32_t f); 269 270 void dump_scsw(struct scsw *scsw); 271 void dump_irb(struct irb *irbp); 272 void dump_schib(struct schib *sch); 273 struct ccw1 *dump_ccw(struct ccw1 *cp); 274 void dump_irb(struct irb *irbp); 275 void dump_pmcw(struct pmcw *p); 276 void dump_orb(struct orb *op); 277 278 int css_enumerate(void); 279 #define MAX_ENABLE_RETRIES 5 280 281 #define IO_SCH_ISC 3 282 int css_enable(int schid, int isc); 283 284 /* Library functions */ 285 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw); 286 int start_single_ccw(unsigned int sid, int code, void *data, int count, 287 unsigned char flags); 288 void css_irq_io(void); 289 int css_residual_count(unsigned int schid); 290 291 void enable_io_isc(uint8_t isc); 292 int wait_and_check_io_completion(int schid); 293 294 #endif 295