Add qemu 2.4.0
[kvmfornfv.git] / qemu / pc-bios / s390-ccw / cio.h
diff --git a/qemu/pc-bios/s390-ccw/cio.h b/qemu/pc-bios/s390-ccw/cio.h
new file mode 100644 (file)
index 0000000..f5b4549
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Channel IO definitions
+ *
+ * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
+ *
+ * Inspired by various s390 headers in Linux 3.9.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#ifndef CIO_H
+#define CIO_H
+
+/*
+ * path management control word
+ */
+struct pmcw {
+    __u32 intparm;        /* interruption parameter */
+    __u32 qf      : 1;    /* qdio facility */
+    __u32 w       : 1;
+    __u32 isc     : 3;    /* interruption sublass */
+    __u32 res5    : 3;    /* reserved zeros */
+    __u32 ena     : 1;    /* enabled */
+    __u32 lm      : 2;    /* limit mode */
+    __u32 mme     : 2;    /* measurement-mode enable */
+    __u32 mp      : 1;    /* multipath mode */
+    __u32 tf      : 1;    /* timing facility */
+    __u32 dnv     : 1;    /* device number valid */
+    __u32 dev     : 16;   /* device number */
+    __u8  lpm;            /* logical path mask */
+    __u8  pnom;           /* path not operational mask */
+    __u8  lpum;           /* last path used mask */
+    __u8  pim;            /* path installed mask */
+    __u16 mbi;            /* measurement-block index */
+    __u8  pom;            /* path operational mask */
+    __u8  pam;            /* path available mask */
+    __u8  chpid[8];       /* CHPID 0-7 (if available) */
+    __u32 unused1 : 8;    /* reserved zeros */
+    __u32 st      : 3;    /* subchannel type */
+    __u32 unused2 : 18;   /* reserved zeros */
+    __u32 mbfc    : 1;    /* measurement block format control */
+    __u32 xmwme   : 1;    /* extended measurement word mode enable */
+    __u32 csense  : 1;    /* concurrent sense; can be enabled ...*/
+                /*  ... per MSCH, however, if facility */
+                /*  ... is not installed, this results */
+                /*  ... in an operand exception.       */
+} __attribute__ ((packed));
+
+/* Target SCHIB configuration. */
+struct schib_config {
+    __u64 mba;
+    __u32 intparm;
+    __u16 mbi;
+    __u32 isc:3;
+    __u32 ena:1;
+    __u32 mme:2;
+    __u32 mp:1;
+    __u32 csense:1;
+    __u32 mbfc:1;
+} __attribute__ ((packed));
+
+struct scsw {
+    __u16 flags;
+    __u16 ctrl;
+    __u32 cpa;
+    __u8 dstat;
+    __u8 cstat;
+    __u16 count;
+} __attribute__ ((packed));
+
+#define SCSW_FCTL_CLEAR_FUNC 0x1000
+#define SCSW_FCTL_HALT_FUNC 0x2000
+#define SCSW_FCTL_START_FUNC 0x4000
+
+/*
+ * subchannel information block
+ */
+struct schib {
+    struct pmcw pmcw;     /* path management control word */
+    struct scsw scsw;     /* subchannel status word */
+    __u64 mba;            /* measurement block address */
+    __u8 mda[4];          /* model dependent area */
+} __attribute__ ((packed,aligned(4)));
+
+struct subchannel_id {
+        __u32 cssid  : 8;
+        __u32        : 4;
+        __u32 m      : 1;
+        __u32 ssid   : 2;
+        __u32 one    : 1;
+        __u32 sch_no : 16;
+} __attribute__ ((packed, aligned(4)));
+
+struct chsc_header {
+    __u16 length;
+    __u16 code;
+} __attribute__((packed));
+
+struct chsc_area_sda {
+    struct chsc_header request;
+    __u8 reserved1:4;
+    __u8 format:4;
+    __u8 reserved2;
+    __u16 operation_code;
+    __u32 reserved3;
+    __u32 reserved4;
+    __u32 operation_data_area[252];
+    struct chsc_header response;
+    __u32 reserved5:4;
+    __u32 format2:4;
+    __u32 reserved6:24;
+} __attribute__((packed));
+
+/*
+ * TPI info structure
+ */
+struct tpi_info {
+    struct subchannel_id schid;
+    __u32 intparm;         /* interruption parameter */
+    __u32 adapter_IO : 1;
+    __u32 reserved2  : 1;
+    __u32 isc        : 3;
+    __u32 reserved3  : 12;
+    __u32 int_type   : 3;
+    __u32 reserved4  : 12;
+} __attribute__ ((packed));
+
+/* channel command word (type 1) */
+struct ccw1 {
+    __u8 cmd_code;
+    __u8 flags;
+    __u16 count;
+    __u32 cda;
+} __attribute__ ((packed));
+
+#define CCW_FLAG_DC              0x80
+#define CCW_FLAG_CC              0x40
+#define CCW_FLAG_SLI             0x20
+#define CCW_FLAG_SKIP            0x10
+#define CCW_FLAG_PCI             0x08
+#define CCW_FLAG_IDA             0x04
+#define CCW_FLAG_SUSPEND         0x02
+
+#define CCW_CMD_NOOP             0x03
+#define CCW_CMD_BASIC_SENSE      0x04
+#define CCW_CMD_TIC              0x08
+#define CCW_CMD_SENSE_ID         0xe4
+
+#define CCW_CMD_SET_VQ           0x13
+#define CCW_CMD_VDEV_RESET       0x33
+#define CCW_CMD_READ_FEAT        0x12
+#define CCW_CMD_WRITE_FEAT       0x11
+#define CCW_CMD_READ_CONF        0x22
+#define CCW_CMD_WRITE_CONF       0x21
+#define CCW_CMD_WRITE_STATUS     0x31
+#define CCW_CMD_SET_IND          0x43
+#define CCW_CMD_SET_CONF_IND     0x53
+#define CCW_CMD_READ_VQ_CONF     0x32
+
+/*
+ * Command-mode operation request block
+ */
+struct cmd_orb {
+    __u32 intparm;    /* interruption parameter */
+    __u32 key:4;      /* flags, like key, suspend control, etc. */
+    __u32 spnd:1;     /* suspend control */
+    __u32 res1:1;     /* reserved */
+    __u32 mod:1;      /* modification control */
+    __u32 sync:1;     /* synchronize control */
+    __u32 fmt:1;      /* format control */
+    __u32 pfch:1;     /* prefetch control */
+    __u32 isic:1;     /* initial-status-interruption control */
+    __u32 alcc:1;     /* address-limit-checking control */
+    __u32 ssic:1;     /* suppress-suspended-interr. control */
+    __u32 res2:1;     /* reserved */
+    __u32 c64:1;      /* IDAW/QDIO 64 bit control  */
+    __u32 i2k:1;      /* IDAW 2/4kB block size control */
+    __u32 lpm:8;      /* logical path mask */
+    __u32 ils:1;      /* incorrect length */
+    __u32 zero:6;     /* reserved zeros */
+    __u32 orbx:1;     /* ORB extension control */
+    __u32 cpa;    /* channel program address */
+}  __attribute__ ((packed, aligned(4)));
+
+struct ciw {
+    __u8 type;
+    __u8 command;
+    __u16 count;
+};
+
+/*
+ * sense-id response buffer layout
+ */
+struct senseid {
+    /* common part */
+    __u8  reserved;   /* always 0x'FF' */
+    __u16 cu_type;    /* control unit type */
+    __u8  cu_model;   /* control unit model */
+    __u16 dev_type;   /* device type */
+    __u8  dev_model;  /* device model */
+    __u8  unused;     /* padding byte */
+    /* extended part */
+    struct ciw ciw[62];
+}  __attribute__ ((packed, aligned(4)));
+
+/* interruption response block */
+struct irb {
+    struct scsw scsw;
+    __u32 esw[5];
+    __u32 ecw[8];
+    __u32 emw[8];
+}  __attribute__ ((packed, aligned(4)));
+
+/*
+ * Some S390 specific IO instructions as inline
+ */
+
+static inline int stsch_err(struct subchannel_id schid, struct schib *addr)
+{
+    register struct subchannel_id reg1 asm ("1") = schid;
+    int ccode = -EIO;
+
+    asm volatile(
+        "    stsch    0(%3)\n"
+        "0:  ipm    %0\n"
+        "    srl    %0,28\n"
+        "1:\n"
+        : "+d" (ccode), "=m" (*addr)
+        : "d" (reg1), "a" (addr)
+        : "cc");
+    return ccode;
+}
+
+static inline int msch(struct subchannel_id schid, struct schib *addr)
+{
+    register struct subchannel_id reg1 asm ("1") = schid;
+    int ccode;
+
+    asm volatile(
+        "    msch    0(%2)\n"
+        "    ipm    %0\n"
+        "    srl    %0,28"
+        : "=d" (ccode)
+        : "d" (reg1), "a" (addr), "m" (*addr)
+        : "cc");
+    return ccode;
+}
+
+static inline int msch_err(struct subchannel_id schid, struct schib *addr)
+{
+    register struct subchannel_id reg1 asm ("1") = schid;
+    int ccode = -EIO;
+
+    asm volatile(
+        "    msch    0(%2)\n"
+        "0:  ipm    %0\n"
+        "    srl    %0,28\n"
+        "1:\n"
+        : "+d" (ccode)
+        : "d" (reg1), "a" (addr), "m" (*addr)
+        : "cc");
+    return ccode;
+}
+
+static inline int tsch(struct subchannel_id schid, struct irb *addr)
+{
+    register struct subchannel_id reg1 asm ("1") = schid;
+    int ccode;
+
+    asm volatile(
+        "    tsch    0(%3)\n"
+        "    ipm    %0\n"
+        "    srl    %0,28"
+        : "=d" (ccode), "=m" (*addr)
+        : "d" (reg1), "a" (addr)
+        : "cc");
+    return ccode;
+}
+
+static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr)
+{
+    register struct subchannel_id reg1 asm("1") = schid;
+    int ccode = -EIO;
+
+    asm volatile(
+        "    ssch    0(%2)\n"
+        "0:  ipm    %0\n"
+        "    srl    %0,28\n"
+        "1:\n"
+        : "+d" (ccode)
+        : "d" (reg1), "a" (addr), "m" (*addr)
+        : "cc", "memory");
+    return ccode;
+}
+
+static inline int csch(struct subchannel_id schid)
+{
+    register struct subchannel_id reg1 asm("1") = schid;
+    int ccode;
+
+    asm volatile(
+        "    csch\n"
+        "    ipm    %0\n"
+        "    srl    %0,28"
+        : "=d" (ccode)
+        : "d" (reg1)
+        : "cc");
+    return ccode;
+}
+
+static inline int tpi(struct tpi_info *addr)
+{
+    int ccode;
+
+    asm volatile(
+        "    tpi    0(%2)\n"
+        "    ipm    %0\n"
+        "    srl    %0,28"
+        : "=d" (ccode), "=m" (*addr)
+        : "a" (addr)
+        : "cc");
+    return ccode;
+}
+
+static inline int chsc(void *chsc_area)
+{
+    typedef struct { char _[4096]; } addr_type;
+    int cc;
+
+    asm volatile(
+        "    .insn    rre,0xb25f0000,%2,0\n"
+        "    ipm    %0\n"
+        "    srl    %0,28\n"
+        : "=d" (cc), "=m" (*(addr_type *) chsc_area)
+        : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
+        : "cc");
+    return cc;
+}
+
+#endif /* CIO_H */