svn commit: r309616 - head/sys/arm/arm

Andrew Turner andrew at FreeBSD.org
Tue Dec 6 12:57:29 UTC 2016


Author: andrew
Date: Tue Dec  6 12:57:28 2016
New Revision: 309616
URL: https://svnweb.freebsd.org/changeset/base/309616

Log:
  Adda new common GIC header to handle the common parts of the GICv2 and
  GICv3 drivers. For now it just contains common distributor registers.
  
  Obtained from:	ABT Systems Ltd
  Sponsored by:	The FreeBSD Foundation

Added:
  head/sys/arm/arm/gic_common.h   (contents, props changed)
Modified:
  head/sys/arm/arm/gic.c

Modified: head/sys/arm/arm/gic.c
==============================================================================
--- head/sys/arm/arm/gic.c	Tue Dec  6 12:57:04 2016	(r309615)
+++ head/sys/arm/arm/gic.c	Tue Dec  6 12:57:28 2016	(r309616)
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #include <arm/arm/gic.h>
+#include <arm/arm/gic_common.h>
 
 #ifdef INTRNG
 #include "pic_if.h"
@@ -76,20 +77,6 @@ __FBSDID("$FreeBSD$");
 /* We are using GICv2 register naming */
 
 /* Distributor Registers */
-#define GICD_CTLR		0x000			/* v1 ICDDCR */
-#define GICD_TYPER		0x004			/* v1 ICDICTR */
-#define GICD_IIDR		0x008			/* v1 ICDIIDR */
-#define GICD_IGROUPR(n)		(0x0080 + ((n) * 4))	/* v1 ICDISER */
-#define GICD_ISENABLER(n)	(0x0100 + ((n) * 4))	/* v1 ICDISER */
-#define GICD_ICENABLER(n)	(0x0180 + ((n) * 4))	/* v1 ICDICER */
-#define GICD_ISPENDR(n)		(0x0200 + ((n) * 4))	/* v1 ICDISPR */
-#define GICD_ICPENDR(n)		(0x0280 + ((n) * 4))	/* v1 ICDICPR */
-#define GICD_ICACTIVER(n)	(0x0380 + ((n) * 4))	/* v1 ICDABR */
-#define GICD_IPRIORITYR(n)	(0x0400 + ((n) * 4))	/* v1 ICDIPR */
-#define GICD_ITARGETSR(n)	(0x0800 + ((n) * 4))	/* v1 ICDIPTR */
-#define GICD_ICFGR(n)		(0x0C00 + ((n) * 4))	/* v1 ICDICFR */
-#define GICD_SGIR(n)		(0x0F00 + ((n) * 4))	/* v1 ICDSGIR */
-#define  GICD_SGI_TARGET_SHIFT	16
 
 /* CPU Registers */
 #define GICC_CTLR		0x0000			/* v1 ICCICR */
@@ -107,14 +94,6 @@ __FBSDID("$FreeBSD$");
 #define	GIC_SUPPORT_SECEXT(_sc)	\
     ((_sc->typer & GICD_TYPER_SECURITYEXT) == GICD_TYPER_SECURITYEXT)
 
-/* First bit is a polarity bit (0 - low, 1 - high) */
-#define GICD_ICFGR_POL_LOW	(0 << 0)
-#define GICD_ICFGR_POL_HIGH	(1 << 0)
-#define GICD_ICFGR_POL_MASK	0x1
-/* Second bit is a trigger bit (0 - level, 1 - edge) */
-#define GICD_ICFGR_TRIG_LVL	(0 << 1)
-#define GICD_ICFGR_TRIG_EDGE	(1 << 1)
-#define GICD_ICFGR_TRIG_MASK	0x2
 
 #ifndef	GIC_DEFAULT_ICFGR_INIT
 #define	GIC_DEFAULT_ICFGR_INIT	0x00000000
@@ -192,14 +171,14 @@ static inline void
 gic_irq_unmask(struct arm_gic_softc *sc, u_int irq)
 {
 
-	gic_d_write_4(sc, GICD_ISENABLER(irq >> 5), (1UL << (irq & 0x1F)));
+	gic_d_write_4(sc, GICD_ISENABLER(irq), (1UL << (irq & 0x1F)));
 }
 
 static inline void
 gic_irq_mask(struct arm_gic_softc *sc, u_int irq)
 {
 
-	gic_d_write_4(sc, GICD_ICENABLER(irq >> 5), (1UL << (irq & 0x1F)));
+	gic_d_write_4(sc, GICD_ICENABLER(irq), (1UL << (irq & 0x1F)));
 }
 #endif
 
@@ -239,11 +218,11 @@ arm_gic_init_secondary(device_t dev)
 	arm_gic_map[cpu] = gic_cpu_mask(sc);
 
 	for (irq = 0; irq < sc->nirqs; irq += 4)
-		gic_d_write_4(sc, GICD_IPRIORITYR(irq >> 2), 0);
+		gic_d_write_4(sc, GICD_IPRIORITYR(irq), 0);
 
 	/* Set all the interrupts to be in Group 0 (secure) */
 	for (irq = 0; GIC_SUPPORT_SECEXT(sc) && irq < sc->nirqs; irq += 32) {
-		gic_d_write_4(sc, GICD_IGROUPR(irq >> 5), 0);
+		gic_d_write_4(sc, GICD_IGROUPR(irq), 0);
 	}
 
 	/* Enable CPU interface */
@@ -276,11 +255,11 @@ arm_gic_init_secondary(device_t dev)
 	arm_gic_map[PCPU_GET(cpuid)] = gic_cpu_mask(sc);
 
 	for (i = 0; i < sc->nirqs; i += 4)
-		gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
+		gic_d_write_4(sc, GICD_IPRIORITYR(i), 0);
 
 	/* Set all the interrupts to be in Group 0 (secure) */
 	for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) {
-		gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
+		gic_d_write_4(sc, GICD_IGROUPR(i), 0);
 	}
 
 	/* Enable CPU interface */
@@ -295,9 +274,9 @@ arm_gic_init_secondary(device_t dev)
 	/*
 	 * Activate the timer interrupts: virtual, secure, and non-secure.
 	 */
-	gic_d_write_4(sc, GICD_ISENABLER(27 >> 5), (1UL << (27 & 0x1F)));
-	gic_d_write_4(sc, GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F)));
-	gic_d_write_4(sc, GICD_ISENABLER(30 >> 5), (1UL << (30 & 0x1F)));
+	gic_d_write_4(sc, GICD_ISENABLER(27), (1UL << (27 & 0x1F)));
+	gic_d_write_4(sc, GICD_ISENABLER(29), (1UL << (29 & 0x1F)));
+	gic_d_write_4(sc, GICD_ISENABLER(30), (1UL << (30 & 0x1F)));
 }
 #endif /* INTRNG */
 #endif /* SMP */
@@ -484,18 +463,19 @@ arm_gic_attach(device_t dev)
 #endif
 
 	icciidr = gic_c_read_4(sc, GICC_IIDR);
-	device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n",
-			icciidr>>20, (icciidr>>16) & 0xF, (icciidr>>12) & 0xf,
-			(icciidr & 0xfff), sc->nirqs);
+	device_printf(dev,
+	    "pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n",
+	    GICD_IIDR_PROD(icciidr), GICD_IIDR_VAR(icciidr),
+	    GICD_IIDR_REV(icciidr), GICD_IIDR_IMPL(icciidr), sc->nirqs);
 
 	/* Set all global interrupts to be level triggered, active low. */
 	for (i = 32; i < sc->nirqs; i += 16) {
-		gic_d_write_4(sc, GICD_ICFGR(i >> 4), GIC_DEFAULT_ICFGR_INIT);
+		gic_d_write_4(sc, GICD_ICFGR(i), GIC_DEFAULT_ICFGR_INIT);
 	}
 
 	/* Disable all interrupts. */
 	for (i = 32; i < sc->nirqs; i += 32) {
-		gic_d_write_4(sc, GICD_ICENABLER(i >> 5), 0xFFFFFFFF);
+		gic_d_write_4(sc, GICD_ICENABLER(i), 0xFFFFFFFF);
 	}
 
 	/* Find the current cpu mask */
@@ -507,15 +487,15 @@ arm_gic_attach(device_t dev)
 	mask |= mask << 16;
 
 	for (i = 0; i < sc->nirqs; i += 4) {
-		gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
+		gic_d_write_4(sc, GICD_IPRIORITYR(i), 0);
 		if (i > 32) {
-			gic_d_write_4(sc, GICD_ITARGETSR(i >> 2), mask);
+			gic_d_write_4(sc, GICD_ITARGETSR(i), mask);
 		}
 	}
 
 	/* Set all the interrupts to be in Group 0 (secure) */
 	for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) {
-		gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
+		gic_d_write_4(sc, GICD_IGROUPR(i), 0);
 	}
 
 	/* Enable CPU interface */
@@ -725,7 +705,7 @@ gic_config(struct arm_gic_softc *sc, u_i
 
 	mtx_lock_spin(&sc->mutex);
 
-	reg = gic_d_read_4(sc, GICD_ICFGR(irq >> 4));
+	reg = gic_d_read_4(sc, GICD_ICFGR(irq));
 	mask = (reg >> 2*(irq % 16)) & 0x3;
 
 	if (pol == INTR_POLARITY_LOW) {
@@ -747,7 +727,7 @@ gic_config(struct arm_gic_softc *sc, u_i
 	/* Set mask */
 	reg = reg & ~(0x3 << 2*(irq % 16));
 	reg = reg | (mask << 2*(irq % 16));
-	gic_d_write_4(sc, GICD_ICFGR(irq >> 4), reg);
+	gic_d_write_4(sc, GICD_ICFGR(irq), reg);
 
 	mtx_unlock_spin(&sc->mutex);
 }
@@ -1089,7 +1069,7 @@ arm_gic_ipi_send(device_t dev, struct in
 		if (CPU_ISSET(i, &cpus))
 			val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT;
 
-	gic_d_write_4(sc, GICD_SGIR(0), val | gi->gi_irq);
+	gic_d_write_4(sc, GICD_SGIR, val | gi->gi_irq);
 }
 
 static int
@@ -1157,7 +1137,7 @@ arm_gic_config(device_t dev, int irq, en
 
 	mtx_lock_spin(&sc->mutex);
 
-	reg = gic_d_read_4(sc, GICD_ICFGR(irq >> 4));
+	reg = gic_d_read_4(sc, GICD_ICFGR(irq));
 	mask = (reg >> 2*(irq % 16)) & 0x3;
 
 	if (pol == INTR_POLARITY_LOW) {
@@ -1179,7 +1159,7 @@ arm_gic_config(device_t dev, int irq, en
 	/* Set mask */
 	reg = reg & ~(0x3 << 2*(irq % 16));
 	reg = reg | (mask << 2*(irq % 16));
-	gic_d_write_4(sc, GICD_ICFGR(irq >> 4), reg);
+	gic_d_write_4(sc, GICD_ICFGR(irq), reg);
 
 	mtx_unlock_spin(&sc->mutex);
 
@@ -1196,7 +1176,7 @@ arm_gic_mask(device_t dev, int irq)
 {
 	struct arm_gic_softc *sc = device_get_softc(dev);
 
-	gic_d_write_4(sc, GICD_ICENABLER(irq >> 5), (1UL << (irq & 0x1F)));
+	gic_d_write_4(sc, GICD_ICENABLER(irq), (1UL << (irq & 0x1F)));
 	gic_c_write_4(sc, GICC_EOIR, irq); /* XXX - not allowed */
 }
 
@@ -1208,7 +1188,7 @@ arm_gic_unmask(device_t dev, int irq)
 	if (irq > GIC_LAST_SGI)
 		arm_irq_memory_barrier(irq);
 
-	gic_d_write_4(sc, GICD_ISENABLER(irq >> 5), (1UL << (irq & 0x1F)));
+	gic_d_write_4(sc, GICD_ISENABLER(irq), (1UL << (irq & 0x1F)));
 }
 
 #ifdef SMP
@@ -1222,7 +1202,7 @@ arm_gic_ipi_send(device_t dev, cpuset_t 
 		if (CPU_ISSET(i, &cpus))
 			val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT;
 
-	gic_d_write_4(sc, GICD_SGIR(0), val | ipi);
+	gic_d_write_4(sc, GICD_SGIR, val | ipi);
 }
 
 static int

Added: head/sys/arm/arm/gic_common.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/arm/gic_common.h	Tue Dec  6 12:57:28 2016	(r309616)
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2016 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _GIC_COMMON_H_
+#define _GIC_COMMON_H_
+
+/* Common register values */
+#define	GICD_CTLR		0x0000				/* v1 ICDDCR */
+#define	GICD_TYPER		0x0004				/* v1 ICDICTR */
+#define	GICD_IIDR		0x0008				/* v1 ICDIIDR */
+#define	 GICD_IIDR_PROD_SHIFT	24
+#define	 GICD_IIDR_PROD_MASK	0xff000000
+#define	 GICD_IIDR_PROD(x)					\
+    (((x) & GICD_IIDR_PROD_MASK) >> GICD_IIDR_PROD_SHIFT)
+#define	 GICD_IIDR_VAR_SHIFT	16
+#define	 GICD_IIDR_VAR_MASK	0x000f0000
+#define	 GICD_IIDR_VAR(x)					\
+    (((x) & GICD_IIDR_VAR_MASK) >> GICD_IIDR_VAR_SHIFT)
+#define	 GICD_IIDR_REV_SHIFT	12
+#define	 GICD_IIDR_REV_MASK	0x0000f000
+#define	 GICD_IIDR_REV(x)					\
+    (((x) & GICD_IIDR_REV_MASK) >> GICD_IIDR_REV_SHIFT)
+#define	 GICD_IIDR_IMPL_SHIFT	0
+#define	 GICD_IIDR_IMPL_MASK	0x00000fff
+#define	 GICD_IIDR_IMPL(x)					\
+    (((x) & GICD_IIDR_IMPL_MASK) >> GICD_IIDR_IMPL_SHIFT)
+#define	GICD_IGROUPR(n)		(0x0080 + (((n) >> 5) * 4))	/* v1 ICDISER */
+#define	GICD_ISENABLER(n)	(0x0100 + (((n) >> 5) * 4))	/* v1 ICDISER */
+#define	GICD_ICENABLER(n)	(0x0180 + (((n) >> 5) * 4))	/* v1 ICDICER */
+#define	GICD_ISPENDR(n)		(0x0200 + (((n) >> 5) * 4))	/* v1 ICDISPR */
+#define	GICD_ICPENDR(n)		(0x0280 + (((n) >> 5) * 4))	/* v1 ICDICPR */
+#define	GICD_ICACTIVER(n)	(0x0380 + (((n) >> 5) * 4))	/* v1 ICDABR */
+#define	GICD_IPRIORITYR(n)	(0x0400 + (((n) >> 2) * 4))	/* v1 ICDIPR */
+#define	GICD_ITARGETSR(n)	(0x0800 + (((n) >> 2) * 4))	/* v1 ICDIPTR */
+#define	GICD_ICFGR(n)		(0x0C00 + (((n) >> 4) * 4))	/* v1 ICDICFR */
+/* First bit is a polarity bit (0 - low, 1 - high) */
+#define	 GICD_ICFGR_POL_LOW	(0 << 0)
+#define	 GICD_ICFGR_POL_HIGH	(1 << 0)
+#define	 GICD_ICFGR_POL_MASK	0x1
+/* Second bit is a trigger bit (0 - level, 1 - edge) */
+#define	 GICD_ICFGR_TRIG_LVL	(0 << 1)
+#define	 GICD_ICFGR_TRIG_EDGE	(1 << 1)
+#define	 GICD_ICFGR_TRIG_MASK	0x2
+#define GICD_SGIR		0x0F00				/* v1 ICDSGIR */
+#define	 GICD_SGI_TARGET_SHIFT	16
+
+#endif /* _GIC_COMMON_H_ */


More information about the svn-src-all mailing list