From nobody Tue May 21 00:58:26 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532686420650538.9372901503409; Fri, 27 Jul 2018 03:13:40 -0700 (PDT) Received: from localhost ([::1]:40148 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizkh-0002JC-5Y for importer@patchew.org; Fri, 27 Jul 2018 06:13:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58490) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSq-0003zY-6D for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSl-0006RO-PR for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:12 -0400 Received: from greensocs.com ([193.104.36.180]:47468) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00064B-1N; Fri, 27 Jul 2018 05:54:54 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id DF907443553; Fri, 27 Jul 2018 11:54:44 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NtBT0Xr9icuQ; Fri, 27 Jul 2018 11:54:43 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 74D8B4434A7; Fri, 27 Jul 2018 11:54:43 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 1A1BB400DC8; Fri, 27 Jul 2018 11:54:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685284; bh=nxv1H9jWe+gmJoPXDNpLVSbyIPMKUfUK6qW8IYnISKo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=mrfw3h0yykMK1abxoogR6kJOMJd98AFvzxniB9iXFj4K1E4fb9n8mINUQnHdHWOl1 I+F06VxvJs6d18XQwDh2Ho6H7nKKiXieyXO5zX4yJ4OXft2i0iP/h4qfc9QZPikbvm i1zRZ/wyxziEfIL/niXn8UkFSwldwG5O3Sri3dhk= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=CSZ5iPtS; dkim=pass (1024-bit key) header.d=greensocs.com header.b=CSZ5iPtS DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685283; bh=nxv1H9jWe+gmJoPXDNpLVSbyIPMKUfUK6qW8IYnISKo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=CSZ5iPtS1gwFE9d9Tvg9XIbPz0wzBpm7Ba+IhnLuFef5uV6pPT9UapkhJvBqxLLuF dphhrSh/rbIWFuv3sH5terJ5pnLia9hdlUMY6Ib3aCqJMP5MbYCRXfFhf0BWmiNjL9 IssLVb8FmZ30VKlz9nCMJmD06Q/mhKAjh5PVJp9I= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685283; bh=nxv1H9jWe+gmJoPXDNpLVSbyIPMKUfUK6qW8IYnISKo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=CSZ5iPtS1gwFE9d9Tvg9XIbPz0wzBpm7Ba+IhnLuFef5uV6pPT9UapkhJvBqxLLuF dphhrSh/rbIWFuv3sH5terJ5pnLia9hdlUMY6Ib3aCqJMP5MbYCRXfFhf0BWmiNjL9 IssLVb8FmZ30VKlz9nCMJmD06Q/mhKAjh5PVJp9I= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:02 +0200 Message-Id: <20180727095421.386-2-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 01/20] intc/arm_gic: Refactor operations on the distributor 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" In preparation for the virtualization extensions implementation, refactor the name of the functions and macros that act on the GIC distributor to make that fact explicit. It will be useful to differentiate them from the ones that will act on the virtual interfaces. Signed-off-by: Luc Michel Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Sai Pavan Boddu Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 163 +++++++++++++++++++++------------------ hw/intc/arm_gic_common.c | 6 +- hw/intc/arm_gic_kvm.c | 23 +++--- hw/intc/gic_internal.h | 51 ++++++------ 4 files changed, 127 insertions(+), 116 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 34dc84ae81..9286236d86 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -90,15 +90,16 @@ void gic_update(GICState *s) continue; } best_prio =3D 0x100; best_irq =3D 1023; for (irq =3D 0; irq < s->num_irq; irq++) { - if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) = && - (!GIC_TEST_ACTIVE(irq, cm)) && - (irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) { - if (GIC_GET_PRIORITY(irq, cpu) < best_prio) { - best_prio =3D GIC_GET_PRIORITY(irq, cpu); + if (GIC_DIST_TEST_ENABLED(irq, cm) && + gic_test_pending(s, irq, cm) && + (!GIC_DIST_TEST_ACTIVE(irq, cm)) && + (irq < GIC_INTERNAL || GIC_DIST_TARGET(irq) & cm)) { + if (GIC_DIST_GET_PRIORITY(irq, cpu) < best_prio) { + best_prio =3D GIC_DIST_GET_PRIORITY(irq, cpu); best_irq =3D irq; } } } =20 @@ -110,11 +111,11 @@ void gic_update(GICState *s) irq_level =3D fiq_level =3D 0; =20 if (best_prio < s->priority_mask[cpu]) { s->current_pending[cpu] =3D best_irq; if (best_prio < s->running_priority[cpu]) { - int group =3D GIC_TEST_GROUP(best_irq, cm); + int group =3D GIC_DIST_TEST_GROUP(best_irq, cm); =20 if (extract32(s->ctlr, group, 1) && extract32(s->cpu_ctlr[cpu], group, 1)) { if (group =3D=3D 0 && s->cpu_ctlr[cpu] & GICC_CTLR_FIQ= _EN) { DPRINTF("Raised pending FIQ %d (cpu %d)\n", @@ -143,39 +144,39 @@ void gic_set_pending_private(GICState *s, int cpu, in= t irq) if (gic_test_pending(s, irq, cm)) { return; } =20 DPRINTF("Set %d pending cpu %d\n", irq, cpu); - GIC_SET_PENDING(irq, cm); + GIC_DIST_SET_PENDING(irq, cm); gic_update(s); } =20 static void gic_set_irq_11mpcore(GICState *s, int irq, int level, int cm, int target) { if (level) { - GIC_SET_LEVEL(irq, cm); - if (GIC_TEST_EDGE_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) { + GIC_DIST_SET_LEVEL(irq, cm); + if (GIC_DIST_TEST_EDGE_TRIGGER(irq) || GIC_DIST_TEST_ENABLED(irq, = cm)) { DPRINTF("Set %d pending mask %x\n", irq, target); - GIC_SET_PENDING(irq, target); + GIC_DIST_SET_PENDING(irq, target); } } else { - GIC_CLEAR_LEVEL(irq, cm); + GIC_DIST_CLEAR_LEVEL(irq, cm); } } =20 static void gic_set_irq_generic(GICState *s, int irq, int level, int cm, int target) { if (level) { - GIC_SET_LEVEL(irq, cm); + GIC_DIST_SET_LEVEL(irq, cm); DPRINTF("Set %d pending mask %x\n", irq, target); - if (GIC_TEST_EDGE_TRIGGER(irq)) { - GIC_SET_PENDING(irq, target); + if (GIC_DIST_TEST_EDGE_TRIGGER(irq)) { + GIC_DIST_SET_PENDING(irq, target); } } else { - GIC_CLEAR_LEVEL(irq, cm); + GIC_DIST_CLEAR_LEVEL(irq, cm); } } =20 /* Process a change in an external IRQ input. */ static void gic_set_irq(void *opaque, int irq, int level) @@ -190,11 +191,11 @@ static void gic_set_irq(void *opaque, int irq, int le= vel) int cm, target; if (irq < (s->num_irq - GIC_INTERNAL)) { /* The first external input line is internal interrupt 32. */ cm =3D ALL_CPU_MASK; irq +=3D GIC_INTERNAL; - target =3D GIC_TARGET(irq); + target =3D GIC_DIST_TARGET(irq); } else { int cpu; irq -=3D (s->num_irq - GIC_INTERNAL); cpu =3D irq / GIC_INTERNAL; irq %=3D GIC_INTERNAL; @@ -202,11 +203,11 @@ static void gic_set_irq(void *opaque, int irq, int le= vel) target =3D cm; } =20 assert(irq >=3D GIC_NR_SGIS); =20 - if (level =3D=3D GIC_TEST_LEVEL(irq, cm)) { + if (level =3D=3D GIC_DIST_TEST_LEVEL(irq, cm)) { return; } =20 if (s->revision =3D=3D REV_11MPCORE) { gic_set_irq_11mpcore(s, irq, level, cm, target); @@ -222,11 +223,11 @@ static uint16_t gic_get_current_pending_irq(GICState = *s, int cpu, MemTxAttrs attrs) { uint16_t pending_irq =3D s->current_pending[cpu]; =20 if (pending_irq < GIC_MAXIRQ && gic_has_groups(s)) { - int group =3D GIC_TEST_GROUP(pending_irq, (1 << cpu)); + int group =3D GIC_DIST_TEST_GROUP(pending_irq, (1 << cpu)); /* On a GIC without the security extensions, reading this register * behaves in the same way as a secure access to a GIC with them. */ bool secure =3D !s->security_extn || attrs.secure; =20 @@ -253,11 +254,11 @@ static int gic_get_group_priority(GICState *s, int cp= u, int irq) int bpr; uint32_t mask; =20 if (gic_has_groups(s) && !(s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) && - GIC_TEST_GROUP(irq, (1 << cpu))) { + GIC_DIST_TEST_GROUP(irq, (1 << cpu))) { bpr =3D s->abpr[cpu] - 1; assert(bpr >=3D 0); } else { bpr =3D s->bpr[cpu]; } @@ -266,11 +267,11 @@ static int gic_get_group_priority(GICState *s, int cp= u, int irq) * a BPR of 1 means they are [7:2], and so on down to * a BPR of 7 meaning no group priority bits at all. */ mask =3D ~0U << ((bpr & 7) + 1); =20 - return GIC_GET_PRIORITY(irq, cpu) & mask; + return GIC_DIST_GET_PRIORITY(irq, cpu) & mask; } =20 static void gic_activate_irq(GICState *s, int cpu, int irq) { /* Set the appropriate Active Priority Register bit for this IRQ, @@ -279,18 +280,18 @@ static void gic_activate_irq(GICState *s, int cpu, in= t irq) int prio =3D gic_get_group_priority(s, cpu, irq); int preemption_level =3D prio >> (GIC_MIN_BPR + 1); int regno =3D preemption_level / 32; int bitno =3D preemption_level % 32; =20 - if (gic_has_groups(s) && GIC_TEST_GROUP(irq, (1 << cpu))) { + if (gic_has_groups(s) && GIC_DIST_TEST_GROUP(irq, (1 << cpu))) { s->nsapr[regno][cpu] |=3D (1 << bitno); } else { s->apr[regno][cpu] |=3D (1 << bitno); } =20 s->running_priority[cpu] =3D prio; - GIC_SET_ACTIVE(irq, 1 << cpu); + GIC_DIST_SET_ACTIVE(irq, 1 << cpu); } =20 static int gic_get_prio_from_apr_bits(GICState *s, int cpu) { /* Recalculate the current running priority for this CPU based @@ -355,20 +356,21 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, Me= mTxAttrs attrs) if (irq >=3D GIC_MAXIRQ) { DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq); return irq; } =20 - if (GIC_GET_PRIORITY(irq, cpu) >=3D s->running_priority[cpu]) { + if (GIC_DIST_GET_PRIORITY(irq, cpu) >=3D s->running_priority[cpu]) { DPRINTF("ACK, pending interrupt (%d) has insufficient priority\n",= irq); return 1023; } =20 if (s->revision =3D=3D REV_11MPCORE) { /* Clear pending flags for both level and edge triggered interrupt= s. * Level triggered IRQs will be reasserted once they become inacti= ve. */ - GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK : cm); + GIC_DIST_CLEAR_PENDING(irq, GIC_DIST_TEST_MODEL(irq) ? ALL_CPU_MASK + : cm); ret =3D irq; } else { if (irq < GIC_NR_SGIS) { /* Lookup the source CPU for the SGI and clear this in the * sgi_pending map. Return the src and clear the overall pend= ing @@ -376,34 +378,37 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, Me= mTxAttrs attrs) */ assert(s->sgi_pending[irq][cpu] !=3D 0); src =3D ctz32(s->sgi_pending[irq][cpu]); s->sgi_pending[irq][cpu] &=3D ~(1 << src); if (s->sgi_pending[irq][cpu] =3D=3D 0) { - GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK = : cm); + GIC_DIST_CLEAR_PENDING(irq, + GIC_DIST_TEST_MODEL(irq) ? ALL_CPU_= MASK + : cm); } ret =3D irq | ((src & 0x7) << 10); } else { /* Clear pending state for both level and edge triggered * interrupts. (level triggered interrupts with an active line * remain pending, see gic_test_pending) */ - GIC_CLEAR_PENDING(irq, GIC_TEST_MODEL(irq) ? ALL_CPU_MASK : cm= ); + GIC_DIST_CLEAR_PENDING(irq, GIC_DIST_TEST_MODEL(irq) ? ALL_CPU= _MASK + : cm); ret =3D irq; } } =20 gic_activate_irq(s, cpu, irq); gic_update(s); DPRINTF("ACK %d\n", irq); return ret; } =20 -void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val, +void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val, MemTxAttrs attrs) { if (s->security_extn && !attrs.secure) { - if (!GIC_TEST_GROUP(irq, (1 << cpu))) { + if (!GIC_DIST_TEST_GROUP(irq, (1 << cpu))) { return; /* Ignore Non-secure access of Group0 IRQ */ } val =3D 0x80 | (val >> 1); /* Non-secure view */ } =20 @@ -412,17 +417,17 @@ void gic_set_priority(GICState *s, int cpu, int irq, = uint8_t val, } else { s->priority2[(irq) - GIC_INTERNAL] =3D val; } } =20 -static uint32_t gic_get_priority(GICState *s, int cpu, int irq, +static uint32_t gic_dist_get_priority(GICState *s, int cpu, int irq, MemTxAttrs attrs) { - uint32_t prio =3D GIC_GET_PRIORITY(irq, cpu); + uint32_t prio =3D GIC_DIST_GET_PRIORITY(irq, cpu); =20 if (s->security_extn && !attrs.secure) { - if (!GIC_TEST_GROUP(irq, (1 << cpu))) { + if (!GIC_DIST_TEST_GROUP(irq, (1 << cpu))) { return 0; /* Non-secure access cannot read priority of Group0 = IRQ */ } prio =3D (prio << 1) & 0xff; /* Non-secure view */ } return prio; @@ -555,11 +560,11 @@ static void gic_deactivate_irq(GICState *s, int cpu, = int irq, MemTxAttrs attrs) * and so this is UNPREDICTABLE. We choose to ignore it. */ return; } =20 - group =3D gic_has_groups(s) && GIC_TEST_GROUP(irq, cm); + group =3D gic_has_groups(s) && GIC_DIST_TEST_GROUP(irq, cm); =20 if (!gic_eoi_split(s, cpu, attrs)) { /* This is UNPREDICTABLE; we choose to ignore it */ qemu_log_mask(LOG_GUEST_ERROR, "gic_deactivate_irq: GICC_DIR write when EOIMode cle= ar"); @@ -569,11 +574,11 @@ static void gic_deactivate_irq(GICState *s, int cpu, = int irq, MemTxAttrs attrs) if (s->security_extn && !attrs.secure && !group) { DPRINTF("Non-secure DI for Group0 interrupt %d ignored\n", irq); return; } =20 - GIC_CLEAR_ACTIVE(irq, cm); + GIC_DIST_CLEAR_ACTIVE(irq, cm); } =20 void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs) { int cm =3D 1 << cpu; @@ -596,18 +601,19 @@ void gic_complete_irq(GICState *s, int cpu, int irq, = MemTxAttrs attrs) } =20 if (s->revision =3D=3D REV_11MPCORE) { /* Mark level triggered interrupts as pending if they are still raised. */ - if (!GIC_TEST_EDGE_TRIGGER(irq) && GIC_TEST_ENABLED(irq, cm) - && GIC_TEST_LEVEL(irq, cm) && (GIC_TARGET(irq) & cm) !=3D 0) { + if (!GIC_DIST_TEST_EDGE_TRIGGER(irq) && GIC_DIST_TEST_ENABLED(irq,= cm) + && GIC_DIST_TEST_LEVEL(irq, cm) + && (GIC_DIST_TARGET(irq) & cm) !=3D 0) { DPRINTF("Set %d pending mask %x\n", irq, cm); - GIC_SET_PENDING(irq, cm); + GIC_DIST_SET_PENDING(irq, cm); } } =20 - group =3D gic_has_groups(s) && GIC_TEST_GROUP(irq, cm); + group =3D gic_has_groups(s) && GIC_DIST_TEST_GROUP(irq, cm); =20 if (s->security_extn && !attrs.secure && !group) { DPRINTF("Non-secure EOI for Group0 interrupt %d ignored\n", irq); return; } @@ -619,11 +625,11 @@ void gic_complete_irq(GICState *s, int cpu, int irq, = MemTxAttrs attrs) =20 gic_drop_prio(s, cpu, group); =20 /* In GICv2 the guest can choose to split priority-drop and deactivate= */ if (!gic_eoi_split(s, cpu, attrs)) { - GIC_CLEAR_ACTIVE(irq, cm); + GIC_DIST_CLEAR_ACTIVE(irq, cm); } gic_update(s); } =20 static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs att= rs) @@ -667,11 +673,11 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr o= ffset, MemTxAttrs attrs) irq =3D (offset - 0x080) * 8 + GIC_BASE_IRQ; if (irq >=3D s->num_irq) { goto bad_reg; } for (i =3D 0; i < 8; i++) { - if (GIC_TEST_GROUP(irq + i, cm)) { + if (GIC_DIST_TEST_GROUP(irq + i, cm)) { res |=3D (1 << i); } } } return res; @@ -687,15 +693,15 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr o= ffset, MemTxAttrs attrs) if (irq >=3D s->num_irq) goto bad_reg; res =3D 0; for (i =3D 0; i < 8; i++) { if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 - if (GIC_TEST_ENABLED(irq + i, cm)) { + if (GIC_DIST_TEST_ENABLED(irq + i, cm)) { res |=3D (1 << i); } } } else if (offset < 0x300) { /* Interrupt Set/Clear Pending. */ @@ -708,11 +714,11 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr o= ffset, MemTxAttrs attrs) goto bad_reg; res =3D 0; mask =3D (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK; for (i =3D 0; i < 8; i++) { if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 if (gic_test_pending(s, irq + i, mask)) { res |=3D (1 << i); @@ -725,24 +731,24 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr o= ffset, MemTxAttrs attrs) goto bad_reg; res =3D 0; mask =3D (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK; for (i =3D 0; i < 8; i++) { if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 - if (GIC_TEST_ACTIVE(irq + i, mask)) { + if (GIC_DIST_TEST_ACTIVE(irq + i, mask)) { res |=3D (1 << i); } } } else if (offset < 0x800) { /* Interrupt Priority. */ irq =3D (offset - 0x400) + GIC_BASE_IRQ; if (irq >=3D s->num_irq) goto bad_reg; - res =3D gic_get_priority(s, cpu, irq, attrs); + res =3D gic_dist_get_priority(s, cpu, irq, attrs); } else if (offset < 0xc00) { /* Interrupt CPU Target. */ if (s->num_cpu =3D=3D 1 && s->revision !=3D REV_11MPCORE) { /* For uniprocessor GICs these RAZ/WI */ res =3D 0; @@ -754,29 +760,31 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr o= ffset, MemTxAttrs attrs) if (irq < 29 && s->revision =3D=3D REV_11MPCORE) { res =3D 0; } else if (irq < GIC_INTERNAL) { res =3D cm; } else { - res =3D GIC_TARGET(irq); + res =3D GIC_DIST_TARGET(irq); } } } else if (offset < 0xf00) { /* Interrupt Configuration. */ irq =3D (offset - 0xc00) * 4 + GIC_BASE_IRQ; if (irq >=3D s->num_irq) goto bad_reg; res =3D 0; for (i =3D 0; i < 4; i++) { if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 - if (GIC_TEST_MODEL(irq + i)) + if (GIC_DIST_TEST_MODEL(irq + i)) { res |=3D (1 << (i * 2)); - if (GIC_TEST_EDGE_TRIGGER(irq + i)) + } + if (GIC_DIST_TEST_EDGE_TRIGGER(irq + i)) { res |=3D (2 << (i * 2)); + } } } else if (offset < 0xf10) { goto bad_reg; } else if (offset < 0xf30) { if (s->revision =3D=3D REV_11MPCORE) { @@ -790,11 +798,11 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr o= ffset, MemTxAttrs attrs) irq =3D (offset - 0xf20); /* GICD_SPENDSGIRn */ } =20 if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq, 1 << cpu)) { res =3D 0; /* Ignore Non-secure access of Group0 IRQ */ } else { res =3D s->sgi_pending[irq][cpu]; } } else if (offset < 0xfd0) { @@ -886,14 +894,14 @@ static void gic_dist_writeb(void *opaque, hwaddr offs= et, for (i =3D 0; i < 8; i++) { /* Group bits are banked for private interrupts */ int cm =3D (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU= _MASK; if (value & (1 << i)) { /* Group1 (Non-secure) */ - GIC_SET_GROUP(irq + i, cm); + GIC_DIST_SET_GROUP(irq + i, cm); } else { /* Group0 (Secure) */ - GIC_CLEAR_GROUP(irq + i, cm); + GIC_DIST_CLEAR_GROUP(irq + i, cm); } } } } else { goto bad_reg; @@ -908,29 +916,30 @@ static void gic_dist_writeb(void *opaque, hwaddr offs= et, } =20 for (i =3D 0; i < 8; i++) { if (value & (1 << i)) { int mask =3D - (irq < GIC_INTERNAL) ? (1 << cpu) : GIC_TARGET(irq + i= ); + (irq < GIC_INTERNAL) ? (1 << cpu) + : GIC_DIST_TARGET(irq + i); int cm =3D (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MAS= K; =20 if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 - if (!GIC_TEST_ENABLED(irq + i, cm)) { + if (!GIC_DIST_TEST_ENABLED(irq + i, cm)) { DPRINTF("Enabled IRQ %d\n", irq + i); trace_gic_enable_irq(irq + i); } - GIC_SET_ENABLED(irq + i, cm); + GIC_DIST_SET_ENABLED(irq + i, cm); /* If a raised level triggered IRQ enabled then mark is as pending. */ - if (GIC_TEST_LEVEL(irq + i, mask) - && !GIC_TEST_EDGE_TRIGGER(irq + i)) { + if (GIC_DIST_TEST_LEVEL(irq + i, mask) + && !GIC_DIST_TEST_EDGE_TRIGGER(irq + i)) { DPRINTF("Set %d pending mask %x\n", irq + i, mask); - GIC_SET_PENDING(irq + i, mask); + GIC_DIST_SET_PENDING(irq + i, mask); } } } } else if (offset < 0x200) { /* Interrupt Clear Enable. */ @@ -944,19 +953,19 @@ static void gic_dist_writeb(void *opaque, hwaddr offs= et, for (i =3D 0; i < 8; i++) { if (value & (1 << i)) { int cm =3D (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MAS= K; =20 if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 - if (GIC_TEST_ENABLED(irq + i, cm)) { + if (GIC_DIST_TEST_ENABLED(irq + i, cm)) { DPRINTF("Disabled IRQ %d\n", irq + i); trace_gic_disable_irq(irq + i); } - GIC_CLEAR_ENABLED(irq + i, cm); + GIC_DIST_CLEAR_ENABLED(irq + i, cm); } } } else if (offset < 0x280) { /* Interrupt Set Pending. */ irq =3D (offset - 0x200) * 8 + GIC_BASE_IRQ; @@ -967,15 +976,15 @@ static void gic_dist_writeb(void *opaque, hwaddr offs= et, } =20 for (i =3D 0; i < 8; i++) { if (value & (1 << i)) { if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 - GIC_SET_PENDING(irq + i, GIC_TARGET(irq + i)); + GIC_DIST_SET_PENDING(irq + i, GIC_DIST_TARGET(irq + i)); } } } else if (offset < 0x300) { /* Interrupt Clear Pending. */ irq =3D (offset - 0x280) * 8 + GIC_BASE_IRQ; @@ -985,30 +994,30 @@ static void gic_dist_writeb(void *opaque, hwaddr offs= et, value =3D 0; } =20 for (i =3D 0; i < 8; i++) { if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 /* ??? This currently clears the pending bit for all CPUs, even for per-CPU interrupts. It's unclear whether this is the corect behavior. */ if (value & (1 << i)) { - GIC_CLEAR_PENDING(irq + i, ALL_CPU_MASK); + GIC_DIST_CLEAR_PENDING(irq + i, ALL_CPU_MASK); } } } else if (offset < 0x400) { /* Interrupt Active. */ goto bad_reg; } else if (offset < 0x800) { /* Interrupt Priority. */ irq =3D (offset - 0x400) + GIC_BASE_IRQ; if (irq >=3D s->num_irq) goto bad_reg; - gic_set_priority(s, cpu, irq, value, attrs); + gic_dist_set_priority(s, cpu, irq, value, attrs); } else if (offset < 0xc00) { /* Interrupt CPU Target. RAZ/WI on uniprocessor GICs, with the * annoying exception of the 11MPCore's GIC. */ if (s->num_cpu !=3D 1 || s->revision =3D=3D REV_11MPCORE) { @@ -1030,25 +1039,25 @@ static void gic_dist_writeb(void *opaque, hwaddr of= fset, goto bad_reg; if (irq < GIC_NR_SGIS) value |=3D 0xaa; for (i =3D 0; i < 4; i++) { if (s->security_extn && !attrs.secure && - !GIC_TEST_GROUP(irq + i, 1 << cpu)) { + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { continue; /* Ignore Non-secure access of Group0 IRQ */ } =20 if (s->revision =3D=3D REV_11MPCORE) { if (value & (1 << (i * 2))) { - GIC_SET_MODEL(irq + i); + GIC_DIST_SET_MODEL(irq + i); } else { - GIC_CLEAR_MODEL(irq + i); + GIC_DIST_CLEAR_MODEL(irq + i); } } if (value & (2 << (i * 2))) { - GIC_SET_EDGE_TRIGGER(irq + i); + GIC_DIST_SET_EDGE_TRIGGER(irq + i); } else { - GIC_CLEAR_EDGE_TRIGGER(irq + i); + GIC_DIST_CLEAR_EDGE_TRIGGER(irq + i); } } } else if (offset < 0xf10) { /* 0xf00 is only handled for 32-bit writes. */ goto bad_reg; @@ -1058,26 +1067,26 @@ static void gic_dist_writeb(void *opaque, hwaddr of= fset, goto bad_reg; } irq =3D (offset - 0xf10); =20 if (!s->security_extn || attrs.secure || - GIC_TEST_GROUP(irq, 1 << cpu)) { + GIC_DIST_TEST_GROUP(irq, 1 << cpu)) { s->sgi_pending[irq][cpu] &=3D ~value; if (s->sgi_pending[irq][cpu] =3D=3D 0) { - GIC_CLEAR_PENDING(irq, 1 << cpu); + GIC_DIST_CLEAR_PENDING(irq, 1 << cpu); } } } else if (offset < 0xf30) { /* GICD_SPENDSGIRn */ if (s->revision =3D=3D REV_11MPCORE) { goto bad_reg; } irq =3D (offset - 0xf20); =20 if (!s->security_extn || attrs.secure || - GIC_TEST_GROUP(irq, 1 << cpu)) { - GIC_SET_PENDING(irq, 1 << cpu); + GIC_DIST_TEST_GROUP(irq, 1 << cpu)) { + GIC_DIST_SET_PENDING(irq, 1 << cpu); s->sgi_pending[irq][cpu] |=3D value; } } else { goto bad_reg; } @@ -1120,11 +1129,11 @@ static void gic_dist_writel(void *opaque, hwaddr of= fset, default: DPRINTF("Bad Soft Int target filter\n"); mask =3D ALL_CPU_MASK; break; } - GIC_SET_PENDING(irq, mask); + GIC_DIST_SET_PENDING(irq, mask); target_cpu =3D ctz32(mask); while (target_cpu < GIC_NCPU) { s->sgi_pending[irq][target_cpu] |=3D (1 << cpu); mask &=3D ~(1 << target_cpu); target_cpu =3D ctz32(mask); diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index aee50a20e0..295ee9cc5e 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -202,12 +202,12 @@ static void arm_gic_common_reset(DeviceState *dev) for (j =3D 0; j < GIC_NR_SGIS; j++) { s->sgi_pending[j][i] =3D 0; } } for (i =3D 0; i < GIC_NR_SGIS; i++) { - GIC_SET_ENABLED(i, ALL_CPU_MASK); - GIC_SET_EDGE_TRIGGER(i); + GIC_DIST_SET_ENABLED(i, ALL_CPU_MASK); + GIC_DIST_SET_EDGE_TRIGGER(i); } =20 for (i =3D 0; i < ARRAY_SIZE(s->priority2); i++) { s->priority2[i] =3D resetprio; } @@ -220,11 +220,11 @@ static void arm_gic_common_reset(DeviceState *dev) s->irq_target[i] =3D 0; } } if (s->security_extn && s->irq_reset_nonsecure) { for (i =3D 0; i < GIC_MAXIRQ; i++) { - GIC_SET_GROUP(i, ALL_CPU_MASK); + GIC_DIST_SET_GROUP(i, ALL_CPU_MASK); } } =20 s->ctlr =3D 0; } diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index 86665080bd..4b611c8d6d 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -138,28 +138,28 @@ static void translate_group(GICState *s, int irq, int= cpu, uint32_t *field, bool to_kernel) { int cm =3D (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK; =20 if (to_kernel) { - *field =3D GIC_TEST_GROUP(irq, cm); + *field =3D GIC_DIST_TEST_GROUP(irq, cm); } else { if (*field & 1) { - GIC_SET_GROUP(irq, cm); + GIC_DIST_SET_GROUP(irq, cm); } } } =20 static void translate_enabled(GICState *s, int irq, int cpu, uint32_t *field, bool to_kernel) { int cm =3D (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK; =20 if (to_kernel) { - *field =3D GIC_TEST_ENABLED(irq, cm); + *field =3D GIC_DIST_TEST_ENABLED(irq, cm); } else { if (*field & 1) { - GIC_SET_ENABLED(irq, cm); + GIC_DIST_SET_ENABLED(irq, cm); } } } =20 static void translate_pending(GICState *s, int irq, int cpu, @@ -169,11 +169,11 @@ static void translate_pending(GICState *s, int irq, i= nt cpu, =20 if (to_kernel) { *field =3D gic_test_pending(s, irq, cm); } else { if (*field & 1) { - GIC_SET_PENDING(irq, cm); + GIC_DIST_SET_PENDING(irq, cm); /* TODO: Capture is level-line is held high in the kernel */ } } } =20 @@ -181,37 +181,38 @@ static void translate_active(GICState *s, int irq, in= t cpu, uint32_t *field, bool to_kernel) { int cm =3D (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK; =20 if (to_kernel) { - *field =3D GIC_TEST_ACTIVE(irq, cm); + *field =3D GIC_DIST_TEST_ACTIVE(irq, cm); } else { if (*field & 1) { - GIC_SET_ACTIVE(irq, cm); + GIC_DIST_SET_ACTIVE(irq, cm); } } } =20 static void translate_trigger(GICState *s, int irq, int cpu, uint32_t *field, bool to_kernel) { if (to_kernel) { - *field =3D (GIC_TEST_EDGE_TRIGGER(irq)) ? 0x2 : 0x0; + *field =3D (GIC_DIST_TEST_EDGE_TRIGGER(irq)) ? 0x2 : 0x0; } else { if (*field & 0x2) { - GIC_SET_EDGE_TRIGGER(irq); + GIC_DIST_SET_EDGE_TRIGGER(irq); } } } =20 static void translate_priority(GICState *s, int irq, int cpu, uint32_t *field, bool to_kernel) { if (to_kernel) { - *field =3D GIC_GET_PRIORITY(irq, cpu) & 0xff; + *field =3D GIC_DIST_GET_PRIORITY(irq, cpu) & 0xff; } else { - gic_set_priority(s, cpu, irq, *field & 0xff, MEMTXATTRS_UNSPECIFIE= D); + gic_dist_set_priority(s, cpu, irq, + *field & 0xff, MEMTXATTRS_UNSPECIFIED); } } =20 static void translate_targets(GICState *s, int irq, int cpu, uint32_t *field, bool to_kernel) diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 7fe87b13de..6f8d242904 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -25,34 +25,35 @@ =20 #define ALL_CPU_MASK ((unsigned)(((1 << GIC_NCPU) - 1))) =20 #define GIC_BASE_IRQ 0 =20 -#define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |=3D (cm) -#define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &=3D ~(cm) -#define GIC_TEST_ENABLED(irq, cm) ((s->irq_state[irq].enabled & (cm)) !=3D= 0) -#define GIC_SET_PENDING(irq, cm) s->irq_state[irq].pending |=3D (cm) -#define GIC_CLEAR_PENDING(irq, cm) s->irq_state[irq].pending &=3D ~(cm) -#define GIC_SET_ACTIVE(irq, cm) s->irq_state[irq].active |=3D (cm) -#define GIC_CLEAR_ACTIVE(irq, cm) s->irq_state[irq].active &=3D ~(cm) -#define GIC_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) !=3D 0) -#define GIC_SET_MODEL(irq) s->irq_state[irq].model =3D true -#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model =3D false -#define GIC_TEST_MODEL(irq) s->irq_state[irq].model -#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level |=3D (cm) -#define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &=3D ~(cm) -#define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) !=3D 0) -#define GIC_SET_EDGE_TRIGGER(irq) s->irq_state[irq].edge_trigger =3D true -#define GIC_CLEAR_EDGE_TRIGGER(irq) s->irq_state[irq].edge_trigger =3D fal= se -#define GIC_TEST_EDGE_TRIGGER(irq) (s->irq_state[irq].edge_trigger) -#define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ? \ +#define GIC_DIST_SET_ENABLED(irq, cm) (s->irq_state[irq].enabled |=3D (cm)) +#define GIC_DIST_CLEAR_ENABLED(irq, cm) (s->irq_state[irq].enabled &=3D ~(= cm)) +#define GIC_DIST_TEST_ENABLED(irq, cm) ((s->irq_state[irq].enabled & (cm))= !=3D 0) +#define GIC_DIST_SET_PENDING(irq, cm) (s->irq_state[irq].pending |=3D (cm)) +#define GIC_DIST_CLEAR_PENDING(irq, cm) (s->irq_state[irq].pending &=3D ~(= cm)) +#define GIC_DIST_SET_ACTIVE(irq, cm) (s->irq_state[irq].active |=3D (cm)) +#define GIC_DIST_CLEAR_ACTIVE(irq, cm) (s->irq_state[irq].active &=3D ~(cm= )) +#define GIC_DIST_TEST_ACTIVE(irq, cm) ((s->irq_state[irq].active & (cm)) != =3D 0) +#define GIC_DIST_SET_MODEL(irq) (s->irq_state[irq].model =3D true) +#define GIC_DIST_CLEAR_MODEL(irq) (s->irq_state[irq].model =3D false) +#define GIC_DIST_TEST_MODEL(irq) (s->irq_state[irq].model) +#define GIC_DIST_SET_LEVEL(irq, cm) (s->irq_state[irq].level |=3D (cm)) +#define GIC_DIST_CLEAR_LEVEL(irq, cm) (s->irq_state[irq].level &=3D ~(cm)) +#define GIC_DIST_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != =3D 0) +#define GIC_DIST_SET_EDGE_TRIGGER(irq) (s->irq_state[irq].edge_trigger =3D= true) +#define GIC_DIST_CLEAR_EDGE_TRIGGER(irq) \ + (s->irq_state[irq].edge_trigger =3D false) +#define GIC_DIST_TEST_EDGE_TRIGGER(irq) (s->irq_state[irq].edge_trigger) +#define GIC_DIST_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ? = \ s->priority1[irq][cpu] : \ s->priority2[(irq) - GIC_INTERNAL]) -#define GIC_TARGET(irq) s->irq_target[irq] -#define GIC_CLEAR_GROUP(irq, cm) (s->irq_state[irq].group &=3D ~(cm)) -#define GIC_SET_GROUP(irq, cm) (s->irq_state[irq].group |=3D (cm)) -#define GIC_TEST_GROUP(irq, cm) ((s->irq_state[irq].group & (cm)) !=3D 0) +#define GIC_DIST_TARGET(irq) (s->irq_target[irq]) +#define GIC_DIST_CLEAR_GROUP(irq, cm) (s->irq_state[irq].group &=3D ~(cm)) +#define GIC_DIST_SET_GROUP(irq, cm) (s->irq_state[irq].group |=3D (cm)) +#define GIC_DIST_TEST_GROUP(irq, cm) ((s->irq_state[irq].group & (cm)) != =3D 0) =20 #define GICD_CTLR_EN_GRP0 (1U << 0) #define GICD_CTLR_EN_GRP1 (1U << 1) =20 #define GICC_CTLR_EN_GRP0 (1U << 0) @@ -77,12 +78,12 @@ void gic_set_pending_private(GICState *s, int cpu, int irq); uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs); void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs); void gic_update(GICState *s); void gic_init_irqs_and_distributor(GICState *s); -void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val, - MemTxAttrs attrs); +void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val, + MemTxAttrs attrs); =20 static inline bool gic_test_pending(GICState *s, int irq, int cm) { if (s->revision =3D=3D REV_11MPCORE) { return s->irq_state[irq].pending & cm; @@ -91,10 +92,10 @@ static inline bool gic_test_pending(GICState *s, int ir= q, int cm) * level-triggered interrupts are either considered pending when t= he * level is active or if software has explicitly written to * GICD_ISPENDR to set the state pending. */ return (s->irq_state[irq].pending & cm) || - (!GIC_TEST_EDGE_TRIGGER(irq) && GIC_TEST_LEVEL(irq, cm)); + (!GIC_DIST_TEST_EDGE_TRIGGER(irq) && GIC_DIST_TEST_LEVEL(irq, = cm)); } } =20 #endif /* QEMU_ARM_GIC_INTERNAL_H */ --=20 2.18.0 From nobody Tue May 21 00:58:26 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532685685128387.9739091390927; Fri, 27 Jul 2018 03:01:25 -0700 (PDT) Received: from localhost ([::1]:40071 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizYp-00018r-Ev for importer@patchew.org; Fri, 27 Jul 2018 06:01:23 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58261) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSi-0003ke-8p for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSf-0006JN-Mi for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:04 -0400 Received: from greensocs.com ([193.104.36.180]:47469) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00064C-1O; Fri, 27 Jul 2018 05:54:54 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id C5DB7443552; Fri, 27 Jul 2018 11:54:44 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eYPaaQD32dMP; Fri, 27 Jul 2018 11:54:44 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id CB0164434B9; Fri, 27 Jul 2018 11:54:43 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 792C9400DC8; Fri, 27 Jul 2018 11:54:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685284; bh=tGF+F1QMsC3Sl8uhC6AMT3vZXThYqbUvIbTOAzBL6/w=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=kVSm6YHfZsV5sRS8kSS68GmSzv128xSVx9fU73q7MSvMri5QPrh5CWkKOvHN/ObqK suzfXaCHkJY1mB04NrwaSnQsnDSzdinQ1yzdIW33wLz3mX3Cgas+S4oOBDe7o/pzCt JSNraIpajnctmGP2vHou++stNOGx/kTB6LoS4PQQ= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=W1RmNtxl; dkim=pass (1024-bit key) header.d=greensocs.com header.b=W1RmNtxl DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685283; bh=tGF+F1QMsC3Sl8uhC6AMT3vZXThYqbUvIbTOAzBL6/w=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=W1RmNtxlgCn+VF+HBI39hygKhCGayqxVugpKWUaELC7U9zi92Bibl6jGaz26HRiC5 x/WAuRYDB21k9rkudgtUo39McufYDZMhpxCKpsfSkDmLM9zQ453X0yzjtk6l6342Hc yVORKA5jyQUz5Dn4WOkj8t1Loz/jsdGn5dEpO4GU= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685283; bh=tGF+F1QMsC3Sl8uhC6AMT3vZXThYqbUvIbTOAzBL6/w=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=W1RmNtxlgCn+VF+HBI39hygKhCGayqxVugpKWUaELC7U9zi92Bibl6jGaz26HRiC5 x/WAuRYDB21k9rkudgtUo39McufYDZMhpxCKpsfSkDmLM9zQ453X0yzjtk6l6342Hc yVORKA5jyQUz5Dn4WOkj8t1Loz/jsdGn5dEpO4GU= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:03 +0200 Message-Id: <20180727095421.386-3-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 02/20] intc/arm_gic: Implement GICD_ISACTIVERn and GICD_ICACTIVERn registers 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement GICD_ISACTIVERn and GICD_ICACTIVERn registers in the GICv2. Those registers allow to set or clear the active state of an IRQ in the distributor. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 61 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 9286236d86..53b749d216 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -723,12 +723,20 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr o= ffset, MemTxAttrs attrs) if (gic_test_pending(s, irq + i, mask)) { res |=3D (1 << i); } } } else if (offset < 0x400) { - /* Interrupt Active. */ - irq =3D (offset - 0x300) * 8 + GIC_BASE_IRQ; + /* Interrupt Set/Clear Active. */ + if (offset < 0x380) { + irq =3D (offset - 0x300) * 8; + } else if (s->revision =3D=3D 2) { + irq =3D (offset - 0x380) * 8; + } else { + goto bad_reg; + } + + irq +=3D GIC_BASE_IRQ; if (irq >=3D s->num_irq) goto bad_reg; res =3D 0; mask =3D (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK; for (i =3D 0; i < 8; i++) { @@ -1005,13 +1013,58 @@ static void gic_dist_writeb(void *opaque, hwaddr of= fset, corect behavior. */ if (value & (1 << i)) { GIC_DIST_CLEAR_PENDING(irq + i, ALL_CPU_MASK); } } + } else if (offset < 0x380) { + /* Interrupt Set Active. */ + if (s->revision !=3D 2) { + goto bad_reg; + } + + irq =3D (offset - 0x300) * 8 + GIC_BASE_IRQ; + if (irq >=3D s->num_irq) { + goto bad_reg; + } + + /* This register is banked per-cpu for PPIs */ + int cm =3D irq < GIC_INTERNAL ? (1 << cpu) : ALL_CPU_MASK; + + for (i =3D 0; i < 8; i++) { + if (s->security_extn && !attrs.secure && + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { + continue; /* Ignore Non-secure access of Group0 IRQ */ + } + + if (value & (1 << i)) { + GIC_DIST_SET_ACTIVE(irq + i, cm); + } + } } else if (offset < 0x400) { - /* Interrupt Active. */ - goto bad_reg; + /* Interrupt Clear Active. */ + if (s->revision !=3D 2) { + goto bad_reg; + } + + irq =3D (offset - 0x380) * 8 + GIC_BASE_IRQ; + if (irq >=3D s->num_irq) { + goto bad_reg; + } + + /* This register is banked per-cpu for PPIs */ + int cm =3D irq < GIC_INTERNAL ? (1 << cpu) : ALL_CPU_MASK; + + for (i =3D 0; i < 8; i++) { + if (s->security_extn && !attrs.secure && + !GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) { + continue; /* Ignore Non-secure access of Group0 IRQ */ + } + + if (value & (1 << i)) { + GIC_DIST_CLEAR_ACTIVE(irq + i, cm); + } + } } else if (offset < 0x800) { /* Interrupt Priority. */ irq =3D (offset - 0x400) + GIC_BASE_IRQ; if (irq >=3D s->num_irq) goto bad_reg; --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532685479841555.8616311693143; Fri, 27 Jul 2018 02:57:59 -0700 (PDT) Received: from localhost ([::1]:40049 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizVM-0005xa-0n for importer@patchew.org; Fri, 27 Jul 2018 05:57:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58287) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSi-0003nc-UV for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSg-0006KB-AQ for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:04 -0400 Received: from greensocs.com ([193.104.36.180]:47467) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00064E-1E; Fri, 27 Jul 2018 05:54:54 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id A8EB54434B9; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ykn9hlZdDPOx; Fri, 27 Jul 2018 11:54:44 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 509D744354B; Fri, 27 Jul 2018 11:54:44 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id CFFC4400DC8; Fri, 27 Jul 2018 11:54:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685285; bh=t5FTPMLWoI8s9cEvq8oRgL4M4MPfkYWLBMKAaqpb6uo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=rD6S/lRgkd5maIHMLfr9wi1W8R05AGL025gacAEuFfGY8mbDQoUegrUgnsmWeYr5l 2nwv/uWdnWKxstJd7LbP4Ja2FNdg8ZxtF0Wb6dMTYrcqWzJ/XAbBQUY1aphxv1hqvh ZaTKE/Mh+jDP3phpjooTyu3LhqAgRDC7+mcw/DpM= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=IBMnOemf; dkim=pass (1024-bit key) header.d=greensocs.com header.b=IBMnOemf DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685284; bh=t5FTPMLWoI8s9cEvq8oRgL4M4MPfkYWLBMKAaqpb6uo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=IBMnOemfIxID2bpmm6JVEaNxPJdPUS00HwdXhxvQ8vtX+Dfyq1iDHxeuXuwPp9w7B WOPx/rxAnc1+Mb4RHb5qNmkbCcc9YgFNThvguMBcCmN3q6+jyXPf2jG9D4uu3/7bY1 8mSYIzbPiS9T7NJzjpvYf+QJQkrS23bGw+EPRU2c= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685284; bh=t5FTPMLWoI8s9cEvq8oRgL4M4MPfkYWLBMKAaqpb6uo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=IBMnOemfIxID2bpmm6JVEaNxPJdPUS00HwdXhxvQ8vtX+Dfyq1iDHxeuXuwPp9w7B WOPx/rxAnc1+Mb4RHb5qNmkbCcc9YgFNThvguMBcCmN3q6+jyXPf2jG9D4uu3/7bY1 8mSYIzbPiS9T7NJzjpvYf+QJQkrS23bGw+EPRU2c= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:04 +0200 Message-Id: <20180727095421.386-4-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 03/20] intc/arm_gic: Remove some dead code and put some functions static 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Some functions are now only used in arm_gic.c, put them static. Some of them where only used by the NVIC implementation and are not used anymore, so remove them. Signed-off-by: Luc Michel Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 23 ++--------------------- hw/intc/gic_internal.h | 4 ---- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 53b749d216..b8eba6e594 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -69,11 +69,11 @@ static inline bool gic_has_groups(GICState *s) return s->revision =3D=3D 2 || s->security_extn; } =20 /* TODO: Many places that call this routine could be optimized. */ /* Update interrupt status after enabled or pending bits have been changed= . */ -void gic_update(GICState *s) +static void gic_update(GICState *s) { int best_irq; int best_prio; int irq; int irq_level, fiq_level; @@ -135,23 +135,10 @@ void gic_update(GICState *s) qemu_set_irq(s->parent_irq[cpu], irq_level); qemu_set_irq(s->parent_fiq[cpu], fiq_level); } } =20 -void gic_set_pending_private(GICState *s, int cpu, int irq) -{ - int cm =3D 1 << cpu; - - if (gic_test_pending(s, irq, cm)) { - return; - } - - DPRINTF("Set %d pending cpu %d\n", irq, cpu); - GIC_DIST_SET_PENDING(irq, cm); - gic_update(s); -} - static void gic_set_irq_11mpcore(GICState *s, int irq, int level, int cm, int target) { if (level) { GIC_DIST_SET_LEVEL(irq, cm); @@ -577,11 +564,11 @@ static void gic_deactivate_irq(GICState *s, int cpu, = int irq, MemTxAttrs attrs) } =20 GIC_DIST_CLEAR_ACTIVE(irq, cm); } =20 -void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs) +static void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs att= rs) { int cm =3D 1 << cpu; int group; =20 DPRINTF("EOI %d\n", irq); @@ -1486,16 +1473,10 @@ static const MemoryRegionOps gic_cpu_ops =3D { .read_with_attrs =3D gic_do_cpu_read, .write_with_attrs =3D gic_do_cpu_write, .endianness =3D DEVICE_NATIVE_ENDIAN, }; =20 -/* This function is used by nvic model */ -void gic_init_irqs_and_distributor(GICState *s) -{ - gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops); -} - static void arm_gic_realize(DeviceState *dev, Error **errp) { /* Device instance realize function for the GIC sysbus device */ int i; GICState *s =3D ARM_GIC(dev); diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 6f8d242904..a2075a94db 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -73,15 +73,11 @@ #define GICC_CTLR_V2_S_MASK 0x61f =20 /* The special cases for the revision property: */ #define REV_11MPCORE 0 =20 -void gic_set_pending_private(GICState *s, int cpu, int irq); uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs); -void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs); -void gic_update(GICState *s); -void gic_init_irqs_and_distributor(GICState *s); void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val, MemTxAttrs attrs); =20 static inline bool gic_test_pending(GICState *s, int irq, int cm) { --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532685478086911.5972399167292; Fri, 27 Jul 2018 02:57:58 -0700 (PDT) Received: from localhost ([::1]:40050 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizVL-0005xm-St for importer@patchew.org; Fri, 27 Jul 2018 05:57:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58217) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSg-0003f7-Hb for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSf-0006IU-0C for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:02 -0400 Received: from greensocs.com ([193.104.36.180]:47470) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00064D-1Q; Fri, 27 Jul 2018 05:54:54 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id D43C744354B; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GijnWCfS8mRU; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 9D21B400DC8; Fri, 27 Jul 2018 11:54:44 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 48D83443485; Fri, 27 Jul 2018 11:54:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685285; bh=1o4L6CAB0JKgZyTsEhAHf1uW//RbD8il0hTMwxGh2Zw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=V1ROwyx1b2c3tqnNOCC+wktuyVNa3DD7sx0OHNFD9vaU/5svcde4G/zaBsoytwKXo l8uDOkf1nZiz20UdyyALXFPBBFhaZAKepiAKgCvnzclq9xdZyZulgQNPX6CGpE+W4B xBfS0uPjuZs6uLi5TdcuQIbL6OFEwa51dlFANYi8= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=tBNFROtm; dkim=pass (1024-bit key) header.d=greensocs.com header.b=tBNFROtm DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685284; bh=1o4L6CAB0JKgZyTsEhAHf1uW//RbD8il0hTMwxGh2Zw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=tBNFROtmSMhKVrhArjPLqpFlnK3vMuFoN0PHG0Cz8pn9SPWIAbSQs4iPwxf75y1GH tV2k5lgdzscC+5+s9wj37w3DfrVmSbqfcEtScMdu5+CQ4+Ol6Ex4pPRA20qjPBOk1g +4doZOTxKOHi4xub5Gy8KFhQTso4L9J+gOamObbg= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685284; bh=1o4L6CAB0JKgZyTsEhAHf1uW//RbD8il0hTMwxGh2Zw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=tBNFROtmSMhKVrhArjPLqpFlnK3vMuFoN0PHG0Cz8pn9SPWIAbSQs4iPwxf75y1GH tV2k5lgdzscC+5+s9wj37w3DfrVmSbqfcEtScMdu5+CQ4+Ol6Ex4pPRA20qjPBOk1g +4doZOTxKOHi4xub5Gy8KFhQTso4L9J+gOamObbg= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:05 +0200 Message-Id: <20180727095421.386-5-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 04/20] vmstate.h: Provide VMSTATE_UINT16_SUB_ARRAY 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Provide a VMSTATE_UINT16_SUB_ARRAY macro to save a uint16_t sub-array in a VMState. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/migration/vmstate.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 42b946ce90..2b501d0466 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -921,10 +921,13 @@ extern const VMStateInfo vmstate_info_qtailq; VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint16, uint16_t) =20 #define VMSTATE_UINT16_ARRAY(_f, _s, _n) \ VMSTATE_UINT16_ARRAY_V(_f, _s, _n, 0) =20 +#define VMSTATE_UINT16_SUB_ARRAY(_f, _s, _start, _num) \ + VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint16, uint16= _t) + #define VMSTATE_UINT16_2DARRAY(_f, _s, _n1, _n2) \ VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, 0) =20 #define VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, _v) \ VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint8, uint8_t) --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 153268652161182.94387585351308; Fri, 27 Jul 2018 03:15:21 -0700 (PDT) Received: from localhost ([::1]:40175 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizm8-0003Oa-Cm for importer@patchew.org; Fri, 27 Jul 2018 06:15:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58499) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSr-000462-Vf for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSp-0006Xg-PO for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:14 -0400 Received: from greensocs.com ([193.104.36.180]:47515) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00068i-SI; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id CE48244355F; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jCziWB-3rlx4; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 2A5754434A7; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 9EF47443485; Fri, 27 Jul 2018 11:54:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685286; bh=Jq07xEg9LqMeplnQxAr0uswiMuKksesjMui5G5vpPK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=VjDmQLmiNhWgcR5YG4nyHmyFzSu1/XjNu8tg59ZPlYyUFJ4aeEByT8fgX8aieaqMS ofdcILgN4wJXFSvZ8Z/7KknrVEi7c+eMGLJ0UvkRnbMDycxIG3DEWd4xyXrcEyn71m d6/5q39OZjI8+6ggplUhxptvenJGLhOqnvsdtqgU= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=5QB5ixxg; dkim=pass (1024-bit key) header.d=greensocs.com header.b=klQVoQ+y DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685285; bh=Jq07xEg9LqMeplnQxAr0uswiMuKksesjMui5G5vpPK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=5QB5ixxgWDiSDukWZmNvCux7W1b5Y/PwGOVwm7DGo6Iw+KTENyGXSpa1ZRB/3Uz/N 6BElHBwRvTYacrACHoVqnrGVYgUaj+doElmRuOel6Ud17rZPGmW5xFFi7xgffnfqwm /ZbPQ4p9ky+jaAcvIdwpGPq3FwHTDg0LQLPh1Bfw= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685284; bh=Jq07xEg9LqMeplnQxAr0uswiMuKksesjMui5G5vpPK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=klQVoQ+y77zrvaQgSBUu3rLdxXGyUyp2v6ycwpLYjGbyjzCV/8TQ1NlUqH/XTsdpa eYeXCL0Ph3g1OqublRqyJkk26Fb/VvhvJI6OV4LeU2j9nOp+DD1iXME3XE9u2kB2RY 0zk0rvTjya04TD4L5O1biy0OMsSpksPOFhjwv8sU= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:06 +0200 Message-Id: <20180727095421.386-6-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 05/20] intc/arm_gic: Add the virtualization extensions to the GIC state 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 3 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add the necessary parts of the virtualization extensions state to the GIC state. We choose to increase the size of the CPU interfaces state to add space for the vCPU interfaces (the GIC_NCPU_VCPU macro). This way, we'll be able to reuse most of the CPU interface code for the vCPUs. The only exception is the APR value, which is stored in h_apr in the virtual interface state for vCPUs. This is due to some complications with the GIC VMState, for which we don't want to break backward compatibility. APRs being stored in 2D arrays, increasing the second dimension would lead to some ugly VMState description. To avoid that, we keep it in h_apr for vCPUs. The vCPUs are numbered from GIC_NCPU to (GIC_NCPU * 2) - 1. The `gic_is_vcpu` function help to determine if a given CPU id correspond to a physical CPU or a virtual one. For the in-kernel KVM VGIC, since the exposed VGIC does not implement the virtualization extensions, we report an error if the corresponding property is set to true. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 2 +- hw/intc/arm_gic_common.c | 148 ++++++++++++++++++++++++++----- hw/intc/arm_gic_kvm.c | 8 +- hw/intc/gic_internal.h | 5 ++ include/hw/intc/arm_gic_common.h | 43 +++++++-- 5 files changed, 173 insertions(+), 33 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index b8eba6e594..5231579985 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -1495,11 +1495,11 @@ static void arm_gic_realize(DeviceState *dev, Error= **errp) "host kernel supports KVM_CAP_ARM_USER_IRQ"); return; } =20 /* This creates distributor and main CPU interface (s->cpuiomem[0]) */ - gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops); + gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops, NULL); =20 /* Extra core-specific regions for the CPU interfaces. This is * necessary for "franken-GIC" implementations, for example on * Exynos 4. * NB that the memory region size of 0x100 applies for the 11MPCore diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index 295ee9cc5e..547dc41185 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -44,10 +44,17 @@ static int gic_post_load(void *opaque, int version_id) c->post_load(s); } return 0; } =20 +static bool gic_virt_state_needed(void *opaque) +{ + GICState *s =3D (GICState *)opaque; + + return s->virt_extn; +} + static const VMStateDescription vmstate_gic_irq_state =3D { .name =3D "arm_gic_irq_state", .version_id =3D 1, .minimum_version_id =3D 1, .fields =3D (VMStateField[]) { @@ -60,38 +67,67 @@ static const VMStateDescription vmstate_gic_irq_state = =3D { VMSTATE_UINT8(group, gic_irq_state), VMSTATE_END_OF_LIST() } }; =20 +static const VMStateDescription vmstate_gic_virt_state =3D { + .name =3D "arm_gic_virt_state", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D gic_virt_state_needed, + .fields =3D (VMStateField[]) { + /* Virtual interface */ + VMSTATE_UINT32_ARRAY(h_hcr, GICState, GIC_NCPU), + VMSTATE_UINT32_ARRAY(h_misr, GICState, GIC_NCPU), + VMSTATE_UINT32_2DARRAY(h_lr, GICState, GIC_MAX_LR, GIC_NCPU), + VMSTATE_UINT32_ARRAY(h_apr, GICState, GIC_NCPU), + + /* Virtual CPU interfaces */ + VMSTATE_UINT32_SUB_ARRAY(cpu_ctlr, GICState, GIC_NCPU, GIC_NCPU), + VMSTATE_UINT16_SUB_ARRAY(priority_mask, GICState, GIC_NCPU, GIC_NC= PU), + VMSTATE_UINT16_SUB_ARRAY(running_priority, GICState, GIC_NCPU, GIC= _NCPU), + VMSTATE_UINT16_SUB_ARRAY(current_pending, GICState, GIC_NCPU, GIC_= NCPU), + VMSTATE_UINT8_SUB_ARRAY(bpr, GICState, GIC_NCPU, GIC_NCPU), + VMSTATE_UINT8_SUB_ARRAY(abpr, GICState, GIC_NCPU, GIC_NCPU), + + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_gic =3D { .name =3D "arm_gic", .version_id =3D 12, .minimum_version_id =3D 12, .pre_save =3D gic_pre_save, .post_load =3D gic_post_load, .fields =3D (VMStateField[]) { VMSTATE_UINT32(ctlr, GICState), - VMSTATE_UINT32_ARRAY(cpu_ctlr, GICState, GIC_NCPU), + VMSTATE_UINT32_SUB_ARRAY(cpu_ctlr, GICState, 0, GIC_NCPU), VMSTATE_STRUCT_ARRAY(irq_state, GICState, GIC_MAXIRQ, 1, vmstate_gic_irq_state, gic_irq_state), VMSTATE_UINT8_ARRAY(irq_target, GICState, GIC_MAXIRQ), VMSTATE_UINT8_2DARRAY(priority1, GICState, GIC_INTERNAL, GIC_NCPU), VMSTATE_UINT8_ARRAY(priority2, GICState, GIC_MAXIRQ - GIC_INTERNAL= ), VMSTATE_UINT8_2DARRAY(sgi_pending, GICState, GIC_NR_SGIS, GIC_NCPU= ), - VMSTATE_UINT16_ARRAY(priority_mask, GICState, GIC_NCPU), - VMSTATE_UINT16_ARRAY(running_priority, GICState, GIC_NCPU), - VMSTATE_UINT16_ARRAY(current_pending, GICState, GIC_NCPU), - VMSTATE_UINT8_ARRAY(bpr, GICState, GIC_NCPU), - VMSTATE_UINT8_ARRAY(abpr, GICState, GIC_NCPU), + VMSTATE_UINT16_SUB_ARRAY(priority_mask, GICState, 0, GIC_NCPU), + VMSTATE_UINT16_SUB_ARRAY(running_priority, GICState, 0, GIC_NCPU), + VMSTATE_UINT16_SUB_ARRAY(current_pending, GICState, 0, GIC_NCPU), + VMSTATE_UINT8_SUB_ARRAY(bpr, GICState, 0, GIC_NCPU), + VMSTATE_UINT8_SUB_ARRAY(abpr, GICState, 0, GIC_NCPU), VMSTATE_UINT32_2DARRAY(apr, GICState, GIC_NR_APRS, GIC_NCPU), VMSTATE_UINT32_2DARRAY(nsapr, GICState, GIC_NR_APRS, GIC_NCPU), VMSTATE_END_OF_LIST() + }, + .subsections =3D (const VMStateDescription * []) { + &vmstate_gic_virt_state, + NULL } }; =20 void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler, - const MemoryRegionOps *ops) + const MemoryRegionOps *ops, + const MemoryRegionOps *virt_ops) { SysBusDevice *sbd =3D SYS_BUS_DEVICE(s); int i =3D s->num_irq - GIC_INTERNAL; =20 /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU. @@ -114,10 +150,15 @@ void gic_init_irqs_and_mmio(GICState *s, qemu_irq_han= dler handler, sysbus_init_irq(sbd, &s->parent_virq[i]); } for (i =3D 0; i < s->num_cpu; i++) { sysbus_init_irq(sbd, &s->parent_vfiq[i]); } + if (s->virt_extn) { + for (i =3D 0; i < s->num_cpu; i++) { + sysbus_init_irq(sbd, &s->maintenance_irq[i]); + } + } =20 /* Distributor */ memory_region_init_io(&s->iomem, OBJECT(s), ops, s, "gic_dist", 0x1000= ); sysbus_init_mmio(sbd, &s->iomem); =20 @@ -125,10 +166,21 @@ void gic_init_irqs_and_mmio(GICState *s, qemu_irq_han= dler handler, * present because it is required by both software emulation and KVM. */ memory_region_init_io(&s->cpuiomem[0], OBJECT(s), ops ? &ops[1] : NULL, s, "gic_cpu", s->revision =3D=3D 2 ? 0x2000 : 0x= 100); sysbus_init_mmio(sbd, &s->cpuiomem[0]); + + if (s->virt_extn) { + memory_region_init_io(&s->vifaceiomem[0], OBJECT(s), virt_ops, + s, "gic_viface", 0x1000); + sysbus_init_mmio(sbd, &s->vifaceiomem[0]); + + memory_region_init_io(&s->vcpuiomem, OBJECT(s), + virt_ops ? &virt_ops[1] : NULL, + s, "gic_vcpu", 0x2000); + sysbus_init_mmio(sbd, &s->vcpuiomem); + } } =20 static void arm_gic_common_realize(DeviceState *dev, Error **errp) { GICState *s =3D ARM_GIC_COMMON(dev); @@ -161,10 +213,52 @@ static void arm_gic_common_realize(DeviceState *dev, = Error **errp) (s->revision =3D=3D REV_11MPCORE)) { error_setg(errp, "this GIC revision does not implement " "the security extensions"); return; } + + if (s->virt_extn) { + if (s->revision !=3D 2) { + error_setg(errp, "GIC virtualization extensions are only " + "supported by revision 2"); + return; + } + + /* For now, set the number of implemented LRs to 4, as found in mo= st + * real GICv2. This could be promoted as a QOM property if we need= to + * emulate a variant with another num_lrs. + */ + s->num_lrs =3D 4; + } +} + +static inline void arm_gic_common_reset_irq_state(GICState *s, int first_c= pu, + int resetprio) +{ + int i, j; + + for (i =3D first_cpu; i < first_cpu + s->num_cpu; i++) { + if (s->revision =3D=3D REV_11MPCORE) { + s->priority_mask[i] =3D 0xf0; + } else { + s->priority_mask[i] =3D resetprio; + } + s->current_pending[i] =3D 1023; + s->running_priority[i] =3D 0x100; + s->cpu_ctlr[i] =3D 0; + s->bpr[i] =3D gic_is_vcpu(i) ? GIC_VIRT_MIN_BPR : GIC_MIN_BPR; + s->abpr[i] =3D gic_is_vcpu(i) ? GIC_VIRT_MIN_ABPR : GIC_MIN_ABPR; + + if (!gic_is_vcpu(i)) { + for (j =3D 0; j < GIC_INTERNAL; j++) { + s->priority1[j][i] =3D resetprio; + } + for (j =3D 0; j < GIC_NR_SGIS; j++) { + s->sgi_pending[j][i] =3D 0; + } + } + } } =20 static void arm_gic_common_reset(DeviceState *dev) { GICState *s =3D ARM_GIC_COMMON(dev); @@ -183,28 +277,19 @@ static void arm_gic_common_reset(DeviceState *dev) } else { resetprio =3D 0; } =20 memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state)); - for (i =3D 0 ; i < s->num_cpu; i++) { - if (s->revision =3D=3D REV_11MPCORE) { - s->priority_mask[i] =3D 0xf0; - } else { - s->priority_mask[i] =3D resetprio; - } - s->current_pending[i] =3D 1023; - s->running_priority[i] =3D 0x100; - s->cpu_ctlr[i] =3D 0; - s->bpr[i] =3D GIC_MIN_BPR; - s->abpr[i] =3D GIC_MIN_ABPR; - for (j =3D 0; j < GIC_INTERNAL; j++) { - s->priority1[j][i] =3D resetprio; - } - for (j =3D 0; j < GIC_NR_SGIS; j++) { - s->sgi_pending[j][i] =3D 0; - } + arm_gic_common_reset_irq_state(s, 0, resetprio); + + if (s->virt_extn) { + /* vCPU states are stored at indexes GIC_NCPU .. GIC_NCPU+num_cpu. + * The exposed vCPU interface does not have security extensions. + */ + arm_gic_common_reset_irq_state(s, GIC_NCPU, 0); } + for (i =3D 0; i < GIC_NR_SGIS; i++) { GIC_DIST_SET_ENABLED(i, ALL_CPU_MASK); GIC_DIST_SET_EDGE_TRIGGER(i); } =20 @@ -224,10 +309,23 @@ static void arm_gic_common_reset(DeviceState *dev) for (i =3D 0; i < GIC_MAXIRQ; i++) { GIC_DIST_SET_GROUP(i, ALL_CPU_MASK); } } =20 + if (s->virt_extn) { + for (i =3D 0; i < s->num_lrs; i++) { + for (j =3D 0; j < s->num_cpu; j++) { + s->h_lr[i][j] =3D 0; + } + } + + for (i =3D 0; i < s->num_cpu; i++) { + s->h_hcr[i] =3D 0; + s->h_misr[i] =3D 0; + } + } + s->ctlr =3D 0; } =20 static void arm_gic_common_linux_init(ARMLinuxBootIf *obj, bool secure_boot) @@ -253,10 +351,12 @@ static Property arm_gic_common_properties[] =3D { * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC. */ DEFINE_PROP_UINT32("revision", GICState, revision, 1), /* True if the GIC should implement the security extensions */ DEFINE_PROP_BOOL("has-security-extensions", GICState, security_extn, 0= ), + /* True if the GIC should implement the virtualization extensions */ + DEFINE_PROP_BOOL("has-virtualization-extensions", GICState, virt_extn,= 0), DEFINE_PROP_END_OF_LIST(), }; =20 static void arm_gic_common_class_init(ObjectClass *klass, void *data) { diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index 4b611c8d6d..a611e8ee12 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -509,10 +509,16 @@ static void kvm_arm_gic_realize(DeviceState *dev, Err= or **errp) error_setg(errp, "the in-kernel VGIC does not implement the " "security extensions"); return; } =20 + if (s->virt_extn) { + error_setg(errp, "the in-kernel VGIC does not implement the " + "virtualization extensions"); + return; + } + if (!kvm_arm_gic_can_save_restore(s)) { error_setg(&s->migration_blocker, "This operating system kernel do= es " "not support vGICv2 migration"); migrate_add_blocker(s->migration_blocker, &local_err); if (local_err) { @@ -520,11 +526,11 @@ static void kvm_arm_gic_realize(DeviceState *dev, Err= or **errp) error_free(s->migration_blocker); return; } } =20 - gic_init_irqs_and_mmio(s, kvm_arm_gicv2_set_irq, NULL); + gic_init_irqs_and_mmio(s, kvm_arm_gicv2_set_irq, NULL, NULL); =20 for (i =3D 0; i < s->num_irq - GIC_INTERNAL; i++) { qemu_irq irq =3D qdev_get_gpio_in(dev, i); kvm_irqchip_set_qemuirq_gsi(kvm_state, irq, i); } diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index a2075a94db..c85427c8e3 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -92,6 +92,11 @@ static inline bool gic_test_pending(GICState *s, int irq= , int cm) return (s->irq_state[irq].pending & cm) || (!GIC_DIST_TEST_EDGE_TRIGGER(irq) && GIC_DIST_TEST_LEVEL(irq, = cm)); } } =20 +static inline bool gic_is_vcpu(int cpu) +{ + return cpu >=3D GIC_NCPU; +} + #endif /* QEMU_ARM_GIC_INTERNAL_H */ diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_com= mon.h index af3ca18e2f..b5585fec45 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -28,17 +28,30 @@ /* First 32 are private to each CPU (SGIs and PPIs). */ #define GIC_INTERNAL 32 #define GIC_NR_SGIS 16 /* Maximum number of possible CPU interfaces, determined by GIC architectu= re */ #define GIC_NCPU 8 +/* Maximum number of possible CPU interfaces with their respective vCPU */ +#define GIC_NCPU_VCPU (GIC_NCPU * 2) =20 #define MAX_NR_GROUP_PRIO 128 #define GIC_NR_APRS (MAX_NR_GROUP_PRIO / 32) =20 #define GIC_MIN_BPR 0 #define GIC_MIN_ABPR (GIC_MIN_BPR + 1) =20 +/* Architectural maximum number of list registers in the virtual interface= */ +#define GIC_MAX_LR 64 + +/* Only 32 priority levels and 32 preemption levels in the vCPU interfaces= */ +#define GIC_VIRT_MAX_GROUP_PRIO_BITS 5 +#define GIC_VIRT_MAX_NR_GROUP_PRIO (1 << GIC_VIRT_MAX_GROUP_PRIO_BITS) +#define GIC_VIRT_NR_APRS (GIC_VIRT_MAX_NR_GROUP_PRIO / 32) + +#define GIC_VIRT_MIN_BPR 2 +#define GIC_VIRT_MIN_ABPR (GIC_VIRT_MIN_BPR + 1) + typedef struct gic_irq_state { /* The enable bits are only banked for per-cpu interrupts. */ uint8_t enabled; uint8_t pending; uint8_t active; @@ -55,18 +68,20 @@ typedef struct GICState { =20 qemu_irq parent_irq[GIC_NCPU]; qemu_irq parent_fiq[GIC_NCPU]; qemu_irq parent_virq[GIC_NCPU]; qemu_irq parent_vfiq[GIC_NCPU]; + qemu_irq maintenance_irq[GIC_NCPU]; + /* GICD_CTLR; for a GIC with the security extensions the NS banked ver= sion * of this register is just an alias of bit 1 of the S banked version. */ uint32_t ctlr; /* GICC_CTLR; again, the NS banked version is just aliases of bits of * the S banked register, so our state only needs to store the S versi= on. */ - uint32_t cpu_ctlr[GIC_NCPU]; + uint32_t cpu_ctlr[GIC_NCPU_VCPU]; =20 gic_irq_state irq_state[GIC_MAXIRQ]; uint8_t irq_target[GIC_MAXIRQ]; uint8_t priority1[GIC_INTERNAL][GIC_NCPU]; uint8_t priority2[GIC_MAXIRQ - GIC_INTERNAL]; @@ -76,43 +91,56 @@ typedef struct GICState { * the bytes in the GIC_SPENDSGIR* registers as * read by the target CPU. */ uint8_t sgi_pending[GIC_NR_SGIS][GIC_NCPU]; =20 - uint16_t priority_mask[GIC_NCPU]; - uint16_t running_priority[GIC_NCPU]; - uint16_t current_pending[GIC_NCPU]; + uint16_t priority_mask[GIC_NCPU_VCPU]; + uint16_t running_priority[GIC_NCPU_VCPU]; + uint16_t current_pending[GIC_NCPU_VCPU]; =20 /* If we present the GICv2 without security extensions to a guest, * the guest can configure the GICC_CTLR to configure group 1 binary p= oint * in the abpr. * For a GIC with Security Extensions we use use bpr for the * secure copy and abpr as storage for the non-secure copy of the regi= ster. */ - uint8_t bpr[GIC_NCPU]; - uint8_t abpr[GIC_NCPU]; + uint8_t bpr[GIC_NCPU_VCPU]; + uint8_t abpr[GIC_NCPU_VCPU]; =20 /* The APR is implementation defined, so we choose a layout identical = to * the KVM ABI layout for QEMU's implementation of the gic: * If an interrupt for preemption level X is active, then * APRn[X mod 32] =3D=3D 0b1, where n =3D X / 32 * otherwise the bit is clear. */ uint32_t apr[GIC_NR_APRS][GIC_NCPU]; uint32_t nsapr[GIC_NR_APRS][GIC_NCPU]; =20 + /* Virtual interface control registers */ + uint32_t h_hcr[GIC_NCPU]; + uint32_t h_misr[GIC_NCPU]; + uint32_t h_lr[GIC_MAX_LR][GIC_NCPU]; + uint32_t h_apr[GIC_NCPU]; + + /* Number of LRs implemented in this GIC instance */ + uint32_t num_lrs; + uint32_t num_cpu; =20 MemoryRegion iomem; /* Distributor */ /* This is just so we can have an opaque pointer which identifies * both this GIC and which CPU interface we should be accessing. */ struct GICState *backref[GIC_NCPU]; MemoryRegion cpuiomem[GIC_NCPU + 1]; /* CPU interfaces */ + MemoryRegion vifaceiomem[GIC_NCPU + 1]; /* Virtual interfaces */ + MemoryRegion vcpuiomem; /* vCPU interface */ + uint32_t num_irq; uint32_t revision; bool security_extn; + bool virt_extn; bool irq_reset_nonsecure; /* configure IRQs as group 1 (NS) on reset? = */ int dev_fd; /* kvm device fd if backed by kvm vgic support */ Error *migration_blocker; } GICState; =20 @@ -132,8 +160,9 @@ typedef struct ARMGICCommonClass { void (*pre_save)(GICState *s); void (*post_load)(GICState *s); } ARMGICCommonClass; =20 void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler, - const MemoryRegionOps *ops); + const MemoryRegionOps *ops, + const MemoryRegionOps *virt_ops); =20 #endif --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532685524770970.487752248213; Fri, 27 Jul 2018 02:58:44 -0700 (PDT) Received: from localhost ([::1]:40052 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizWF-0006l6-FG for importer@patchew.org; Fri, 27 Jul 2018 05:58:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58303) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSj-0003oi-ED for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSg-0006Ks-Q0 for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:05 -0400 Received: from greensocs.com ([193.104.36.180]:47516) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00068b-Ra; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id CE8BB443570; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id c6crNpTrM_Kz; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 828FB443555; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 1A29D4434B9; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685286; bh=21cmLP2brOwuMgaEtN0LAagVBK9JRr+/txf5bmVYiXk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bHTXOqRHwEyZ43XuBBWPkIjiK5JLVYhpOIQvRet/rg3O7f6PfUqBeCZod2ZiZbwh/ ro5nazAyrZjjF9fxlVe1bfTcl8iP3Nd0ABmEsdA7cF2tSz5JmiT9Mjdx6vIfinIUSw k7ucGdJOp/BlvnipGh5kG0fsAoiDWwyLlv/1se2M= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=IAqU9W61; dkim=pass (1024-bit key) header.d=greensocs.com header.b=IAqU9W61 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685285; bh=21cmLP2brOwuMgaEtN0LAagVBK9JRr+/txf5bmVYiXk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=IAqU9W61LyUTf7iNWgVAAsAVjWo3bA/56Z06gNAQz5z6iFdhzNSA6tQaeZ6PCaPrU ktGxbT7OCSM7AYwgZV3xxrVduBDeAgphx6+VpsB1WeCcaFiBVm9hAXhVDEktYEwk8F 4Gqb20kRb6/AQBMFRcM1f/NJdF1TI7KYQc0MWWjM= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685285; bh=21cmLP2brOwuMgaEtN0LAagVBK9JRr+/txf5bmVYiXk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=IAqU9W61LyUTf7iNWgVAAsAVjWo3bA/56Z06gNAQz5z6iFdhzNSA6tQaeZ6PCaPrU ktGxbT7OCSM7AYwgZV3xxrVduBDeAgphx6+VpsB1WeCcaFiBVm9hAXhVDEktYEwk8F 4Gqb20kRb6/AQBMFRcM1f/NJdF1TI7KYQc0MWWjM= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:07 +0200 Message-Id: <20180727095421.386-7-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 06/20] intc/arm_gic: Add virtual interface register definitions 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add the register definitions for the virtual interface of the GICv2. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/gic_internal.h | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index c85427c8e3..1aa888a576 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -19,10 +19,11 @@ */ =20 #ifndef QEMU_ARM_GIC_INTERNAL_H #define QEMU_ARM_GIC_INTERNAL_H =20 +#include "hw/registerfields.h" #include "hw/intc/arm_gic.h" =20 #define ALL_CPU_MASK ((unsigned)(((1 << GIC_NCPU) - 1))) =20 #define GIC_BASE_IRQ 0 @@ -62,10 +63,74 @@ #define GICC_CTLR_FIQ_EN (1U << 3) #define GICC_CTLR_CBPR (1U << 4) /* GICv1: SBPR */ #define GICC_CTLR_EOIMODE (1U << 9) #define GICC_CTLR_EOIMODE_NS (1U << 10) =20 +REG32(GICH_HCR, 0x0) + FIELD(GICH_HCR, EN, 0, 1) + FIELD(GICH_HCR, UIE, 1, 1) + FIELD(GICH_HCR, LRENPIE, 2, 1) + FIELD(GICH_HCR, NPIE, 3, 1) + FIELD(GICH_HCR, VGRP0EIE, 4, 1) + FIELD(GICH_HCR, VGRP0DIE, 5, 1) + FIELD(GICH_HCR, VGRP1EIE, 6, 1) + FIELD(GICH_HCR, VGRP1DIE, 7, 1) + FIELD(GICH_HCR, EOICount, 27, 5) + +#define GICH_HCR_MASK \ + (R_GICH_HCR_EN_MASK | R_GICH_HCR_UIE_MASK | \ + R_GICH_HCR_LRENPIE_MASK | R_GICH_HCR_NPIE_MASK | \ + R_GICH_HCR_VGRP0EIE_MASK | R_GICH_HCR_VGRP0DIE_MASK | \ + R_GICH_HCR_VGRP1EIE_MASK | R_GICH_HCR_VGRP1DIE_MASK | \ + R_GICH_HCR_EOICount_MASK) + +REG32(GICH_VTR, 0x4) + FIELD(GICH_VTR, ListRegs, 0, 6) + FIELD(GICH_VTR, PREbits, 26, 3) + FIELD(GICH_VTR, PRIbits, 29, 3) + +REG32(GICH_VMCR, 0x8) + FIELD(GICH_VMCR, VMCCtlr, 0, 10) + FIELD(GICH_VMCR, VMABP, 18, 3) + FIELD(GICH_VMCR, VMBP, 21, 3) + FIELD(GICH_VMCR, VMPriMask, 27, 5) + +REG32(GICH_MISR, 0x10) + FIELD(GICH_MISR, EOI, 0, 1) + FIELD(GICH_MISR, U, 1, 1) + FIELD(GICH_MISR, LRENP, 2, 1) + FIELD(GICH_MISR, NP, 3, 1) + FIELD(GICH_MISR, VGrp0E, 4, 1) + FIELD(GICH_MISR, VGrp0D, 5, 1) + FIELD(GICH_MISR, VGrp1E, 6, 1) + FIELD(GICH_MISR, VGrp1D, 7, 1) + +REG32(GICH_EISR0, 0x20) +REG32(GICH_EISR1, 0x24) +REG32(GICH_ELRSR0, 0x30) +REG32(GICH_ELRSR1, 0x34) +REG32(GICH_APR, 0xf0) + +REG32(GICH_LR0, 0x100) + FIELD(GICH_LR0, VirtualID, 0, 10) + FIELD(GICH_LR0, PhysicalID, 10, 10) + FIELD(GICH_LR0, CPUID, 10, 3) + FIELD(GICH_LR0, EOI, 19, 1) + FIELD(GICH_LR0, Priority, 23, 5) + FIELD(GICH_LR0, State, 28, 2) + FIELD(GICH_LR0, Grp1, 30, 1) + FIELD(GICH_LR0, HW, 31, 1) + +/* Last LR register */ +REG32(GICH_LR63, 0x1fc) + +#define GICH_LR_MASK \ + (R_GICH_LR0_VirtualID_MASK | R_GICH_LR0_PhysicalID_MASK | \ + R_GICH_LR0_CPUID_MASK | R_GICH_LR0_EOI_MASK | \ + R_GICH_LR0_Priority_MASK | R_GICH_LR0_State_MASK | \ + R_GICH_LR0_Grp1_MASK | R_GICH_LR0_HW_MASK) + /* Valid bits for GICC_CTLR for GICv1, v1 with security extensions, * GICv2 and GICv2 with security extensions: */ #define GICC_CTLR_V1_MASK 0x1 #define GICC_CTLR_V1_S_MASK 0x1f --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532685647393518.5516093583908; Fri, 27 Jul 2018 03:00:47 -0700 (PDT) Received: from localhost ([::1]:40067 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizYD-0000cd-Ta for importer@patchew.org; Fri, 27 Jul 2018 06:00:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58322) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSk-0003qP-1F for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSg-0006L0-QM for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:06 -0400 Received: from greensocs.com ([193.104.36.180]:47518) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00068j-SN; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id BAB3D443573; Fri, 27 Jul 2018 11:54:47 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wNS0Ebf84BDQ; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id D757F44355C; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 7DCFC443485; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685287; bh=5wWi0/l9uiiL4aZjpWYX1GFAUVZ40KgXixAKCyknCK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=gfjbCp4PYTaroGqAn19iLuNH2P5++m/WElURhTPleQDRmU0tuxBIu8iOhEgUeSIvI FC8HyRM4ddFgR/5R9zpzFIcQIY0b+XVpX9tNYN+MbSg5uAN/9c+xAfK2f02I6DL4Zo FV7hhIWwQ60VjH7tQQ/BXGpRh2Y0M7OKf4PiR1K4= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=Fo+EoMuO; dkim=pass (1024-bit key) header.d=greensocs.com header.b=Fo+EoMuO DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685285; bh=5wWi0/l9uiiL4aZjpWYX1GFAUVZ40KgXixAKCyknCK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Fo+EoMuOZ7RCHjpXTq0IaiRAUWBF8W76uUigqoBti1bwul1edWwv4c9yiGKkjfXtK 5VG5BcvVA0gJdC6gi/n4ItrROVbhlvLV/VVXFCp00MAfAdbBF9yRP1IOmH+nGybkIZ hE/L1nUs3Likr88iIad58yN37ZPMiaUz9y7FHQk8= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685285; bh=5wWi0/l9uiiL4aZjpWYX1GFAUVZ40KgXixAKCyknCK8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Fo+EoMuOZ7RCHjpXTq0IaiRAUWBF8W76uUigqoBti1bwul1edWwv4c9yiGKkjfXtK 5VG5BcvVA0gJdC6gi/n4ItrROVbhlvLV/VVXFCp00MAfAdbBF9yRP1IOmH+nGybkIZ hE/L1nUs3Likr88iIad58yN37ZPMiaUz9y7FHQk8= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:08 +0200 Message-Id: <20180727095421.386-8-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 07/20] intc/arm_gic: Add virtualization extensions helper macros and functions 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add some helper macros and functions related to the virtualization extensions to gic_internal.h. The GICH_LR_* macros help extracting specific fields of a list register value. The only tricky one is the priority field as only the MSB are stored. The value must be shifted accordingly to obtain the correct priority value. gic_is_vcpu() and gic_get_vcpu_real_id() help with (v)CPU id manipulation to abstract the fact that vCPU id are in the range [ GIC_NCPU; (GIC_NCPU + num_cpu) [. gic_lr_* and gic_virq_is_valid() help with the list registers. gic_get_lr_entry() returns the LR entry for a given (vCPU, irq) pair. It is meant to be used in contexts where we know for sure that the entry exists, so we assert that entry is actually found, and the caller can avoid the NULL check on the returned pointer. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 5 +++ hw/intc/gic_internal.h | 74 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 5231579985..41141fee53 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -59,10 +59,15 @@ static inline int gic_get_current_cpu(GICState *s) return current_cpu->cpu_index; } return 0; } =20 +static inline int gic_get_current_vcpu(GICState *s) +{ + return gic_get_current_cpu(s) + GIC_NCPU; +} + /* Return true if this GIC config has interrupt groups, which is * true if we're a GICv2, or a GICv1 with the security extensions. */ static inline bool gic_has_groups(GICState *s) { diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 1aa888a576..cc5acc5d41 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -127,10 +127,24 @@ REG32(GICH_LR63, 0x1fc) (R_GICH_LR0_VirtualID_MASK | R_GICH_LR0_PhysicalID_MASK | \ R_GICH_LR0_CPUID_MASK | R_GICH_LR0_EOI_MASK | \ R_GICH_LR0_Priority_MASK | R_GICH_LR0_State_MASK | \ R_GICH_LR0_Grp1_MASK | R_GICH_LR0_HW_MASK) =20 +#define GICH_LR_STATE_INVALID 0 +#define GICH_LR_STATE_PENDING 1 +#define GICH_LR_STATE_ACTIVE 2 +#define GICH_LR_STATE_ACTIVE_PENDING 3 + +#define GICH_LR_VIRT_ID(entry) (FIELD_EX32(entry, GICH_LR0, VirtualID)) +#define GICH_LR_PHYS_ID(entry) (FIELD_EX32(entry, GICH_LR0, PhysicalID)) +#define GICH_LR_CPUID(entry) (FIELD_EX32(entry, GICH_LR0, CPUID)) +#define GICH_LR_EOI(entry) (FIELD_EX32(entry, GICH_LR0, EOI)) +#define GICH_LR_PRIORITY(entry) (FIELD_EX32(entry, GICH_LR0, Priority) << = 3) +#define GICH_LR_STATE(entry) (FIELD_EX32(entry, GICH_LR0, State)) +#define GICH_LR_GROUP(entry) (FIELD_EX32(entry, GICH_LR0, Grp1)) +#define GICH_LR_HW(entry) (FIELD_EX32(entry, GICH_LR0, HW)) + /* Valid bits for GICC_CTLR for GICv1, v1 with security extensions, * GICv2 and GICv2 with security extensions: */ #define GICC_CTLR_V1_MASK 0x1 #define GICC_CTLR_V1_S_MASK 0x1f @@ -162,6 +176,66 @@ static inline bool gic_test_pending(GICState *s, int i= rq, int cm) static inline bool gic_is_vcpu(int cpu) { return cpu >=3D GIC_NCPU; } =20 +static inline int gic_get_vcpu_real_id(int cpu) +{ + return (cpu >=3D GIC_NCPU) ? (cpu - GIC_NCPU) : cpu; +} + +/* Return true if the given vIRQ state exists in a LR and is either active= or + * pending and active. + * + * This function is used to check that a guest's `end of interrupt' or + * `interrupts deactivation' request is valid, and matches with a LR of an + * already acknowledged vIRQ (i.e. has the active bit set in its state). + */ +static inline bool gic_virq_is_valid(GICState *s, int irq, int vcpu) +{ + int cpu =3D gic_get_vcpu_real_id(vcpu); + int lr_idx; + + for (lr_idx =3D 0; lr_idx < s->num_lrs; lr_idx++) { + uint32_t *entry =3D &s->h_lr[lr_idx][cpu]; + + if ((GICH_LR_VIRT_ID(*entry) =3D=3D irq) && + (GICH_LR_STATE(*entry) & GICH_LR_STATE_ACTIVE)) { + return true; + } + } + + return false; +} + +/* Return a pointer on the LR entry matching the given vIRQ. + * + * This function is used to retrieve an LR for which we know for sure that= the + * corresponding vIRQ exists in the current context (i.e. its current stat= e is + * not `invalid'): + * - Either the corresponding vIRQ has been validated with gic_virq_is_v= alid() + * so it is `active' or `active and pending', + * - Or it was pending and has been selected by gic_get_best_virq(). It = is now + * `pending', `active' or `active and pending', depending on what the = guest + * already did with this vIRQ. + * + * Having multiple LRs with the same VirtualID leads to UNPREDICTABLE + * behaviour in the GIC. We choose to return the first one that matches. + */ +static inline uint32_t *gic_get_lr_entry(GICState *s, int irq, int vcpu) +{ + int cpu =3D gic_get_vcpu_real_id(vcpu); + int lr_idx; + + for (lr_idx =3D 0; lr_idx < s->num_lrs; lr_idx++) { + uint32_t *entry =3D &s->h_lr[lr_idx][cpu]; + + if ((GICH_LR_VIRT_ID(*entry) =3D=3D irq) && + (GICH_LR_STATE(*entry) !=3D GICH_LR_STATE_INVALID)) { + return entry; + } + } + + g_assert_not_reached(); +} + #endif /* QEMU_ARM_GIC_INTERNAL_H */ --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532685829221247.93873030665884; Fri, 27 Jul 2018 03:03:49 -0700 (PDT) Received: from localhost ([::1]:40088 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizaz-0002Ya-LM for importer@patchew.org; Fri, 27 Jul 2018 06:03:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58376) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSl-0003tt-Ch for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSh-0006LW-5a for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:07 -0400 Received: from greensocs.com ([193.104.36.180]:47517) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00068l-S5; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id D515544357F; Fri, 27 Jul 2018 11:54:47 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Qi6-DV3oJmOz; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 4BF01443485; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id D5B34443557; Fri, 27 Jul 2018 11:54:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685287; bh=1ZvPDdOhgZcw/g26n9kLneoLa70xnMn+7OWpKcPXGm0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=gUw9/R6FobY6OtooBaGYy2GLNDWdqc35iAH7KhVLKh+FzePyyry6Y56dv3HR53rou X+OnZkepYy7qQiwC0XJmKZ0SJfmPg/N97g0blGTGl8a/1xT4KiGnrbi8DCDaUhbqPK 2PCuVqimJQqVvAo5ZBLvTfAgLVlKAXyYudO1Y/R8= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=S3WKF9qE; dkim=pass (1024-bit key) header.d=greensocs.com header.b=S3WKF9qE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685286; bh=1ZvPDdOhgZcw/g26n9kLneoLa70xnMn+7OWpKcPXGm0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=S3WKF9qE3MfxbE07c9YirND+nUHjnrSj0GjFNMaxqGLyJ6Dhl6VdIkeeLLkV4Dzqu qfqIdeAVtoAqHg15idMDfU9oCNFyO18xPgpGlqpmFIvIO7L002FTP3DLASthCDN7ar cYhgCikRw7us8N0lQejnkvNo9wWvspe/8VpouCrE= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685286; bh=1ZvPDdOhgZcw/g26n9kLneoLa70xnMn+7OWpKcPXGm0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=S3WKF9qE3MfxbE07c9YirND+nUHjnrSj0GjFNMaxqGLyJ6Dhl6VdIkeeLLkV4Dzqu qfqIdeAVtoAqHg15idMDfU9oCNFyO18xPgpGlqpmFIvIO7L002FTP3DLASthCDN7ar cYhgCikRw7us8N0lQejnkvNo9wWvspe/8VpouCrE= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:09 +0200 Message-Id: <20180727095421.386-9-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 08/20] intc/arm_gic: Refactor secure/ns access check in the CPU interface 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" An access to the CPU interface is non-secure if the current GIC instance implements the security extensions, and the memory access is actually non-secure. Until then, it was checked with tests such as if (s->security_extn && !attrs.secure) { ... } in various places of the CPU interface code. With the implementation of the virtualization extensions, those tests must be updated to take into account whether we are in a vCPU interface or not. This is because the exposed vCPU interface does not implement security extensions. This commits replaces all those tests with a call to the gic_cpu_ns_access() function to check if the current access to the CPU interface is non-secure. This function takes into account whether the current CPU is a vCPU or not. Note that this function is used only in the (v)CPU interface code path. The distributor code path is left unchanged, as the distributor is not exposed to vCPUs at all. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/intc/arm_gic.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 41141fee53..94d5982e2a 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -72,10 +72,15 @@ static inline int gic_get_current_vcpu(GICState *s) static inline bool gic_has_groups(GICState *s) { return s->revision =3D=3D 2 || s->security_extn; } =20 +static inline bool gic_cpu_ns_access(GICState *s, int cpu, MemTxAttrs attr= s) +{ + return !gic_is_vcpu(cpu) && s->security_extn && !attrs.secure; +} + /* TODO: Many places that call this routine could be optimized. */ /* Update interrupt status after enabled or pending bits have been changed= . */ static void gic_update(GICState *s) { int best_irq; @@ -219,11 +224,11 @@ static uint16_t gic_get_current_pending_irq(GICState = *s, int cpu, if (pending_irq < GIC_MAXIRQ && gic_has_groups(s)) { int group =3D GIC_DIST_TEST_GROUP(pending_irq, (1 << cpu)); /* On a GIC without the security extensions, reading this register * behaves in the same way as a secure access to a GIC with them. */ - bool secure =3D !s->security_extn || attrs.secure; + bool secure =3D !gic_cpu_ns_access(s, cpu, attrs); =20 if (group =3D=3D 0 && !secure) { /* Group0 interrupts hidden from Non-secure access */ return 1023; } @@ -426,11 +431,11 @@ static uint32_t gic_dist_get_priority(GICState *s, in= t cpu, int irq, } =20 static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask, MemTxAttrs attrs) { - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { if (s->priority_mask[cpu] & 0x80) { /* Priority Mask in upper half */ pmask =3D 0x80 | (pmask >> 1); } else { /* Non-secure write ignored if priority mask is in lower half = */ @@ -442,11 +447,11 @@ static void gic_set_priority_mask(GICState *s, int cp= u, uint8_t pmask, =20 static uint32_t gic_get_priority_mask(GICState *s, int cpu, MemTxAttrs att= rs) { uint32_t pmask =3D s->priority_mask[cpu]; =20 - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { if (pmask & 0x80) { /* Priority Mask in upper half, return Non-secure view */ pmask =3D (pmask << 1) & 0xff; } else { /* Priority Mask in lower half, RAZ */ @@ -458,11 +463,11 @@ static uint32_t gic_get_priority_mask(GICState *s, in= t cpu, MemTxAttrs attrs) =20 static uint32_t gic_get_cpu_control(GICState *s, int cpu, MemTxAttrs attrs) { uint32_t ret =3D s->cpu_ctlr[cpu]; =20 - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { /* Construct the NS banked view of GICC_CTLR from the correct * bits of the S banked view. We don't need to move the bypass * control bits because we don't implement that (IMPDEF) part * of the GIC architecture. */ @@ -474,11 +479,11 @@ static uint32_t gic_get_cpu_control(GICState *s, int = cpu, MemTxAttrs attrs) static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value, MemTxAttrs attrs) { uint32_t mask; =20 - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { /* The NS view can only write certain bits in the register; * the rest are unchanged */ mask =3D GICC_CTLR_EN_GRP1; if (s->revision =3D=3D 2) { @@ -505,11 +510,11 @@ static uint8_t gic_get_running_priority(GICState *s, = int cpu, MemTxAttrs attrs) if ((s->revision !=3D REV_11MPCORE) && (s->running_priority[cpu] > 0xf= f)) { /* Idle priority */ return 0xff; } =20 - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { if (s->running_priority[cpu] & 0x80) { /* Running priority in upper half of range: return the Non-sec= ure * view of the priority. */ return s->running_priority[cpu] << 1; @@ -529,11 +534,11 @@ static bool gic_eoi_split(GICState *s, int cpu, MemTx= Attrs attrs) { if (s->revision !=3D 2) { /* Before GICv2 prio-drop and deactivate are not separable */ return false; } - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { return s->cpu_ctlr[cpu] & GICC_CTLR_EOIMODE_NS; } return s->cpu_ctlr[cpu] & GICC_CTLR_EOIMODE; } =20 @@ -561,11 +566,11 @@ static void gic_deactivate_irq(GICState *s, int cpu, = int irq, MemTxAttrs attrs) qemu_log_mask(LOG_GUEST_ERROR, "gic_deactivate_irq: GICC_DIR write when EOIMode cle= ar"); return; } =20 - if (s->security_extn && !attrs.secure && !group) { + if (gic_cpu_ns_access(s, cpu, attrs) && !group) { DPRINTF("Non-secure DI for Group0 interrupt %d ignored\n", irq); return; } =20 GIC_DIST_CLEAR_ACTIVE(irq, cm); @@ -603,11 +608,11 @@ static void gic_complete_irq(GICState *s, int cpu, in= t irq, MemTxAttrs attrs) } } =20 group =3D gic_has_groups(s) && GIC_DIST_TEST_GROUP(irq, cm); =20 - if (s->security_extn && !attrs.secure && !group) { + if (gic_cpu_ns_access(s, cpu, attrs) && !group) { DPRINTF("Non-secure EOI for Group0 interrupt %d ignored\n", irq); return; } =20 /* Secure EOI with GICC_CTLR.AckCtl =3D=3D 0 when the IRQ is a Group 1 @@ -1279,11 +1284,11 @@ static MemTxResult gic_cpu_read(GICState *s, int cp= u, int offset, break; case 0x04: /* Priority mask */ *data =3D gic_get_priority_mask(s, cpu, attrs); break; case 0x08: /* Binary Point */ - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) { /* NS view of BPR when CBPR is 1 */ *data =3D MIN(s->bpr[cpu] + 1, 7); } else { /* BPR is banked. Non-secure copy stored in ABPR. */ @@ -1306,11 +1311,11 @@ static MemTxResult gic_cpu_read(GICState *s, int cp= u, int offset, /* GIC v2, no security: ABPR * GIC v1, no security: not implemented (RAZ/WI) * With security extensions, secure access: ABPR (alias of NS BPR) * With security extensions, nonsecure access: RAZ/WI */ - if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) { + if (!gic_has_groups(s) || (gic_cpu_ns_access(s, cpu, attrs))) { *data =3D 0; } else { *data =3D s->abpr[cpu]; } break; @@ -1318,11 +1323,11 @@ static MemTxResult gic_cpu_read(GICState *s, int cp= u, int offset, { int regno =3D (offset - 0xd0) / 4; =20 if (regno >=3D GIC_NR_APRS || s->revision !=3D 2) { *data =3D 0; - } else if (s->security_extn && !attrs.secure) { + } else if (gic_cpu_ns_access(s, cpu, attrs)) { /* NS view of GICC_APR is the top half of GIC_NSAPR */ *data =3D gic_apr_ns_view(s, regno, cpu); } else { *data =3D s->apr[regno][cpu]; } @@ -1331,11 +1336,11 @@ static MemTxResult gic_cpu_read(GICState *s, int cp= u, int offset, case 0xe0: case 0xe4: case 0xe8: case 0xec: { int regno =3D (offset - 0xe0) / 4; =20 if (regno >=3D GIC_NR_APRS || s->revision !=3D 2 || !gic_has_group= s(s) || - (s->security_extn && !attrs.secure)) { + gic_cpu_ns_access(s, cpu, attrs)) { *data =3D 0; } else { *data =3D s->nsapr[regno][cpu]; } break; @@ -1358,11 +1363,11 @@ static MemTxResult gic_cpu_write(GICState *s, int c= pu, int offset, break; case 0x04: /* Priority mask */ gic_set_priority_mask(s, cpu, value, attrs); break; case 0x08: /* Binary Point */ - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) { /* WI when CBPR is 1 */ return MEMTX_OK; } else { s->abpr[cpu] =3D MAX(value & 0x7, GIC_MIN_ABPR); @@ -1373,11 +1378,11 @@ static MemTxResult gic_cpu_write(GICState *s, int c= pu, int offset, break; case 0x10: /* End Of Interrupt */ gic_complete_irq(s, cpu, value & 0x3ff, attrs); return MEMTX_OK; case 0x1c: /* Aliased Binary Point */ - if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) { + if (!gic_has_groups(s) || (gic_cpu_ns_access(s, cpu, attrs))) { /* unimplemented, or NS access: RAZ/WI */ return MEMTX_OK; } else { s->abpr[cpu] =3D MAX(value & 0x7, GIC_MIN_ABPR); } @@ -1387,11 +1392,11 @@ static MemTxResult gic_cpu_write(GICState *s, int c= pu, int offset, int regno =3D (offset - 0xd0) / 4; =20 if (regno >=3D GIC_NR_APRS || s->revision !=3D 2) { return MEMTX_OK; } - if (s->security_extn && !attrs.secure) { + if (gic_cpu_ns_access(s, cpu, attrs)) { /* NS view of GICC_APR is the top half of GIC_NSAPR */ gic_apr_write_ns_view(s, regno, cpu, value); } else { s->apr[regno][cpu] =3D value; } @@ -1402,11 +1407,11 @@ static MemTxResult gic_cpu_write(GICState *s, int c= pu, int offset, int regno =3D (offset - 0xe0) / 4; =20 if (regno >=3D GIC_NR_APRS || s->revision !=3D 2) { return MEMTX_OK; } - if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) { + if (!gic_has_groups(s) || (gic_cpu_ns_access(s, cpu, attrs))) { return MEMTX_OK; } s->nsapr[regno][cpu] =3D value; break; } --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532686356359668.4771311066684; Fri, 27 Jul 2018 03:12:36 -0700 (PDT) Received: from localhost ([::1]:40142 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizjf-0001SS-5R for importer@patchew.org; Fri, 27 Jul 2018 06:12:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58453) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSo-0003wi-4I for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSl-0006QR-60 for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:10 -0400 Received: from greensocs.com ([193.104.36.180]:47519) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00068n-Ti; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id BE04244572B; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jZOq2lA-cswM; Fri, 27 Jul 2018 11:54:47 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 9147E443557; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 405FD400DC8; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685288; bh=spls3mB/uY79yFvW2CylmjxAsCX0R5OwcdB6AiJDS1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=7tm5UJvN8hcnSBLewy/KTP28yt/RczAkGC7wqtHv0xDHMVxjIcyxkYjov8tzDkodQ Ctm1j+bjw3fdysOlguQN7eZ36YYHXi8XtX2nSMQN4XM+hImSzMU7V+WX5EJG7RlqnH AUY6Kdy9nqUgB9WrTZP8ZCPvX4gf1jVwktT1lClo= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=TInwgScZ; dkim=pass (1024-bit key) header.d=greensocs.com header.b=TInwgScZ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685286; bh=spls3mB/uY79yFvW2CylmjxAsCX0R5OwcdB6AiJDS1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=TInwgScZXBTjpltmoDy9trmCoYHjuji02jRi/Gw4yQ5vANz6erFfCyvC+5SiStDKN KM989QjXQ0usp60F2aKV3YY18q86hftS9fvPEItYdMi4DOlWDSx+IWtrpw0vlzGw9k lPnorUew5kgl5hN0z2vAaDr7tVxnOKvkMHrwWEq4= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685286; bh=spls3mB/uY79yFvW2CylmjxAsCX0R5OwcdB6AiJDS1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=TInwgScZXBTjpltmoDy9trmCoYHjuji02jRi/Gw4yQ5vANz6erFfCyvC+5SiStDKN KM989QjXQ0usp60F2aKV3YY18q86hftS9fvPEItYdMi4DOlWDSx+IWtrpw0vlzGw9k lPnorUew5kgl5hN0z2vAaDr7tVxnOKvkMHrwWEq4= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:10 +0200 Message-Id: <20180727095421.386-10-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 09/20] intc/arm_gic: Add virtualization enabled IRQ helper functions 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add some helper functions to gic_internal.h to get or change the state of an IRQ. When the current CPU is not a vCPU, the call is forwarded to the GIC distributor. Otherwise, it acts on the list register matching the IRQ in the current CPU virtual interface. gic_clear_active can have a side effect on the distributor, even in the vCPU case, when the correponding LR has the HW field set. Use those functions in the CPU interface code path to prepare for the vCPU interface implementation. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- hw/intc/arm_gic.c | 32 +++++++--------- hw/intc/gic_internal.h | 83 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 18 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 94d5982e2a..26ed7ea58a 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -220,11 +220,12 @@ static uint16_t gic_get_current_pending_irq(GICState = *s, int cpu, MemTxAttrs attrs) { uint16_t pending_irq =3D s->current_pending[cpu]; =20 if (pending_irq < GIC_MAXIRQ && gic_has_groups(s)) { - int group =3D GIC_DIST_TEST_GROUP(pending_irq, (1 << cpu)); + int group =3D gic_test_group(s, pending_irq, cpu); + /* On a GIC without the security extensions, reading this register * behaves in the same way as a secure access to a GIC with them. */ bool secure =3D !gic_cpu_ns_access(s, cpu, attrs); =20 @@ -251,11 +252,11 @@ static int gic_get_group_priority(GICState *s, int cp= u, int irq) int bpr; uint32_t mask; =20 if (gic_has_groups(s) && !(s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) && - GIC_DIST_TEST_GROUP(irq, (1 << cpu))) { + gic_test_group(s, irq, cpu)) { bpr =3D s->abpr[cpu] - 1; assert(bpr >=3D 0); } else { bpr =3D s->bpr[cpu]; } @@ -264,11 +265,11 @@ static int gic_get_group_priority(GICState *s, int cp= u, int irq) * a BPR of 1 means they are [7:2], and so on down to * a BPR of 7 meaning no group priority bits at all. */ mask =3D ~0U << ((bpr & 7) + 1); =20 - return GIC_DIST_GET_PRIORITY(irq, cpu) & mask; + return gic_get_priority(s, irq, cpu) & mask; } =20 static void gic_activate_irq(GICState *s, int cpu, int irq) { /* Set the appropriate Active Priority Register bit for this IRQ, @@ -277,18 +278,18 @@ static void gic_activate_irq(GICState *s, int cpu, in= t irq) int prio =3D gic_get_group_priority(s, cpu, irq); int preemption_level =3D prio >> (GIC_MIN_BPR + 1); int regno =3D preemption_level / 32; int bitno =3D preemption_level % 32; =20 - if (gic_has_groups(s) && GIC_DIST_TEST_GROUP(irq, (1 << cpu))) { + if (gic_has_groups(s) && gic_test_group(s, irq, cpu)) { s->nsapr[regno][cpu] |=3D (1 << bitno); } else { s->apr[regno][cpu] |=3D (1 << bitno); } =20 s->running_priority[cpu] =3D prio; - GIC_DIST_SET_ACTIVE(irq, 1 << cpu); + gic_set_active(s, irq, cpu); } =20 static int gic_get_prio_from_apr_bits(GICState *s, int cpu) { /* Recalculate the current running priority for this CPU based @@ -353,21 +354,20 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, Me= mTxAttrs attrs) if (irq >=3D GIC_MAXIRQ) { DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq); return irq; } =20 - if (GIC_DIST_GET_PRIORITY(irq, cpu) >=3D s->running_priority[cpu]) { + if (gic_get_priority(s, irq, cpu) >=3D s->running_priority[cpu]) { DPRINTF("ACK, pending interrupt (%d) has insufficient priority\n",= irq); return 1023; } =20 if (s->revision =3D=3D REV_11MPCORE) { /* Clear pending flags for both level and edge triggered interrupt= s. * Level triggered IRQs will be reasserted once they become inacti= ve. */ - GIC_DIST_CLEAR_PENDING(irq, GIC_DIST_TEST_MODEL(irq) ? ALL_CPU_MASK - : cm); + gic_clear_pending(s, irq, cpu); ret =3D irq; } else { if (irq < GIC_NR_SGIS) { /* Lookup the source CPU for the SGI and clear this in the * sgi_pending map. Return the src and clear the overall pend= ing @@ -375,22 +375,19 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, Me= mTxAttrs attrs) */ assert(s->sgi_pending[irq][cpu] !=3D 0); src =3D ctz32(s->sgi_pending[irq][cpu]); s->sgi_pending[irq][cpu] &=3D ~(1 << src); if (s->sgi_pending[irq][cpu] =3D=3D 0) { - GIC_DIST_CLEAR_PENDING(irq, - GIC_DIST_TEST_MODEL(irq) ? ALL_CPU_= MASK - : cm); + gic_clear_pending(s, irq, cpu); } ret =3D irq | ((src & 0x7) << 10); } else { /* Clear pending state for both level and edge triggered * interrupts. (level triggered interrupts with an active line * remain pending, see gic_test_pending) */ - GIC_DIST_CLEAR_PENDING(irq, GIC_DIST_TEST_MODEL(irq) ? ALL_CPU= _MASK - : cm); + gic_clear_pending(s, irq, cpu); ret =3D irq; } } =20 gic_activate_irq(s, cpu, irq); @@ -542,11 +539,10 @@ static bool gic_eoi_split(GICState *s, int cpu, MemTx= Attrs attrs) return s->cpu_ctlr[cpu] & GICC_CTLR_EOIMODE; } =20 static void gic_deactivate_irq(GICState *s, int cpu, int irq, MemTxAttrs a= ttrs) { - int cm =3D 1 << cpu; int group; =20 if (irq >=3D s->num_irq) { /* * This handles two cases: @@ -557,11 +553,11 @@ static void gic_deactivate_irq(GICState *s, int cpu, = int irq, MemTxAttrs attrs) * and so this is UNPREDICTABLE. We choose to ignore it. */ return; } =20 - group =3D gic_has_groups(s) && GIC_DIST_TEST_GROUP(irq, cm); + group =3D gic_has_groups(s) && gic_test_group(s, irq, cpu); =20 if (!gic_eoi_split(s, cpu, attrs)) { /* This is UNPREDICTABLE; we choose to ignore it */ qemu_log_mask(LOG_GUEST_ERROR, "gic_deactivate_irq: GICC_DIR write when EOIMode cle= ar"); @@ -571,11 +567,11 @@ static void gic_deactivate_irq(GICState *s, int cpu, = int irq, MemTxAttrs attrs) if (gic_cpu_ns_access(s, cpu, attrs) && !group) { DPRINTF("Non-secure DI for Group0 interrupt %d ignored\n", irq); return; } =20 - GIC_DIST_CLEAR_ACTIVE(irq, cm); + gic_clear_active(s, irq, cpu); } =20 static void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs att= rs) { int cm =3D 1 << cpu; @@ -606,11 +602,11 @@ static void gic_complete_irq(GICState *s, int cpu, in= t irq, MemTxAttrs attrs) DPRINTF("Set %d pending mask %x\n", irq, cm); GIC_DIST_SET_PENDING(irq, cm); } } =20 - group =3D gic_has_groups(s) && GIC_DIST_TEST_GROUP(irq, cm); + group =3D gic_has_groups(s) && gic_test_group(s, irq, cpu); =20 if (gic_cpu_ns_access(s, cpu, attrs) && !group) { DPRINTF("Non-secure EOI for Group0 interrupt %d ignored\n", irq); return; } @@ -622,11 +618,11 @@ static void gic_complete_irq(GICState *s, int cpu, in= t irq, MemTxAttrs attrs) =20 gic_drop_prio(s, cpu, group); =20 /* In GICv2 the guest can choose to split priority-drop and deactivate= */ if (!gic_eoi_split(s, cpu, attrs)) { - GIC_DIST_CLEAR_ACTIVE(irq, cm); + gic_clear_active(s, irq, cpu); } gic_update(s); } =20 static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs att= rs) diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index cc5acc5d41..45c2af0bf5 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -141,10 +141,17 @@ REG32(GICH_LR63, 0x1fc) #define GICH_LR_PRIORITY(entry) (FIELD_EX32(entry, GICH_LR0, Priority) << = 3) #define GICH_LR_STATE(entry) (FIELD_EX32(entry, GICH_LR0, State)) #define GICH_LR_GROUP(entry) (FIELD_EX32(entry, GICH_LR0, Grp1)) #define GICH_LR_HW(entry) (FIELD_EX32(entry, GICH_LR0, HW)) =20 +#define GICH_LR_CLEAR_PENDING(entry) \ + ((entry) &=3D ~(GICH_LR_STATE_PENDING << R_GICH_LR0_State_SHIFT)) +#define GICH_LR_SET_ACTIVE(entry) \ + ((entry) |=3D (GICH_LR_STATE_ACTIVE << R_GICH_LR0_State_SHIFT)) +#define GICH_LR_CLEAR_ACTIVE(entry) \ + ((entry) &=3D ~(GICH_LR_STATE_ACTIVE << R_GICH_LR0_State_SHIFT)) + /* Valid bits for GICC_CTLR for GICv1, v1 with security extensions, * GICv2 and GICv2 with security extensions: */ #define GICC_CTLR_V1_MASK 0x1 #define GICC_CTLR_V1_S_MASK 0x1f @@ -236,6 +243,82 @@ static inline uint32_t *gic_get_lr_entry(GICState *s, = int irq, int vcpu) } =20 g_assert_not_reached(); } =20 +static inline bool gic_test_group(GICState *s, int irq, int cpu) +{ + if (gic_is_vcpu(cpu)) { + uint32_t *entry =3D gic_get_lr_entry(s, irq, cpu); + return GICH_LR_GROUP(*entry); + } else { + return GIC_DIST_TEST_GROUP(irq, 1 << cpu); + } +} + +static inline void gic_clear_pending(GICState *s, int irq, int cpu) +{ + if (gic_is_vcpu(cpu)) { + uint32_t *entry =3D gic_get_lr_entry(s, irq, cpu); + GICH_LR_CLEAR_PENDING(*entry); + } else { + /* Clear pending state for both level and edge triggered + * interrupts. (level triggered interrupts with an active line + * remain pending, see gic_test_pending) + */ + GIC_DIST_CLEAR_PENDING(irq, GIC_DIST_TEST_MODEL(irq) ? ALL_CPU_MASK + : (1 << cpu)); + } +} + +static inline void gic_set_active(GICState *s, int irq, int cpu) +{ + if (gic_is_vcpu(cpu)) { + uint32_t *entry =3D gic_get_lr_entry(s, irq, cpu); + GICH_LR_SET_ACTIVE(*entry); + } else { + GIC_DIST_SET_ACTIVE(irq, 1 << cpu); + } +} + +static inline void gic_clear_active(GICState *s, int irq, int cpu) +{ + if (gic_is_vcpu(cpu)) { + uint32_t *entry =3D gic_get_lr_entry(s, irq, cpu); + GICH_LR_CLEAR_ACTIVE(*entry); + + if (GICH_LR_HW(*entry)) { + /* Hardware interrupt. We must forward the deactivation reques= t to + * the distributor. + */ + int phys_irq =3D GICH_LR_PHYS_ID(*entry); + int rcpu =3D gic_get_vcpu_real_id(cpu); + + if (phys_irq < GIC_NR_SGIS || phys_irq >=3D GIC_MAXIRQ) { + /* UNPREDICTABLE behaviour, we choose to ignore the reques= t */ + return; + } + + /* This is equivalent to a NS write to DIR on the physical CPU + * interface. Hence group0 interrupt deactivation is ignored if + * the GIC is secure. + */ + if (!s->security_extn || GIC_DIST_TEST_GROUP(phys_irq, 1 << rc= pu)) { + GIC_DIST_CLEAR_ACTIVE(phys_irq, 1 << rcpu); + } + } + } else { + GIC_DIST_CLEAR_ACTIVE(irq, 1 << cpu); + } +} + +static inline int gic_get_priority(GICState *s, int irq, int cpu) +{ + if (gic_is_vcpu(cpu)) { + uint32_t *entry =3D gic_get_lr_entry(s, irq, cpu); + return GICH_LR_PRIORITY(*entry); + } else { + return GIC_DIST_GET_PRIORITY(irq, cpu); + } +} + #endif /* QEMU_ARM_GIC_INTERNAL_H */ --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 153268587556057.36796787001663; Fri, 27 Jul 2018 03:04:35 -0700 (PDT) Received: from localhost ([::1]:40091 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizbq-00036Y-7x for importer@patchew.org; Fri, 27 Jul 2018 06:04:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58400) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSm-0003vf-BH for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSi-0006NI-Do for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from greensocs.com ([193.104.36.180]:47520) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00068t-Ta; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id C997344A0E2; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ir5G3Vo3QMoY; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id E9024443572; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 9488D400DC8; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685288; bh=RHBfXmsfK8Wt+vPCtdwaxY95CxsEuU7z0TJvQS8Edxw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=WqefBYgv3QhYFuo8S5j2WzZsmaaMByZAttUx6+y3nthxsO/nRfy8DAvUFH5eC0Owp RmJrmitoZRttrjE993wUL6zKtwX13Dm/h/or/qppAD3ZrUJvobM7dJRN6Ne5UpakF0 DFv3qGmYCN2BAkK/lTNxkvusYCbU6Kqda3JAkVbg= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=pz9QpLKE; dkim=pass (1024-bit key) header.d=greensocs.com header.b=pz9QpLKE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685286; bh=RHBfXmsfK8Wt+vPCtdwaxY95CxsEuU7z0TJvQS8Edxw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=pz9QpLKEIlikSGLkmSqEWMngQEw1WjIiJeV2F0X6RgG9BtAUgw/rFopkZ/Rei0+UD 4aUnmvjLQQ/YSOwqPpqqzg79ZQYQRawKXLKnqZCnbJsH7T/eA1fCN3krG7hCqN0EIt XVabr/YoVS6EE9xCwubM1AkscJYMKvKNad3OBB0w= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685286; bh=RHBfXmsfK8Wt+vPCtdwaxY95CxsEuU7z0TJvQS8Edxw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=pz9QpLKEIlikSGLkmSqEWMngQEw1WjIiJeV2F0X6RgG9BtAUgw/rFopkZ/Rei0+UD 4aUnmvjLQQ/YSOwqPpqqzg79ZQYQRawKXLKnqZCnbJsH7T/eA1fCN3krG7hCqN0EIt XVabr/YoVS6EE9xCwubM1AkscJYMKvKNad3OBB0w= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:11 +0200 Message-Id: <20180727095421.386-11-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 10/20] intc/arm_gic: Implement virtualization extensions in gic_(activate_irq|drop_prio) 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement virtualization extensions in gic_activate_irq() and gic_drop_prio() and in gic_get_prio_from_apr_bits() called by gic_drop_prio(). When the current CPU is a vCPU: - Use GIC_VIRT_MIN_BPR and GIC_VIRT_NR_APRS instead of their non-virt counterparts, - the vCPU APR is stored in the virtual interface, in h_apr. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 50 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 26ed7ea58a..de73dc9f54 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -274,30 +274,47 @@ static void gic_activate_irq(GICState *s, int cpu, in= t irq) { /* Set the appropriate Active Priority Register bit for this IRQ, * and update the running priority. */ int prio =3D gic_get_group_priority(s, cpu, irq); - int preemption_level =3D prio >> (GIC_MIN_BPR + 1); + int min_bpr =3D gic_is_vcpu(cpu) ? GIC_VIRT_MIN_BPR : GIC_MIN_BPR; + int preemption_level =3D prio >> (min_bpr + 1); int regno =3D preemption_level / 32; int bitno =3D preemption_level % 32; + uint32_t *papr =3D NULL; =20 - if (gic_has_groups(s) && gic_test_group(s, irq, cpu)) { - s->nsapr[regno][cpu] |=3D (1 << bitno); + if (gic_is_vcpu(cpu)) { + assert(regno =3D=3D 0); + papr =3D &s->h_apr[gic_get_vcpu_real_id(cpu)]; + } else if (gic_has_groups(s) && gic_test_group(s, irq, cpu)) { + papr =3D &s->nsapr[regno][cpu]; } else { - s->apr[regno][cpu] |=3D (1 << bitno); + papr =3D &s->apr[regno][cpu]; } =20 + *papr |=3D (1 << bitno); + s->running_priority[cpu] =3D prio; gic_set_active(s, irq, cpu); } =20 static int gic_get_prio_from_apr_bits(GICState *s, int cpu) { /* Recalculate the current running priority for this CPU based * on the set bits in the Active Priority Registers. */ int i; + + if (gic_is_vcpu(cpu)) { + uint32_t apr =3D s->h_apr[gic_get_vcpu_real_id(cpu)]; + if (apr) { + return ctz32(apr) << (GIC_VIRT_MIN_BPR + 1); + } else { + return 0x100; + } + } + for (i =3D 0; i < GIC_NR_APRS; i++) { uint32_t apr =3D s->apr[i][cpu] | s->nsapr[i][cpu]; if (!apr) { continue; } @@ -322,20 +339,29 @@ static void gic_drop_prio(GICState *s, int cpu, int g= roup) * behaviour of the GIC is UNPREDICTABLE, which for us means that * the values of the APR registers might become incorrect and the * running priority will be wrong, so interrupts that should preempt * might not do so, and interrupts that should not preempt might do so. */ - int i; + if (gic_is_vcpu(cpu)) { + int rcpu =3D gic_get_vcpu_real_id(cpu); =20 - for (i =3D 0; i < GIC_NR_APRS; i++) { - uint32_t *papr =3D group ? &s->nsapr[i][cpu] : &s->apr[i][cpu]; - if (!*papr) { - continue; + if (s->h_apr[rcpu]) { + /* Clear lowest set bit */ + s->h_apr[rcpu] &=3D s->h_apr[rcpu] - 1; + } + } else { + int i; + + for (i =3D 0; i < GIC_NR_APRS; i++) { + uint32_t *papr =3D group ? &s->nsapr[i][cpu] : &s->apr[i][cpu]; + if (!*papr) { + continue; + } + /* Clear lowest set bit */ + *papr &=3D *papr - 1; + break; } - /* Clear lowest set bit */ - *papr &=3D *papr - 1; - break; } =20 s->running_priority[cpu] =3D gic_get_prio_from_apr_bits(s, cpu); } =20 --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 153268598170751.07193315996847; Fri, 27 Jul 2018 03:06:21 -0700 (PDT) Received: from localhost ([::1]:40105 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizdc-0004v7-Kr for importer@patchew.org; Fri, 27 Jul 2018 06:06:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58395) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSm-0003vX-AI for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSi-0006Md-0M for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from greensocs.com ([193.104.36.180]:47522) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00068w-Tj; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id A7ABA44A0ED; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id x9UaHX8zwHrr; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 5CCE7443555; Fri, 27 Jul 2018 11:54:47 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id EA333400DC8; Fri, 27 Jul 2018 11:54:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685289; bh=xAHr68KhTy99xqhWJCA5rOyjUrOn4IWYSYzyr9p/TEY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=weUOvuL5BHOLE6pGyYGoLGiuc5KbN8aFDGSUYufU0cMtMLNA/84fl/+haE1xHSVFR 78u0p00g91DzYrrZ3Y0SO/kL/OnffhEHKaJGZ7zYQ0cyj3qLMDwJ9y0S1zVvAY+Cm9 LsLq8DevVuRV1gOZ7sF9fq84ORCy2/WypbGy9CM8= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=wSat81Rr; dkim=pass (1024-bit key) header.d=greensocs.com header.b=wSat81Rr DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685287; bh=xAHr68KhTy99xqhWJCA5rOyjUrOn4IWYSYzyr9p/TEY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=wSat81RrlO42dGXoRSqss54l1nHdkobMs8qcVIvCJugyw9s61ywCZZxJ+1aVMLAbM Z+bYxT6St/Bth0BZ/CY4W6xyQ5v1F3upeOFRN9BASTg6x3l4PHtMvUGeMhRLuwy+Ev PcXXCCNO++lobZ9X5T6dqwP6MSXQRr06x9cG+JJA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685287; bh=xAHr68KhTy99xqhWJCA5rOyjUrOn4IWYSYzyr9p/TEY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=wSat81RrlO42dGXoRSqss54l1nHdkobMs8qcVIvCJugyw9s61ywCZZxJ+1aVMLAbM Z+bYxT6St/Bth0BZ/CY4W6xyQ5v1F3upeOFRN9BASTg6x3l4PHtMvUGeMhRLuwy+Ev PcXXCCNO++lobZ9X5T6dqwP6MSXQRr06x9cG+JJA= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:12 +0200 Message-Id: <20180727095421.386-12-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 11/20] intc/arm_gic: Implement virtualization extensions in gic_acknowledge_irq 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement virtualization extensions in the gic_acknowledge_irq() function. This function changes the state of the highest priority IRQ from pending to active. When the current CPU is a vCPU, modifying the state of an IRQ modifies the corresponding LR entry. However if we clear the pending flag before setting the active one, we lose track of the LR entry as it becomes invalid. The next call to gic_get_lr_entry() will fail. To overcome this issue, we call gic_activate_irq() before gic_clear_pending(). This does not change the general behaviour of gic_acknowledge_irq. We also move the SGI case in gic_clear_pending_sgi() to enhance code readability as the virtualization extensions support adds a if-else level. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 52 ++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index de73dc9f54..d80acde989 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -363,21 +363,48 @@ static void gic_drop_prio(GICState *s, int cpu, int g= roup) } =20 s->running_priority[cpu] =3D gic_get_prio_from_apr_bits(s, cpu); } =20 +static inline uint32_t gic_clear_pending_sgi(GICState *s, int irq, int cpu) +{ + int src; + uint32_t ret; + + if (!gic_is_vcpu(cpu)) { + /* Lookup the source CPU for the SGI and clear this in the + * sgi_pending map. Return the src and clear the overall pending + * state on this CPU if the SGI is not pending from any CPUs. + */ + assert(s->sgi_pending[irq][cpu] !=3D 0); + src =3D ctz32(s->sgi_pending[irq][cpu]); + s->sgi_pending[irq][cpu] &=3D ~(1 << src); + if (s->sgi_pending[irq][cpu] =3D=3D 0) { + gic_clear_pending(s, irq, cpu); + } + ret =3D irq | ((src & 0x7) << 10); + } else { + uint32_t *lr_entry =3D gic_get_lr_entry(s, irq, cpu); + src =3D GICH_LR_CPUID(*lr_entry); + + gic_clear_pending(s, irq, cpu); + ret =3D irq | (src << 10); + } + + return ret; +} + uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs) { - int ret, irq, src; - int cm =3D 1 << cpu; + int ret, irq; =20 /* gic_get_current_pending_irq() will return 1022 or 1023 appropriately * for the case where this GIC supports grouping and the pending inter= rupt * is in the wrong group. */ irq =3D gic_get_current_pending_irq(s, cpu, attrs); - trace_gic_acknowledge_irq(cpu, irq); + trace_gic_acknowledge_irq(gic_get_vcpu_real_id(cpu), irq); =20 if (irq >=3D GIC_MAXIRQ) { DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq); return irq; } @@ -385,40 +412,27 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, Me= mTxAttrs attrs) if (gic_get_priority(s, irq, cpu) >=3D s->running_priority[cpu]) { DPRINTF("ACK, pending interrupt (%d) has insufficient priority\n",= irq); return 1023; } =20 + gic_activate_irq(s, cpu, irq); + if (s->revision =3D=3D REV_11MPCORE) { /* Clear pending flags for both level and edge triggered interrupt= s. * Level triggered IRQs will be reasserted once they become inacti= ve. */ gic_clear_pending(s, irq, cpu); ret =3D irq; } else { if (irq < GIC_NR_SGIS) { - /* Lookup the source CPU for the SGI and clear this in the - * sgi_pending map. Return the src and clear the overall pend= ing - * state on this CPU if the SGI is not pending from any CPUs. - */ - assert(s->sgi_pending[irq][cpu] !=3D 0); - src =3D ctz32(s->sgi_pending[irq][cpu]); - s->sgi_pending[irq][cpu] &=3D ~(1 << src); - if (s->sgi_pending[irq][cpu] =3D=3D 0) { - gic_clear_pending(s, irq, cpu); - } - ret =3D irq | ((src & 0x7) << 10); + ret =3D gic_clear_pending_sgi(s, irq, cpu); } else { - /* Clear pending state for both level and edge triggered - * interrupts. (level triggered interrupts with an active line - * remain pending, see gic_test_pending) - */ gic_clear_pending(s, irq, cpu); ret =3D irq; } } =20 - gic_activate_irq(s, cpu, irq); gic_update(s); DPRINTF("ACK %d\n", irq); return ret; } =20 --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532685626304181.28088212744512; Fri, 27 Jul 2018 03:00:26 -0700 (PDT) Received: from localhost ([::1]:40064 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizXt-0000LW-01 for importer@patchew.org; Fri, 27 Jul 2018 06:00:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58290) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSi-0003ng-W5 for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSg-0006KH-B1 for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:04 -0400 Received: from greensocs.com ([193.104.36.180]:47523) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSY-00068v-TV; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id AEA4D44A0F2; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hB1MMotST5hW; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id AE6E7400DC8; Fri, 27 Jul 2018 11:54:47 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 591264434A7; Fri, 27 Jul 2018 11:54:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685289; bh=5WV/wNLjNyQfMb2EzAtNl4rfaf6k6INk+sl6UaUVf2I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=QUA7H0ux95QNv+t+mLigacy9aeJ+TeHszSiW5Q+7ZDeWKNbkQ6H3Z/GBwukgN0fGC h8raCqdZaIhihlAzd8Qz1TcWTeS4eaC6v5r+EcWrl+JDHhbsKak+iQOC0irBu3kTCI DA5lB0PCrmdnIIUlEK3uY2fP+7OnPcxKE4VmfCyY= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=UzthTwPJ; dkim=pass (1024-bit key) header.d=greensocs.com header.b=UzthTwPJ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685287; bh=5WV/wNLjNyQfMb2EzAtNl4rfaf6k6INk+sl6UaUVf2I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UzthTwPJNJQibOzESpmFNGfp+hQAVuRIHhkXYDdLItDQvTIEKe88+OWkAEUUbHiim Qn8Kx6ZDaR9vzltqBK3foiSVNPusAuwbL7LMjcL9pboAtowHM4bS8Rk4diJbOdSavZ d3Xgbygqp0jiXBSM6LxWZJPihqLpdRqZu25eMyfE= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685287; bh=5WV/wNLjNyQfMb2EzAtNl4rfaf6k6INk+sl6UaUVf2I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=UzthTwPJNJQibOzESpmFNGfp+hQAVuRIHhkXYDdLItDQvTIEKe88+OWkAEUUbHiim Qn8Kx6ZDaR9vzltqBK3foiSVNPusAuwbL7LMjcL9pboAtowHM4bS8Rk4diJbOdSavZ d3Xgbygqp0jiXBSM6LxWZJPihqLpdRqZu25eMyfE= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:13 +0200 Message-Id: <20180727095421.386-13-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 12/20] intc/arm_gic: Implement virtualization extensions in gic_(deactivate|complete_irq) 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement virtualization extensions in the gic_deactivate_irq() and gic_complete_irq() functions. When the guest writes an invalid vIRQ to V_EOIR or V_DIR, since the GICv2 specification is not entirely clear here, we adopt the behaviour observed on real hardware: * When V_CTRL.EOIMode is false (EOI split is disabled): - In case of an invalid vIRQ write to V_EOIR: -> If some bits are set in H_APR, an invalid vIRQ write to V_EOIR triggers a priority drop, and increments V_HCR.EOICount. -> If V_APR is already cleared, nothing happen - An invalid vIRQ write to V_DIR is ignored. * When V_CTRL.EOIMode is true: - In case of an invalid vIRQ write to V_EOIR: -> If some bits are set in H_APR, an invalid vIRQ write to V_EOIR triggers a priority drop. -> If V_APR is already cleared, nothing happen - An invalid vIRQ write to V_DIR increments V_HCR.EOICount. Signed-off-by: Luc Michel --- hw/intc/arm_gic.c | 51 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index d80acde989..3cddf65826 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -581,31 +581,41 @@ static bool gic_eoi_split(GICState *s, int cpu, MemTx= Attrs attrs) =20 static void gic_deactivate_irq(GICState *s, int cpu, int irq, MemTxAttrs a= ttrs) { int group; =20 - if (irq >=3D s->num_irq) { + if (irq >=3D GIC_MAXIRQ || (!gic_is_vcpu(cpu) && irq >=3D s->num_irq))= { /* * This handles two cases: * 1. If software writes the ID of a spurious interrupt [ie 1023] * to the GICC_DIR, the GIC ignores that write. * 2. If software writes the number of a non-existent interrupt * this must be a subcase of "value written is not an active inter= rupt" - * and so this is UNPREDICTABLE. We choose to ignore it. + * and so this is UNPREDICTABLE. We choose to ignore it. For vCPUs, + * all IRQs potentially exist, so this limit does not apply. */ return; } =20 - group =3D gic_has_groups(s) && gic_test_group(s, irq, cpu); - if (!gic_eoi_split(s, cpu, attrs)) { /* This is UNPREDICTABLE; we choose to ignore it */ qemu_log_mask(LOG_GUEST_ERROR, "gic_deactivate_irq: GICC_DIR write when EOIMode cle= ar"); return; } =20 + if (gic_is_vcpu(cpu) && !gic_virq_is_valid(s, irq, cpu)) { + /* This vIRQ does not have an LR entry which is either active or + * pending and active. Increment EOICount and ignore the write. + */ + int rcpu =3D gic_get_vcpu_real_id(cpu); + s->h_hcr[rcpu] +=3D 1 << R_GICH_HCR_EOICount_SHIFT; + return; + } + + group =3D gic_has_groups(s) && gic_test_group(s, irq, cpu); + if (gic_cpu_ns_access(s, cpu, attrs) && !group) { DPRINTF("Non-secure DI for Group0 interrupt %d ignored\n", irq); return; } =20 @@ -616,10 +626,43 @@ static void gic_complete_irq(GICState *s, int cpu, in= t irq, MemTxAttrs attrs) { int cm =3D 1 << cpu; int group; =20 DPRINTF("EOI %d\n", irq); + if (gic_is_vcpu(cpu)) { + /* The call to gic_prio_drop() will clear a bit in GICH_APR iff the + * running prio is < 0x100. + */ + bool prio_drop =3D s->running_priority[cpu] < 0x100; + + if (irq >=3D GIC_MAXIRQ) { + /* Ignore spurious interrupt */ + return; + } + + gic_drop_prio(s, cpu, 0); + + if (!gic_eoi_split(s, cpu, attrs)) { + bool valid =3D gic_virq_is_valid(s, irq, cpu); + if (prio_drop && !valid) { + /* We are in a situation where: + * - V_CTRL.EOIMode is false (no EOI split), + * - The call to gic_drop_prio() cleared a bit in GICH_A= PR, + * - This vIRQ does not have an LR entry which is either + * active or pending and active. + * In that case, we must increment EOICount. + */ + int rcpu =3D gic_get_vcpu_real_id(cpu); + s->h_hcr[rcpu] +=3D 1 << R_GICH_HCR_EOICount_SHIFT; + } else if (valid) { + gic_clear_active(s, irq, cpu); + } + } + + return; + } + if (irq >=3D s->num_irq) { /* This handles two cases: * 1. If software writes the ID of a spurious interrupt [ie 1023] * to the GICC_EOIR, the GIC ignores that write. * 2. If software writes the number of a non-existent interrupt --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532686118786701.0812782867825; Fri, 27 Jul 2018 03:08:38 -0700 (PDT) Received: from localhost ([::1]:40116 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizfp-0006cJ-Iy for importer@patchew.org; Fri, 27 Jul 2018 06:08:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58406) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSm-0003w4-GK for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSh-0006Lw-Dl for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from greensocs.com ([193.104.36.180]:47525) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSZ-00069K-1M; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 8D91844A0FE; Fri, 27 Jul 2018 11:54:50 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cOmBRSCSPms6; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 22F7E44355C; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id B2D024434A7; Fri, 27 Jul 2018 11:54:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685290; bh=WZVYUk5e9FgMbKjFEeWXbGta6Qxx+9ye+Ey0gO/42s4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=NgmYLZF/43UUIa4qV/Oik5R8go6XvUnCceEXjjmIVF3e3vjpVX7y36aBEWGfr+nLR QI+nPrzmWXKvMb+tb9gZ9QSYWJ120vNa0qx8sItBHT+zkRya3FZmcRgO2hrhENIbeL axk1s+Nqe6MUIMBVteD+mFMOAc9PjlZijaz+YoeM= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=VvK65OGe; dkim=pass (1024-bit key) header.d=greensocs.com header.b=qvTzLGAj DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685288; bh=WZVYUk5e9FgMbKjFEeWXbGta6Qxx+9ye+Ey0gO/42s4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=VvK65OGezA1+n0/k0PfI48+tdonz1dHQBcYbxfQh9KvSnJct4lDmYzFiDl2cLZPjE sB+SAJL0GbeCNKzhGHK1Hbq8YRdnGvPvgjn0eJxhpRghvkmRdDzEo4IVSQakXoHoJu KojWoPUpJxyiAIpeN1bu6Y86SW8stwfZlIPx6MEE= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685287; bh=WZVYUk5e9FgMbKjFEeWXbGta6Qxx+9ye+Ey0gO/42s4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=qvTzLGAjgVtY3Yq0x/fvwy8VJqrVXjKPmfBgGwoMQ88j5puE1Xn984j71+mZvU/zq 28vtLas1xgi8La8l5gquPLF5EPo4KJ80IH1Rl+tnMk0lauaRkiBLxaBiXqR5yF5zSV XuGUr27mnD72zpAlt67/5U8q9sds8KEIA+WR7U+k= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:14 +0200 Message-Id: <20180727095421.386-14-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 13/20] intc/arm_gic: Implement virtualization extensions in gic_cpu_(read|write) 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 3 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement virtualization extensions in the gic_cpu_read() and gic_cpu_write() functions. Those are the last bits missing to fully support virtualization extensions in the CPU interface path. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 3cddf65826..0e1b23047e 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -1399,13 +1399,16 @@ static MemTxResult gic_cpu_read(GICState *s, int cp= u, int offset, } break; case 0xd0: case 0xd4: case 0xd8: case 0xdc: { int regno =3D (offset - 0xd0) / 4; + int nr_aprs =3D gic_is_vcpu(cpu) ? GIC_VIRT_NR_APRS : GIC_NR_APRS; =20 - if (regno >=3D GIC_NR_APRS || s->revision !=3D 2) { + if (regno >=3D nr_aprs || s->revision !=3D 2) { *data =3D 0; + } else if (gic_is_vcpu(cpu)) { + *data =3D s->h_apr[gic_get_vcpu_real_id(cpu)]; } else if (gic_cpu_ns_access(s, cpu, attrs)) { /* NS view of GICC_APR is the top half of GIC_NSAPR */ *data =3D gic_apr_ns_view(s, regno, cpu); } else { *data =3D s->apr[regno][cpu]; @@ -1415,11 +1418,11 @@ static MemTxResult gic_cpu_read(GICState *s, int cp= u, int offset, case 0xe0: case 0xe4: case 0xe8: case 0xec: { int regno =3D (offset - 0xe0) / 4; =20 if (regno >=3D GIC_NR_APRS || s->revision !=3D 2 || !gic_has_group= s(s) || - gic_cpu_ns_access(s, cpu, attrs)) { + gic_cpu_ns_access(s, cpu, attrs) || gic_is_vcpu(cpu)) { *data =3D 0; } else { *data =3D s->nsapr[regno][cpu]; } break; @@ -1450,11 +1453,12 @@ static MemTxResult gic_cpu_write(GICState *s, int c= pu, int offset, return MEMTX_OK; } else { s->abpr[cpu] =3D MAX(value & 0x7, GIC_MIN_ABPR); } } else { - s->bpr[cpu] =3D MAX(value & 0x7, GIC_MIN_BPR); + int min_bpr =3D gic_is_vcpu(cpu) ? GIC_VIRT_MIN_BPR : GIC_MIN_= BPR; + s->bpr[cpu] =3D MAX(value & 0x7, min_bpr); } break; case 0x10: /* End Of Interrupt */ gic_complete_irq(s, cpu, value & 0x3ff, attrs); return MEMTX_OK; @@ -1467,15 +1471,18 @@ static MemTxResult gic_cpu_write(GICState *s, int c= pu, int offset, } break; case 0xd0: case 0xd4: case 0xd8: case 0xdc: { int regno =3D (offset - 0xd0) / 4; + int nr_aprs =3D gic_is_vcpu(cpu) ? GIC_VIRT_NR_APRS : GIC_NR_APRS; =20 - if (regno >=3D GIC_NR_APRS || s->revision !=3D 2) { + if (regno >=3D nr_aprs || s->revision !=3D 2) { return MEMTX_OK; } - if (gic_cpu_ns_access(s, cpu, attrs)) { + if (gic_is_vcpu(cpu)) { + s->h_apr[gic_get_vcpu_real_id(cpu)] =3D value; + } else if (gic_cpu_ns_access(s, cpu, attrs)) { /* NS view of GICC_APR is the top half of GIC_NSAPR */ gic_apr_write_ns_view(s, regno, cpu, value); } else { s->apr[regno][cpu] =3D value; } @@ -1486,10 +1493,13 @@ static MemTxResult gic_cpu_write(GICState *s, int c= pu, int offset, int regno =3D (offset - 0xe0) / 4; =20 if (regno >=3D GIC_NR_APRS || s->revision !=3D 2) { return MEMTX_OK; } + if (gic_is_vcpu(cpu)) { + return MEMTX_OK; + } if (!gic_has_groups(s) || (gic_cpu_ns_access(s, cpu, attrs))) { return MEMTX_OK; } s->nsapr[regno][cpu] =3D value; break; --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532686268791484.976969890256; Fri, 27 Jul 2018 03:11:08 -0700 (PDT) Received: from localhost ([::1]:40126 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizhd-0008Le-Pg for importer@patchew.org; Fri, 27 Jul 2018 06:10:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58396) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSm-0003vY-9u for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSi-0006N8-Aw for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from greensocs.com ([193.104.36.180]:47526) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSZ-00069I-18; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 8594A44A0F6; Fri, 27 Jul 2018 11:54:50 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zC4pEp7RQr7p; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id A60584434A7; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 20CB9443485; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685290; bh=cHsBGH+B8QsVcvDWbU048HeIcJif0GXd7IS1ZEW5Egw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=BXSfjHLN2HjhquaZmuf2m+SpHbvmTDUF4uSIALRLa53nblcEJn9ynLDasibf2PRm0 0fQ1kKL8z2us5Vc2jFb+olFB5PWRgtT6O6xMVSNm0NH7oZc1oqmCXIJCOhr1kwsk24 tQbzM3+Q1/vO+mXmUeYWmmvhKjfWTpq24//+vucE= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=v1yHMrwP; dkim=pass (1024-bit key) header.d=greensocs.com header.b=v1yHMrwP DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685288; bh=cHsBGH+B8QsVcvDWbU048HeIcJif0GXd7IS1ZEW5Egw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=v1yHMrwPgUdTbK8x9bUJMWw+buVPTjtj7i+mLWdNVWZWZYneUJLusWB2Mh57lLNWX vXHybOZtLLvLcKEt1opjp9dHub3azHsmGXzXwyoDcYh75QwMPSdMcqSJeYehFMEaIC hmtUrADd5PDcU0qTqeyVU1ZqZ9ypRxWw8Mqx1yZk= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685288; bh=cHsBGH+B8QsVcvDWbU048HeIcJif0GXd7IS1ZEW5Egw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=v1yHMrwPgUdTbK8x9bUJMWw+buVPTjtj7i+mLWdNVWZWZYneUJLusWB2Mh57lLNWX vXHybOZtLLvLcKEt1opjp9dHub3azHsmGXzXwyoDcYh75QwMPSdMcqSJeYehFMEaIC hmtUrADd5PDcU0qTqeyVU1ZqZ9ypRxWw8Mqx1yZk= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:15 +0200 Message-Id: <20180727095421.386-15-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 14/20] intc/arm_gic: Wire the vCPU interface 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add the read/write functions to handle accesses to the vCPU interface. Those accesses are forwarded to the real CPU interface, with the CPU id being converted to the corresponding vCPU id (vCPU id =3D CPU id + GIC_NCPU). Signed-off-by: Luc Michel --- hw/intc/arm_gic.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 0e1b23047e..7ee2e6bcbb 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -1553,10 +1553,27 @@ static MemTxResult gic_do_cpu_write(void *opaque, h= waddr addr, GICState *s =3D *backref; int id =3D (backref - s->backref); return gic_cpu_write(s, id, addr, value, attrs); } =20 +static MemTxResult gic_thisvcpu_read(void *opaque, hwaddr addr, uint64_t *= data, + unsigned size, MemTxAttrs attrs) +{ + GICState *s =3D (GICState *)opaque; + + return gic_cpu_read(s, gic_get_current_vcpu(s), addr, data, attrs); +} + +static MemTxResult gic_thisvcpu_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size, + MemTxAttrs attrs) +{ + GICState *s =3D (GICState *)opaque; + + return gic_cpu_write(s, gic_get_current_vcpu(s), addr, value, attrs); +} + static const MemoryRegionOps gic_ops[2] =3D { { .read_with_attrs =3D gic_dist_read, .write_with_attrs =3D gic_dist_write, .endianness =3D DEVICE_NATIVE_ENDIAN, @@ -1572,10 +1589,23 @@ static const MemoryRegionOps gic_cpu_ops =3D { .read_with_attrs =3D gic_do_cpu_read, .write_with_attrs =3D gic_do_cpu_write, .endianness =3D DEVICE_NATIVE_ENDIAN, }; =20 +static const MemoryRegionOps gic_virt_ops[2] =3D { + { + .read_with_attrs =3D NULL, + .write_with_attrs =3D NULL, + .endianness =3D DEVICE_NATIVE_ENDIAN, + }, + { + .read_with_attrs =3D gic_thisvcpu_read, + .write_with_attrs =3D gic_thisvcpu_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + } +}; + static void arm_gic_realize(DeviceState *dev, Error **errp) { /* Device instance realize function for the GIC sysbus device */ int i; GICState *s =3D ARM_GIC(dev); @@ -1593,12 +1623,15 @@ static void arm_gic_realize(DeviceState *dev, Error= **errp) error_setg(errp, "KVM with user space irqchip only works when the " "host kernel supports KVM_CAP_ARM_USER_IRQ"); return; } =20 - /* This creates distributor and main CPU interface (s->cpuiomem[0]) */ - gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops, NULL); + /* This creates distributor, main CPU interface (s->cpuiomem[0]) and if + * enabled, virtualization extensions related interfaces (main virtual + * interface (s->vifaceiomem[0]) and virtual CPU interface). + */ + gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops, gic_virt_ops); =20 /* Extra core-specific regions for the CPU interfaces. This is * necessary for "franken-GIC" implementations, for example on * Exynos 4. * NB that the memory region size of 0x100 applies for the 11MPCore --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532686045544333.41092669338764; Fri, 27 Jul 2018 03:07:25 -0700 (PDT) Received: from localhost ([::1]:40107 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizeb-0005eu-7N for importer@patchew.org; Fri, 27 Jul 2018 06:07:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58430) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSn-0003wf-KF for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSl-0006QL-28 for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:09 -0400 Received: from greensocs.com ([193.104.36.180]:47516) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSZ-00068b-BK; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 81649400DC8; Fri, 27 Jul 2018 11:54:51 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Rkv04sM-VRLO; Fri, 27 Jul 2018 11:54:50 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 2CC8F443572; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id AB854443485; Fri, 27 Jul 2018 11:54:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685291; bh=D8nOeM0hkgP3m8t/j+HxFvspboGSK9VoL5Iu0bUzWvE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=7AjKhycwAUjMZ0yNuH3kIcXvZRNNP74WFUMHvtETWe2GS5JbzQI0MmLHpV98OZwnF Hcc76O5WMpiBRE5dPXk9UbFsEYoIfU4137AgLxMEE7tkI4kStUA80Qzb8HYzYaN9J7 2BOVCyENdDFTTz68rOJ3J6QmJ5k5kGdG80MrBJmI= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=qVEoA2GY; dkim=pass (1024-bit key) header.d=greensocs.com header.b=1m14VJX+ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685289; bh=D8nOeM0hkgP3m8t/j+HxFvspboGSK9VoL5Iu0bUzWvE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=qVEoA2GYjlbIuVeU26aSpUuQq//eSJmvSx9lgnXC6kSxErpB3ItUqC2RWIG0WQd3X yhBmGDxFqkE5Uudj9N731y4b+eYEdaLv17nMGiGS/XCisu5+NzkztDl7LyM+lNOzcn 9LKyMNWSatTBbgaBJBPMKNh4KIEfnv0h564F5Dog= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685288; bh=D8nOeM0hkgP3m8t/j+HxFvspboGSK9VoL5Iu0bUzWvE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=1m14VJX+LEtX3SiEWcK1eWe75C19HvrbWw8ucreOBcZ22Z6MayUMOCx7PG4zd2Ruh BzHQqhukUfYvOXDcX++mAyHtKG+5VDP2/P7bQzf9SHtQIny8pySdsIVtfCqXHVXmvD wFQBXgrZ2b2s1d9s2tnF6y74JUynizIUaKAWyJRk= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:16 +0200 Message-Id: <20180727095421.386-16-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 15/20] intc/arm_gic: Implement the virtual interface registers 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 3 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement the read and write functions for the virtual interface of the virtualization extensions in the GICv2. One mirror region per CPU is also created, which maps to that specific CPU id. This is required by the GIC architecture specification. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 235 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 233 insertions(+), 2 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 7ee2e6bcbb..6063196487 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -145,10 +145,28 @@ static void gic_update(GICState *s) qemu_set_irq(s->parent_irq[cpu], irq_level); qemu_set_irq(s->parent_fiq[cpu], fiq_level); } } =20 +/* Return true if this LR is empty, i.e. the corresponding bit + * in ELRSR is set. + */ +static inline bool gic_lr_entry_is_free(uint32_t entry) +{ + return (GICH_LR_STATE(entry) =3D=3D GICH_LR_STATE_INVALID) + && (GICH_LR_HW(entry) || !GICH_LR_EOI(entry)); +} + +/* Return true if this LR should trigger an EOI maintenance interrupt, i.e= . the + * corrsponding bit in EISR is set. + */ +static inline bool gic_lr_entry_is_eoi(uint32_t entry) +{ + return (GICH_LR_STATE(entry) =3D=3D GICH_LR_STATE_INVALID) + && !GICH_LR_HW(entry) && GICH_LR_EOI(entry); +} + static void gic_set_irq_11mpcore(GICState *s, int irq, int level, int cm, int target) { if (level) { GIC_DIST_SET_LEVEL(irq, cm); @@ -1570,10 +1588,204 @@ static MemTxResult gic_thisvcpu_write(void *opaque= , hwaddr addr, GICState *s =3D (GICState *)opaque; =20 return gic_cpu_write(s, gic_get_current_vcpu(s), addr, value, attrs); } =20 +static uint32_t gic_compute_eisr(GICState *s, int cpu, int lr_start) +{ + int lr_idx; + uint32_t ret =3D 0; + + for (lr_idx =3D lr_start; lr_idx < s->num_lrs; lr_idx++) { + uint32_t *entry =3D &s->h_lr[lr_idx][cpu]; + ret =3D deposit32(ret, lr_idx - lr_start, 1, + gic_lr_entry_is_eoi(*entry)); + } + + return ret; +} + +static uint32_t gic_compute_elrsr(GICState *s, int cpu, int lr_start) +{ + int lr_idx; + uint32_t ret =3D 0; + + for (lr_idx =3D lr_start; lr_idx < s->num_lrs; lr_idx++) { + uint32_t *entry =3D &s->h_lr[lr_idx][cpu]; + ret =3D deposit32(ret, lr_idx - lr_start, 1, + gic_lr_entry_is_free(*entry)); + } + + return ret; +} + +static void gic_vmcr_write(GICState *s, uint32_t value, MemTxAttrs attrs) +{ + int vcpu =3D gic_get_current_vcpu(s); + uint32_t ctlr; + uint32_t abpr; + uint32_t bpr; + uint32_t prio_mask; + + ctlr =3D FIELD_EX32(value, GICH_VMCR, VMCCtlr); + abpr =3D FIELD_EX32(value, GICH_VMCR, VMABP); + bpr =3D FIELD_EX32(value, GICH_VMCR, VMBP); + prio_mask =3D FIELD_EX32(value, GICH_VMCR, VMPriMask) << 3; + + gic_set_cpu_control(s, vcpu, ctlr, attrs); + s->abpr[vcpu] =3D MAX(abpr, GIC_VIRT_MIN_ABPR); + s->bpr[vcpu] =3D MAX(bpr, GIC_VIRT_MIN_BPR); + gic_set_priority_mask(s, vcpu, prio_mask, attrs); +} + +static MemTxResult gic_hyp_read(void *opaque, int cpu, hwaddr addr, + uint64_t *data, MemTxAttrs attrs) +{ + GICState *s =3D ARM_GIC(opaque); + int vcpu =3D cpu + GIC_NCPU; + + switch (addr) { + case A_GICH_HCR: /* Hypervisor Control */ + *data =3D s->h_hcr[cpu]; + break; + + case A_GICH_VTR: /* VGIC Type */ + *data =3D FIELD_DP32(0, GICH_VTR, ListRegs, s->num_lrs - 1); + *data =3D FIELD_DP32(*data, GICH_VTR, PREbits, + GIC_VIRT_MAX_GROUP_PRIO_BITS - 1); + *data =3D FIELD_DP32(*data, GICH_VTR, PRIbits, + (7 - GIC_VIRT_MIN_BPR) - 1); + break; + + case A_GICH_VMCR: /* Virtual Machine Control */ + *data =3D FIELD_DP32(0, GICH_VMCR, VMCCtlr, + extract32(s->cpu_ctlr[vcpu], 0, 10)); + *data =3D FIELD_DP32(*data, GICH_VMCR, VMABP, s->abpr[vcpu]); + *data =3D FIELD_DP32(*data, GICH_VMCR, VMBP, s->bpr[vcpu]); + *data =3D FIELD_DP32(*data, GICH_VMCR, VMPriMask, + extract32(s->priority_mask[vcpu], 3, 5)); + break; + + case A_GICH_MISR: /* Maintenance Interrupt Status */ + *data =3D s->h_misr[cpu]; + break; + + case A_GICH_EISR0: /* End of Interrupt Status 0 and 1 */ + case A_GICH_EISR1: + *data =3D gic_compute_eisr(s, cpu, (addr - A_GICH_EISR0) * 8); + break; + + case A_GICH_ELRSR0: /* Empty List Status 0 and 1 */ + case A_GICH_ELRSR1: + *data =3D gic_compute_elrsr(s, cpu, (addr - A_GICH_ELRSR0) * 8); + break; + + case A_GICH_APR: /* Active Priorities */ + *data =3D s->h_apr[cpu]; + break; + + case A_GICH_LR0 ... A_GICH_LR63: /* List Registers */ + { + int lr_idx =3D (addr - A_GICH_LR0) / 4; + + if (lr_idx > s->num_lrs) { + *data =3D 0; + } else { + *data =3D s->h_lr[lr_idx][cpu]; + } + break; + } + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "gic_hyp_read: Bad offset %" HWADDR_PRIx "\n", addr); + return MEMTX_OK; + } + + return MEMTX_OK; +} + +static MemTxResult gic_hyp_write(void *opaque, int cpu, hwaddr addr, + uint64_t value, MemTxAttrs attrs) +{ + GICState *s =3D ARM_GIC(opaque); + int vcpu =3D cpu + GIC_NCPU; + + switch (addr) { + case A_GICH_HCR: /* Hypervisor Control */ + s->h_hcr[cpu] =3D value & GICH_HCR_MASK; + break; + + case A_GICH_VMCR: /* Virtual Machine Control */ + gic_vmcr_write(s, value, attrs); + break; + + case A_GICH_APR: /* Active Priorities */ + s->h_apr[cpu] =3D value; + s->running_priority[vcpu] =3D gic_get_prio_from_apr_bits(s, vcpu); + break; + + case A_GICH_LR0 ... A_GICH_LR63: /* List Registers */ + { + int lr_idx =3D (addr - A_GICH_LR0) / 4; + + if (lr_idx > s->num_lrs) { + return MEMTX_OK; + } + + s->h_lr[lr_idx][cpu] =3D value & GICH_LR_MASK; + break; + } + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "gic_hyp_write: Bad offset %" HWADDR_PRIx "\n", addr= ); + return MEMTX_OK; + } + + return MEMTX_OK; +} + +static MemTxResult gic_thiscpu_hyp_read(void *opaque, hwaddr addr, uint64_= t *data, + unsigned size, MemTxAttrs attrs) +{ + GICState *s =3D (GICState *)opaque; + + return gic_hyp_read(s, gic_get_current_cpu(s), addr, data, attrs); +} + +static MemTxResult gic_thiscpu_hyp_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size, + MemTxAttrs attrs) +{ + GICState *s =3D (GICState *)opaque; + + return gic_hyp_write(s, gic_get_current_cpu(s), addr, value, attrs); +} + +static MemTxResult gic_do_hyp_read(void *opaque, hwaddr addr, uint64_t *da= ta, + unsigned size, MemTxAttrs attrs) +{ + GICState **backref =3D (GICState **)opaque; + GICState *s =3D *backref; + int id =3D (backref - s->backref); + + return gic_hyp_read(s, id, addr, data, attrs); +} + +static MemTxResult gic_do_hyp_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size, + MemTxAttrs attrs) +{ + GICState **backref =3D (GICState **)opaque; + GICState *s =3D *backref; + int id =3D (backref - s->backref); + + return gic_hyp_write(s, id + GIC_NCPU, addr, value, attrs); + +} + static const MemoryRegionOps gic_ops[2] =3D { { .read_with_attrs =3D gic_dist_read, .write_with_attrs =3D gic_dist_write, .endianness =3D DEVICE_NATIVE_ENDIAN, @@ -1591,21 +1803,27 @@ static const MemoryRegionOps gic_cpu_ops =3D { .endianness =3D DEVICE_NATIVE_ENDIAN, }; =20 static const MemoryRegionOps gic_virt_ops[2] =3D { { - .read_with_attrs =3D NULL, - .write_with_attrs =3D NULL, + .read_with_attrs =3D gic_thiscpu_hyp_read, + .write_with_attrs =3D gic_thiscpu_hyp_write, .endianness =3D DEVICE_NATIVE_ENDIAN, }, { .read_with_attrs =3D gic_thisvcpu_read, .write_with_attrs =3D gic_thisvcpu_write, .endianness =3D DEVICE_NATIVE_ENDIAN, } }; =20 +static const MemoryRegionOps gic_viface_ops =3D { + .read_with_attrs =3D gic_do_hyp_read, + .write_with_attrs =3D gic_do_hyp_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, +}; + static void arm_gic_realize(DeviceState *dev, Error **errp) { /* Device instance realize function for the GIC sysbus device */ int i; GICState *s =3D ARM_GIC(dev); @@ -1643,10 +1861,23 @@ static void arm_gic_realize(DeviceState *dev, Error= **errp) s->backref[i] =3D s; memory_region_init_io(&s->cpuiomem[i+1], OBJECT(s), &gic_cpu_ops, &s->backref[i], "gic_cpu", 0x100); sysbus_init_mmio(sbd, &s->cpuiomem[i+1]); } + + /* Extra core-specific regions for virtual interfaces. This is require= d by + * the GICv2 specification. + */ + if (s->virt_extn) { + for (i =3D 0; i < s->num_cpu; i++) { + memory_region_init_io(&s->vifaceiomem[i + 1], OBJECT(s), + &gic_viface_ops, &s->backref[i], + "gic_viface", 0x1000); + sysbus_init_mmio(sbd, &s->vifaceiomem[i + 1]); + } + } + } =20 static void arm_gic_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532685878026441.15295157690196; Fri, 27 Jul 2018 03:04:38 -0700 (PDT) Received: from localhost ([::1]:40092 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizbw-0003As-Pm for importer@patchew.org; Fri, 27 Jul 2018 06:04:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58420) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSn-0003wM-7Y for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSk-0006Pr-Fl for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:09 -0400 Received: from greensocs.com ([193.104.36.180]:47531) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSZ-0006Ag-Ix; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 98B0A44355C; Fri, 27 Jul 2018 11:54:51 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id LgK21aYC7uX3; Fri, 27 Jul 2018 11:54:50 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 7FCFF443485; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 25666443557; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685291; bh=0nWuiCI2Sfl8isJ+W/w8e+MYSZZzizdpCMSw8CG2vQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=mlbN1PrX4AhzaFn/xu7+6VXXMG5qVWisOOECF0a7qWl10LiRi/T2Nh51kwO0fxJZX VfSzkYwaM6MCRAYlBuJAuF7neYQZ+lshtM71fMhGLjF8NJuZI+PTFn9Iv4jB/roz+6 6bve9BfAublP0JJ4LxHjfBjl3URH8ERMyULOQU74= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=gkutp6fx; dkim=pass (1024-bit key) header.d=greensocs.com header.b=gkutp6fx DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685289; bh=0nWuiCI2Sfl8isJ+W/w8e+MYSZZzizdpCMSw8CG2vQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=gkutp6fx//y3z30DGFsLeDlZouiVDlYS6VYokI1rtZ1bqJgz2zyQgs8abShdJ7ile iNR176lZTVg4dLZd90b+FzuNAhtXdrDJ7JU+Xa+xfdvJciqe0oxfZ1qaKKb7pBSwUO xjC/Ad7hj4SJb7Nciim/GBn+7fb6fbH0jQgscXe0= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685289; bh=0nWuiCI2Sfl8isJ+W/w8e+MYSZZzizdpCMSw8CG2vQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=gkutp6fx//y3z30DGFsLeDlZouiVDlYS6VYokI1rtZ1bqJgz2zyQgs8abShdJ7ile iNR176lZTVg4dLZd90b+FzuNAhtXdrDJ7JU+Xa+xfdvJciqe0oxfZ1qaKKb7pBSwUO xjC/Ad7hj4SJb7Nciim/GBn+7fb6fbH0jQgscXe0= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:17 +0200 Message-Id: <20180727095421.386-17-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 16/20] intc/arm_gic: Implement gic_update_virt() function 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add the gic_update_virt() function to update the vCPU interface states and raise vIRQ and vFIQ as needed. This commit renames gic_update() to gic_update_internal() and generalizes it to handle both cases, with a `virt' parameter to track whether we are updating the CPU or vCPU interfaces. The main difference between CPU and vCPU is the way we select the best IRQ. This part has been split into the gic_get_best_(v)irq functions. For the virt case, the LRs are iterated to find the best candidate. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 175 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 136 insertions(+), 39 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 6063196487..6b97e19796 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -77,78 +77,153 @@ static inline bool gic_has_groups(GICState *s) static inline bool gic_cpu_ns_access(GICState *s, int cpu, MemTxAttrs attr= s) { return !gic_is_vcpu(cpu) && s->security_extn && !attrs.secure; } =20 +static inline void gic_get_best_irq(GICState *s, int cpu, + int *best_irq, int *best_prio, int *gr= oup) +{ + int irq; + int cm =3D 1 << cpu; + + *best_irq =3D 1023; + *best_prio =3D 0x100; + + for (irq =3D 0; irq < s->num_irq; irq++) { + if (GIC_DIST_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm)= && + (!GIC_DIST_TEST_ACTIVE(irq, cm)) && + (irq < GIC_INTERNAL || GIC_DIST_TARGET(irq) & cm)) { + if (GIC_DIST_GET_PRIORITY(irq, cpu) < *best_prio) { + *best_prio =3D GIC_DIST_GET_PRIORITY(irq, cpu); + *best_irq =3D irq; + } + } + } + + if (*best_irq < 1023) { + *group =3D GIC_DIST_TEST_GROUP(*best_irq, cm); + } +} + +static inline void gic_get_best_virq(GICState *s, int cpu, + int *best_irq, int *best_prio, int *g= roup) +{ + int lr_idx =3D 0; + + *best_irq =3D 1023; + *best_prio =3D 0x100; + + for (lr_idx =3D 0; lr_idx < s->num_lrs; lr_idx++) { + uint32_t lr_entry =3D s->h_lr[lr_idx][cpu]; + int state =3D GICH_LR_STATE(lr_entry); + + if (state =3D=3D GICH_LR_STATE_PENDING) { + int prio =3D GICH_LR_PRIORITY(lr_entry); + + if (prio < *best_prio) { + *best_prio =3D prio; + *best_irq =3D GICH_LR_VIRT_ID(lr_entry); + *group =3D GICH_LR_GROUP(lr_entry); + } + } + } +} + +/* Return true if IRQ signaling is enabled for the given cpu and at least = one + * of the given groups: + * - in the non-virt case, the distributor must be enabled for one of the + * given groups + * - in the virt case, the virtual interface must be enabled. + * - in all cases, the (v)CPU interface must be enabled for one of the g= iven + * groups. + */ +static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool vi= rt, + int group_mask) +{ + if (!virt && !(s->ctlr & group_mask)) { + return false; + } + + if (virt && !(s->h_hcr[cpu] & R_GICH_HCR_EN_MASK)) { + return false; + } + + if (!(s->cpu_ctlr[cpu] & group_mask)) { + return false; + } + + return true; +} + /* TODO: Many places that call this routine could be optimized. */ /* Update interrupt status after enabled or pending bits have been changed= . */ -static void gic_update(GICState *s) +static inline void gic_update_internal(GICState *s, bool virt) { int best_irq; int best_prio; - int irq; int irq_level, fiq_level; - int cpu; - int cm; + int cpu, cpu_iface; + int group =3D 0; + qemu_irq *irq_lines =3D virt ? s->parent_virq : s->parent_irq; + qemu_irq *fiq_lines =3D virt ? s->parent_vfiq : s->parent_fiq; =20 for (cpu =3D 0; cpu < s->num_cpu; cpu++) { - cm =3D 1 << cpu; - s->current_pending[cpu] =3D 1023; - if (!(s->ctlr & (GICD_CTLR_EN_GRP0 | GICD_CTLR_EN_GRP1)) - || !(s->cpu_ctlr[cpu] & (GICC_CTLR_EN_GRP0 | GICC_CTLR_EN_GRP1= ))) { - qemu_irq_lower(s->parent_irq[cpu]); - qemu_irq_lower(s->parent_fiq[cpu]); + cpu_iface =3D virt ? (cpu + GIC_NCPU) : cpu; + + s->current_pending[cpu_iface] =3D 1023; + if (!gic_irq_signaling_enabled(s, cpu, virt, + GICD_CTLR_EN_GRP0 | GICD_CTLR_EN_GR= P1)) { + qemu_irq_lower(irq_lines[cpu]); + qemu_irq_lower(fiq_lines[cpu]); continue; } - best_prio =3D 0x100; - best_irq =3D 1023; - for (irq =3D 0; irq < s->num_irq; irq++) { - if (GIC_DIST_TEST_ENABLED(irq, cm) && - gic_test_pending(s, irq, cm) && - (!GIC_DIST_TEST_ACTIVE(irq, cm)) && - (irq < GIC_INTERNAL || GIC_DIST_TARGET(irq) & cm)) { - if (GIC_DIST_GET_PRIORITY(irq, cpu) < best_prio) { - best_prio =3D GIC_DIST_GET_PRIORITY(irq, cpu); - best_irq =3D irq; - } - } + + if (virt) { + gic_get_best_virq(s, cpu, &best_irq, &best_prio, &group); + } else { + gic_get_best_irq(s, cpu, &best_irq, &best_prio, &group); } =20 if (best_irq !=3D 1023) { trace_gic_update_bestirq(cpu, best_irq, best_prio, - s->priority_mask[cpu], s->running_priority[cpu]); + s->priority_mask[cpu_iface], s->running_priority[cpu_iface= ]); } =20 irq_level =3D fiq_level =3D 0; =20 - if (best_prio < s->priority_mask[cpu]) { - s->current_pending[cpu] =3D best_irq; - if (best_prio < s->running_priority[cpu]) { - int group =3D GIC_DIST_TEST_GROUP(best_irq, cm); - - if (extract32(s->ctlr, group, 1) && - extract32(s->cpu_ctlr[cpu], group, 1)) { - if (group =3D=3D 0 && s->cpu_ctlr[cpu] & GICC_CTLR_FIQ= _EN) { + if (best_prio < s->priority_mask[cpu_iface]) { + s->current_pending[cpu_iface] =3D best_irq; + if (best_prio < s->running_priority[cpu_iface]) { + if (gic_irq_signaling_enabled(s, cpu, virt, 1 << group)) { + if (group =3D=3D 0 && + s->cpu_ctlr[cpu_iface] & GICC_CTLR_FIQ_EN) { DPRINTF("Raised pending FIQ %d (cpu %d)\n", - best_irq, cpu); + best_irq, cpu_iface); fiq_level =3D 1; - trace_gic_update_set_irq(cpu, "fiq", fiq_level); + trace_gic_update_set_irq(cpu, virt ? "vfiq" : "fiq= ", + fiq_level); } else { DPRINTF("Raised pending IRQ %d (cpu %d)\n", - best_irq, cpu); + best_irq, cpu_iface); irq_level =3D 1; - trace_gic_update_set_irq(cpu, "irq", irq_level); + trace_gic_update_set_irq(cpu, virt ? "virq" : "irq= ", + irq_level); } } } } =20 - qemu_set_irq(s->parent_irq[cpu], irq_level); - qemu_set_irq(s->parent_fiq[cpu], fiq_level); + qemu_set_irq(irq_lines[cpu], irq_level); + qemu_set_irq(fiq_lines[cpu], fiq_level); } } =20 +static void gic_update(GICState *s) +{ + gic_update_internal(s, false); +} + /* Return true if this LR is empty, i.e. the corresponding bit * in ELRSR is set. */ static inline bool gic_lr_entry_is_free(uint32_t entry) { @@ -163,10 +238,15 @@ static inline bool gic_lr_entry_is_eoi(uint32_t entry) { return (GICH_LR_STATE(entry) =3D=3D GICH_LR_STATE_INVALID) && !GICH_LR_HW(entry) && GICH_LR_EOI(entry); } =20 +static void gic_update_virt(GICState *s) +{ + gic_update_internal(s, true); +} + static void gic_set_irq_11mpcore(GICState *s, int irq, int level, int cm, int target) { if (level) { GIC_DIST_SET_LEVEL(irq, cm); @@ -447,11 +527,15 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, Me= mTxAttrs attrs) gic_clear_pending(s, irq, cpu); ret =3D irq; } } =20 - gic_update(s); + if (gic_is_vcpu(cpu)) { + gic_update_virt(s); + } else { + gic_update(s); + } DPRINTF("ACK %d\n", irq); return ret; } =20 void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val, @@ -625,10 +709,15 @@ static void gic_deactivate_irq(GICState *s, int cpu, = int irq, MemTxAttrs attrs) /* This vIRQ does not have an LR entry which is either active or * pending and active. Increment EOICount and ignore the write. */ int rcpu =3D gic_get_vcpu_real_id(cpu); s->h_hcr[rcpu] +=3D 1 << R_GICH_HCR_EOICount_SHIFT; + + /* Update the virtual interface in case a maintenance interrupt sh= ould + * be raised. + */ + gic_update_virt(s); return; } =20 group =3D gic_has_groups(s) && gic_test_group(s, irq, cpu); =20 @@ -674,10 +763,11 @@ static void gic_complete_irq(GICState *s, int cpu, in= t irq, MemTxAttrs attrs) } else if (valid) { gic_clear_active(s, irq, cpu); } } =20 + gic_update_virt(s); return; } =20 if (irq >=3D s->num_irq) { /* This handles two cases: @@ -1529,11 +1619,17 @@ static MemTxResult gic_cpu_write(GICState *s, int c= pu, int offset, default: qemu_log_mask(LOG_GUEST_ERROR, "gic_cpu_write: Bad offset %x\n", (int)offset); return MEMTX_OK; } - gic_update(s); + + if (gic_is_vcpu(cpu)) { + gic_update_virt(s); + } else { + gic_update(s); + } + return MEMTX_OK; } =20 /* Wrappers to read/write the GIC CPU interface for the current CPU */ static MemTxResult gic_thiscpu_read(void *opaque, hwaddr addr, uint64_t *d= ata, @@ -1740,10 +1836,11 @@ static MemTxResult gic_hyp_write(void *opaque, int = cpu, hwaddr addr, qemu_log_mask(LOG_GUEST_ERROR, "gic_hyp_write: Bad offset %" HWADDR_PRIx "\n", addr= ); return MEMTX_OK; } =20 + gic_update_virt(s); return MEMTX_OK; } =20 static MemTxResult gic_thiscpu_hyp_read(void *opaque, hwaddr addr, uint64_= t *data, unsigned size, MemTxAttrs attrs) --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 153268552014062.12648320502046; Fri, 27 Jul 2018 02:58:40 -0700 (PDT) Received: from localhost ([::1]:40051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizWA-0006fc-MX for importer@patchew.org; Fri, 27 Jul 2018 05:58:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58313) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSj-0003oy-NV for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSh-0006LN-3h for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:05 -0400 Received: from greensocs.com ([193.104.36.180]:47518) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSZ-00068j-CA; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 6921B443485; Fri, 27 Jul 2018 11:54:52 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Jw1QZl8GHk3W; Fri, 27 Jul 2018 11:54:51 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 10D1A443555; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 80E5D443557; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685292; bh=pNNl64R+LFdPfExuU2lnihGUsf+QguDPJQcNXojg8Hs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=u+PUit6G7pP3VmVfL8MI+sRQAMp/Jn5W+vtniikjHIlrxrz0QPn68Hg/jt6ArKAwh 4Ns7LEm04L78MWnD3C/J+yO/oJbX+2x2r9uxfscpkwTqyM3Hm5G4zqQQaFmYG3BPgR 4m31gCZIA/OsAZk2hpnLi6IBxyC9qW8Po/CHULLs= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=PGJK69mD; dkim=pass (1024-bit key) header.d=greensocs.com header.b=Gcf6C9Bw DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685290; bh=pNNl64R+LFdPfExuU2lnihGUsf+QguDPJQcNXojg8Hs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=PGJK69mDR4kCu8sotVGhvDMFko89FY5pCZiaK6bfUtafd/V2niMec4lRWZ+8IDg08 X3iTv/SxJZZdTqf1L+mM1gPHtSG5hVNfCPIVtGJeNfjUIT+SDrxCYGeKawlmg7sydR YtK5XFx+olgVZ9A3oM6Sb4cT2dmyZU/jER0HsdHI= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685289; bh=pNNl64R+LFdPfExuU2lnihGUsf+QguDPJQcNXojg8Hs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Gcf6C9Bw8qsQXLuyinNH5XwTu8SSvyhrXaFLhp5Q2Mq43kVafoWdvXTZEBmRY1IOD 22b5noRYeLs+1LmeAJhBWt1Tm+OJ5VyoVnRDApQZovqV9b2TpfprucMRanAUdMJxbP oHNmds/sEp87acJYbn0FIaVR4H9oUD5oP/2ZaXtA= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:18 +0200 Message-Id: <20180727095421.386-18-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 17/20] intc/arm_gic: Implement maintenance interrupt generation 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 3 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement the maintenance interrupt generation that is part of the GICv2 virtualization extensions. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 6b97e19796..6ff7da3e5d 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -238,13 +238,110 @@ static inline bool gic_lr_entry_is_eoi(uint32_t entr= y) { return (GICH_LR_STATE(entry) =3D=3D GICH_LR_STATE_INVALID) && !GICH_LR_HW(entry) && GICH_LR_EOI(entry); } =20 +static inline void gic_extract_lr_info(GICState *s, int cpu, + int *num_eoi, int *num_valid, int *num_pen= ding) +{ + int lr_idx; + + *num_eoi =3D 0; + *num_valid =3D 0; + *num_pending =3D 0; + + for (lr_idx =3D 0; lr_idx < s->num_lrs; lr_idx++) { + uint32_t *entry =3D &s->h_lr[lr_idx][cpu]; + + if (gic_lr_entry_is_eoi(*entry)) { + (*num_eoi)++; + } + + if (GICH_LR_STATE(*entry) !=3D GICH_LR_STATE_INVALID) { + (*num_valid)++; + } + + if (GICH_LR_STATE(*entry) =3D=3D GICH_LR_STATE_PENDING) { + (*num_pending)++; + } + } +} + +static void gic_compute_misr(GICState *s, int cpu) +{ + uint32_t value =3D 0; + int vcpu =3D cpu + GIC_NCPU; + + int num_eoi, num_valid, num_pending; + + gic_extract_lr_info(s, cpu, &num_eoi, &num_valid, &num_pending); + + /* EOI */ + if (num_eoi) { + value |=3D R_GICH_MISR_EOI_MASK; + } + + /* U: true if only 0 or 1 LR entry is valid */ + if ((s->h_hcr[cpu] & R_GICH_HCR_UIE_MASK) && (num_valid < 2)) { + value |=3D R_GICH_MISR_U_MASK; + } + + /* LRENP: EOICount is not 0 */ + if ((s->h_hcr[cpu] & R_GICH_HCR_LRENPIE_MASK) && + ((s->h_hcr[cpu] & R_GICH_HCR_EOICount_MASK) !=3D 0)) { + value |=3D R_GICH_MISR_LRENP_MASK; + } + + /* NP: no pending interrupts */ + if ((s->h_hcr[cpu] & R_GICH_HCR_NPIE_MASK) && (num_pending =3D=3D 0)) { + value |=3D R_GICH_MISR_NP_MASK; + } + + /* VGrp0E: group0 virq signaling enabled */ + if ((s->h_hcr[cpu] & R_GICH_HCR_VGRP0EIE_MASK) && + (s->cpu_ctlr[vcpu] & GICC_CTLR_EN_GRP0)) { + value |=3D R_GICH_MISR_VGrp0E_MASK; + } + + /* VGrp0D: group0 virq signaling disabled */ + if ((s->h_hcr[cpu] & R_GICH_HCR_VGRP0DIE_MASK) && + !(s->cpu_ctlr[vcpu] & GICC_CTLR_EN_GRP0)) { + value |=3D R_GICH_MISR_VGrp0D_MASK; + } + + /* VGrp1E: group1 virq signaling enabled */ + if ((s->h_hcr[cpu] & R_GICH_HCR_VGRP1EIE_MASK) && + (s->cpu_ctlr[vcpu] & GICC_CTLR_EN_GRP1)) { + value |=3D R_GICH_MISR_VGrp1E_MASK; + } + + /* VGrp1D: group1 virq signaling disabled */ + if ((s->h_hcr[cpu] & R_GICH_HCR_VGRP1DIE_MASK) && + !(s->cpu_ctlr[vcpu] & GICC_CTLR_EN_GRP1)) { + value |=3D R_GICH_MISR_VGrp1D_MASK; + } + + s->h_misr[cpu] =3D value; +} + +static void gic_update_maintenance(GICState *s) +{ + int cpu =3D 0; + int maint_level; + + for (cpu =3D 0; cpu < s->num_cpu; cpu++) { + gic_compute_misr(s, cpu); + maint_level =3D (s->h_hcr[cpu] & R_GICH_HCR_EN_MASK) && s->h_misr[= cpu]; + + qemu_set_irq(s->maintenance_irq[cpu], maint_level); + } +} + static void gic_update_virt(GICState *s) { gic_update_internal(s, true); + gic_update_maintenance(s); } =20 static void gic_set_irq_11mpcore(GICState *s, int irq, int level, int cm, int target) { --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532686283109785.6657115486373; Fri, 27 Jul 2018 03:11:23 -0700 (PDT) Received: from localhost ([::1]:40130 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fiziT-0000Vf-QZ for importer@patchew.org; Fri, 27 Jul 2018 06:11:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58407) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSm-0003w5-GJ for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSk-0006PZ-0A for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from greensocs.com ([193.104.36.180]:47534) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSZ-0006Au-KV; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 9E8EB443555; Fri, 27 Jul 2018 11:54:52 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EQyWFexLhLR5; Fri, 27 Jul 2018 11:54:51 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 49481443557; Fri, 27 Jul 2018 11:54:50 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id E2FD8400DC8; Fri, 27 Jul 2018 11:54:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685292; bh=NPr6OjFh0pz4ZmPkNP0eT08Q4MxZN27JaWCOFwGMd5I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ymo13dPxbe6wyqDpNb4AyZDoqUnygM+iXoZGMClPzySaTaXy5jhSiRLi7uPoTFxzZ H5WwbUMCg20CIXoNFXy9gMOxvEt8Oej66GGGyhz4+FVZ8GzMN+NrwAFgcHkMO6HARf 0OguhdM3LQyMX8l3A9R3gvZE4vruQS3zq8abpH/k= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=KaIac/ys; dkim=pass (1024-bit key) header.d=greensocs.com header.b=KaIac/ys DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685290; bh=NPr6OjFh0pz4ZmPkNP0eT08Q4MxZN27JaWCOFwGMd5I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=KaIac/yswLLMtTQeWS52vO/LJfJppoFCcuUFVbc+cIzw1TaiSVZf9c8c/rW1lvaXJ Xq69E5Es/NwU9d3wuO6F+adVlNwoXQ9WcGcs/n2e6fiIRgwjSqypEncpdGldqvKKv4 comdmpA/HjaGh6whu/MT/CPNDCuHEfUYD04Vi+/g= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685290; bh=NPr6OjFh0pz4ZmPkNP0eT08Q4MxZN27JaWCOFwGMd5I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=KaIac/yswLLMtTQeWS52vO/LJfJppoFCcuUFVbc+cIzw1TaiSVZf9c8c/rW1lvaXJ Xq69E5Es/NwU9d3wuO6F+adVlNwoXQ9WcGcs/n2e6fiIRgwjSqypEncpdGldqvKKv4 comdmpA/HjaGh6whu/MT/CPNDCuHEfUYD04Vi+/g= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:19 +0200 Message-Id: <20180727095421.386-19-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 18/20] intc/arm_gic: Improve traces 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_6 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add some traces to the ARM GIC to catch register accesses (distributor, (v)cpu interface and virtual interface), and to take into account virtualization extensions (print `vcpu` instead of `cpu` when needed). Also add some virtualization extensions specific traces: LR updating and maintenance IRQ generation. Signed-off-by: Luc Michel Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Peter Maydell --- hw/intc/arm_gic.c | 31 +++++++++++++++++++++++++------ hw/intc/trace-events | 12 ++++++++++-- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 6ff7da3e5d..c1b35fc1ee 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -182,12 +182,14 @@ static inline void gic_update_internal(GICState *s, b= ool virt) } else { gic_get_best_irq(s, cpu, &best_irq, &best_prio, &group); } =20 if (best_irq !=3D 1023) { - trace_gic_update_bestirq(cpu, best_irq, best_prio, - s->priority_mask[cpu_iface], s->running_priority[cpu_iface= ]); + trace_gic_update_bestirq(virt ? "vcpu" : "cpu", cpu, + best_irq, best_prio, + s->priority_mask[cpu_iface], + s->running_priority[cpu_iface]); } =20 irq_level =3D fiq_level =3D 0; =20 if (best_prio < s->priority_mask[cpu_iface]) { @@ -330,10 +332,11 @@ static void gic_update_maintenance(GICState *s) =20 for (cpu =3D 0; cpu < s->num_cpu; cpu++) { gic_compute_misr(s, cpu); maint_level =3D (s->h_hcr[cpu] & R_GICH_HCR_EN_MASK) && s->h_misr[= cpu]; =20 + trace_gic_update_maintenance_irq(cpu, maint_level); qemu_set_irq(s->maintenance_irq[cpu], maint_level); } } =20 static void gic_update_virt(GICState *s) @@ -595,11 +598,12 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, Me= mTxAttrs attrs) /* gic_get_current_pending_irq() will return 1022 or 1023 appropriately * for the case where this GIC supports grouping and the pending inter= rupt * is in the wrong group. */ irq =3D gic_get_current_pending_irq(s, cpu, attrs); - trace_gic_acknowledge_irq(gic_get_vcpu_real_id(cpu), irq); + trace_gic_acknowledge_irq(gic_is_vcpu(cpu) ? "vcpu" : "cpu", + gic_get_vcpu_real_id(cpu), irq); =20 if (irq >=3D GIC_MAXIRQ) { DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq); return irq; } @@ -1128,24 +1132,27 @@ static MemTxResult gic_dist_read(void *opaque, hwad= dr offset, uint64_t *data, unsigned size, MemTxAttrs attrs) { switch (size) { case 1: *data =3D gic_dist_readb(opaque, offset, attrs); - return MEMTX_OK; + break; case 2: *data =3D gic_dist_readb(opaque, offset, attrs); *data |=3D gic_dist_readb(opaque, offset + 1, attrs) << 8; - return MEMTX_OK; + break; case 4: *data =3D gic_dist_readb(opaque, offset, attrs); *data |=3D gic_dist_readb(opaque, offset + 1, attrs) << 8; *data |=3D gic_dist_readb(opaque, offset + 2, attrs) << 16; *data |=3D gic_dist_readb(opaque, offset + 3, attrs) << 24; - return MEMTX_OK; + break; default: return MEMTX_ERROR; } + + trace_gic_dist_read(offset, size, *data); + return MEMTX_OK; } =20 static void gic_dist_writeb(void *opaque, hwaddr offset, uint32_t value, MemTxAttrs attrs) { @@ -1480,10 +1487,12 @@ static void gic_dist_writel(void *opaque, hwaddr of= fset, } =20 static MemTxResult gic_dist_write(void *opaque, hwaddr offset, uint64_t da= ta, unsigned size, MemTxAttrs attrs) { + trace_gic_dist_write(offset, size, data); + switch (size) { case 1: gic_dist_writeb(opaque, offset, data, attrs); return MEMTX_OK; case 2: @@ -1636,16 +1645,22 @@ static MemTxResult gic_cpu_read(GICState *s, int cp= u, int offset, qemu_log_mask(LOG_GUEST_ERROR, "gic_cpu_read: Bad offset %x\n", (int)offset); *data =3D 0; break; } + + trace_gic_cpu_read(gic_is_vcpu(cpu) ? "vcpu" : "cpu", + gic_get_vcpu_real_id(cpu), offset, *data); return MEMTX_OK; } =20 static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset, uint32_t value, MemTxAttrs attrs) { + trace_gic_cpu_write(gic_is_vcpu(cpu) ? "vcpu" : "cpu", + gic_get_vcpu_real_id(cpu), offset, value); + switch (offset) { case 0x00: /* Control */ gic_set_cpu_control(s, cpu, value, attrs); break; case 0x04: /* Priority mask */ @@ -1892,19 +1907,22 @@ static MemTxResult gic_hyp_read(void *opaque, int c= pu, hwaddr addr, qemu_log_mask(LOG_GUEST_ERROR, "gic_hyp_read: Bad offset %" HWADDR_PRIx "\n", addr); return MEMTX_OK; } =20 + trace_gic_hyp_read(addr, *data); return MEMTX_OK; } =20 static MemTxResult gic_hyp_write(void *opaque, int cpu, hwaddr addr, uint64_t value, MemTxAttrs attrs) { GICState *s =3D ARM_GIC(opaque); int vcpu =3D cpu + GIC_NCPU; =20 + trace_gic_hyp_write(addr, value); + switch (addr) { case A_GICH_HCR: /* Hypervisor Control */ s->h_hcr[cpu] =3D value & GICH_HCR_MASK; break; =20 @@ -1924,10 +1942,11 @@ static MemTxResult gic_hyp_write(void *opaque, int = cpu, hwaddr addr, if (lr_idx > s->num_lrs) { return MEMTX_OK; } =20 s->h_lr[lr_idx][cpu] =3D value & GICH_LR_MASK; + trace_gic_lr_entry(cpu, lr_idx, s->h_lr[lr_idx][cpu]); break; } =20 default: qemu_log_mask(LOG_GUEST_ERROR, diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 5fb18e65c9..81c7c399f7 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -90,13 +90,21 @@ aspeed_vic_write(uint64_t offset, unsigned size, uint32= _t data) "To 0x%" PRIx64 =20 # hw/intc/arm_gic.c gic_enable_irq(int irq) "irq %d enabled" gic_disable_irq(int irq) "irq %d disabled" gic_set_irq(int irq, int level, int cpumask, int target) "irq %d level %d = cpumask 0x%x target 0x%x" -gic_update_bestirq(int cpu, int irq, int prio, int priority_mask, int runn= ing_priority) "cpu %d irq %d priority %d cpu priority mask %d cpu running p= riority %d" +gic_update_bestirq(const char *s, int cpu, int irq, int prio, int priority= _mask, int running_priority) "%s %d irq %d priority %d cpu priority mask %d= cpu running priority %d" gic_update_set_irq(int cpu, const char *name, int level) "cpu[%d]: %s =3D = %d" -gic_acknowledge_irq(int cpu, int irq) "cpu %d acknowledged irq %d" +gic_acknowledge_irq(const char *s, int cpu, int irq) "%s %d acknowledged i= rq %d" +gic_cpu_write(const char *s, int cpu, int addr, uint32_t val) "%s %d iface= write at 0x%08x 0x%08" PRIx32 +gic_cpu_read(const char *s, int cpu, int addr, uint32_t val) "%s %d iface = read at 0x%08x: 0x%08" PRIx32 +gic_hyp_read(int addr, uint32_t val) "hyp read at 0x%08x: 0x%08" PRIx32 +gic_hyp_write(int addr, uint32_t val) "hyp write at 0x%08x: 0x%08" PRIx32 +gic_dist_read(int addr, unsigned int size, uint32_t val) "dist read at 0x%= 08x size %u: 0x%08" PRIx32 +gic_dist_write(int addr, unsigned int size, uint32_t val) "dist write at 0= x%08x size %u: 0x%08" PRIx32 +gic_lr_entry(int cpu, int entry, uint32_t val) "cpu %d: new lr entry %d: 0= x%08" PRIx32 +gic_update_maintenance_irq(int cpu, int val) "cpu %d: maintenance =3D %d" =20 # hw/intc/arm_gicv3_cpuif.c gicv3_icc_pmr_read(uint32_t cpu, uint64_t val) "GICv3 ICC_PMR read cpu 0x%= x value 0x%" PRIx64 gicv3_icc_pmr_write(uint32_t cpu, uint64_t val) "GICv3 ICC_PMR write cpu 0= x%x value 0x%" PRIx64 gicv3_icc_bpr_read(int grp, uint32_t cpu, uint64_t val) "GICv3 ICC_BPR%d r= ead cpu 0x%x value 0x%" PRIx64 --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532686024033477.74930388246673; Fri, 27 Jul 2018 03:07:04 -0700 (PDT) Received: from localhost ([::1]:40106 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizeI-0005Po-Sa for importer@patchew.org; Fri, 27 Jul 2018 06:07:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58404) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSm-0003vx-G3 for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSj-0006Oo-K6 for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from greensocs.com ([193.104.36.180]:47517) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSZ-00068l-Cs; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 5A956443557; Fri, 27 Jul 2018 11:54:53 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id a9VFysUyp8CO; Fri, 27 Jul 2018 11:54:52 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 9D82B44B82A; Fri, 27 Jul 2018 11:54:50 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 4A471400DC8; Fri, 27 Jul 2018 11:54:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685293; bh=O6QDoy0sN0FD36p5qvRQ8d/ZzOPZvnpLjxX+1yuYjJo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=T1uoHYomK7n3X2heAVMY+91hUXKSeK2Q1ROxPEtK8iY1TdPDC07d9YoBYEiVkXZn1 c6T0BLQBI3nsRJnuT3qQtWsKSgx+31GMPVQi/0zfdy5EZDHcDCvJLj/K1vcNq5s530 KaCW+Z1Dx8Vg5AP4L2QQ0AoGwMByoHFwFeMpg6VY= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=6UXUneoJ; dkim=pass (1024-bit key) header.d=greensocs.com header.b=6UXUneoJ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685290; bh=O6QDoy0sN0FD36p5qvRQ8d/ZzOPZvnpLjxX+1yuYjJo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=6UXUneoJpv2JnlBIcN3fV24YaDq+zPUQTRQb7fUiH/anQ2WQuAYxWk5UxHzYGxjwy QO4s4p/txEbsWHVJWRfyDlLC5D4HtIhxgl9YTfHug0/RMA+xHCK3TPm5uDkrX0dGaY Rnosa1fUL4x8sggIbFl01HP8XmXi3clwhSk0P+/w= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685290; bh=O6QDoy0sN0FD36p5qvRQ8d/ZzOPZvnpLjxX+1yuYjJo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=6UXUneoJpv2JnlBIcN3fV24YaDq+zPUQTRQb7fUiH/anQ2WQuAYxWk5UxHzYGxjwy QO4s4p/txEbsWHVJWRfyDlLC5D4HtIhxgl9YTfHug0/RMA+xHCK3TPm5uDkrX0dGaY Rnosa1fUL4x8sggIbFl01HP8XmXi3clwhSk0P+/w= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:20 +0200 Message-Id: <20180727095421.386-20-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 19/20] xlnx-zynqmp: Improve GIC wiring and MMIO mapping 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This commit improve the way the GIC is realized and connected in the ZynqMP SoC. The security extensions are enabled only if requested in the machine state. The same goes for the virtualization extensions. All the GIC to APU CPU(s) IRQ lines are now connected, including FIQ, vIRQ and vFIQ. The missing CPU to GIC timers IRQ connections are also added (HYP and SEC timers). The GIC maintenance IRQs are back-wired to the correct GIC PPIs. Finally, the MMIO mappings are reworked to take into account the ZynqMP specifics. The GIC (v)CPU interface is aliased 16 times: * for the first 0x1000 bytes from 0xf9010000 to 0xf901f000 * for the second 0x1000 bytes from 0xf9020000 to 0xf902f000 Mappings of the virtual interface and virtual CPU interface are mapped only when virtualization extensions are requested. The XlnxZynqMPGICRegion struct has been enhanced to be able to catch all this information. Signed-off-by: Luc Michel Reviewed-by: Edgar E. Iglesias --- hw/arm/xlnx-zynqmp.c | 92 ++++++++++++++++++++++++++++++++---- include/hw/arm/xlnx-zynqmp.h | 4 +- 2 files changed, 86 insertions(+), 10 deletions(-) diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index 8de4868eb9..c195040350 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -27,16 +27,21 @@ =20 #define GIC_NUM_SPI_INTR 160 =20 #define ARM_PHYS_TIMER_PPI 30 #define ARM_VIRT_TIMER_PPI 27 +#define ARM_HYP_TIMER_PPI 26 +#define ARM_SEC_TIMER_PPI 29 +#define GIC_MAINTENANCE_PPI 25 =20 #define GEM_REVISION 0x40070106 =20 #define GIC_BASE_ADDR 0xf9000000 #define GIC_DIST_ADDR 0xf9010000 #define GIC_CPU_ADDR 0xf9020000 +#define GIC_VIFACE_ADDR 0xf9040000 +#define GIC_VCPU_ADDR 0xf9060000 =20 #define SATA_INTR 133 #define SATA_ADDR 0xFD0C0000 #define SATA_NUM_PORTS 2 =20 @@ -109,15 +114,58 @@ static const int adma_ch_intr[XLNX_ZYNQMP_NUM_ADMA_CH= ] =3D { }; =20 typedef struct XlnxZynqMPGICRegion { int region_index; uint32_t address; + uint32_t offset; + bool virt; } XlnxZynqMPGICRegion; =20 static const XlnxZynqMPGICRegion xlnx_zynqmp_gic_regions[] =3D { - { .region_index =3D 0, .address =3D GIC_DIST_ADDR, }, - { .region_index =3D 1, .address =3D GIC_CPU_ADDR, }, + /* Distributor */ + { + .region_index =3D 0, + .address =3D GIC_DIST_ADDR, + .offset =3D 0, + .virt =3D false + }, + + /* CPU interface */ + { + .region_index =3D 1, + .address =3D GIC_CPU_ADDR, + .offset =3D 0, + .virt =3D false + }, + { + .region_index =3D 1, + .address =3D GIC_CPU_ADDR + 0x10000, + .offset =3D 0x1000, + .virt =3D false + }, + + /* Virtual interface */ + { + .region_index =3D 2, + .address =3D GIC_VIFACE_ADDR, + .offset =3D 0, + .virt =3D true + }, + + /* Virtual CPU interface */ + { + .region_index =3D 3, + .address =3D GIC_VCPU_ADDR, + .offset =3D 0, + .virt =3D true + }, + { + .region_index =3D 3, + .address =3D GIC_VCPU_ADDR + 0x10000, + .offset =3D 0x1000, + .virt =3D true + }, }; =20 static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index) { return GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index; @@ -279,10 +327,13 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Err= or **errp) } =20 qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32= ); qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2); qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", num_apus); + qdev_prop_set_bit(DEVICE(&s->gic), "has-security-extensions", s->secur= e); + qdev_prop_set_bit(DEVICE(&s->gic), + "has-virtualization-extensions", s->virt); =20 /* Realize APUs before realizing the GIC. KVM requires this. */ for (i =3D 0; i < num_apus; i++) { char *name; =20 @@ -323,38 +374,63 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Err= or **errp) =20 assert(ARRAY_SIZE(xlnx_zynqmp_gic_regions) =3D=3D XLNX_ZYNQMP_GIC_REGI= ONS); for (i =3D 0; i < XLNX_ZYNQMP_GIC_REGIONS; i++) { SysBusDevice *gic =3D SYS_BUS_DEVICE(&s->gic); const XlnxZynqMPGICRegion *r =3D &xlnx_zynqmp_gic_regions[i]; - MemoryRegion *mr =3D sysbus_mmio_get_region(gic, r->region_index); + MemoryRegion *mr; uint32_t addr =3D r->address; int j; =20 - sysbus_mmio_map(gic, r->region_index, addr); + if (r->virt && !s->virt) { + continue; + } =20 + mr =3D sysbus_mmio_get_region(gic, r->region_index); for (j =3D 0; j < XLNX_ZYNQMP_GIC_ALIASES; j++) { MemoryRegion *alias =3D &s->gic_mr[i][j]; =20 - addr +=3D XLNX_ZYNQMP_GIC_REGION_SIZE; memory_region_init_alias(alias, OBJECT(s), "zynqmp-gic-alias",= mr, - 0, XLNX_ZYNQMP_GIC_REGION_SIZE); + r->offset, XLNX_ZYNQMP_GIC_REGION_SIZ= E); memory_region_add_subregion(system_memory, addr, alias); + + addr +=3D XLNX_ZYNQMP_GIC_REGION_SIZE; } } =20 for (i =3D 0; i < num_apus; i++) { qemu_irq irq; =20 sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i, qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]), ARM_CPU_IRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus, + qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]), + ARM_CPU_FIQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus * 2, + qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]), + ARM_CPU_VIRQ)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus * 3, + qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]), + ARM_CPU_VFIQ)); irq =3D qdev_get_gpio_in(DEVICE(&s->gic), arm_gic_ppi_index(i, ARM_PHYS_TIMER_PPI)); - qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 0, irq); + qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), GTIMER_PHYS, irq); irq =3D qdev_get_gpio_in(DEVICE(&s->gic), arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI)); - qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq); + qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), GTIMER_VIRT, irq); + irq =3D qdev_get_gpio_in(DEVICE(&s->gic), + arm_gic_ppi_index(i, ARM_HYP_TIMER_PPI)); + qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), GTIMER_HYP, irq); + irq =3D qdev_get_gpio_in(DEVICE(&s->gic), + arm_gic_ppi_index(i, ARM_SEC_TIMER_PPI)); + qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), GTIMER_SEC, irq); + + if (s->virt) { + irq =3D qdev_get_gpio_in(DEVICE(&s->gic), + arm_gic_ppi_index(i, GIC_MAINTENANCE_PP= I)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + num_apus * 4, = irq); + } } =20 if (s->has_rpu) { info_report("The 'has_rpu' property is no longer required, to use = the " "RPUs just use -smp 6."); diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 82b6ec2486..98f925ab84 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -51,20 +51,20 @@ =20 #define XLNX_ZYNQMP_NUM_OCM_BANKS 4 #define XLNX_ZYNQMP_OCM_RAM_0_ADDRESS 0xFFFC0000 #define XLNX_ZYNQMP_OCM_RAM_SIZE 0x10000 =20 -#define XLNX_ZYNQMP_GIC_REGIONS 2 +#define XLNX_ZYNQMP_GIC_REGIONS 6 =20 /* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k off= sets * and under-decodes the 64k region. This mirrors the 4k regions to every = 4k * aligned address in the 64k region. To implement each GIC region needs a * number of memory region aliases. */ =20 #define XLNX_ZYNQMP_GIC_REGION_SIZE 0x1000 -#define XLNX_ZYNQMP_GIC_ALIASES (0x10000 / XLNX_ZYNQMP_GIC_REGION_SIZE= - 1) +#define XLNX_ZYNQMP_GIC_ALIASES (0x10000 / XLNX_ZYNQMP_GIC_REGION_SIZE) =20 #define XLNX_ZYNQMP_MAX_LOW_RAM_SIZE 0x80000000ull =20 #define XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE 0x800000000ull #define XLNX_ZYNQMP_HIGH_RAM_START 0x800000000ull --=20 2.18.0 From nobody Tue May 21 00:58:27 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532686187893593.3417281069304; Fri, 27 Jul 2018 03:09:47 -0700 (PDT) Received: from localhost ([::1]:40119 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizgf-00078f-4U for importer@patchew.org; Fri, 27 Jul 2018 06:09:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58394) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSm-0003vW-9O for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fizSj-0006Oj-GO for qemu-devel@nongnu.org; Fri, 27 Jul 2018 05:55:08 -0400 Received: from greensocs.com ([193.104.36.180]:47535) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fizSZ-0006B0-Kk; Fri, 27 Jul 2018 05:54:55 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id A1732443572; Fri, 27 Jul 2018 11:54:53 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BHXmSf6Yr7mv; Fri, 27 Jul 2018 11:54:52 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 115A94434A7; Fri, 27 Jul 2018 11:54:51 +0200 (CEST) Received: from michell-laptop.bar.greensocs.com (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 9FF92400DC8; Fri, 27 Jul 2018 11:54:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685293; bh=uZEKjMi5WZD5BNpHU2rDoZN/EycDavakkg6gt1G4ncg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=5Nt/BstQM//qrzpDMhPn3Hv+GUyEKIaMQvD/SSpIzQ+ZmOJ8KOipeFZlLo0RPCbNK p4df/vzGKZrMP8KoS3rbjWpkQ7PSafYcePMbu971C1tiR3l+vQIjQMaMJwFwJyaBME a/zU0zRzjPSGX0a/Y5k71bEl+vgbjJ9D8kzGn4Q4= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=o4AOi6QW; dkim=pass (1024-bit key) header.d=greensocs.com header.b=JOojs2vF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685291; bh=uZEKjMi5WZD5BNpHU2rDoZN/EycDavakkg6gt1G4ncg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=o4AOi6QWxrzISVlhfkMe23tIvM5TN837lDKFsFfM0+Nt0tB7q2vo0zRRloTq0gJdb T9ICQKoA/+zGt+ZJYvo8hUgJsjCw2EgoUORH6P8q+HycI0OVoyq1W5SvHhUfHWygxv DRMYjH6mbxkgp03eE2Vh2IJDq7qHXwihd/OzEibw= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1532685290; bh=uZEKjMi5WZD5BNpHU2rDoZN/EycDavakkg6gt1G4ncg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=JOojs2vFMlGcXXJn0Hs6RTAnRHZfaQ5IbMXY+dBRRWxnN1VKcvRWPzvQkxRk3JUU2 8l5ZsR1RlskSkmM98dNP6KQw7BKRuAtVnhYo1iL5i/87LRpIE9tNIPPmGJ3mjXBt/1 D/Q4eW/izRwfSxifw2MMzchptU0kpLpFXXeMNJV0= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2018 11:54:21 +0200 Message-Id: <20180727095421.386-21-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180727095421.386-1-luc.michel@greensocs.com> References: <20180727095421.386-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 20/20] arm/virt: Add support for GICv2 virtualization extensions 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: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 3 invalid signatures) X-ZohoMail: RDKM_2 RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add support for GICv2 virtualization extensions by mapping the necessary I/O regions and connecting the maintenance IRQ lines. Declare those additions in the device tree and in the ACPI tables. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 6 +++-- hw/arm/virt.c | 52 +++++++++++++++++++++++++++++++++------- include/hw/arm/virt.h | 4 +++- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 6ea47e2588..ce31abd62c 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -657,21 +657,23 @@ build_madt(GArray *table_data, BIOSLinker *linker, Vi= rtMachineState *vms) =20 gicc->type =3D ACPI_APIC_GENERIC_CPU_INTERFACE; gicc->length =3D sizeof(*gicc); if (vms->gic_version =3D=3D 2) { gicc->base_address =3D cpu_to_le64(memmap[VIRT_GIC_CPU].base); + gicc->gich_base_address =3D cpu_to_le64(memmap[VIRT_GIC_HYP].b= ase); + gicc->gicv_base_address =3D cpu_to_le64(memmap[VIRT_GIC_VCPU].= base); } gicc->cpu_interface_number =3D cpu_to_le32(i); gicc->arm_mpidr =3D cpu_to_le64(armcpu->mp_affinity); gicc->uid =3D cpu_to_le32(i); gicc->flags =3D cpu_to_le32(ACPI_MADT_GICC_ENABLED); =20 if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) { gicc->performance_interrupt =3D cpu_to_le32(PPI(VIRTUAL_PMU_IR= Q)); } - if (vms->virt && vms->gic_version =3D=3D 3) { - gicc->vgic_interrupt =3D cpu_to_le32(PPI(ARCH_GICV3_MAINT_IRQ)= ); + if (vms->virt) { + gicc->vgic_interrupt =3D cpu_to_le32(PPI(ARCH_GIC_MAINT_IRQ)); } } =20 if (vms->gic_version =3D=3D 3) { AcpiMadtGenericTranslator *gic_its; diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 281ddcdf6e..0807be985c 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -129,10 +129,12 @@ static const MemMapEntry a15memmap[] =3D { [VIRT_CPUPERIPHS] =3D { 0x08000000, 0x00020000 }, /* GIC distributor and CPU interfaces sit inside the CPU peripheral sp= ace */ [VIRT_GIC_DIST] =3D { 0x08000000, 0x00010000 }, [VIRT_GIC_CPU] =3D { 0x08010000, 0x00010000 }, [VIRT_GIC_V2M] =3D { 0x08020000, 0x00001000 }, + [VIRT_GIC_HYP] =3D { 0x08030000, 0x00010000 }, + [VIRT_GIC_VCPU] =3D { 0x08040000, 0x00010000 }, /* The space in between here is reserved for GICv3 CPU/vCPU/HYP */ [VIRT_GIC_ITS] =3D { 0x08080000, 0x00020000 }, /* This redistributor space allows up to 2*64kB*123 CPUs */ [VIRT_GIC_REDIST] =3D { 0x080A0000, 0x00F60000 }, [VIRT_UART] =3D { 0x09000000, 0x00001000 }, @@ -438,22 +440,37 @@ static void fdt_add_gic_node(VirtMachineState *vms) 2, vms->memmap[VIRT_GIC_REDIST2].= size); } =20 if (vms->virt) { qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", - GIC_FDT_IRQ_TYPE_PPI, ARCH_GICV3_MAINT_= IRQ, + GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IR= Q, GIC_FDT_IRQ_FLAGS_LEVEL_HI); } } else { /* 'cortex-a15-gic' means 'GIC v2' */ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "arm,cortex-a15-gic"); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", - 2, vms->memmap[VIRT_GIC_DIST].base, - 2, vms->memmap[VIRT_GIC_DIST].size, - 2, vms->memmap[VIRT_GIC_CPU].base, - 2, vms->memmap[VIRT_GIC_CPU].size); + if (!vms->virt) { + qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + 2, vms->memmap[VIRT_GIC_DIST].bas= e, + 2, vms->memmap[VIRT_GIC_DIST].siz= e, + 2, vms->memmap[VIRT_GIC_CPU].base, + 2, vms->memmap[VIRT_GIC_CPU].size= ); + } else { + qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + 2, vms->memmap[VIRT_GIC_DIST].bas= e, + 2, vms->memmap[VIRT_GIC_DIST].siz= e, + 2, vms->memmap[VIRT_GIC_CPU].base, + 2, vms->memmap[VIRT_GIC_CPU].size, + 2, vms->memmap[VIRT_GIC_HYP].base, + 2, vms->memmap[VIRT_GIC_HYP].size, + 2, vms->memmap[VIRT_GIC_VCPU].bas= e, + 2, vms->memmap[VIRT_GIC_VCPU].siz= e); + qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", + GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IR= Q, + GIC_FDT_IRQ_FLAGS_LEVEL_HI); + } } =20 qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->gic_phandle); g_free(nodename); } @@ -571,10 +588,15 @@ static void create_gic(VirtMachineState *vms, qemu_ir= q *pic) vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_= SIZE; =20 qdev_prop_set_uint32(gicdev, "redist-region-count[1]", MIN(smp_cpus - redist0_count, redist1_capacity)); } + } else { + if (!kvm_irqchip_in_kernel()) { + qdev_prop_set_bit(gicdev, "has-virtualization-extensions", + vms->virt); + } } qdev_init_nofail(gicdev); gicbusdev =3D SYS_BUS_DEVICE(gicdev); sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base); if (type =3D=3D 3) { @@ -582,10 +604,14 @@ static void create_gic(VirtMachineState *vms, qemu_ir= q *pic) if (nb_redist_regions =3D=3D 2) { sysbus_mmio_map(gicbusdev, 2, vms->memmap[VIRT_GIC_REDIST2].ba= se); } } else { sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base); + if (vms->virt) { + sysbus_mmio_map(gicbusdev, 2, vms->memmap[VIRT_GIC_HYP].base); + sysbus_mmio_map(gicbusdev, 3, vms->memmap[VIRT_GIC_VCPU].base); + } } =20 /* Wire the outputs from each CPU's generic timer and the GICv3 * maintenance interrupt signal to the appropriate GIC PPI inputs, * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inpu= ts. @@ -608,13 +634,21 @@ static void create_gic(VirtMachineState *vms, qemu_ir= q *pic) qdev_connect_gpio_out(cpudev, irq, qdev_get_gpio_in(gicdev, ppibase + timer_irq[irq= ])); } =20 - qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",= 0, - qdev_get_gpio_in(gicdev, ppibase - + ARCH_GICV3_MAINT_IR= Q)); + if (type =3D=3D 3) { + qemu_irq irq =3D qdev_get_gpio_in(gicdev, + ppibase + ARCH_GIC_MAINT_IRQ); + qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interru= pt", + 0, irq); + } else if (vms->virt) { + qemu_irq irq =3D qdev_get_gpio_in(gicdev, + ppibase + ARCH_GIC_MAINT_IRQ); + sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq); + } + qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, qdev_get_gpio_in(gicdev, ppibase + VIRTUAL_PMU_IRQ)); =20 sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_= IRQ)); diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 9a870ccb6a..4cc57a7ef6 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -40,11 +40,11 @@ =20 #define NUM_GICV2M_SPIS 64 #define NUM_VIRTIO_TRANSPORTS 32 #define NUM_SMMU_IRQS 4 =20 -#define ARCH_GICV3_MAINT_IRQ 9 +#define ARCH_GIC_MAINT_IRQ 9 =20 #define ARCH_TIMER_VIRT_IRQ 11 #define ARCH_TIMER_S_EL1_IRQ 13 #define ARCH_TIMER_NS_EL1_IRQ 14 #define ARCH_TIMER_NS_EL2_IRQ 10 @@ -58,10 +58,12 @@ enum { VIRT_MEM, VIRT_CPUPERIPHS, VIRT_GIC_DIST, VIRT_GIC_CPU, VIRT_GIC_V2M, + VIRT_GIC_HYP, + VIRT_GIC_VCPU, VIRT_GIC_ITS, VIRT_GIC_REDIST, VIRT_GIC_REDIST2, VIRT_SMMU, VIRT_UART, --=20 2.18.0