From owner-svn-src-projects@FreeBSD.ORG Mon Aug 11 16:57:48 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C1CF3687 for ; Mon, 11 Aug 2014 16:57:48 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AFCCD249C for ; Mon, 11 Aug 2014 16:57:48 +0000 (UTC) Received: from andrew (uid 1231) (envelope-from andrew@FreeBSD.org) id 23fc by svn.freebsd.org (DragonFly Mail Agent v0.9+); Mon, 11 Aug 2014 16:57:47 +0000 From: Andrew Turner Date: Mon, 11 Aug 2014 16:57:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r269819 - in projects/arm64/sys: arm/arm arm64/arm64 arm64/include X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <53e8f60c.23fc.37502c6a@svn.freebsd.org> X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Aug 2014 16:57:48 -0000 Author: andrew Date: Mon Aug 11 16:57:47 2014 New Revision: 269819 URL: http://svnweb.freebsd.org/changeset/base/269819 Log: Get interrupts working through the GICv2 driver. Modified: projects/arm64/sys/arm/arm/gic.c projects/arm64/sys/arm64/arm64/exception.S projects/arm64/sys/arm64/arm64/intr_machdep.c projects/arm64/sys/arm64/arm64/pic_if.m projects/arm64/sys/arm64/include/intr.h Modified: projects/arm64/sys/arm/arm/gic.c ============================================================================== --- projects/arm64/sys/arm/arm/gic.c Mon Aug 11 16:57:42 2014 (r269818) +++ projects/arm64/sys/arm/arm/gic.c Mon Aug 11 16:57:47 2014 (r269819) @@ -135,10 +135,10 @@ static struct arm_gic_softc *arm_gic_sc static int gic_config_irq(int irq, enum intr_trigger trig, enum intr_polarity pol); -static void gic_pre_filter(device_t, u_int); -static void gic_post_filter(device_t, u_int); -void gic_mask_irq(device_t, u_int); -void gic_unmask_irq(device_t, u_int); +static pic_dispatch_t gic_dispatch; +static pic_eoi_t gic_eoi; +static pic_mask_t gic_mask_irq; +static pic_unmask_t gic_unmask_irq; static int arm_gic_probe(device_t dev) @@ -269,8 +269,8 @@ static device_method_t arm_gic_methods[] DEVMETHOD(device_attach, arm_gic_attach), /* pic_if */ - DEVMETHOD(pic_pre_filter, gic_pre_filter), - DEVMETHOD(pic_post_filter, gic_post_filter), + DEVMETHOD(pic_dispatch, gic_dispatch), + DEVMETHOD(pic_eoi, gic_eoi), DEVMETHOD(pic_mask, gic_mask_irq), DEVMETHOD(pic_unmask, gic_unmask_irq), @@ -289,13 +289,37 @@ EARLY_DRIVER_MODULE(gic, simplebus, arm_ BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0); -static void -gic_pre_filter(device_t dev, u_int irq) +static void gic_dispatch(device_t dev, struct trapframe *frame) { + uint32_t active_irq; + int first = 1; + + while (1) { + active_irq = gic_c_read_4(GICC_IAR); + + /* + * Immediatly EOIR the SGIs, because doing so requires the other + * bits (ie CPU number), not just the IRQ number, and we do not + * have this information later. + */ + + if ((active_irq & 0x3ff) <= GIC_LAST_IPI) + gic_c_write_4(GICC_EOIR, active_irq); + active_irq &= 0x3FF; + + if (active_irq == 0x3FF) { + if (first) + printf("Spurious interrupt detected\n"); + return; + } + + cpu_dispatch_intr(active_irq, frame); + first = 0; + } } static void -gic_post_filter(device_t dev, u_int irq) +gic_eoi(device_t dev, u_int irq) { /* TODO: Get working on arm64 */ #if 0 Modified: projects/arm64/sys/arm64/arm64/exception.S ============================================================================== --- projects/arm64/sys/arm64/arm64/exception.S Mon Aug 11 16:57:42 2014 (r269818) +++ projects/arm64/sys/arm64/arm64/exception.S Mon Aug 11 16:57:47 2014 (r269819) @@ -103,6 +103,13 @@ handle_el1h_sync: restore_registers eret +handle_el1h_irq: + save_registers + mov x0, sp + bl cpu_intr + restore_registers + eret + .macro vempty .align 7 EMIT('Z'); @@ -114,6 +121,11 @@ handle_el1h_sync: b handle_el1h_sync .endm +.macro el1h_irq + .align 7 + b handle_el1h_irq +.endm + .macro el1h_error .align 7 EMIT('C'); @@ -129,7 +141,7 @@ exception_vectors: vempty /* Error EL1t */ el1h_sync /* Synchronous EL1h */ - vempty /* IRQ EL1h */ + el1h_irq /* IRQ EL1h */ vempty /* FIQ EL1h */ el1h_error /* Error EL1h */ Modified: projects/arm64/sys/arm64/arm64/intr_machdep.c ============================================================================== --- projects/arm64/sys/arm64/arm64/intr_machdep.c Mon Aug 11 16:57:42 2014 (r269818) +++ projects/arm64/sys/arm64/arm64/intr_machdep.c Mon Aug 11 16:57:47 2014 (r269819) @@ -87,61 +87,26 @@ arm_unmask_irq(u_int irq) PIC_UNMASK(root_pic, irq); } -#if 0 static void -mips_mask_soft_irq(void *source) -{ - uintptr_t irq = (uintptr_t)source; - - mips_wr_status(mips_rd_status() & ~((1 << irq) << 8)); -} - -static void -mips_unmask_soft_irq(void *source) -{ - uintptr_t irq = (uintptr_t)source; - - mips_wr_status(mips_rd_status() | ((1 << irq) << 8)); -} - -/* - * Perform initialization of interrupts prior to setting - * handlings - */ -void -cpu_init_interrupts() +intr_pre_ithread(void *arg) { - int i; - char name[MAXCOMLEN + 1]; - - /* - * Initialize all available vectors so spare IRQ - * would show up in systat output - */ - for (i = 0; i < NSOFT_IRQS; i++) { - snprintf(name, MAXCOMLEN + 1, "sint%d:", i); - mips_intr_counters[i] = mips_intrcnt_create(name); - } + u_int irq = (uintptr_t)arg; - for (i = 0; i < NHARD_IRQS; i++) { - snprintf(name, MAXCOMLEN + 1, "int%d:", i); - mips_intr_counters[NSOFT_IRQS + i] = mips_intrcnt_create(name); - } + PIC_PRE_ITHREAD(root_pic, irq); } -#endif static void -intr_pre_ithread(void *arg) +intr_post_ithread(void *arg) { - int irq = (uintptr_t)arg; + u_int irq = (uintptr_t)arg; - PIC_PRE_FILTER(root_pic, irq); + PIC_POST_ITHREAD(root_pic, irq); } static void -intr_post_ithread(void *arg) +intr_post_filter(void *arg) { - int irq = (uintptr_t)arg; + u_int irq = (uintptr_t)arg; PIC_POST_FILTER(root_pic, irq); } @@ -172,7 +137,7 @@ cpu_establish_intr(const char *name, dri if (event == NULL) { error = intr_event_create(&event, (void *)(uintptr_t)irq, 0, irq, intr_pre_ithread, intr_post_ithread, - NULL, NULL, "int%d", irq); + intr_post_filter, NULL, "int%d", irq); if (error) return; intr_events[irq] = event; @@ -188,65 +153,24 @@ cpu_establish_intr(const char *name, dri #endif } -#if 0 void -cpu_intr(struct trapframe *tf) +cpu_dispatch_intr(u_int irq, struct trapframe *tf) { struct intr_event *event; - register_t cause, status; - int hard, i, intr; - critical_enter(); - - cause = mips_rd_cause(); - status = mips_rd_status(); - intr = (cause & MIPS_INT_MASK) >> 8; - /* - * Do not handle masked interrupts. They were masked by - * pre_ithread function (mips_mask_XXX_intr) and will be - * unmasked once ithread is through with handler - */ - intr &= (status & MIPS_INT_MASK) >> 8; - while ((i = fls(intr)) != 0) { - intr &= ~(1 << (i - 1)); - switch (i) { - case 1: case 2: - /* Software interrupt. */ - i--; /* Get a 0-offset interrupt. */ - hard = 0; - event = softintr_events[i]; - mips_intrcnt_inc(mips_intr_counters[i]); - break; - default: - /* Hardware interrupt. */ - i -= 2; /* Trim software interrupt bits. */ - i--; /* Get a 0-offset interrupt. */ - hard = 1; - event = hardintr_events[i]; - mips_intrcnt_inc(mips_intr_counters[NSOFT_IRQS + i]); - break; - } - - if (!event || TAILQ_EMPTY(&event->ie_handlers)) { - printf("stray %s interrupt %d\n", - hard ? "hard" : "soft", i); - continue; - } - - if (intr_event_handle(event, tf) != 0) { - printf("stray %s interrupt %d\n", - hard ? "hard" : "soft", i); - } + event = intr_events[irq]; + if (intr_event_handle(event, tf) != 0) { + /* Stray irq */ + printf("Stray IRQ %u\n", irq); + arm_mask_irq(irq); } +} - KASSERT(i == 0, ("all interrupts handled")); - +void +cpu_intr(struct trapframe *tf) +{ + critical_enter(); + PIC_DISPATCH(root_pic, tf); critical_exit(); - -#ifdef HWPMC_HOOKS - if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) - pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, tf); -#endif } -#endif Modified: projects/arm64/sys/arm64/arm64/pic_if.m ============================================================================== --- projects/arm64/sys/arm64/arm64/pic_if.m Mon Aug 11 16:57:42 2014 (r269818) +++ projects/arm64/sys/arm64/arm64/pic_if.m Mon Aug 11 16:57:47 2014 (r269819) @@ -43,14 +43,19 @@ CODE { *pol = INTR_POLARITY_CONFORM; } - static void pic_pre_filter(device_t dev, u_int irq) + static void pic_pre_ithread(device_t dev, u_int irq) { PIC_MASK(dev, irq); + PIC_EOI(dev, irq); } - static void pic_post_filter(device_t dev, u_int irq) + static void pic_post_ithread(device_t dev, u_int irq) { PIC_UNMASK(dev, irq); + } + + static void pic_post_filter(device_t dev, u_int irq) + { PIC_EOI(dev, irq); } }; @@ -87,10 +92,15 @@ METHOD void enable { u_int vector; }; -METHOD void pre_filter { +METHOD void pre_ithread { + device_t dev; + u_int irq; +} DEFAULT pic_pre_ithread; + +METHOD void post_ithread { device_t dev; u_int irq; -} DEFAULT pic_pre_filter; +} DEFAULT pic_post_ithread; METHOD void post_filter { device_t dev; Modified: projects/arm64/sys/arm64/include/intr.h ============================================================================== --- projects/arm64/sys/arm64/include/intr.h Mon Aug 11 16:57:42 2014 (r269818) +++ projects/arm64/sys/arm64/include/intr.h Mon Aug 11 16:57:47 2014 (r269819) @@ -32,6 +32,8 @@ void cpu_set_pic(device_t, u_int); void cpu_establish_intr(const char *, driver_filter_t *, void (*)(void*), void *, int, int, void **); +void cpu_dispatch_intr(u_int, struct trapframe *); +void cpu_intr(struct trapframe *); void arm_mask_irq(u_int); void arm_unmask_irq(u_int);