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