mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
s390x/css: introduce css data stream
This is a preparation for introducing handling for indirect data addressing and modified indirect data addressing (CCW). Here we introduce an interface which should make the addressing scheme transparent for the client code. Here we implement only the basic scheme (no IDA or MIDA). Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com> Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com> Message-Id: <20170921180841.24490-2-pasic@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
947a38bd6f
commit
57065a70d0
2 changed files with 122 additions and 0 deletions
|
@ -787,6 +787,61 @@ static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* If out of bounds marks the stream broken. If broken returns -EINVAL,
|
||||
* otherwise the requested length (may be zero)
|
||||
*/
|
||||
static inline int cds_check_len(CcwDataStream *cds, int len)
|
||||
{
|
||||
if (cds->at_byte + len > cds->count) {
|
||||
cds->flags |= CDS_F_STREAM_BROKEN;
|
||||
}
|
||||
return cds->flags & CDS_F_STREAM_BROKEN ? -EINVAL : len;
|
||||
}
|
||||
|
||||
static int ccw_dstream_rw_noflags(CcwDataStream *cds, void *buff, int len,
|
||||
CcwDataStreamOp op)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cds_check_len(cds, len);
|
||||
if (ret <= 0) {
|
||||
return ret;
|
||||
}
|
||||
if (op == CDS_OP_A) {
|
||||
goto incr;
|
||||
}
|
||||
ret = address_space_rw(&address_space_memory, cds->cda,
|
||||
MEMTXATTRS_UNSPECIFIED, buff, len, op);
|
||||
if (ret != MEMTX_OK) {
|
||||
cds->flags |= CDS_F_STREAM_BROKEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
incr:
|
||||
cds->at_byte += len;
|
||||
cds->cda += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)
|
||||
{
|
||||
/*
|
||||
* We don't support MIDA (an optional facility) yet and we
|
||||
* catch this earlier. Just for expressing the precondition.
|
||||
*/
|
||||
g_assert(!(orb->ctrl1 & ORB_CTRL1_MASK_MIDAW));
|
||||
cds->flags = (orb->ctrl0 & ORB_CTRL0_MASK_I2K ? CDS_F_I2K : 0) |
|
||||
(orb->ctrl0 & ORB_CTRL0_MASK_C64 ? CDS_F_C64 : 0) |
|
||||
(ccw->flags & CCW_FLAG_IDA ? CDS_F_IDA : 0);
|
||||
cds->count = ccw->count;
|
||||
cds->cda_orig = ccw->cda;
|
||||
ccw_dstream_rewind(cds);
|
||||
if (!(cds->flags & CDS_F_IDA)) {
|
||||
cds->op_handler = ccw_dstream_rw_noflags;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
|
||||
bool suspend_allowed)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue