Commit cad684c5 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20140923' into staging



s390x/kvm: some fixes and cleanups

1. sclp: get of of duplicate defines
2. ccw: implement and fix handling of some special cases

# gpg: Signature made Tue 23 Sep 2014 13:10:47 BST using RSA key ID B5A61C7C
# gpg: Can't check signature: public key not found

* remotes/borntraeger/tags/s390x-20140923:
  s390x/css: catch ccw sequence errors
  s390x/css: support format-0 ccws
  s390x: remove duplicate defines in SCLP code

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 380f649e e8601dd5
Loading
Loading
Loading
Loading
+31 −9
Original line number Diff line number Diff line
@@ -243,17 +243,25 @@ static void copy_sense_id_to_guest(SenseId *dest, SenseId *src)
    }
}

static CCW1 copy_ccw_from_guest(hwaddr addr)
static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1)
{
    CCW1 tmp;
    CCW0 tmp0;
    CCW1 tmp1;
    CCW1 ret;

    cpu_physical_memory_read(addr, &tmp, sizeof(tmp));
    ret.cmd_code = tmp.cmd_code;
    ret.flags = tmp.flags;
    ret.count = be16_to_cpu(tmp.count);
    ret.cda = be32_to_cpu(tmp.cda);

    if (fmt1) {
        cpu_physical_memory_read(addr, &tmp1, sizeof(tmp1));
        ret.cmd_code = tmp1.cmd_code;
        ret.flags = tmp1.flags;
        ret.count = be16_to_cpu(tmp1.count);
        ret.cda = be32_to_cpu(tmp1.cda);
    } else {
        cpu_physical_memory_read(addr, &tmp0, sizeof(tmp0));
        ret.cmd_code = tmp0.cmd_code;
        ret.flags = tmp0.flags;
        ret.count = be16_to_cpu(tmp0.count);
        ret.cda = be16_to_cpu(tmp0.cda1) | (tmp0.cda0 << 16);
    }
    return ret;
}

@@ -268,7 +276,8 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr)
        return -EIO;
    }

    ccw = copy_ccw_from_guest(ccw_addr);
    /* Translate everything to format-1 ccws - the information is the same. */
    ccw = copy_ccw_from_guest(ccw_addr, sch->ccw_fmt_1);

    /* Check for invalid command codes. */
    if ((ccw.cmd_code & 0x0f) == 0) {
@@ -285,6 +294,13 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr)

    check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));

    if (!ccw.cda) {
        if (sch->ccw_no_data_cnt == 255) {
            return -EINVAL;
        }
        sch->ccw_no_data_cnt++;
    }

    /* Look at the command. */
    switch (ccw.cmd_code) {
    case CCW_CMD_NOOP:
@@ -386,6 +402,8 @@ static void sch_handle_start_func(SubchDev *sch, ORB *orb)
            s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
            return;
        }
        sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
        sch->ccw_no_data_cnt = 0;
    } else {
        s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
    }
@@ -1347,6 +1365,8 @@ void subch_device_save(SubchDev *s, QEMUFile *f)
        qemu_put_byte(f, s->id.ciw[i].command);
        qemu_put_be16(f, s->id.ciw[i].count);
    }
    qemu_put_byte(f, s->ccw_fmt_1);
    qemu_put_byte(f, s->ccw_no_data_cnt);
    return;
}

@@ -1402,6 +1422,8 @@ int subch_device_load(SubchDev *s, QEMUFile *f)
        s->id.ciw[i].command = qemu_get_byte(f);
        s->id.ciw[i].count = qemu_get_be16(f);
    }
    s->ccw_fmt_1 = qemu_get_byte(f);
    s->ccw_no_data_cnt = qemu_get_byte(f);
    return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -76,7 +76,9 @@ struct SubchDev {
    hwaddr channel_prog;
    CCW1 last_cmd;
    bool last_cmd_valid;
    bool ccw_fmt_1;
    bool thinint_active;
    uint8_t ccw_no_data_cnt;
    /* transport-provided data: */
    int (*ccw_cb) (SubchDev *, CCW1);
    SenseId id;
+0 −2
Original line number Diff line number Diff line
@@ -28,8 +28,6 @@
#define SCLP_UNASSIGN_STORAGE                   0x000C0001
#define SCLP_CMD_READ_EVENT_DATA                0x00770005
#define SCLP_CMD_WRITE_EVENT_DATA               0x00760005
#define SCLP_CMD_READ_EVENT_DATA                0x00770005
#define SCLP_CMD_WRITE_EVENT_DATA               0x00760005
#define SCLP_CMD_WRITE_EVENT_MASK               0x00780005

/* SCLP Memory hotplug codes */
+10 −0
Original line number Diff line number Diff line
@@ -156,6 +156,16 @@ typedef struct ORB {
#define ORB_CTRL1_MASK_ORBX 0x01
#define ORB_CTRL1_MASK_INVALID 0x3e

/* channel command word (type 0) */
typedef struct CCW0 {
        uint8_t cmd_code;
        uint8_t cda0;
        uint16_t cda1;
        uint8_t flags;
        uint8_t reserved;
        uint16_t count;
} QEMU_PACKED CCW0;

/* channel command word (type 1) */
typedef struct CCW1 {
    uint8_t cmd_code;