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