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 CSS_H 10 #define 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_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 uint32_t flags2; 98 }; 99 #define PMCW_CHANNEL_TYPE(pmcw) (pmcw->flags2 >> 21) 100 101 struct schib { 102 struct pmcw pmcw; 103 struct scsw scsw; 104 uint8_t md[12]; 105 } __attribute__ ((aligned(4))); 106 107 struct irb { 108 struct scsw scsw; 109 uint32_t esw[5]; 110 uint32_t ecw[8]; 111 uint32_t emw[8]; 112 } __attribute__ ((aligned(4))); 113 114 #define CCW_CMD_SENSE_ID 0xe4 115 #define CSS_SENSEID_COMMON_LEN 8 116 struct senseid { 117 /* common part */ 118 uint8_t reserved; /* always 0x'FF' */ 119 uint16_t cu_type; /* control unit type */ 120 uint8_t cu_model; /* control unit model */ 121 uint16_t dev_type; /* device type */ 122 uint8_t dev_model; /* device model */ 123 uint8_t unused; /* padding byte */ 124 uint8_t padding[256 - 8]; /* Extended part */ 125 } __attribute__ ((aligned(4))) __attribute__ ((packed)); 126 127 /* CSS low level access functions */ 128 129 static inline int ssch(unsigned long schid, struct orb *addr) 130 { 131 register long long reg1 asm("1") = schid; 132 int cc; 133 134 asm volatile( 135 " ssch 0(%2)\n" 136 " ipm %0\n" 137 " srl %0,28\n" 138 : "=d" (cc) 139 : "d" (reg1), "a" (addr), "m" (*addr) 140 : "cc", "memory"); 141 return cc; 142 } 143 144 static inline int stsch(unsigned long schid, struct schib *addr) 145 { 146 register unsigned long reg1 asm ("1") = schid; 147 int cc; 148 149 asm volatile( 150 " stsch 0(%3)\n" 151 " ipm %0\n" 152 " srl %0,28" 153 : "=d" (cc), "=m" (*addr) 154 : "d" (reg1), "a" (addr) 155 : "cc"); 156 return cc; 157 } 158 159 static inline int msch(unsigned long schid, struct schib *addr) 160 { 161 register unsigned long reg1 asm ("1") = schid; 162 int cc; 163 164 asm volatile( 165 " msch 0(%3)\n" 166 " ipm %0\n" 167 " srl %0,28" 168 : "=d" (cc) 169 : "d" (reg1), "m" (*addr), "a" (addr) 170 : "cc"); 171 return cc; 172 } 173 174 static inline int tsch(unsigned long schid, struct irb *addr) 175 { 176 register unsigned long reg1 asm ("1") = schid; 177 int cc; 178 179 asm volatile( 180 " tsch 0(%3)\n" 181 " ipm %0\n" 182 " srl %0,28" 183 : "=d" (cc), "=m" (*addr) 184 : "d" (reg1), "a" (addr) 185 : "cc"); 186 return cc; 187 } 188 189 static inline int hsch(unsigned long schid) 190 { 191 register unsigned long reg1 asm("1") = schid; 192 int cc; 193 194 asm volatile( 195 " hsch\n" 196 " ipm %0\n" 197 " srl %0,28" 198 : "=d" (cc) 199 : "d" (reg1) 200 : "cc"); 201 return cc; 202 } 203 204 static inline int xsch(unsigned long schid) 205 { 206 register unsigned long reg1 asm("1") = schid; 207 int cc; 208 209 asm volatile( 210 " xsch\n" 211 " ipm %0\n" 212 " srl %0,28" 213 : "=d" (cc) 214 : "d" (reg1) 215 : "cc"); 216 return cc; 217 } 218 219 static inline int csch(unsigned long schid) 220 { 221 register unsigned long reg1 asm("1") = schid; 222 int cc; 223 224 asm volatile( 225 " csch\n" 226 " ipm %0\n" 227 " srl %0,28" 228 : "=d" (cc) 229 : "d" (reg1) 230 : "cc"); 231 return cc; 232 } 233 234 static inline int rsch(unsigned long schid) 235 { 236 register unsigned long reg1 asm("1") = schid; 237 int cc; 238 239 asm volatile( 240 " rsch\n" 241 " ipm %0\n" 242 " srl %0,28" 243 : "=d" (cc) 244 : "d" (reg1) 245 : "cc"); 246 return cc; 247 } 248 249 static inline int rchp(unsigned long chpid) 250 { 251 register unsigned long reg1 asm("1") = chpid; 252 int cc; 253 254 asm volatile( 255 " rchp\n" 256 " ipm %0\n" 257 " srl %0,28" 258 : "=d" (cc) 259 : "d" (reg1) 260 : "cc"); 261 return cc; 262 } 263 264 /* Debug functions */ 265 char *dump_pmcw_flags(uint16_t f); 266 char *dump_scsw_flags(uint32_t f); 267 268 void dump_scsw(struct scsw *scsw); 269 void dump_irb(struct irb *irbp); 270 void dump_schib(struct schib *sch); 271 struct ccw1 *dump_ccw(struct ccw1 *cp); 272 void dump_irb(struct irb *irbp); 273 void dump_pmcw(struct pmcw *p); 274 void dump_orb(struct orb *op); 275 276 int css_enumerate(void); 277 #define MAX_ENABLE_RETRIES 5 278 279 #define IO_SCH_ISC 3 280 int css_enable(int schid, int isc); 281 282 /* Library functions */ 283 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw); 284 struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags); 285 void css_irq_io(void); 286 int css_residual_count(unsigned int schid); 287 288 void enable_io_isc(uint8_t isc); 289 int wait_and_check_io_completion(int schid); 290 291 #endif 292