Page MenuHomeFreeBSD

D40161.id127099.diff
No OneTemporary

D40161.id127099.diff

diff --git a/sys/arm/allwinner/a10/a10_intc.c b/sys/arm/allwinner/a10/a10_intc.c
--- a/sys/arm/allwinner/a10/a10_intc.c
+++ b/sys/arm/allwinner/a10/a10_intc.c
@@ -180,11 +180,13 @@
}
static int
-a10_intr(void *arg)
+a10_intr(void *arg, uint32_t type __diagused)
{
struct a10_aintc_softc *sc = arg;
u_int irq;
+ MPASS(type == INTR_TYPE_IRQ);
+
irq = a10_pending_irq(sc);
if (irq == -1 || irq > A10_INTR_MAX_NIRQS) {
device_printf(sc->sc_dev, "Spurious interrupt %d\n", irq);
diff --git a/sys/arm/arm/gic.h b/sys/arm/arm/gic.h
--- a/sys/arm/arm/gic.h
+++ b/sys/arm/arm/gic.h
@@ -78,6 +78,7 @@
int arm_gic_attach(device_t);
int arm_gic_detach(device_t);
int arm_gicv2m_attach(device_t);
-int arm_gic_intr(void *);
+int arm_gic_intr_handler(void *);
+int arm_gic_intr(void *, uint32_t type);
#endif /* _ARM_GIC_H_ */
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -532,7 +532,15 @@
}
int
-arm_gic_intr(void *arg)
+arm_gic_intr(void *arg, uint32_t type __diagused)
+{
+ MPASS(type == INTR_TYPE_IRQ);
+
+ return (arm_gic_intr_handler(arg));
+}
+
+int
+arm_gic_intr_handler(void *arg)
{
struct arm_gic_softc *sc = arg;
struct gic_irqsrc *gi;
diff --git a/sys/arm/arm/gic_fdt.c b/sys/arm/arm/gic_fdt.c
--- a/sys/arm/arm/gic_fdt.c
+++ b/sys/arm/arm/gic_fdt.c
@@ -168,7 +168,7 @@
goto cleanup;
}
if (bus_setup_intr(dev, sc->base.gic_res[2], INTR_TYPE_CLK,
- arm_gic_intr, NULL, sc, &sc->base.gic_intrhand)) {
+ arm_gic_intr_handler, NULL, sc, &sc->base.gic_intrhand)) {
device_printf(dev, "could not setup irq handler\n");
intr_pic_deregister(dev, xref);
goto cleanup;
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_intr.c b/sys/arm/broadcom/bcm2835/bcm2835_intr.c
--- a/sys/arm/broadcom/bcm2835/bcm2835_intr.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_intr.c
@@ -210,7 +210,7 @@
}
static int
-bcm2835_intc_intr(void *arg)
+bcm2835_intc_intr_handler(void *arg)
{
int irq, num;
struct bcm_intc_softc *sc = arg;
@@ -233,6 +233,14 @@
return (FILTER_HANDLED);
}
+static int
+bcm2835_intc_intr(void *arg, uint32_t type __diagused)
+{
+ MPASS(type == INTR_TYPE_IRQ);
+
+ return (bcm2835_intc_intr_handler(arg));
+}
+
static void
bcm_intc_enable_intr(device_t dev, struct intr_irqsrc *isrc)
{
@@ -412,7 +420,7 @@
}
} else {
if (bus_setup_intr(dev, sc->intc_irq_res, INTR_TYPE_CLK,
- bcm2835_intc_intr, NULL, sc, &sc->intc_irq_hdl)) {
+ bcm2835_intc_intr_handler, NULL, sc, &sc->intc_irq_hdl)) {
/* XXX clean up */
device_printf(dev, "could not setup irq handler\n");
return (ENXIO);
diff --git a/sys/arm/broadcom/bcm2835/bcm2836.c b/sys/arm/broadcom/bcm2835/bcm2836.c
--- a/sys/arm/broadcom/bcm2835/bcm2836.c
+++ b/sys/arm/broadcom/bcm2835/bcm2836.c
@@ -384,13 +384,15 @@
}
static int
-bcm_lintc_intr(void *arg)
+bcm_lintc_intr(void *arg, uint32_t type __diagused)
{
struct bcm_lintc_softc *sc;
u_int cpu;
uint32_t num, reg;
struct trapframe *tf;
+ MPASS(type == INTR_TYPE_IRQ);
+
sc = arg;
cpu = PCPU_GET(cpuid);
tf = curthread->td_intr_frame;
diff --git a/sys/arm/freescale/imx/tzic.c b/sys/arm/freescale/imx/tzic.c
--- a/sys/arm/freescale/imx/tzic.c
+++ b/sys/arm/freescale/imx/tzic.c
@@ -101,12 +101,14 @@
}
static int
-tzic_intr(void *arg)
+tzic_intr(void *arg, uint32_t type __diagused)
{
struct tzic_softc *sc = arg;
int b, i, irq;
uint32_t pending;
+ MPASS(type == INTR_TYPE_IRQ);
+
/* Get active interrupt */
for (i = 0; i < TZIC_NIRQS / 32; ++i) {
pending = tzic_read_4(sc, TZIC_PND(i));
diff --git a/sys/arm/ti/aintc.c b/sys/arm/ti/aintc.c
--- a/sys/arm/ti/aintc.c
+++ b/sys/arm/ti/aintc.c
@@ -117,11 +117,13 @@
}
static int
-ti_aintc_intr(void *arg)
+ti_aintc_intr(void *arg, uint32_t type __diagused)
{
uint32_t irq;
struct ti_aintc_softc *sc = arg;
+ MPASS(type == INTR_TYPE_IRQ);
+
/* Get active interrupt */
irq = aintc_read_4(sc, INTC_SIR_IRQ);
if ((irq & INTC_SIR_SPURIOUS_MASK) != 0) {
diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S
--- a/sys/arm64/arm64/exception.S
+++ b/sys/arm64/arm64/exception.S
@@ -27,6 +27,7 @@
#include <machine/asm.h>
#include <machine/armreg.h>
+#include <machine/intr.h>
#include "assym.inc"
.text
@@ -167,7 +168,7 @@
.macro do_ast
mrs x19, daif
/* Make sure the IRQs are enabled before calling ast() */
- bic x19, x19, #PSR_I
+ bic x19, x19, #(PSR_I | PSR_F)
1:
/*
* Mask interrupts while checking the ast pending flag
@@ -210,6 +211,15 @@
ERET
END(handle_el1h_irq)
+ENTRY(handle_el1h_fiq)
+ save_registers 1
+ mov x0, sp
+ mov x1, #INTR_TYPE_FIQ
+ bl intr_irq_handler_type
+ restore_registers 1
+ ERET
+END(handle_el1h_irq)
+
ENTRY(handle_el0_sync)
save_registers 0
ldr x0, [x18, #PC_CURTHREAD]
@@ -230,6 +240,16 @@
ERET
END(handle_el0_irq)
+ENTRY(handle_el0_fiq)
+ save_registers 0
+ mov x0, sp
+ mov x1, #INTR_TYPE_FIQ
+ bl intr_irq_handler_type
+ do_ast
+ restore_registers 0
+ ERET
+END(handle_el0_fiq)
+
ENTRY(handle_serror)
save_registers 0
mov x0, sp
@@ -268,16 +288,16 @@
vector el1h_sync 1 /* Synchronous EL1h */
vector el1h_irq 1 /* IRQ EL1h */
- vempty 1 /* FIQ EL1h */
+ vector el1h_fiq 1 /* FIQ EL1h */
vector serror 1 /* Error EL1h */
vector el0_sync 0 /* Synchronous 64-bit EL0 */
vector el0_irq 0 /* IRQ 64-bit EL0 */
- vempty 0 /* FIQ 64-bit EL0 */
+ vector el0_fiq 0 /* FIQ 64-bit EL0 */
vector serror 0 /* Error 64-bit EL0 */
vector el0_sync 0 /* Synchronous 32-bit EL0 */
vector el0_irq 0 /* IRQ 32-bit EL0 */
- vempty 0 /* FIQ 32-bit EL0 */
+ vector el0_fiq 0 /* FIQ 32-bit EL0 */
vector serror 0 /* Error 32-bit EL0 */
diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c
--- a/sys/arm64/arm64/gic_v3.c
+++ b/sys/arm64/arm64/gic_v3.c
@@ -589,7 +589,7 @@
}
int
-arm_gic_v3_intr(void *arg)
+arm_gic_v3_intr(void *arg, uint32_t type __diagused)
{
struct gic_v3_softc *sc = arg;
struct gic_v3_irqsrc *gi;
@@ -597,6 +597,8 @@
uint64_t active_irq;
struct trapframe *tf;
+ /* No FIQs here yet */
+ MPASS(type == INTR_TYPE_IRQ);
pic = sc->gic_pic;
while (1) {
diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h
--- a/sys/arm64/arm64/gic_v3_var.h
+++ b/sys/arm64/arm64/gic_v3_var.h
@@ -109,7 +109,7 @@
/* Device methods */
int gic_v3_attach(device_t dev);
int gic_v3_detach(device_t dev);
-int arm_gic_v3_intr(void *);
+int arm_gic_v3_intr(void *, uint32_t type);
uint32_t gic_r_read_4(device_t, bus_size_t);
uint64_t gic_r_read_8(device_t, bus_size_t);
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -196,7 +196,7 @@
#define DAIF_I (1 << 1)
#define DAIF_F (1 << 0)
#define DAIF_ALL (DAIF_D | DAIF_A | DAIF_I | DAIF_F)
-#define DAIF_INTR (DAIF_I) /* All exceptions that pass */
+#define DAIF_INTR (DAIF_I | DAIF_F) /* All exceptions that pass */
/* through the intr framework */
/* DBGBCR<n>_EL1 - Debug Breakpoint Control Registers */
@@ -2058,7 +2058,7 @@
#define PSR_D 0x00000200UL
#define PSR_DAIF (PSR_D | PSR_A | PSR_I | PSR_F)
/* The default DAIF mask. These bits are valid in spsr_el1 and daif */
-#define PSR_DAIF_DEFAULT (PSR_F)
+#define PSR_DAIF_DEFAULT (0)
#define PSR_IL 0x00100000UL
#define PSR_SS 0x00200000UL
#define PSR_V 0x10000000UL
diff --git a/sys/arm64/include/intr.h b/sys/arm64/include/intr.h
--- a/sys/arm64/include/intr.h
+++ b/sys/arm64/include/intr.h
@@ -27,16 +27,18 @@
#ifndef _MACHINE_INTR_H_
#define _MACHINE_INTR_H_
+/*
+ * We basically only want to expose some interrupt types that must be kept in
+ * sync between assembly and C here.
+ */
+#ifndef LOCORE
+
#ifdef FDT
#include <dev/ofw/openfirm.h>
#endif
#include <sys/intr.h>
-#ifndef NIRQ
-#define NIRQ 16384 /* XXX - It should be an option. */
-#endif
-
static inline void
arm_irq_memory_barrier(uintptr_t irq)
{
@@ -46,10 +48,19 @@
void intr_ipi_dispatch(u_int);
#endif
+#endif /* LOCORE */
+
+#ifndef NIRQ
+#define NIRQ 16384 /* XXX - It should be an option. */
+#endif
+
#ifdef DEV_ACPI
#define ACPI_INTR_XREF 1
#define ACPI_MSI_XREF 2
#define ACPI_GPIO_XREF 3
#endif
+/* Platform interrupt types */
+#define INTR_TYPE_FIQ 0x0001
+
#endif /* _MACHINE_INTR_H */
diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c
--- a/sys/kern/subr_intr.c
+++ b/sys/kern/subr_intr.c
@@ -94,6 +94,7 @@
MALLOC_DEFINE(M_INTRNG, "intr", "intr interrupt handling");
/* Main interrupt handler called from assembler -> 'hidden' for C code. */
+void intr_irq_handler_type(struct trapframe *tf, uint32_t type);
void intr_irq_handler(struct trapframe *tf);
/* Root interrupt controller stuff. */
@@ -101,6 +102,7 @@
static intr_irq_filter_t *irq_root_filter;
static void *irq_root_arg;
static u_int irq_root_ipicount;
+static uint32_t irq_root_typemask;
struct intr_pic_child {
SLIST_ENTRY(intr_pic_child) pc_next;
@@ -337,12 +339,23 @@
* from the assembler, where CPU interrupt is served.
*/
void
-intr_irq_handler(struct trapframe *tf)
+intr_irq_handler_type(struct trapframe *tf, uint32_t type)
{
struct trapframe * oldframe;
struct thread * td;
KASSERT(irq_root_filter != NULL, ("%s: no filter", __func__));
+ KASSERT((irq_root_typemask & type) != 0,
+ ("%s: unknown irq type (%x)", __func__, type));
+
+ /*
+ * We could allow this possibility, but it doesn't make sense at the
+ * moment so we should defend against it early on. Root filter
+ * implementations should be more carefully considered if we start to
+ * allow multiple types firing at once for some reason.
+ */
+ KASSERT((type & ~(1 << (ffs(type) - 1))) == 0,
+ ("%s: multiple irq types specified (%x)", __func__, type));
kasan_mark(tf, sizeof(*tf), sizeof(*tf), 0);
@@ -351,7 +364,7 @@
td = curthread;
oldframe = td->td_intr_frame;
td->td_intr_frame = tf;
- irq_root_filter(irq_root_arg);
+ irq_root_filter(irq_root_arg, type);
td->td_intr_frame = oldframe;
critical_exit();
#ifdef HWPMC_HOOKS
@@ -361,6 +374,12 @@
#endif
}
+void
+intr_irq_handler(struct trapframe *tf)
+{
+ intr_irq_handler_type(tf, INTR_TYPE_IRQ);
+}
+
int
intr_child_irq_handler(struct intr_pic *parent, uintptr_t irq)
{
@@ -883,8 +902,8 @@
* an interrupts property and thus no explicit interrupt parent."
*/
int
-intr_pic_claim_root(device_t dev, intptr_t xref, intr_irq_filter_t *filter,
- void *arg, u_int ipicount)
+intr_pic_claim_root_type(device_t dev, intptr_t xref, intr_irq_filter_t *filter,
+ void *arg, u_int ipicount, uint32_t typemask)
{
struct intr_pic *pic;
@@ -903,6 +922,11 @@
return (EINVAL);
}
+ if (typemask == 0) {
+ device_printf(dev, "typemask must be specified\n");
+ return (EINVAL);
+ }
+
/*
* Only one interrupt controllers could be on the root for now.
* Note that we further suppose that there is not threaded interrupt
@@ -917,11 +941,21 @@
irq_root_filter = filter;
irq_root_arg = arg;
irq_root_ipicount = ipicount;
+ irq_root_typemask = typemask;
debugf("irq root set to %s\n", device_get_nameunit(dev));
return (0);
}
+int
+intr_pic_claim_root(device_t dev, intptr_t xref, intr_irq_filter_t *filter,
+ void *arg, u_int ipicount)
+{
+
+ return (intr_pic_claim_root_type(dev, xref, filter, arg, ipicount,
+ INTR_TYPE_IRQ));
+}
+
/*
* Add a handler to manage a sub range of a parents interrupts.
*/
diff --git a/sys/riscv/riscv/plic.c b/sys/riscv/riscv/plic.c
--- a/sys/riscv/riscv/plic.c
+++ b/sys/riscv/riscv/plic.c
@@ -157,13 +157,15 @@
}
static int
-plic_intr(void *arg)
+plic_intr(void *arg, uint32_t type __diagused)
{
struct plic_softc *sc;
struct trapframe *tf;
uint32_t pending;
uint32_t cpu;
+ MPASS(type == INTR_TYPE_IRQ);
+
sc = arg;
cpu = PCPU_GET(cpuid);
diff --git a/sys/sys/intr.h b/sys/sys/intr.h
--- a/sys/sys/intr.h
+++ b/sys/sys/intr.h
@@ -63,14 +63,20 @@
#ifdef notyet
#define INTR_SOLO INTR_MD1
-typedef int intr_irq_filter_t(void *arg, struct trapframe *tf);
+typedef int intr_irq_filter_t(void *arg, uint32_t type, struct trapframe *tf);
#else
-typedef int intr_irq_filter_t(void *arg);
+typedef int intr_irq_filter_t(void *arg, uint32_t type);
#endif
typedef int intr_child_irq_filter_t(void *arg, uintptr_t irq);
#define INTR_ISRC_NAMELEN (MAXCOMLEN + 1)
+/*
+ * For INTR types, the top bit is reserved for INTRNG usage. Every bit below it
+ * may be used for a platform type (e.g., FIQs).
+ */
+#define INTR_TYPE_IRQ 0x80000000U /* IRQs */
+
#define INTR_ISRCF_IPI 0x01 /* IPI interrupt */
#define INTR_ISRCF_PPI 0x02 /* PPI interrupt */
#define INTR_ISRCF_BOUND 0x04 /* bound to a CPU */
@@ -110,6 +116,8 @@
struct intr_pic *intr_pic_register(device_t, intptr_t);
int intr_pic_deregister(device_t, intptr_t);
+int intr_pic_claim_root_type(device_t, intptr_t, intr_irq_filter_t *, void *,
+ u_int, uint32_t);
int intr_pic_claim_root(device_t, intptr_t, intr_irq_filter_t *, void *, u_int);
int intr_pic_add_handler(device_t, struct intr_pic *,
intr_child_irq_filter_t *, void *, uintptr_t, uintptr_t);

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 22, 3:10 AM (1 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35318231
Default Alt Text
D40161.id127099.diff (12 KB)

Event Timeline