qemu/pc-bios/s390-ccw/cio.h
<<
>>
Prefs
   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 {
  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. */
  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
  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 */
 117typedef 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
 124typedef 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
 133struct chsc_header {
 134    __u16 length;
 135    __u16 code;
 136} __attribute__((packed));
 137
 138typedef 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 */
 156struct 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) */
 168typedef 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) */
 184typedef 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 */
 231typedef 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
 253struct 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 */
 267typedef 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 */
 315typedef 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 */
 338typedef 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 */
 346typedef 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 */
 353typedef struct CcwSearchIdData {
 354    uint16_t cyl;
 355    uint16_t head;
 356    uint8_t record;
 357} __attribute__((packed)) CcwSearchIdData;
 358
 359int enable_mss_facility(void);
 360void enable_subchannel(SubChannelId schid);
 361uint16_t cu_type(SubChannelId schid);
 362int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
 363                 uint16_t data_size);
 364int 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
 370static 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
 386static 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
 401static 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
 417static 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
 432static 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
 448static 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
 463static 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
 477static 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