From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9BB2C33CA4 for ; Fri, 10 Jan 2020 14:54:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8186021744 for ; Fri, 10 Jan 2020 14:54:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="TWwPaLqN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728351AbgAJOyk (ORCPT ); Fri, 10 Jan 2020 09:54:40 -0500 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:25269 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728309AbgAJOyj (ORCPT ); Fri, 10 Jan 2020 09:54:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1578668077; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hksWhfx/qjqLBl2kwSG6HIa1DnV2Yh8CnWY4dayzAHc=; b=TWwPaLqNjuisTNHbR4U+BXIxgzDnwYdd94Z3tY8iFkJZL8ACl5RLakr91MVo9f6F5ofi3V xXVmTPtLfmq4D+6epSFQOtxIF/zoQlxzoqxH3rYzIfDMh9qi41OqvQCq/SYmuPbpgexSl6 uPMoxWX2pl9TbEsdT2/z6VPN1umEDwI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-22-sLHCnH1HO6O3PHQlEJkQ_A-1; Fri, 10 Jan 2020 09:54:33 -0500 X-MC-Unique: sLHCnH1HO6O3PHQlEJkQ_A-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 328261AEEF5; Fri, 10 Jan 2020 14:54:32 +0000 (UTC) Received: from laptop.redhat.com (ovpn-117-108.ams2.redhat.com [10.36.117.108]) by smtp.corp.redhat.com (Postfix) with ESMTP id D26397C407; Fri, 10 Jan 2020 14:54:25 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, maz@kernel.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, qemu-devel@nongnu.org, qemu-arm@nongnu.org Cc: drjones@redhat.com, andre.przywara@arm.com, peter.maydell@linaro.org, yuzenghui@huawei.com, alexandru.elisei@arm.com, thuth@redhat.com Subject: [kvm-unit-tests PATCH v2 02/16] arm: gic: Provide per-IRQ helper functions Date: Fri, 10 Jan 2020 15:53:58 +0100 Message-Id: <20200110145412.14937-3-eric.auger@redhat.com> In-Reply-To: <20200110145412.14937-1-eric.auger@redhat.com> References: <20200110145412.14937-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Content-Transfer-Encoding: quoted-printable Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Andre Przywara A common theme when accessing per-IRQ parameters in the GIC distributor is to set fields of a certain bit width in a range of MMIO registers. Examples are the enabled status (one bit per IRQ), the level/edge configuration (2 bits per IRQ) or the priority (8 bits per IRQ). Add a generic helper function which is able to mask and set the respective number of bits, given the IRQ number and the MMIO offset. Provide wrappers using this function to easily allow configuring an IRQ. For now assume that private IRQ numbers always refer to the current CPU. In a GICv2 accessing the "other" private IRQs is not easily doable (the registers are banked per CPU on the same MMIO address), so we impose the same limitation on GICv3, even though those registers are not banked there anymore. Signed-off-by: Andre Przywara --- initialize reg --- lib/arm/asm/gic-v3.h | 2 + lib/arm/asm/gic.h | 8 ++++ lib/arm/gic.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/lib/arm/asm/gic-v3.h b/lib/arm/asm/gic-v3.h index 0dc838b..6beeab6 100644 --- a/lib/arm/asm/gic-v3.h +++ b/lib/arm/asm/gic-v3.h @@ -23,6 +23,8 @@ #define GICD_CTLR_ENABLE_G1A (1U << 1) #define GICD_CTLR_ENABLE_G1 (1U << 0) =20 +#define GICD_IROUTER 0x6000 + /* Re-Distributor registers, offsets from RD_base */ #define GICR_TYPER 0x0008 =20 diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h index 09826fd..21cdb58 100644 --- a/lib/arm/asm/gic.h +++ b/lib/arm/asm/gic.h @@ -74,5 +74,13 @@ extern void gic_write_eoir(u32 irqstat); extern void gic_ipi_send_single(int irq, int cpu); extern void gic_ipi_send_mask(int irq, const cpumask_t *dest); =20 +void gic_set_irq_bit(int irq, int offset); +void gic_enable_irq(int irq); +void gic_disable_irq(int irq); +void gic_set_irq_priority(int irq, u8 prio); +void gic_set_irq_target(int irq, int cpu); +void gic_set_irq_group(int irq, int group); +int gic_get_irq_group(int irq); + #endif /* !__ASSEMBLY__ */ #endif /* _ASMARM_GIC_H_ */ diff --git a/lib/arm/gic.c b/lib/arm/gic.c index 9430116..aa9cb86 100644 --- a/lib/arm/gic.c +++ b/lib/arm/gic.c @@ -146,3 +146,93 @@ void gic_ipi_send_mask(int irq, const cpumask_t *des= t) assert(gic_common_ops && gic_common_ops->ipi_send_mask); gic_common_ops->ipi_send_mask(irq, dest); } + +enum gic_bit_access { + ACCESS_READ, + ACCESS_SET, + ACCESS_RMW +}; + +static u8 gic_masked_irq_bits(int irq, int offset, int bits, u8 value, + enum gic_bit_access access) +{ + void *base; + int split =3D 32 / bits; + int shift =3D (irq % split) * bits; + u32 reg =3D 0, mask =3D ((1U << bits) - 1) << shift; + + switch (gic_version()) { + case 2: + base =3D gicv2_dist_base(); + break; + case 3: + if (irq < 32) + base =3D gicv3_sgi_base(); + else + base =3D gicv3_dist_base(); + break; + default: + return 0; + } + base +=3D offset + (irq / split) * 4; + + switch (access) { + case ACCESS_READ: + return (readl(base) & mask) >> shift; + case ACCESS_SET: + reg =3D 0; + break; + case ACCESS_RMW: + reg =3D readl(base) & ~mask; + break; + } + + writel(reg | ((u32)value << shift), base); + + return 0; +} + +void gic_set_irq_bit(int irq, int offset) +{ + gic_masked_irq_bits(irq, offset, 1, 1, ACCESS_SET); +} + +void gic_enable_irq(int irq) +{ + gic_set_irq_bit(irq, GICD_ISENABLER); +} + +void gic_disable_irq(int irq) +{ + gic_set_irq_bit(irq, GICD_ICENABLER); +} + +void gic_set_irq_priority(int irq, u8 prio) +{ + gic_masked_irq_bits(irq, GICD_IPRIORITYR, 8, prio, ACCESS_RMW); +} + +void gic_set_irq_target(int irq, int cpu) +{ + if (irq < 32) + return; + + if (gic_version() =3D=3D 2) { + gic_masked_irq_bits(irq, GICD_ITARGETSR, 8, 1U << cpu, + ACCESS_RMW); + + return; + } + + writeq(cpus[cpu], gicv3_dist_base() + GICD_IROUTER + irq * 8); +} + +void gic_set_irq_group(int irq, int group) +{ + gic_masked_irq_bits(irq, GICD_IGROUPR, 1, group, ACCESS_RMW); +} + +int gic_get_irq_group(int irq) +{ + return gic_masked_irq_bits(irq, GICD_IGROUPR, 1, 0, ACCESS_READ); +} --=20 2.20.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F29FCC282DD for ; Fri, 10 Jan 2020 14:59:43 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C212220721 for ; Fri, 10 Jan 2020 14:59:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="TWwPaLqN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C212220721 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:47200 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ipvlG-0002Nd-DO for qemu-devel@archiver.kernel.org; Fri, 10 Jan 2020 09:59:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:51778) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ipvgN-0003oT-TS for qemu-devel@nongnu.org; Fri, 10 Jan 2020 09:54:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ipvgM-0004sl-B4 for qemu-devel@nongnu.org; Fri, 10 Jan 2020 09:54:39 -0500 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:50933) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ipvgM-0004qc-5s for qemu-devel@nongnu.org; Fri, 10 Jan 2020 09:54:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1578668077; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hksWhfx/qjqLBl2kwSG6HIa1DnV2Yh8CnWY4dayzAHc=; b=TWwPaLqNjuisTNHbR4U+BXIxgzDnwYdd94Z3tY8iFkJZL8ACl5RLakr91MVo9f6F5ofi3V xXVmTPtLfmq4D+6epSFQOtxIF/zoQlxzoqxH3rYzIfDMh9qi41OqvQCq/SYmuPbpgexSl6 uPMoxWX2pl9TbEsdT2/z6VPN1umEDwI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-22-sLHCnH1HO6O3PHQlEJkQ_A-1; Fri, 10 Jan 2020 09:54:33 -0500 X-MC-Unique: sLHCnH1HO6O3PHQlEJkQ_A-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 328261AEEF5; Fri, 10 Jan 2020 14:54:32 +0000 (UTC) Received: from laptop.redhat.com (ovpn-117-108.ams2.redhat.com [10.36.117.108]) by smtp.corp.redhat.com (Postfix) with ESMTP id D26397C407; Fri, 10 Jan 2020 14:54:25 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, maz@kernel.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, qemu-devel@nongnu.org, qemu-arm@nongnu.org Subject: [kvm-unit-tests PATCH v2 02/16] arm: gic: Provide per-IRQ helper functions Date: Fri, 10 Jan 2020 15:53:58 +0100 Message-Id: <20200110145412.14937-3-eric.auger@redhat.com> In-Reply-To: <20200110145412.14937-1-eric.auger@redhat.com> References: <20200110145412.14937-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, drjones@redhat.com, andre.przywara@arm.com, thuth@redhat.com, yuzenghui@huawei.com, alexandru.elisei@arm.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Andre Przywara A common theme when accessing per-IRQ parameters in the GIC distributor is to set fields of a certain bit width in a range of MMIO registers. Examples are the enabled status (one bit per IRQ), the level/edge configuration (2 bits per IRQ) or the priority (8 bits per IRQ). Add a generic helper function which is able to mask and set the respective number of bits, given the IRQ number and the MMIO offset. Provide wrappers using this function to easily allow configuring an IRQ. For now assume that private IRQ numbers always refer to the current CPU. In a GICv2 accessing the "other" private IRQs is not easily doable (the registers are banked per CPU on the same MMIO address), so we impose the same limitation on GICv3, even though those registers are not banked there anymore. Signed-off-by: Andre Przywara --- initialize reg --- lib/arm/asm/gic-v3.h | 2 + lib/arm/asm/gic.h | 8 ++++ lib/arm/gic.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/lib/arm/asm/gic-v3.h b/lib/arm/asm/gic-v3.h index 0dc838b..6beeab6 100644 --- a/lib/arm/asm/gic-v3.h +++ b/lib/arm/asm/gic-v3.h @@ -23,6 +23,8 @@ #define GICD_CTLR_ENABLE_G1A (1U << 1) #define GICD_CTLR_ENABLE_G1 (1U << 0) =20 +#define GICD_IROUTER 0x6000 + /* Re-Distributor registers, offsets from RD_base */ #define GICR_TYPER 0x0008 =20 diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h index 09826fd..21cdb58 100644 --- a/lib/arm/asm/gic.h +++ b/lib/arm/asm/gic.h @@ -74,5 +74,13 @@ extern void gic_write_eoir(u32 irqstat); extern void gic_ipi_send_single(int irq, int cpu); extern void gic_ipi_send_mask(int irq, const cpumask_t *dest); =20 +void gic_set_irq_bit(int irq, int offset); +void gic_enable_irq(int irq); +void gic_disable_irq(int irq); +void gic_set_irq_priority(int irq, u8 prio); +void gic_set_irq_target(int irq, int cpu); +void gic_set_irq_group(int irq, int group); +int gic_get_irq_group(int irq); + #endif /* !__ASSEMBLY__ */ #endif /* _ASMARM_GIC_H_ */ diff --git a/lib/arm/gic.c b/lib/arm/gic.c index 9430116..aa9cb86 100644 --- a/lib/arm/gic.c +++ b/lib/arm/gic.c @@ -146,3 +146,93 @@ void gic_ipi_send_mask(int irq, const cpumask_t *des= t) assert(gic_common_ops && gic_common_ops->ipi_send_mask); gic_common_ops->ipi_send_mask(irq, dest); } + +enum gic_bit_access { + ACCESS_READ, + ACCESS_SET, + ACCESS_RMW +}; + +static u8 gic_masked_irq_bits(int irq, int offset, int bits, u8 value, + enum gic_bit_access access) +{ + void *base; + int split =3D 32 / bits; + int shift =3D (irq % split) * bits; + u32 reg =3D 0, mask =3D ((1U << bits) - 1) << shift; + + switch (gic_version()) { + case 2: + base =3D gicv2_dist_base(); + break; + case 3: + if (irq < 32) + base =3D gicv3_sgi_base(); + else + base =3D gicv3_dist_base(); + break; + default: + return 0; + } + base +=3D offset + (irq / split) * 4; + + switch (access) { + case ACCESS_READ: + return (readl(base) & mask) >> shift; + case ACCESS_SET: + reg =3D 0; + break; + case ACCESS_RMW: + reg =3D readl(base) & ~mask; + break; + } + + writel(reg | ((u32)value << shift), base); + + return 0; +} + +void gic_set_irq_bit(int irq, int offset) +{ + gic_masked_irq_bits(irq, offset, 1, 1, ACCESS_SET); +} + +void gic_enable_irq(int irq) +{ + gic_set_irq_bit(irq, GICD_ISENABLER); +} + +void gic_disable_irq(int irq) +{ + gic_set_irq_bit(irq, GICD_ICENABLER); +} + +void gic_set_irq_priority(int irq, u8 prio) +{ + gic_masked_irq_bits(irq, GICD_IPRIORITYR, 8, prio, ACCESS_RMW); +} + +void gic_set_irq_target(int irq, int cpu) +{ + if (irq < 32) + return; + + if (gic_version() =3D=3D 2) { + gic_masked_irq_bits(irq, GICD_ITARGETSR, 8, 1U << cpu, + ACCESS_RMW); + + return; + } + + writeq(cpus[cpu], gicv3_dist_base() + GICD_IROUTER + irq * 8); +} + +void gic_set_irq_group(int irq, int group) +{ + gic_masked_irq_bits(irq, GICD_IGROUPR, 1, group, ACCESS_RMW); +} + +int gic_get_irq_group(int irq) +{ + return gic_masked_irq_bits(irq, GICD_IGROUPR, 1, 0, ACCESS_READ); +} --=20 2.20.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96C17C33CA3 for ; Fri, 10 Jan 2020 14:54:41 +0000 (UTC) Received: from mm01.cs.columbia.edu (mm01.cs.columbia.edu [128.59.11.253]) by mail.kernel.org (Postfix) with ESMTP id 4EF8A2082E for ; Fri, 10 Jan 2020 14:54:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="TWwPaLqN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4EF8A2082E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvmarm-bounces@lists.cs.columbia.edu Received: from localhost (localhost [127.0.0.1]) by mm01.cs.columbia.edu (Postfix) with ESMTP id CEC964B17F; Fri, 10 Jan 2020 09:54:40 -0500 (EST) X-Virus-Scanned: at lists.cs.columbia.edu Authentication-Results: mm01.cs.columbia.edu (amavisd-new); dkim=softfail (fail, message has been altered) header.i=@redhat.com Received: from mm01.cs.columbia.edu ([127.0.0.1]) by localhost (mm01.cs.columbia.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Kfo-5MMqKn8Q; Fri, 10 Jan 2020 09:54:39 -0500 (EST) Received: from mm01.cs.columbia.edu (localhost [127.0.0.1]) by mm01.cs.columbia.edu (Postfix) with ESMTP id B68344B17A; Fri, 10 Jan 2020 09:54:39 -0500 (EST) Received: from localhost (localhost [127.0.0.1]) by mm01.cs.columbia.edu (Postfix) with ESMTP id E45AE4B17F for ; Fri, 10 Jan 2020 09:54:38 -0500 (EST) X-Virus-Scanned: at lists.cs.columbia.edu Received: from mm01.cs.columbia.edu ([127.0.0.1]) by localhost (mm01.cs.columbia.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id C89CjzD3uMM7 for ; Fri, 10 Jan 2020 09:54:37 -0500 (EST) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) by mm01.cs.columbia.edu (Postfix) with ESMTP id DA0094AEFF for ; Fri, 10 Jan 2020 09:54:37 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1578668077; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hksWhfx/qjqLBl2kwSG6HIa1DnV2Yh8CnWY4dayzAHc=; b=TWwPaLqNjuisTNHbR4U+BXIxgzDnwYdd94Z3tY8iFkJZL8ACl5RLakr91MVo9f6F5ofi3V xXVmTPtLfmq4D+6epSFQOtxIF/zoQlxzoqxH3rYzIfDMh9qi41OqvQCq/SYmuPbpgexSl6 uPMoxWX2pl9TbEsdT2/z6VPN1umEDwI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-22-sLHCnH1HO6O3PHQlEJkQ_A-1; Fri, 10 Jan 2020 09:54:33 -0500 X-MC-Unique: sLHCnH1HO6O3PHQlEJkQ_A-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 328261AEEF5; Fri, 10 Jan 2020 14:54:32 +0000 (UTC) Received: from laptop.redhat.com (ovpn-117-108.ams2.redhat.com [10.36.117.108]) by smtp.corp.redhat.com (Postfix) with ESMTP id D26397C407; Fri, 10 Jan 2020 14:54:25 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, maz@kernel.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, qemu-devel@nongnu.org, qemu-arm@nongnu.org Subject: [kvm-unit-tests PATCH v2 02/16] arm: gic: Provide per-IRQ helper functions Date: Fri, 10 Jan 2020 15:53:58 +0100 Message-Id: <20200110145412.14937-3-eric.auger@redhat.com> In-Reply-To: <20200110145412.14937-1-eric.auger@redhat.com> References: <20200110145412.14937-1-eric.auger@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Cc: andre.przywara@arm.com, thuth@redhat.com X-BeenThere: kvmarm@lists.cs.columbia.edu X-Mailman-Version: 2.1.14 Precedence: list List-Id: Where KVM/ARM decisions are made List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: kvmarm-bounces@lists.cs.columbia.edu Sender: kvmarm-bounces@lists.cs.columbia.edu From: Andre Przywara A common theme when accessing per-IRQ parameters in the GIC distributor is to set fields of a certain bit width in a range of MMIO registers. Examples are the enabled status (one bit per IRQ), the level/edge configuration (2 bits per IRQ) or the priority (8 bits per IRQ). Add a generic helper function which is able to mask and set the respective number of bits, given the IRQ number and the MMIO offset. Provide wrappers using this function to easily allow configuring an IRQ. For now assume that private IRQ numbers always refer to the current CPU. In a GICv2 accessing the "other" private IRQs is not easily doable (the registers are banked per CPU on the same MMIO address), so we impose the same limitation on GICv3, even though those registers are not banked there anymore. Signed-off-by: Andre Przywara --- initialize reg --- lib/arm/asm/gic-v3.h | 2 + lib/arm/asm/gic.h | 8 ++++ lib/arm/gic.c | 90 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/lib/arm/asm/gic-v3.h b/lib/arm/asm/gic-v3.h index 0dc838b..6beeab6 100644 --- a/lib/arm/asm/gic-v3.h +++ b/lib/arm/asm/gic-v3.h @@ -23,6 +23,8 @@ #define GICD_CTLR_ENABLE_G1A (1U << 1) #define GICD_CTLR_ENABLE_G1 (1U << 0) +#define GICD_IROUTER 0x6000 + /* Re-Distributor registers, offsets from RD_base */ #define GICR_TYPER 0x0008 diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h index 09826fd..21cdb58 100644 --- a/lib/arm/asm/gic.h +++ b/lib/arm/asm/gic.h @@ -74,5 +74,13 @@ extern void gic_write_eoir(u32 irqstat); extern void gic_ipi_send_single(int irq, int cpu); extern void gic_ipi_send_mask(int irq, const cpumask_t *dest); +void gic_set_irq_bit(int irq, int offset); +void gic_enable_irq(int irq); +void gic_disable_irq(int irq); +void gic_set_irq_priority(int irq, u8 prio); +void gic_set_irq_target(int irq, int cpu); +void gic_set_irq_group(int irq, int group); +int gic_get_irq_group(int irq); + #endif /* !__ASSEMBLY__ */ #endif /* _ASMARM_GIC_H_ */ diff --git a/lib/arm/gic.c b/lib/arm/gic.c index 9430116..aa9cb86 100644 --- a/lib/arm/gic.c +++ b/lib/arm/gic.c @@ -146,3 +146,93 @@ void gic_ipi_send_mask(int irq, const cpumask_t *dest) assert(gic_common_ops && gic_common_ops->ipi_send_mask); gic_common_ops->ipi_send_mask(irq, dest); } + +enum gic_bit_access { + ACCESS_READ, + ACCESS_SET, + ACCESS_RMW +}; + +static u8 gic_masked_irq_bits(int irq, int offset, int bits, u8 value, + enum gic_bit_access access) +{ + void *base; + int split = 32 / bits; + int shift = (irq % split) * bits; + u32 reg = 0, mask = ((1U << bits) - 1) << shift; + + switch (gic_version()) { + case 2: + base = gicv2_dist_base(); + break; + case 3: + if (irq < 32) + base = gicv3_sgi_base(); + else + base = gicv3_dist_base(); + break; + default: + return 0; + } + base += offset + (irq / split) * 4; + + switch (access) { + case ACCESS_READ: + return (readl(base) & mask) >> shift; + case ACCESS_SET: + reg = 0; + break; + case ACCESS_RMW: + reg = readl(base) & ~mask; + break; + } + + writel(reg | ((u32)value << shift), base); + + return 0; +} + +void gic_set_irq_bit(int irq, int offset) +{ + gic_masked_irq_bits(irq, offset, 1, 1, ACCESS_SET); +} + +void gic_enable_irq(int irq) +{ + gic_set_irq_bit(irq, GICD_ISENABLER); +} + +void gic_disable_irq(int irq) +{ + gic_set_irq_bit(irq, GICD_ICENABLER); +} + +void gic_set_irq_priority(int irq, u8 prio) +{ + gic_masked_irq_bits(irq, GICD_IPRIORITYR, 8, prio, ACCESS_RMW); +} + +void gic_set_irq_target(int irq, int cpu) +{ + if (irq < 32) + return; + + if (gic_version() == 2) { + gic_masked_irq_bits(irq, GICD_ITARGETSR, 8, 1U << cpu, + ACCESS_RMW); + + return; + } + + writeq(cpus[cpu], gicv3_dist_base() + GICD_IROUTER + irq * 8); +} + +void gic_set_irq_group(int irq, int group) +{ + gic_masked_irq_bits(irq, GICD_IGROUPR, 1, group, ACCESS_RMW); +} + +int gic_get_irq_group(int irq) +{ + return gic_masked_irq_bits(irq, GICD_IGROUPR, 1, 0, ACCESS_READ); +} -- 2.20.1 _______________________________________________ kvmarm mailing list kvmarm@lists.cs.columbia.edu https://lists.cs.columbia.edu/mailman/listinfo/kvmarm