From nobody Sat Nov 23 21:31:42 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1731155906321303.82805299984443; Sat, 9 Nov 2024 04:38:26 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t9kRv-0002zt-Un; Sat, 09 Nov 2024 07:20:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9kQ8-0007VB-LS; Sat, 09 Nov 2024 07:18:30 -0500 Received: from isrv.corpit.ru ([86.62.121.231]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9kQ5-0005KC-EA; Sat, 09 Nov 2024 07:18:27 -0500 Received: from tsrv.corpit.ru (tsrv.tls.msk.ru [192.168.177.2]) by isrv.corpit.ru (Postfix) with ESMTP id C6C06A164B; Sat, 9 Nov 2024 15:08:08 +0300 (MSK) Received: from tls.msk.ru (mjt.wg.tls.msk.ru [192.168.177.130]) by tsrv.corpit.ru (Postfix) with SMTP id 818F4167FD1; Sat, 9 Nov 2024 15:09:03 +0300 (MSK) Received: (nullmailer pid 3296228 invoked by uid 1000); Sat, 09 Nov 2024 12:09:01 -0000 From: Michael Tokarev To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, Yong-Xuan Wang , Alistair Francis , Michael Tokarev Subject: [Stable-9.1.2 33/58] hw/intc/riscv_aplic: Check and update pending when write sourcecfg Date: Sat, 9 Nov 2024 15:08:34 +0300 Message-Id: <20241109120901.3295995-33-mjt@tls.msk.ru> X-Mailer: git-send-email 2.39.5 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=86.62.121.231; envelope-from=mjt@tls.msk.ru; helo=isrv.corpit.ru X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1731155907107116600 Content-Type: text/plain; charset="utf-8" From: Yong-Xuan Wang The section 4.5.2 of the RISC-V AIA specification says that any write to a sourcecfg register of an APLIC might (or might not) cause the corresponding interrupt-pending bit to be set to one if the rectified input value is high (=3D 1) under the new source mode. If an interrupt is asserted before the driver configs its interrupt type to APLIC, it's pending bit will not be set except a relevant write to a setip or setipnum register. When we write the interrupt type to sourcecfg register, if the APLIC device doesn't check rectified input value and update the pending bit, this interrupt might never becomes pending. For APLIC.m, we can manully set pending by setip or setipnum registers in driver. But for APLIC.w, the pending status totally depends on the rectified input value, we can't control the pending status via mmio registers. In this case, hw should check and update pending status for us when writing sourcecfg registers. Update QEMU emulation to handle "pre-existing" interrupts. Signed-off-by: Yong-Xuan Wang Acked-by: Alistair Francis Message-ID: <20241004104649.13129-1-yongxuan.wang@sifive.com> Signed-off-by: Alistair Francis (cherry picked from commit 2ae6cca1d3389801ee72fc5e58c52573218f3514) Signed-off-by: Michael Tokarev diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c index 32edd6d07b..4a262c82f0 100644 --- a/hw/intc/riscv_aplic.c +++ b/hw/intc/riscv_aplic.c @@ -159,31 +159,42 @@ static bool is_kvm_aia(bool msimode) return kvm_irqchip_in_kernel() && msimode; } =20 +static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic, + uint32_t irq) +{ + uint32_t sourcecfg, sm, raw_input, irq_inverted; + + if (!irq || aplic->num_irqs <=3D irq) { + return false; + } + + sourcecfg =3D aplic->sourcecfg[irq]; + if (sourcecfg & APLIC_SOURCECFG_D) { + return false; + } + + sm =3D sourcecfg & APLIC_SOURCECFG_SM_MASK; + if (sm =3D=3D APLIC_SOURCECFG_SM_INACTIVE) { + return false; + } + + raw_input =3D (aplic->state[irq] & APLIC_ISTATE_INPUT) ? 1 : 0; + irq_inverted =3D (sm =3D=3D APLIC_SOURCECFG_SM_LEVEL_LOW || + sm =3D=3D APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0; + + return !!(raw_input ^ irq_inverted); +} + static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic, uint32_t word) { - uint32_t i, irq, sourcecfg, sm, raw_input, irq_inverted, ret =3D 0; + uint32_t i, irq, rectified_val, ret =3D 0; =20 for (i =3D 0; i < 32; i++) { irq =3D word * 32 + i; - if (!irq || aplic->num_irqs <=3D irq) { - continue; - } =20 - sourcecfg =3D aplic->sourcecfg[irq]; - if (sourcecfg & APLIC_SOURCECFG_D) { - continue; - } - - sm =3D sourcecfg & APLIC_SOURCECFG_SM_MASK; - if (sm =3D=3D APLIC_SOURCECFG_SM_INACTIVE) { - continue; - } - - raw_input =3D (aplic->state[irq] & APLIC_ISTATE_INPUT) ? 1 : 0; - irq_inverted =3D (sm =3D=3D APLIC_SOURCECFG_SM_LEVEL_LOW || - sm =3D=3D APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0; - ret |=3D (raw_input ^ irq_inverted) << i; + rectified_val =3D riscv_aplic_irq_rectified_val(aplic, irq); + ret |=3D rectified_val << i; } =20 return ret; @@ -702,6 +713,10 @@ static void riscv_aplic_write(void *opaque, hwaddr add= r, uint64_t value, (aplic->sourcecfg[irq] =3D=3D 0)) { riscv_aplic_set_pending_raw(aplic, irq, false); riscv_aplic_set_enabled_raw(aplic, irq, false); + } else { + if (riscv_aplic_irq_rectified_val(aplic, irq)) { + riscv_aplic_set_pending_raw(aplic, irq, true); + } } } else if (aplic->mmode && aplic->msimode && (addr =3D=3D APLIC_MMSICFGADDR)) { --=20 2.39.5