From owner-svn-src-projects@FreeBSD.ORG Wed Aug 6 14:20:03 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 1F65AF32 for ; Wed, 6 Aug 2014 14:20:03 +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 0E12820E3 for ; Wed, 6 Aug 2014 14:20:03 +0000 (UTC) Received: from andrew (uid 1231) (envelope-from andrew@FreeBSD.org) id 5dcd by svn.freebsd.org (DragonFly Mail Agent v0.9+); Wed, 06 Aug 2014 14:20:01 +0000 From: Andrew Turner Date: Wed, 6 Aug 2014 14:20:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r269626 - in projects/arm64/sys: arm/arm arm64/arm64 arm64/include conf X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <53e23991.5dcd.4899f857@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: Wed, 06 Aug 2014 14:20:03 -0000 Author: andrew Date: Wed Aug 6 14:20:01 2014 New Revision: 269626 URL: http://svnweb.freebsd.org/changeset/base/269626 Log: First cut at interrupt handling Added: projects/arm64/sys/arm64/arm64/intr_machdep.c projects/arm64/sys/arm64/arm64/pic_if.m projects/arm64/sys/arm64/include/intr.h - copied, changed from r269625, projects/arm64/sys/arm64/include/cpufunc.h Modified: projects/arm64/sys/arm/arm/gic.c projects/arm64/sys/arm64/arm64/autoconf.c projects/arm64/sys/arm64/arm64/nexus.c projects/arm64/sys/arm64/include/cpufunc.h projects/arm64/sys/conf/files.arm64 Modified: projects/arm64/sys/arm/arm/gic.c ============================================================================== --- projects/arm64/sys/arm/arm/gic.c Wed Aug 6 14:19:57 2014 (r269625) +++ projects/arm64/sys/arm/arm/gic.c Wed Aug 6 14:20:01 2014 (r269626) @@ -1,5 +1,6 @@ /*- * Copyright (c) 2011 The FreeBSD Foundation + * Copyright (c) 2014 Andrew Turner * All rights reserved. * * Developed by Damjan Marion @@ -47,9 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#if 0 #include -#endif #include #include @@ -57,6 +56,9 @@ __FBSDID("$FreeBSD$"); #include #include + +#include "pic_if.h" + /* We are using GICv2 register naming */ /* Distributor Registers */ @@ -131,7 +133,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_post_filter(void *); +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 int arm_gic_probe(device_t dev) @@ -217,11 +222,7 @@ arm_gic_attach(device_t dev) sc->nirqs = gic_d_read_4(GICD_TYPER); sc->nirqs = 32 * ((sc->nirqs & 0x1f) + 1); -#if 0 - /* Set up function pointers */ - arm_post_filter = gic_post_filter; - arm_config_irq = gic_config_irq; -#endif + cpu_set_pic(dev, sc->nirqs); icciidr = gic_c_read_4(GICC_IIDR); device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x sc->nirqs %u\n", @@ -263,6 +264,13 @@ arm_gic_attach(device_t dev) static device_method_t arm_gic_methods[] = { DEVMETHOD(device_probe, arm_gic_probe), DEVMETHOD(device_attach, arm_gic_attach), + + /* pic_if */ + DEVMETHOD(pic_pre_filter, gic_pre_filter), + DEVMETHOD(pic_post_filter, gic_post_filter), + DEVMETHOD(pic_mask, gic_mask_irq), + DEVMETHOD(pic_unmask, gic_unmask_irq), + { 0, 0 } }; @@ -278,10 +286,13 @@ DRIVER_MODULE(gic, simplebus, arm_gic_dr DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0); static void -gic_post_filter(void *arg) +gic_pre_filter(device_t dev, u_int irq) { - uintptr_t irq = (uintptr_t) arg; +} +static void +gic_post_filter(device_t dev, u_int irq) +{ gic_c_write_4(GICC_EOIR, irq); } @@ -311,22 +322,22 @@ arm_get_next_irq(int last_irq) return active_irq; } +#endif void -arm_mask_irq(uintptr_t nb) +gic_mask_irq(device_t dev, u_int irq) { - gic_d_write_4(GICD_ICENABLER(nb >> 5), (1UL << (nb & 0x1F))); - gic_c_write_4(GICC_EOIR, nb); + gic_d_write_4(GICD_ICENABLER(irq >> 5), (1UL << (irq & 0x1F))); + gic_c_write_4(GICC_EOIR, irq); } void -arm_unmask_irq(uintptr_t nb) +gic_unmask_irq(device_t dev, u_int irq) { - gic_d_write_4(GICD_ISENABLER(nb >> 5), (1UL << (nb & 0x1F))); + gic_d_write_4(GICD_ISENABLER(irq >> 5), (1UL << (irq & 0x1F))); } -#endif static int gic_config_irq(int irq, enum intr_trigger trig, Modified: projects/arm64/sys/arm64/arm64/autoconf.c ============================================================================== --- projects/arm64/sys/arm64/arm64/autoconf.c Wed Aug 6 14:19:57 2014 (r269625) +++ projects/arm64/sys/arm64/arm64/autoconf.c Wed Aug 6 14:20:01 2014 (r269626) @@ -99,6 +99,7 @@ configure(void *dummy) static void configure_final(void *dummy) { + intr_enable(); cninit_finish(); if (bootverbose) Added: projects/arm64/sys/arm64/arm64/intr_machdep.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/arm64/arm64/intr_machdep.c Wed Aug 6 14:20:01 2014 (r269626) @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2006 Oleksandr Tymoshenko + * Copyright (c) 2002-2004 Juli Mallett + * All rights reserved. + * + * 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, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * From: projects/arm64/sys/mips/mips/intr_machdep.c r233318 + */ + +#include +__FBSDID("$FreeBSD: projects/arm64/sys/mips/mips/intr_machdep.c 233318 2012-03-22 17:47:52Z gonzo $"); + +#include +#include +#include +#include +#include + +#include + +#include "pic_if.h" + +#define NIRQS 1024 + +static struct intr_event *intr_events[NIRQS]; +static device_t root_pic; +static u_int num_irq; + +#if 0 +static struct intr_event *softintr_events[NSOFT_IRQS]; +static mips_intrcnt_t mips_intr_counters[NSOFT_IRQS + NHARD_IRQS]; + +static int intrcnt_index; + +mips_intrcnt_t +mips_intrcnt_create(const char* name) +{ + mips_intrcnt_t counter = &intrcnt[intrcnt_index++]; + + mips_intrcnt_setname(counter, name); + return counter; +} + +void +mips_intrcnt_setname(mips_intrcnt_t counter, const char *name) +{ + int idx = counter - intrcnt; + + KASSERT(counter != NULL, ("mips_intrcnt_setname: NULL counter")); + + snprintf(intrnames + (MAXCOMLEN + 1) * idx, + MAXCOMLEN + 1, "%-*s", MAXCOMLEN, name); +} +#endif + +void +arm_mask_irq(u_int irq) +{ + + PIC_MASK(root_pic, irq); +} + +void +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() +{ + 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); + } + + for (i = 0; i < NHARD_IRQS; i++) { + snprintf(name, MAXCOMLEN + 1, "int%d:", i); + mips_intr_counters[NSOFT_IRQS + i] = mips_intrcnt_create(name); + } +} +#endif + +static void +intr_pre_ithread(void *arg) +{ + int irq = (uintptr_t)arg; + + PIC_PRE_FILTER(root_pic, irq); +} + +static void +intr_post_ithread(void *arg) +{ + int irq = (uintptr_t)arg; + + PIC_POST_FILTER(root_pic, irq); +} + +void +cpu_set_pic(device_t pic, u_int nirq) +{ + + KASSERT(root_pic == NULL, ("Unable to set the pic twice")); + KASSERT(nirq <= NIRQS, ("PIC is trying to handle too many IRQs")); + + num_irq = nirq; + root_pic = pic; +} + +void +cpu_establish_intr(const char *name, driver_filter_t *filt, + void (*handler)(void*), void *arg, int irq, int flags, void **cookiep) +{ + struct intr_event *event; + int error; + + if (irq < 0 || irq >= num_irq) + panic("%s called for unknown intr %d", __func__, irq); + + /* TODO: Add locking for the intr_events array */ + event = intr_events[irq]; + 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); + if (error) + return; + intr_events[irq] = event; + PIC_UNMASK(root_pic, irq); + } + + intr_event_add_handler(event, name, filt, handler, arg, + intr_priority(flags), flags, cookiep); + +#if 0 + mips_intrcnt_setname(mips_intr_counters[NSOFT_IRQS + irq], + event->ie_fullname); +#endif +} + +#if 0 +void +cpu_intr(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); + } + } + + KASSERT(i == 0, ("all interrupts handled")); + + 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/nexus.c ============================================================================== --- projects/arm64/sys/arm64/arm64/nexus.c Wed Aug 6 14:19:57 2014 (r269625) +++ projects/arm64/sys/arm64/arm64/nexus.c Wed Aug 6 14:20:01 2014 (r269626) @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include -//#include +#include #include "opt_platform.h" @@ -249,20 +249,16 @@ static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { -#if 0 int irq; if ((rman_get_flags(res) & RF_SHAREABLE) == 0) flags |= INTR_EXCL; for (irq = rman_get_start(res); irq <= rman_get_end(res); irq++) { - arm_setup_irqhandler(device_get_nameunit(child), - filt, intr, arg, irq, flags, cookiep); - arm_unmask_irq(irq); + cpu_establish_intr(device_get_nameunit(child), filt, intr, + arg, irq, flags, cookiep); } return (0); -#endif - panic("nexus_setup_intr"); } static int Added: projects/arm64/sys/arm64/arm64/pic_if.m ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/arm64/arm64/pic_if.m Wed Aug 6 14:20:01 2014 (r269626) @@ -0,0 +1,119 @@ +#- +# Copyright (c) 1998 Doug Rabson +# All rights reserved. +# +# 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. +# +# from: src/sys/kern/bus_if.m,v 1.21 2002/04/21 11:16:10 markm Exp +# $FreeBSD: projects/arm64/sys/powerpc/powerpc/pic_if.m 257059 2013-10-24 15:37:32Z nwhitehorn $ +# + +#include +#include +#include + +INTERFACE pic; + +CODE { + static pic_translate_code_t pic_translate_code_default; + + static void pic_translate_code_default(device_t dev, u_int irq, + int code, enum intr_trigger *trig, enum intr_polarity *pol) + { + *trig = INTR_TRIGGER_CONFORM; + *pol = INTR_POLARITY_CONFORM; + } + + static void pic_pre_filter(device_t dev, u_int irq) + { + PIC_MASK(dev, irq); + } + + static void pic_post_filter(device_t dev, u_int irq) + { + PIC_UNMASK(dev, irq); + PIC_EOI(dev, irq); + } +}; + +METHOD void bind { + device_t dev; + u_int irq; + cpuset_t cpumask; +}; + +METHOD void translate_code { + device_t dev; + u_int irq; + int code; + enum intr_trigger *trig; + enum intr_polarity *pol; +} DEFAULT pic_translate_code_default; + +METHOD void config { + device_t dev; + u_int irq; + enum intr_trigger trig; + enum intr_polarity pol; +}; + +METHOD void dispatch { + device_t dev; + struct trapframe *tf; +}; + +METHOD void enable { + device_t dev; + u_int irq; + u_int vector; +}; + +METHOD void pre_filter { + device_t dev; + u_int irq; +} DEFAULT pic_pre_filter; + +METHOD void post_filter { + device_t dev; + u_int irq; +} DEFAULT pic_post_filter; + +METHOD void eoi { + device_t dev; + u_int irq; +}; + +METHOD void ipi { + device_t dev; + u_int cpu; +}; + +METHOD void mask { + device_t dev; + u_int irq; +}; + +METHOD void unmask { + device_t dev; + u_int irq; +}; + Modified: projects/arm64/sys/arm64/include/cpufunc.h ============================================================================== --- projects/arm64/sys/arm64/include/cpufunc.h Wed Aug 6 14:19:57 2014 (r269625) +++ projects/arm64/sys/arm64/include/cpufunc.h Wed Aug 6 14:20:01 2014 (r269626) @@ -57,7 +57,13 @@ intr_restore(register_t s) { __asm __volatile("msr daif, %x0" : : "r" (s)); +} + +static __inline void +intr_enable(void) +{ + __asm __volatile("msr daifclr, #2"); } #endif /* _KERNEL */ Copied and modified: projects/arm64/sys/arm64/include/intr.h (from r269625, projects/arm64/sys/arm64/include/cpufunc.h) ============================================================================== --- projects/arm64/sys/arm64/include/cpufunc.h Wed Aug 6 14:19:57 2014 (r269625, copy source) +++ projects/arm64/sys/arm64/include/intr.h Wed Aug 6 14:20:01 2014 (r269626) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014 Andrew Turner + * Copyright (c) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,39 +26,13 @@ * $FreeBSD$ */ -#ifndef _MACHINE_CPUFUNC_H_ -#define _MACHINE_CPUFUNC_H_ +#ifndef _MACHINE_INTR_H_ +#define _MACHINE_INTR_H_ -#ifdef _KERNEL +void cpu_set_pic(device_t, u_int); +void cpu_establish_intr(const char *, driver_filter_t *, void (*)(void*), + void *, int, int, void **); +void arm_mask_irq(u_int); +void arm_unmask_irq(u_int); -static __inline void -breakpoint(void) -{ - - __asm("brk #0"); -} - -static __inline register_t -intr_disable(void) -{ - /* DAIF is a 32-bit register */ - uint32_t ret; - - __asm __volatile( - "mrs %x0, daif \n" - "msr daifset, #2 \n" - : "=&r" (ret)); - - return (ret); -} - -static __inline void -intr_restore(register_t s) -{ - - __asm __volatile("msr daif, %x0" : : "r" (s)); - -} - -#endif /* _KERNEL */ -#endif /* _MACHINE_CPUFUNC_H_ */ +#endif /* _MACHINE_INTR_H */ Modified: projects/arm64/sys/conf/files.arm64 ============================================================================== --- projects/arm64/sys/conf/files.arm64 Wed Aug 6 14:19:57 2014 (r269625) +++ projects/arm64/sys/conf/files.arm64 Wed Aug 6 14:20:01 2014 (r269626) @@ -13,11 +13,13 @@ arm64/arm64/dump_machdep.c standard arm64/arm64/elf_machdep.c standard arm64/arm64/exception.S standard arm64/arm64/identcpu.c standard +arm64/arm64/intr_machdep.c standard arm64/arm64/in_cksum.c optional inet | inet6 arm64/arm64/locore.S standard no-obj arm64/arm64/machdep.c standard arm64/arm64/mem.c standard arm64/arm64/nexus.c standard +arm64/arm64/pic_if.m standard arm64/arm64/pmap.c standard arm64/arm64/stack_machdep.c standard arm64/arm64/support.c standard