From mboxrd@z Thu Jan 1 00:00:00 1970 From: Auger Eric Subject: Re: [kvm-unit-tests PATCH v6 06/11] arm/arm64: add initial gicv2 support Date: Wed, 23 Nov 2016 11:38:28 +0100 Message-ID: <1c53a385-dd4a-77ab-4548-0e9b9654755c@redhat.com> References: <1479157719-31021-1-git-send-email-drjones@redhat.com> <1479157719-31021-7-git-send-email-drjones@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Cc: pbonzini@redhat.com, andre.przywara@arm.com, peter.maydell@linaro.org, alex.bennee@linaro.org, marc.zyngier@arm.com, christoffer.dall@linaro.org To: Andrew Jones , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, qemu-devel@nongnu.org, qemu-arm@nongnu.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:58800 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934274AbcKWKid (ORCPT ); Wed, 23 Nov 2016 05:38:33 -0500 In-Reply-To: <1479157719-31021-7-git-send-email-drjones@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: Hi, On 14/11/2016 22:08, Andrew Jones wrote: > Add some gicv2 support. This just adds init and enable > functions, allowing unit tests to start messing with it. > > Reviewed-by: Andre Przywara > Signed-off-by: Andrew Jones > > --- > v6: added comments (register offset headers) [Alex] > v5: share/use only the modern register names [Andre] > v4: > - only take defines from kernel we need now [Andre] > - moved defines to asm/gic.h so they'll be shared with v3 [drew] > - simplify enable by not caring if we reinit the distributor [drew] > - init all GICD_INT_DEF_PRI_X4 registers [Eric] > --- > arm/Makefile.common | 1 + > lib/arm/asm/gic-v2.h | 34 ++++++++++++++++++++++ > lib/arm/asm/gic.h | 39 ++++++++++++++++++++++++++ > lib/arm/gic.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/arm64/asm/gic-v2.h | 1 + > lib/arm64/asm/gic.h | 1 + > 6 files changed, 152 insertions(+) > create mode 100644 lib/arm/asm/gic-v2.h > create mode 100644 lib/arm/asm/gic.h > create mode 100644 lib/arm/gic.c > create mode 100644 lib/arm64/asm/gic-v2.h > create mode 100644 lib/arm64/asm/gic.h > > diff --git a/arm/Makefile.common b/arm/Makefile.common > index f37b5c2a3de4..6f56015c43c4 100644 > --- a/arm/Makefile.common > +++ b/arm/Makefile.common > @@ -46,6 +46,7 @@ cflatobjs += lib/arm/mmu.o > cflatobjs += lib/arm/bitops.o > cflatobjs += lib/arm/psci.o > cflatobjs += lib/arm/smp.o > +cflatobjs += lib/arm/gic.o > > libeabi = lib/arm/libeabi.a > eabiobjs = lib/arm/eabi_compat.o > diff --git a/lib/arm/asm/gic-v2.h b/lib/arm/asm/gic-v2.h > new file mode 100644 > index 000000000000..c2d5fecd4886 > --- /dev/null > +++ b/lib/arm/asm/gic-v2.h > @@ -0,0 +1,34 @@ > +/* > + * All GIC* defines are lifted from include/linux/irqchip/arm-gic.h > + * > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. > + */ > +#ifndef _ASMARM_GIC_V2_H_ > +#define _ASMARM_GIC_V2_H_ > + > +#ifndef _ASMARM_GIC_H_ > +#error Do not directly include . Include > +#endif > + > +#define GICD_ENABLE 0x1 > +#define GICC_ENABLE 0x1 > + > +#ifndef __ASSEMBLY__ > + > +struct gicv2_data { > + void *dist_base; > + void *cpu_base; > + unsigned int irq_nr; > +}; > +extern struct gicv2_data gicv2_data; > + > +#define gicv2_dist_base() (gicv2_data.dist_base) > +#define gicv2_cpu_base() (gicv2_data.cpu_base) > + > +extern int gicv2_init(void); > +extern void gicv2_enable_defaults(void); > + > +#endif /* !__ASSEMBLY__ */ > +#endif /* _ASMARM_GIC_V2_H_ */ > diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h > new file mode 100644 > index 000000000000..e3580bd1d42d > --- /dev/null > +++ b/lib/arm/asm/gic.h > @@ -0,0 +1,39 @@ > +/* > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. > + */ > +#ifndef _ASMARM_GIC_H_ > +#define _ASMARM_GIC_H_ > + > +#include > + > +/* Distributor registers */ > +#define GICD_CTLR 0x0000 > +#define GICD_TYPER 0x0004 > +#define GICD_ISENABLER 0x0100 > +#define GICD_IPRIORITYR 0x0400 > + > +#define GICD_TYPER_IRQS(typer) ((((typer) & 0x1f) + 1) * 32) > +#define GICD_INT_EN_SET_SGI 0x0000ffff > +#define GICD_INT_DEF_PRI_X4 0xa0a0a0a0 > + > +/* CPU interface registers */ > +#define GICC_CTLR 0x0000 > +#define GICC_PMR 0x0004 > + > +#define GICC_INT_PRI_THRESHOLD 0xf0 > + > +#ifndef __ASSEMBLY__ > + > +/* > + * gic_init will try to find all known gics, and then > + * initialize the gic data for the one found. > + * returns > + * 0 : no gic was found > + * > 0 : the gic version of the gic found > + */ > +extern int gic_init(void); > + > +#endif /* !__ASSEMBLY__ */ > +#endif /* _ASMARM_GIC_H_ */ > diff --git a/lib/arm/gic.c b/lib/arm/gic.c > new file mode 100644 > index 000000000000..d655105e058b > --- /dev/null > +++ b/lib/arm/gic.c > @@ -0,0 +1,76 @@ > +/* > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. > + */ > +#include > +#include > +#include > + > +struct gicv2_data gicv2_data; > + > +/* > + * Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt > + */ > +static bool > +gic_get_dt_bases(const char *compatible, void **base1, void **base2) > +{ > + struct dt_pbus_reg reg; > + struct dt_device gic; > + struct dt_bus bus; > + int node, ret; > + > + dt_bus_init_defaults(&bus); > + dt_device_init(&gic, &bus, NULL); > + > + node = dt_device_find_compatible(&gic, compatible); > + assert(node >= 0 || node == -FDT_ERR_NOTFOUND); > + > + if (node == -FDT_ERR_NOTFOUND) > + return false; > + > + dt_device_bind_node(&gic, node); > + > + ret = dt_pbus_translate(&gic, 0, ®); > + assert(ret == 0); > + *base1 = ioremap(reg.addr, reg.size); > + > + ret = dt_pbus_translate(&gic, 1, ®); > + assert(ret == 0); > + *base2 = ioremap(reg.addr, reg.size); > + > + return true; > +} > + > +int gicv2_init(void) > +{ > + return gic_get_dt_bases("arm,cortex-a15-gic", > + &gicv2_data.dist_base, &gicv2_data.cpu_base); > +} > + > +int gic_init(void) > +{ > + if (gicv2_init()) > + return 2; > + return 0; > +} > + > +void gicv2_enable_defaults(void) > +{ > + void *dist = gicv2_dist_base(); > + void *cpu_base = gicv2_cpu_base(); > + unsigned int i; > + > + gicv2_data.irq_nr = GICD_TYPER_IRQS(readl(dist + GICD_TYPER)); > + if (gicv2_data.irq_nr > 1020) > + gicv2_data.irq_nr = 1020; > + > + for (i = 0; i < gicv2_data.irq_nr; i += 4) > + writel(GICD_INT_DEF_PRI_X4, dist + GICD_IPRIORITYR + i); > + > + writel(GICD_INT_EN_SET_SGI, dist + GICD_ISENABLER + 0); > + writel(GICD_ENABLE, dist + GICD_CTLR); > + > + writel(GICC_INT_PRI_THRESHOLD, cpu_base + GICC_PMR); > + writel(GICC_ENABLE, cpu_base + GICC_CTLR); > +} > diff --git a/lib/arm64/asm/gic-v2.h b/lib/arm64/asm/gic-v2.h > new file mode 100644 > index 000000000000..52226624a209 > --- /dev/null > +++ b/lib/arm64/asm/gic-v2.h > @@ -0,0 +1 @@ > +#include "../../arm/asm/gic-v2.h" > diff --git a/lib/arm64/asm/gic.h b/lib/arm64/asm/gic.h > new file mode 100644 > index 000000000000..e5eb302a31b4 > --- /dev/null > +++ b/lib/arm64/asm/gic.h > @@ -0,0 +1 @@ > +#include "../../arm/asm/gic.h" > Reviewed-by: Eric Auger Eric From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53059) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c9Uwu-0000Ce-QL for qemu-devel@nongnu.org; Wed, 23 Nov 2016 05:38:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c9Uwt-0001am-BX for qemu-devel@nongnu.org; Wed, 23 Nov 2016 05:38:44 -0500 References: <1479157719-31021-1-git-send-email-drjones@redhat.com> <1479157719-31021-7-git-send-email-drjones@redhat.com> From: Auger Eric Message-ID: <1c53a385-dd4a-77ab-4548-0e9b9654755c@redhat.com> Date: Wed, 23 Nov 2016 11:38:28 +0100 MIME-Version: 1.0 In-Reply-To: <1479157719-31021-7-git-send-email-drjones@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [kvm-unit-tests PATCH v6 06/11] arm/arm64: add initial gicv2 support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Andrew Jones , kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, qemu-devel@nongnu.org, qemu-arm@nongnu.org Cc: pbonzini@redhat.com, andre.przywara@arm.com, peter.maydell@linaro.org, alex.bennee@linaro.org, marc.zyngier@arm.com, christoffer.dall@linaro.org Hi, On 14/11/2016 22:08, Andrew Jones wrote: > Add some gicv2 support. This just adds init and enable > functions, allowing unit tests to start messing with it. > > Reviewed-by: Andre Przywara > Signed-off-by: Andrew Jones > > --- > v6: added comments (register offset headers) [Alex] > v5: share/use only the modern register names [Andre] > v4: > - only take defines from kernel we need now [Andre] > - moved defines to asm/gic.h so they'll be shared with v3 [drew] > - simplify enable by not caring if we reinit the distributor [drew] > - init all GICD_INT_DEF_PRI_X4 registers [Eric] > --- > arm/Makefile.common | 1 + > lib/arm/asm/gic-v2.h | 34 ++++++++++++++++++++++ > lib/arm/asm/gic.h | 39 ++++++++++++++++++++++++++ > lib/arm/gic.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/arm64/asm/gic-v2.h | 1 + > lib/arm64/asm/gic.h | 1 + > 6 files changed, 152 insertions(+) > create mode 100644 lib/arm/asm/gic-v2.h > create mode 100644 lib/arm/asm/gic.h > create mode 100644 lib/arm/gic.c > create mode 100644 lib/arm64/asm/gic-v2.h > create mode 100644 lib/arm64/asm/gic.h > > diff --git a/arm/Makefile.common b/arm/Makefile.common > index f37b5c2a3de4..6f56015c43c4 100644 > --- a/arm/Makefile.common > +++ b/arm/Makefile.common > @@ -46,6 +46,7 @@ cflatobjs += lib/arm/mmu.o > cflatobjs += lib/arm/bitops.o > cflatobjs += lib/arm/psci.o > cflatobjs += lib/arm/smp.o > +cflatobjs += lib/arm/gic.o > > libeabi = lib/arm/libeabi.a > eabiobjs = lib/arm/eabi_compat.o > diff --git a/lib/arm/asm/gic-v2.h b/lib/arm/asm/gic-v2.h > new file mode 100644 > index 000000000000..c2d5fecd4886 > --- /dev/null > +++ b/lib/arm/asm/gic-v2.h > @@ -0,0 +1,34 @@ > +/* > + * All GIC* defines are lifted from include/linux/irqchip/arm-gic.h > + * > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. > + */ > +#ifndef _ASMARM_GIC_V2_H_ > +#define _ASMARM_GIC_V2_H_ > + > +#ifndef _ASMARM_GIC_H_ > +#error Do not directly include . Include > +#endif > + > +#define GICD_ENABLE 0x1 > +#define GICC_ENABLE 0x1 > + > +#ifndef __ASSEMBLY__ > + > +struct gicv2_data { > + void *dist_base; > + void *cpu_base; > + unsigned int irq_nr; > +}; > +extern struct gicv2_data gicv2_data; > + > +#define gicv2_dist_base() (gicv2_data.dist_base) > +#define gicv2_cpu_base() (gicv2_data.cpu_base) > + > +extern int gicv2_init(void); > +extern void gicv2_enable_defaults(void); > + > +#endif /* !__ASSEMBLY__ */ > +#endif /* _ASMARM_GIC_V2_H_ */ > diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h > new file mode 100644 > index 000000000000..e3580bd1d42d > --- /dev/null > +++ b/lib/arm/asm/gic.h > @@ -0,0 +1,39 @@ > +/* > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. > + */ > +#ifndef _ASMARM_GIC_H_ > +#define _ASMARM_GIC_H_ > + > +#include > + > +/* Distributor registers */ > +#define GICD_CTLR 0x0000 > +#define GICD_TYPER 0x0004 > +#define GICD_ISENABLER 0x0100 > +#define GICD_IPRIORITYR 0x0400 > + > +#define GICD_TYPER_IRQS(typer) ((((typer) & 0x1f) + 1) * 32) > +#define GICD_INT_EN_SET_SGI 0x0000ffff > +#define GICD_INT_DEF_PRI_X4 0xa0a0a0a0 > + > +/* CPU interface registers */ > +#define GICC_CTLR 0x0000 > +#define GICC_PMR 0x0004 > + > +#define GICC_INT_PRI_THRESHOLD 0xf0 > + > +#ifndef __ASSEMBLY__ > + > +/* > + * gic_init will try to find all known gics, and then > + * initialize the gic data for the one found. > + * returns > + * 0 : no gic was found > + * > 0 : the gic version of the gic found > + */ > +extern int gic_init(void); > + > +#endif /* !__ASSEMBLY__ */ > +#endif /* _ASMARM_GIC_H_ */ > diff --git a/lib/arm/gic.c b/lib/arm/gic.c > new file mode 100644 > index 000000000000..d655105e058b > --- /dev/null > +++ b/lib/arm/gic.c > @@ -0,0 +1,76 @@ > +/* > + * Copyright (C) 2016, Red Hat Inc, Andrew Jones > + * > + * This work is licensed under the terms of the GNU LGPL, version 2. > + */ > +#include > +#include > +#include > + > +struct gicv2_data gicv2_data; > + > +/* > + * Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt > + */ > +static bool > +gic_get_dt_bases(const char *compatible, void **base1, void **base2) > +{ > + struct dt_pbus_reg reg; > + struct dt_device gic; > + struct dt_bus bus; > + int node, ret; > + > + dt_bus_init_defaults(&bus); > + dt_device_init(&gic, &bus, NULL); > + > + node = dt_device_find_compatible(&gic, compatible); > + assert(node >= 0 || node == -FDT_ERR_NOTFOUND); > + > + if (node == -FDT_ERR_NOTFOUND) > + return false; > + > + dt_device_bind_node(&gic, node); > + > + ret = dt_pbus_translate(&gic, 0, ®); > + assert(ret == 0); > + *base1 = ioremap(reg.addr, reg.size); > + > + ret = dt_pbus_translate(&gic, 1, ®); > + assert(ret == 0); > + *base2 = ioremap(reg.addr, reg.size); > + > + return true; > +} > + > +int gicv2_init(void) > +{ > + return gic_get_dt_bases("arm,cortex-a15-gic", > + &gicv2_data.dist_base, &gicv2_data.cpu_base); > +} > + > +int gic_init(void) > +{ > + if (gicv2_init()) > + return 2; > + return 0; > +} > + > +void gicv2_enable_defaults(void) > +{ > + void *dist = gicv2_dist_base(); > + void *cpu_base = gicv2_cpu_base(); > + unsigned int i; > + > + gicv2_data.irq_nr = GICD_TYPER_IRQS(readl(dist + GICD_TYPER)); > + if (gicv2_data.irq_nr > 1020) > + gicv2_data.irq_nr = 1020; > + > + for (i = 0; i < gicv2_data.irq_nr; i += 4) > + writel(GICD_INT_DEF_PRI_X4, dist + GICD_IPRIORITYR + i); > + > + writel(GICD_INT_EN_SET_SGI, dist + GICD_ISENABLER + 0); > + writel(GICD_ENABLE, dist + GICD_CTLR); > + > + writel(GICC_INT_PRI_THRESHOLD, cpu_base + GICC_PMR); > + writel(GICC_ENABLE, cpu_base + GICC_CTLR); > +} > diff --git a/lib/arm64/asm/gic-v2.h b/lib/arm64/asm/gic-v2.h > new file mode 100644 > index 000000000000..52226624a209 > --- /dev/null > +++ b/lib/arm64/asm/gic-v2.h > @@ -0,0 +1 @@ > +#include "../../arm/asm/gic-v2.h" > diff --git a/lib/arm64/asm/gic.h b/lib/arm64/asm/gic.h > new file mode 100644 > index 000000000000..e5eb302a31b4 > --- /dev/null > +++ b/lib/arm64/asm/gic.h > @@ -0,0 +1 @@ > +#include "../../arm/asm/gic.h" > Reviewed-by: Eric Auger Eric