xref: /openbmc/qemu/pc-bios/s390-ccw/cio.h (revision 9dea2df8)
1 /*
2  * Channel IO definitions
3  *
4  * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
5  *
6  * Inspired by various s390 headers in Linux 3.9.
7  *
8  * This work is licensed under the terms of the GNU GPL, version 2 or (at
9  * your option) any later version. See the COPYING file in the top-level
10  * directory.
11  */
12 
13 #ifndef CIO_H
14 #define CIO_H
15 
16 /*
17  * path management control word
18  */
19 struct pmcw {
20     __u32 intparm;        /* interruption parameter */
21     __u32 qf      : 1;    /* qdio facility */
22     __u32 w       : 1;
23     __u32 isc     : 3;    /* interruption sublass */
24     __u32 res5    : 3;    /* reserved zeros */
25     __u32 ena     : 1;    /* enabled */
26     __u32 lm      : 2;    /* limit mode */
27     __u32 mme     : 2;    /* measurement-mode enable */
28     __u32 mp      : 1;    /* multipath mode */
29     __u32 tf      : 1;    /* timing facility */
30     __u32 dnv     : 1;    /* device number valid */
31     __u32 dev     : 16;   /* device number */
32     __u8  lpm;            /* logical path mask */
33     __u8  pnom;           /* path not operational mask */
34     __u8  lpum;           /* last path used mask */
35     __u8  pim;            /* path installed mask */
36     __u16 mbi;            /* measurement-block index */
37     __u8  pom;            /* path operational mask */
38     __u8  pam;            /* path available mask */
39     __u8  chpid[8];       /* CHPID 0-7 (if available) */
40     __u32 unused1 : 8;    /* reserved zeros */
41     __u32 st      : 3;    /* subchannel type */
42     __u32 unused2 : 18;   /* reserved zeros */
43     __u32 mbfc    : 1;    /* measurement block format control */
44     __u32 xmwme   : 1;    /* extended measurement word mode enable */
45     __u32 csense  : 1;    /* concurrent sense; can be enabled ...*/
46                 /*  ... per MSCH, however, if facility */
47                 /*  ... is not installed, this results */
48                 /*  ... in an operand exception.       */
49 } __attribute__ ((packed));
50 
51 /* Target SCHIB configuration. */
52 struct schib_config {
53     __u64 mba;
54     __u32 intparm;
55     __u16 mbi;
56     __u32 isc:3;
57     __u32 ena:1;
58     __u32 mme:2;
59     __u32 mp:1;
60     __u32 csense:1;
61     __u32 mbfc:1;
62 } __attribute__ ((packed));
63 
64 struct scsw {
65     __u16 flags;
66     __u16 ctrl;
67     __u32 cpa;
68     __u8 dstat;
69     __u8 cstat;
70     __u16 count;
71 } __attribute__ ((packed));
72 
73 #define SCSW_FCTL_CLEAR_FUNC 0x1000
74 #define SCSW_FCTL_HALT_FUNC 0x2000
75 #define SCSW_FCTL_START_FUNC 0x4000
76 
77 /*
78  * subchannel information block
79  */
80 struct schib {
81     struct pmcw pmcw;     /* path management control word */
82     struct scsw scsw;     /* subchannel status word */
83     __u64 mba;            /* measurement block address */
84     __u8 mda[4];          /* model dependent area */
85 } __attribute__ ((packed,aligned(4)));
86 
87 struct subchannel_id {
88         __u32 cssid  : 8;
89         __u32        : 4;
90         __u32 m      : 1;
91         __u32 ssid   : 2;
92         __u32 one    : 1;
93         __u32 sch_no : 16;
94 } __attribute__ ((packed, aligned(4)));
95 
96 struct chsc_header {
97     __u16 length;
98     __u16 code;
99 } __attribute__((packed));
100 
101 struct chsc_area_sda {
102     struct chsc_header request;
103     __u8 reserved1:4;
104     __u8 format:4;
105     __u8 reserved2;
106     __u16 operation_code;
107     __u32 reserved3;
108     __u32 reserved4;
109     __u32 operation_data_area[252];
110     struct chsc_header response;
111     __u32 reserved5:4;
112     __u32 format2:4;
113     __u32 reserved6:24;
114 } __attribute__((packed));
115 
116 /*
117  * TPI info structure
118  */
119 struct tpi_info {
120     struct subchannel_id schid;
121     __u32 intparm;         /* interruption parameter */
122     __u32 adapter_IO : 1;
123     __u32 reserved2  : 1;
124     __u32 isc        : 3;
125     __u32 reserved3  : 12;
126     __u32 int_type   : 3;
127     __u32 reserved4  : 12;
128 } __attribute__ ((packed, aligned(4)));
129 
130 /* channel command word (type 1) */
131 struct ccw1 {
132     __u8 cmd_code;
133     __u8 flags;
134     __u16 count;
135     __u32 cda;
136 } __attribute__ ((packed, aligned(8)));
137 
138 #define CCW_FLAG_DC              0x80
139 #define CCW_FLAG_CC              0x40
140 #define CCW_FLAG_SLI             0x20
141 #define CCW_FLAG_SKIP            0x10
142 #define CCW_FLAG_PCI             0x08
143 #define CCW_FLAG_IDA             0x04
144 #define CCW_FLAG_SUSPEND         0x02
145 
146 #define CCW_CMD_NOOP             0x03
147 #define CCW_CMD_BASIC_SENSE      0x04
148 #define CCW_CMD_TIC              0x08
149 #define CCW_CMD_SENSE_ID         0xe4
150 
151 #define CCW_CMD_SET_VQ           0x13
152 #define CCW_CMD_VDEV_RESET       0x33
153 #define CCW_CMD_READ_FEAT        0x12
154 #define CCW_CMD_WRITE_FEAT       0x11
155 #define CCW_CMD_READ_CONF        0x22
156 #define CCW_CMD_WRITE_CONF       0x21
157 #define CCW_CMD_WRITE_STATUS     0x31
158 #define CCW_CMD_SET_IND          0x43
159 #define CCW_CMD_SET_CONF_IND     0x53
160 #define CCW_CMD_READ_VQ_CONF     0x32
161 
162 /*
163  * Command-mode operation request block
164  */
165 struct cmd_orb {
166     __u32 intparm;    /* interruption parameter */
167     __u32 key:4;      /* flags, like key, suspend control, etc. */
168     __u32 spnd:1;     /* suspend control */
169     __u32 res1:1;     /* reserved */
170     __u32 mod:1;      /* modification control */
171     __u32 sync:1;     /* synchronize control */
172     __u32 fmt:1;      /* format control */
173     __u32 pfch:1;     /* prefetch control */
174     __u32 isic:1;     /* initial-status-interruption control */
175     __u32 alcc:1;     /* address-limit-checking control */
176     __u32 ssic:1;     /* suppress-suspended-interr. control */
177     __u32 res2:1;     /* reserved */
178     __u32 c64:1;      /* IDAW/QDIO 64 bit control  */
179     __u32 i2k:1;      /* IDAW 2/4kB block size control */
180     __u32 lpm:8;      /* logical path mask */
181     __u32 ils:1;      /* incorrect length */
182     __u32 zero:6;     /* reserved zeros */
183     __u32 orbx:1;     /* ORB extension control */
184     __u32 cpa;    /* channel program address */
185 }  __attribute__ ((packed, aligned(4)));
186 
187 struct ciw {
188     __u8 type;
189     __u8 command;
190     __u16 count;
191 };
192 
193 /*
194  * sense-id response buffer layout
195  */
196 struct senseid {
197     /* common part */
198     __u8  reserved;   /* always 0x'FF' */
199     __u16 cu_type;    /* control unit type */
200     __u8  cu_model;   /* control unit model */
201     __u16 dev_type;   /* device type */
202     __u8  dev_model;  /* device model */
203     __u8  unused;     /* padding byte */
204     /* extended part */
205     struct ciw ciw[62];
206 }  __attribute__ ((packed, aligned(4)));
207 
208 /* interruption response block */
209 struct irb {
210     struct scsw scsw;
211     __u32 esw[5];
212     __u32 ecw[8];
213     __u32 emw[8];
214 }  __attribute__ ((packed, aligned(4)));
215 
216 /*
217  * Some S390 specific IO instructions as inline
218  */
219 
220 static inline int stsch_err(struct subchannel_id schid, struct schib *addr)
221 {
222     register struct subchannel_id reg1 asm ("1") = schid;
223     int ccode = -EIO;
224 
225     asm volatile(
226         "    stsch    0(%3)\n"
227         "0:  ipm    %0\n"
228         "    srl    %0,28\n"
229         "1:\n"
230         : "+d" (ccode), "=m" (*addr)
231         : "d" (reg1), "a" (addr)
232         : "cc");
233     return ccode;
234 }
235 
236 static inline int msch(struct subchannel_id schid, struct schib *addr)
237 {
238     register struct subchannel_id reg1 asm ("1") = schid;
239     int ccode;
240 
241     asm volatile(
242         "    msch    0(%2)\n"
243         "    ipm    %0\n"
244         "    srl    %0,28"
245         : "=d" (ccode)
246         : "d" (reg1), "a" (addr), "m" (*addr)
247         : "cc");
248     return ccode;
249 }
250 
251 static inline int msch_err(struct subchannel_id schid, struct schib *addr)
252 {
253     register struct subchannel_id reg1 asm ("1") = schid;
254     int ccode = -EIO;
255 
256     asm volatile(
257         "    msch    0(%2)\n"
258         "0:  ipm    %0\n"
259         "    srl    %0,28\n"
260         "1:\n"
261         : "+d" (ccode)
262         : "d" (reg1), "a" (addr), "m" (*addr)
263         : "cc");
264     return ccode;
265 }
266 
267 static inline int tsch(struct subchannel_id schid, struct irb *addr)
268 {
269     register struct subchannel_id reg1 asm ("1") = schid;
270     int ccode;
271 
272     asm volatile(
273         "    tsch    0(%3)\n"
274         "    ipm    %0\n"
275         "    srl    %0,28"
276         : "=d" (ccode), "=m" (*addr)
277         : "d" (reg1), "a" (addr)
278         : "cc");
279     return ccode;
280 }
281 
282 static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr)
283 {
284     register struct subchannel_id reg1 asm("1") = schid;
285     int ccode = -EIO;
286 
287     asm volatile(
288         "    ssch    0(%2)\n"
289         "0:  ipm    %0\n"
290         "    srl    %0,28\n"
291         "1:\n"
292         : "+d" (ccode)
293         : "d" (reg1), "a" (addr), "m" (*addr)
294         : "cc", "memory");
295     return ccode;
296 }
297 
298 static inline int csch(struct subchannel_id schid)
299 {
300     register struct subchannel_id reg1 asm("1") = schid;
301     int ccode;
302 
303     asm volatile(
304         "    csch\n"
305         "    ipm    %0\n"
306         "    srl    %0,28"
307         : "=d" (ccode)
308         : "d" (reg1)
309         : "cc");
310     return ccode;
311 }
312 
313 static inline int tpi(struct tpi_info *addr)
314 {
315     int ccode;
316 
317     asm volatile(
318         "    tpi    0(%2)\n"
319         "    ipm    %0\n"
320         "    srl    %0,28"
321         : "=d" (ccode), "=m" (*addr)
322         : "a" (addr)
323         : "cc");
324     return ccode;
325 }
326 
327 static inline int chsc(void *chsc_area)
328 {
329     typedef struct { char _[4096]; } addr_type;
330     int cc;
331 
332     asm volatile(
333         "    .insn    rre,0xb25f0000,%2,0\n"
334         "    ipm    %0\n"
335         "    srl    %0,28\n"
336         : "=d" (cc), "=m" (*(addr_type *) chsc_area)
337         : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
338         : "cc");
339     return cc;
340 }
341 
342 #endif /* CIO_H */
343