Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163214327
D40161.id127099.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D40161.id127099.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D40161: arm64/intrng: add support for FIQs
Attached
Detach File
Event Timeline
Log In to Comment