qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

cio.h (13993B)


      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 subclass */
     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     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;
    136 } __attribute__ ((packed, aligned(4))) SubChannelId;
    137 
    138 struct chsc_header {
    139     __u16 length;
    140     __u16 code;
    141 } __attribute__((packed));
    142 
    143 typedef struct chsc_area_sda {
    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;
    156 } __attribute__((packed)) ChscAreaSda;
    157 
    158 /*
    159  * TPI info structure
    160  */
    161 struct tpi_info {
    162     struct subchannel_id schid;
    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;
    170 } __attribute__ ((packed, aligned(4)));
    171 
    172 /* channel command word (format 0) */
    173 typedef 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) */
    189 typedef struct ccw1 {
    190     __u8 cmd_code;
    191     __u8 flags;
    192     __u16 count;
    193     __u32 cda;
    194 } __attribute__ ((packed, aligned(8))) Ccw1;
    195 
    196 /* do_cio() CCW formats */
    197 #define CCW_FMT0                 0x00
    198 #define CCW_FMT1                 0x01
    199 
    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 
    208 /* Common CCW commands */
    209 #define CCW_CMD_READ_IPL         0x02
    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 
    215 /* Virtio CCW commands */
    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 
    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 
    233 /*
    234  * Command-mode operation request block
    235  */
    236 typedef struct cmd_orb {
    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 */
    256 }  __attribute__ ((packed, aligned(4))) CmdOrb;
    257 
    258 struct ciw {
    259     __u8 type;
    260     __u8 command;
    261     __u16 count;
    262 };
    263 
    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 
    269 /*
    270  * sense-id response buffer layout
    271  */
    272 typedef struct senseid {
    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];
    282 }  __attribute__ ((packed, aligned(4))) SenseId;
    283 
    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 */
    320 typedef 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 
    342 /* interruption response block */
    343 typedef struct irb {
    344     struct scsw scsw;
    345     __u32 esw[5];
    346     __u32 ecw[8];
    347     __u32 emw[8];
    348 }  __attribute__ ((packed, aligned(4))) Irb;
    349 
    350 /* Used for SEEK ccw commands */
    351 typedef 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 */
    358 typedef struct CcwSearchIdData {
    359     uint16_t cyl;
    360     uint16_t head;
    361     uint8_t record;
    362 } __attribute__((packed)) CcwSearchIdData;
    363 
    364 int enable_mss_facility(void);
    365 void enable_subchannel(SubChannelId schid);
    366 uint16_t cu_type(SubChannelId schid);
    367 int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
    368                  uint16_t data_size);
    369 int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt);
    370 
    371 /*
    372  * Some S390 specific IO instructions as inline
    373  */
    374 
    375 static 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 
    391 static 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 
    406 static 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 
    422 static 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 
    437 static 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 
    453 static 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 
    468 static 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 
    482 static 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 */