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    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
 138struct chsc_header {
 139    __u16 length;
 140    __u16 code;
 141} __attribute__((packed));
 142
 143typedef 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 */
 161struct 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) */
 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) */
 189typedef 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 */
 236typedef 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
 258struct 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 */
 272typedef 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 */
 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
 342/* interruption response block */
 343typedef 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 */
 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
 364int enable_mss_facility(void);
 365void enable_subchannel(SubChannelId schid);
 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);
 370
 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 */
 498