From patchwork Wed Sep 13 11:50:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Halil Pasic X-Patchwork-Id: 9951309 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 11B83603F4 for ; Wed, 13 Sep 2017 11:52:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0362C28FCE for ; Wed, 13 Sep 2017 11:52:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EC56928F84; Wed, 13 Sep 2017 11:52:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D510E28F8C for ; Wed, 13 Sep 2017 11:52:23 +0000 (UTC) Received: from localhost ([::1]:41772 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ds6D0-0000T3-5R for patchwork-qemu-devel@patchwork.kernel.org; Wed, 13 Sep 2017 07:51:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43350) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ds6Bs-0000S4-Sh for qemu-devel@nongnu.org; Wed, 13 Sep 2017 07:50:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ds6Bo-0005Tn-As for qemu-devel@nongnu.org; Wed, 13 Sep 2017 07:50:48 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:59602 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ds6Bn-0005TP-VO for qemu-devel@nongnu.org; Wed, 13 Sep 2017 07:50:44 -0400 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v8DBn4FA032983 for ; Wed, 13 Sep 2017 07:50:43 -0400 Received: from e06smtp11.uk.ibm.com (e06smtp11.uk.ibm.com [195.75.94.107]) by mx0b-001b2d01.pphosted.com with ESMTP id 2cy2qsme2w-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 13 Sep 2017 07:50:43 -0400 Received: from localhost by e06smtp11.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 13 Sep 2017 12:50:41 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp11.uk.ibm.com (192.168.101.141) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 13 Sep 2017 12:50:40 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v8DBoe4t24576132; Wed, 13 Sep 2017 11:50:40 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 51FCB4C044; Wed, 13 Sep 2017 12:47:13 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 23DCC4C040; Wed, 13 Sep 2017 12:47:13 +0100 (BST) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTPS; Wed, 13 Sep 2017 12:47:13 +0100 (BST) From: Halil Pasic To: Cornelia Huck Date: Wed, 13 Sep 2017 13:50:29 +0200 X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170913115029.47626-1-pasic@linux.vnet.ibm.com> References: <20170913115029.47626-1-pasic@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17091311-0040-0000-0000-000003F9A11D X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17091311-0041-0000-0000-0000209ABBB3 Message-Id: <20170913115029.47626-5-pasic@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-09-13_04:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1709130186 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH v2 4/4] s390x/css: support ccw IDA X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dong Jia Shi , Halil Pasic , Pierre Morel , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Let's add indirect data addressing support for our virtual channel subsystem. This implementation does no bother with any kind of prefetching. We simply step trough the IDAL on demand. Signed-off-by: Halil Pasic --- hw/s390x/css.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 6b0cd8861b..e34b2af4eb 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -819,6 +819,113 @@ incr: return 0; } +/* returns values between 1 and bsz, where bs is a power of 2 */ +static inline uint16_t ida_continuous_left(hwaddr cda, uint64_t bsz) +{ + return bsz - (cda & (bsz - 1)); +} + +static inline uint64_t ccw_ida_block_size(uint8_t flags) +{ + return 1ULL << (((flags ^ CDS_F_C64) & (CDS_F_C64 | CDS_F_I2K)) ? 11 : 12); +} + +static inline int ida_read_next_idaw(CcwDataStream *cds) +{ + union {uint64_t fmt2; uint32_t fmt1; } idaw; + bool is_fmt2 = cds->flags & CDS_F_C64; + int ret; + hwaddr idaw_addr; + + if (is_fmt2) { + idaw_addr = cds->cda_orig + sizeof(idaw.fmt2) * cds->at_idaw; + if (idaw_addr & 0x07) { + return -EINVAL; /* channel program check */ + } + ret = address_space_rw(&address_space_memory, idaw_addr, + MEMTXATTRS_UNSPECIFIED, (void *) &idaw.fmt2, + sizeof(idaw.fmt2), false); + cds->cda = be64_to_cpu(idaw.fmt2); + } else { + idaw_addr = cds->cda_orig + sizeof(idaw.fmt1) * cds->at_idaw; + if (idaw_addr & 0x03) { + return -EINVAL; /* channel program check */ + + } + ret = address_space_rw(&address_space_memory, idaw_addr, + MEMTXATTRS_UNSPECIFIED, (void *) &idaw.fmt1, + sizeof(idaw.fmt1), false); + cds->cda = be64_to_cpu(idaw.fmt1); + } + ++(cds->at_idaw); + if (ret != MEMTX_OK) { + /* assume inaccessible address */ + return -EINVAL; /* channel program check */ + + } + return 0; +} + +static int ccw_dstream_rw_ida(CcwDataStream *cds, void *buff, int len, + CcwDataStreamOp op) +{ + uint64_t bsz = ccw_ida_block_size(cds->flags); + int ret = 0; + uint16_t cont_left, iter_len; + + ret = cds_check_len(cds, len); + if (ret <= 0) { + return ret; + } + if (!cds->at_idaw) { + /* read first idaw */ + ret = ida_read_next_idaw(cds); + if (ret) { + goto err; + } + cont_left = ida_continuous_left(cds->cda, bsz); + } else { + cont_left = ida_continuous_left(cds->cda, bsz); + if (cont_left == bsz) { + ret = ida_read_next_idaw(cds); + if (ret) { + goto err; + } + if (cds->cda & (bsz - 1)) { + ret = -EINVAL; /* channel program check */ + goto err; + } + } + } + do { + iter_len = MIN(len, cont_left); + if (op != CDS_OP_A) { + ret = address_space_rw(&address_space_memory, cds->cda, + MEMTXATTRS_UNSPECIFIED, buff, iter_len, op); + if (ret != MEMTX_OK) { + /* assume inaccessible address */ + ret = -EINVAL; /* channel program check */ + goto err; + } + } + cds->at_byte += iter_len; + cds->cda += iter_len; + len -= iter_len; + if (!len) { + break; + } + ret = ida_read_next_idaw(cds); + if (ret) { + goto err; + } + cont_left = bsz; + } while (true); + return ret; +err: + cds->flags |= CDS_F_STREAM_BROKEN; + return ret; +} + void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb) { /* @@ -835,7 +942,7 @@ void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb) if (!(cds->flags & CDS_F_IDA)) { cds->op_handler = ccw_dstream_rw_noflags; } else { - assert(false); + cds->op_handler = ccw_dstream_rw_ida; } }