xref: /openbmc/qemu/pc-bios/s390-ccw/cio.h (revision 2038f8c8)
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 /* Function Control */
74 #define SCSW_FCTL_START_FUNC 0x4000
75 #define SCSW_FCTL_HALT_FUNC 0x2000
76 #define SCSW_FCTL_CLEAR_FUNC 0x1000
77 
78 /* Activity Control */
79 #define SCSW_ACTL_RESUME_PEND   0x0800
80 #define SCSW_ACTL_START_PEND    0x0400
81 #define SCSW_ACTL_HALT_PEND     0x0200
82 #define SCSW_ACTL_CLEAR_PEND    0x0100
83 #define SCSW_ACTL_CH_ACTIVE     0x0080
84 #define SCSW_ACTL_DEV_ACTIVE    0x0040
85 #define SCSW_ACTL_SUSPENDED     0x0020
86 
87 /* Status Control */
88 #define SCSW_SCTL_ALERT         0x0010
89 #define SCSW_SCTL_INTERMED      0x0008
90 #define SCSW_SCTL_PRIMARY       0x0004
91 #define SCSW_SCTL_SECONDARY     0x0002
92 #define SCSW_SCTL_STATUS_PEND   0x0001
93 
94 /* SCSW Device Status Flags */
95 #define SCSW_DSTAT_ATTN     0x80
96 #define SCSW_DSTAT_STATMOD  0x40
97 #define SCSW_DSTAT_CUEND    0x20
98 #define SCSW_DSTAT_BUSY     0x10
99 #define SCSW_DSTAT_CHEND    0x08
100 #define SCSW_DSTAT_DEVEND   0x04
101 #define SCSW_DSTAT_UCHK     0x02
102 #define SCSW_DSTAT_UEXCP    0x01
103 
104 /* SCSW Subchannel Status Flags */
105 #define SCSW_CSTAT_PCINT    0x80
106 #define SCSW_CSTAT_BADLEN   0x40
107 #define SCSW_CSTAT_PROGCHK  0x20
108 #define SCSW_CSTAT_PROTCHK  0x10
109 #define SCSW_CSTAT_CHDCHK   0x08
110 #define SCSW_CSTAT_CHCCHK   0x04
111 #define SCSW_CSTAT_ICCHK    0x02
112 #define SCSW_CSTAT_CHAINCHK 0x01
113 
114 /*
115  * subchannel information block
116  */
117 typedef struct schib {
118     struct pmcw pmcw;     /* path management control word */
119     struct scsw scsw;     /* subchannel status word */
120     __u64 mba;            /* measurement block address */
121     __u8 mda[4];          /* model dependent area */
122 } __attribute__ ((packed, aligned(4))) Schib;
123 
124 typedef struct subchannel_id {
125         __u32 cssid:8;
126         __u32:4;
127         __u32 m:1;
128         __u32 ssid:2;
129         __u32 one:1;
130         __u32 sch_no:16;
131 } __attribute__ ((packed, aligned(4))) SubChannelId;
132 
133 struct chsc_header {
134     __u16 length;
135     __u16 code;
136 } __attribute__((packed));
137 
138 typedef struct chsc_area_sda {
139     struct chsc_header request;
140     __u8 reserved1:4;
141     __u8 format:4;
142     __u8 reserved2;
143     __u16 operation_code;
144     __u32 reserved3;
145     __u32 reserved4;
146     __u32 operation_data_area[252];
147     struct chsc_header response;
148     __u32 reserved5:4;
149     __u32 format2:4;
150     __u32 reserved6:24;
151 } __attribute__((packed)) ChscAreaSda;
152 
153 /*
154  * TPI info structure
155  */
156 struct tpi_info {
157     struct subchannel_id schid;
158     __u32 intparm;      /* interruption parameter */
159     __u32 adapter_IO:1;
160     __u32 reserved2:1;
161     __u32 isc:3;
162     __u32 reserved3:12;
163     __u32 int_type:3;
164     __u32 reserved4:12;
165 } __attribute__ ((packed, aligned(4)));
166 
167 /* channel command word (format 0) */
168 typedef struct ccw0 {
169     __u8 cmd_code;
170     __u32 cda:24;
171     __u32 chainData:1;
172     __u32 chain:1;
173     __u32 sli:1;
174     __u32 skip:1;
175     __u32 pci:1;
176     __u32 ida:1;
177     __u32 suspend:1;
178     __u32 mida:1;
179     __u8 reserved;
180     __u16 count;
181 } __attribute__ ((packed, aligned(8))) Ccw0;
182 
183 /* channel command word (format 1) */
184 typedef struct ccw1 {
185     __u8 cmd_code;
186     __u8 flags;
187     __u16 count;
188     __u32 cda;
189 } __attribute__ ((packed, aligned(8))) Ccw1;
190 
191 /* do_cio() CCW formats */
192 #define CCW_FMT0                 0x00
193 #define CCW_FMT1                 0x01
194 
195 #define CCW_FLAG_DC              0x80
196 #define CCW_FLAG_CC              0x40
197 #define CCW_FLAG_SLI             0x20
198 #define CCW_FLAG_SKIP            0x10
199 #define CCW_FLAG_PCI             0x08
200 #define CCW_FLAG_IDA             0x04
201 #define CCW_FLAG_SUSPEND         0x02
202 
203 /* Common CCW commands */
204 #define CCW_CMD_READ_IPL         0x02
205 #define CCW_CMD_NOOP             0x03
206 #define CCW_CMD_BASIC_SENSE      0x04
207 #define CCW_CMD_TIC              0x08
208 #define CCW_CMD_SENSE_ID         0xe4
209 
210 /* Virtio CCW commands */
211 #define CCW_CMD_SET_VQ           0x13
212 #define CCW_CMD_VDEV_RESET       0x33
213 #define CCW_CMD_READ_FEAT        0x12
214 #define CCW_CMD_WRITE_FEAT       0x11
215 #define CCW_CMD_READ_CONF        0x22
216 #define CCW_CMD_WRITE_CONF       0x21
217 #define CCW_CMD_WRITE_STATUS     0x31
218 #define CCW_CMD_SET_IND          0x43
219 #define CCW_CMD_SET_CONF_IND     0x53
220 #define CCW_CMD_READ_VQ_CONF     0x32
221 
222 /* DASD CCW commands */
223 #define CCW_CMD_DASD_READ             0x06
224 #define CCW_CMD_DASD_SEEK             0x07
225 #define CCW_CMD_DASD_SEARCH_ID_EQ     0x31
226 #define CCW_CMD_DASD_READ_MT          0x86
227 
228 /*
229  * Command-mode operation request block
230  */
231 typedef struct cmd_orb {
232     __u32 intparm;    /* interruption parameter */
233     __u32 key:4;      /* flags, like key, suspend control, etc. */
234     __u32 spnd:1;     /* suspend control */
235     __u32 res1:1;     /* reserved */
236     __u32 mod:1;      /* modification control */
237     __u32 sync:1;     /* synchronize control */
238     __u32 fmt:1;      /* format control */
239     __u32 pfch:1;     /* prefetch control */
240     __u32 isic:1;     /* initial-status-interruption control */
241     __u32 alcc:1;     /* address-limit-checking control */
242     __u32 ssic:1;     /* suppress-suspended-interr. control */
243     __u32 res2:1;     /* reserved */
244     __u32 c64:1;      /* IDAW/QDIO 64 bit control  */
245     __u32 i2k:1;      /* IDAW 2/4kB block size control */
246     __u32 lpm:8;      /* logical path mask */
247     __u32 ils:1;      /* incorrect length */
248     __u32 zero:6;     /* reserved zeros */
249     __u32 orbx:1;     /* ORB extension control */
250     __u32 cpa;    /* channel program address */
251 }  __attribute__ ((packed, aligned(4))) CmdOrb;
252 
253 struct ciw {
254     __u8 type;
255     __u8 command;
256     __u16 count;
257 };
258 
259 #define CU_TYPE_UNKNOWN         0x0000
260 #define CU_TYPE_DASD_2107       0x2107
261 #define CU_TYPE_VIRTIO          0x3832
262 #define CU_TYPE_DASD_3990       0x3990
263 
264 /*
265  * sense-id response buffer layout
266  */
267 typedef struct senseid {
268     /* common part */
269     __u8  reserved;   /* always 0x'FF' */
270     __u16 cu_type;    /* control unit type */
271     __u8  cu_model;   /* control unit model */
272     __u16 dev_type;   /* device type */
273     __u8  dev_model;  /* device model */
274     __u8  unused;     /* padding byte */
275     /* extended part */
276     struct ciw ciw[62];
277 }  __attribute__ ((packed, aligned(4))) SenseId;
278 
279 /*
280  * architected values for first sense byte - common_status. Bits 0-5 of this
281  * field are common to all device types.
282  */
283 #define SNS_STAT0_CMD_REJECT         0x80
284 #define SNS_STAT0_INTERVENTION_REQ   0x40
285 #define SNS_STAT0_BUS_OUT_CHECK      0x20
286 #define SNS_STAT0_EQUIPMENT_CHECK    0x10
287 #define SNS_STAT0_DATA_CHECK         0x08
288 #define SNS_STAT0_OVERRUN            0x04
289 #define SNS_STAT0_INCOMPL_DOMAIN     0x01
290 
291 /* ECKD DASD status[0] byte */
292 #define SNS_STAT1_PERM_ERR           0x80
293 #define SNS_STAT1_INV_TRACK_FORMAT   0x40
294 #define SNS_STAT1_EOC                0x20
295 #define SNS_STAT1_MESSAGE_TO_OPER    0x10
296 #define SNS_STAT1_NO_REC_FOUND       0x08
297 #define SNS_STAT1_FILE_PROTECTED     0x04
298 #define SNS_STAT1_WRITE_INHIBITED    0x02
299 #define SNS_STAT1_IMPRECISE_END      0x01
300 
301 /* ECKD DASD status[1] byte */
302 #define SNS_STAT2_REQ_INH_WRITE      0x80
303 #define SNS_STAT2_CORRECTABLE        0x40
304 #define SNS_STAT2_FIRST_LOG_ERR      0x20
305 #define SNS_STAT2_ENV_DATA_PRESENT   0x10
306 #define SNS_STAT2_IMPRECISE_END      0x04
307 
308 /* ECKD DASD 24-byte Sense fmt_msg codes */
309 #define SENSE24_FMT_PROG_SYS    0x0
310 #define SENSE24_FMT_EQUIPMENT   0x2
311 #define SENSE24_FMT_CONTROLLER  0x3
312 #define SENSE24_FMT_MISC        0xF
313 
314 /* basic sense response buffer layout */
315 typedef struct SenseDataEckdDasd {
316     uint8_t common_status;
317     uint8_t status[2];
318     uint8_t res_count;
319     uint8_t phys_drive_id;
320     uint8_t low_cyl_addr;
321     uint8_t head_high_cyl_addr;
322     uint8_t fmt_msg;
323     uint64_t fmt_dependent_info[2];
324     uint8_t reserved;
325     uint8_t program_action_code;
326     uint16_t config_info;
327     uint8_t mcode_hicyl;
328     uint8_t cyl_head_addr[3];
329 }  __attribute__ ((packed, aligned(4))) SenseDataEckdDasd;
330 
331 #define ECKD_SENSE24_GET_FMT(sd)     (sd->fmt_msg & 0xF0 >> 4)
332 #define ECKD_SENSE24_GET_MSG(sd)     (sd->fmt_msg & 0x0F)
333 
334 #define unit_check(irb)         ((irb)->scsw.dstat & SCSW_DSTAT_UCHK)
335 #define iface_ctrl_check(irb)   ((irb)->scsw.cstat & SCSW_CSTAT_ICCHK)
336 
337 /* interruption response block */
338 typedef struct irb {
339     struct scsw scsw;
340     __u32 esw[5];
341     __u32 ecw[8];
342     __u32 emw[8];
343 }  __attribute__ ((packed, aligned(4))) Irb;
344 
345 /* Used for SEEK ccw commands */
346 typedef struct CcwSeekData {
347     uint16_t reserved;
348     uint16_t cyl;
349     uint16_t head;
350 } __attribute__((packed)) CcwSeekData;
351 
352 /* Used for SEARCH ID ccw commands */
353 typedef struct CcwSearchIdData {
354     uint16_t cyl;
355     uint16_t head;
356     uint8_t record;
357 } __attribute__((packed)) CcwSearchIdData;
358 
359 int enable_mss_facility(void);
360 void enable_subchannel(SubChannelId schid);
361 uint16_t cu_type(SubChannelId schid);
362 int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
363                  uint16_t data_size);
364 int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt);
365 
366 /*
367  * Some S390 specific IO instructions as inline
368  */
369 
370 static inline int stsch_err(struct subchannel_id schid, struct schib *addr)
371 {
372     register struct subchannel_id reg1 asm ("1") = schid;
373     int ccode = -EIO;
374 
375     asm volatile(
376         "    stsch    0(%3)\n"
377         "0:  ipm    %0\n"
378         "    srl    %0,28\n"
379         "1:\n"
380         : "+d" (ccode), "=m" (*addr)
381         : "d" (reg1), "a" (addr)
382         : "cc");
383     return ccode;
384 }
385 
386 static inline int msch(struct subchannel_id schid, struct schib *addr)
387 {
388     register struct subchannel_id reg1 asm ("1") = schid;
389     int ccode;
390 
391     asm volatile(
392         "    msch    0(%2)\n"
393         "    ipm    %0\n"
394         "    srl    %0,28"
395         : "=d" (ccode)
396         : "d" (reg1), "a" (addr), "m" (*addr)
397         : "cc");
398     return ccode;
399 }
400 
401 static inline int msch_err(struct subchannel_id schid, struct schib *addr)
402 {
403     register struct subchannel_id reg1 asm ("1") = schid;
404     int ccode = -EIO;
405 
406     asm volatile(
407         "    msch    0(%2)\n"
408         "0:  ipm    %0\n"
409         "    srl    %0,28\n"
410         "1:\n"
411         : "+d" (ccode)
412         : "d" (reg1), "a" (addr), "m" (*addr)
413         : "cc");
414     return ccode;
415 }
416 
417 static inline int tsch(struct subchannel_id schid, struct irb *addr)
418 {
419     register struct subchannel_id reg1 asm ("1") = schid;
420     int ccode;
421 
422     asm volatile(
423         "    tsch    0(%3)\n"
424         "    ipm    %0\n"
425         "    srl    %0,28"
426         : "=d" (ccode), "=m" (*addr)
427         : "d" (reg1), "a" (addr)
428         : "cc");
429     return ccode;
430 }
431 
432 static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr)
433 {
434     register struct subchannel_id reg1 asm("1") = schid;
435     int ccode = -EIO;
436 
437     asm volatile(
438         "    ssch    0(%2)\n"
439         "0:  ipm    %0\n"
440         "    srl    %0,28\n"
441         "1:\n"
442         : "+d" (ccode)
443         : "d" (reg1), "a" (addr), "m" (*addr)
444         : "cc", "memory");
445     return ccode;
446 }
447 
448 static inline int csch(struct subchannel_id schid)
449 {
450     register struct subchannel_id reg1 asm("1") = schid;
451     int ccode;
452 
453     asm volatile(
454         "    csch\n"
455         "    ipm    %0\n"
456         "    srl    %0,28"
457         : "=d" (ccode)
458         : "d" (reg1)
459         : "cc");
460     return ccode;
461 }
462 
463 static inline int tpi(struct tpi_info *addr)
464 {
465     int ccode;
466 
467     asm volatile(
468         "    tpi    0(%2)\n"
469         "    ipm    %0\n"
470         "    srl    %0,28"
471         : "=d" (ccode), "=m" (*addr)
472         : "a" (addr)
473         : "cc");
474     return ccode;
475 }
476 
477 static inline int chsc(void *chsc_area)
478 {
479     typedef struct { char _[4096]; } addr_type;
480     int cc;
481 
482     asm volatile(
483         "    .insn    rre,0xb25f0000,%2,0\n"
484         "    ipm    %0\n"
485         "    srl    %0,28\n"
486         : "=d" (cc), "=m" (*(addr_type *) chsc_area)
487         : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
488         : "cc");
489     return cc;
490 }
491 
492 #endif /* CIO_H */
493