mirror of https://gitlab.com/qemu-project/qemu
s390x/css: support format-0 ccws
Add support for format-0 ccws in channel programs. As a format-1 ccw contains the same information as format-0 ccws, only supporting larger addresses, simply convert every ccw to format-1 as we walk the chain. Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
parent
450749141e
commit
a327c9215d
|
@ -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;
|
CCW1 ret;
|
||||||
|
|
||||||
cpu_physical_memory_read(addr, &tmp, sizeof(tmp));
|
if (fmt1) {
|
||||||
ret.cmd_code = tmp.cmd_code;
|
cpu_physical_memory_read(addr, &tmp1, sizeof(tmp1));
|
||||||
ret.flags = tmp.flags;
|
ret.cmd_code = tmp1.cmd_code;
|
||||||
ret.count = be16_to_cpu(tmp.count);
|
ret.flags = tmp1.flags;
|
||||||
ret.cda = be32_to_cpu(tmp.cda);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +276,8 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr)
|
||||||
return -EIO;
|
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. */
|
/* Check for invalid command codes. */
|
||||||
if ((ccw.cmd_code & 0x0f) == 0) {
|
if ((ccw.cmd_code & 0x0f) == 0) {
|
||||||
|
@ -386,6 +395,7 @@ static void sch_handle_start_func(SubchDev *sch, ORB *orb)
|
||||||
s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
|
s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
|
||||||
} else {
|
} else {
|
||||||
s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
|
s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
|
||||||
}
|
}
|
||||||
|
@ -1347,6 +1357,7 @@ void subch_device_save(SubchDev *s, QEMUFile *f)
|
||||||
qemu_put_byte(f, s->id.ciw[i].command);
|
qemu_put_byte(f, s->id.ciw[i].command);
|
||||||
qemu_put_be16(f, s->id.ciw[i].count);
|
qemu_put_be16(f, s->id.ciw[i].count);
|
||||||
}
|
}
|
||||||
|
qemu_put_byte(f, s->ccw_fmt_1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1402,6 +1413,7 @@ int subch_device_load(SubchDev *s, QEMUFile *f)
|
||||||
s->id.ciw[i].command = qemu_get_byte(f);
|
s->id.ciw[i].command = qemu_get_byte(f);
|
||||||
s->id.ciw[i].count = qemu_get_be16(f);
|
s->id.ciw[i].count = qemu_get_be16(f);
|
||||||
}
|
}
|
||||||
|
s->ccw_fmt_1 = qemu_get_byte(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ struct SubchDev {
|
||||||
hwaddr channel_prog;
|
hwaddr channel_prog;
|
||||||
CCW1 last_cmd;
|
CCW1 last_cmd;
|
||||||
bool last_cmd_valid;
|
bool last_cmd_valid;
|
||||||
|
bool ccw_fmt_1;
|
||||||
bool thinint_active;
|
bool thinint_active;
|
||||||
/* transport-provided data: */
|
/* transport-provided data: */
|
||||||
int (*ccw_cb) (SubchDev *, CCW1);
|
int (*ccw_cb) (SubchDev *, CCW1);
|
||||||
|
|
|
@ -156,6 +156,16 @@ typedef struct ORB {
|
||||||
#define ORB_CTRL1_MASK_ORBX 0x01
|
#define ORB_CTRL1_MASK_ORBX 0x01
|
||||||
#define ORB_CTRL1_MASK_INVALID 0x3e
|
#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) */
|
/* channel command word (type 1) */
|
||||||
typedef struct CCW1 {
|
typedef struct CCW1 {
|
||||||
uint8_t cmd_code;
|
uint8_t cmd_code;
|
||||||
|
|
Loading…
Reference in New Issue