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