Date: Wed, 16 Jun 2004 00:00:41 GMT From: Juli Mallett <jmallett@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 55053 for review Message-ID: <200406160000.i5G00fFr014900@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=55053 Change 55053 by jmallett@jmallett_oingo on 2004/06/16 00:00:16 Allocate IRQs as resourced via the CPU. XXX sgimips still touches cpu_establish_hardintr directly. That's due to the bug of me not having those interrupts hanging off something hurr. Affected files ... .. //depot/projects/mips/sys/mips/mips/clock_r4k.c#3 edit .. //depot/projects/mips/sys/mips/mips/cpu.c#5 edit Differences ... ==== //depot/projects/mips/sys/mips/mips/clock_r4k.c#3 (text+ko) ==== @@ -30,13 +30,13 @@ #include <sys/proc.h> #include <sys/bus.h> #include <sys/kernel.h> +#include <sys/rman.h> #include <sys/time.h> #include <sys/timetc.h> #include <machine/clock.h> #include <machine/cpu.h> #include <machine/cpuinfo.h> -#include <machine/intr.h> static unsigned r4k_get_timecount(struct timecounter *); @@ -83,15 +83,16 @@ struct clockframe cf; struct trapframe *tf; - if (curthread == NULL) - return; + /* + * Magic. Setting up with an arg of NULL means we get passed tf. + */ + tf = arg; + cf.sr = tf->tf_regs[TF_SR]; + cf.pc = tf->tf_regs[TF_EPC]; /* * Set next clock edge. */ - tf = curthread->td_frame; - cf.sr = tf->tf_regs[TF_SR]; - cf.pc = tf->tf_regs[TF_EPC]; if (clocks_running) hardclock(&cf); mips_wr_compare(mips_rd_count() + curcpu()->ci_cycles_per_hz); @@ -110,9 +111,26 @@ static int r4k_clock_attach(device_t dev) { + struct resource *irq; + int error; + int rid; + r4k_timecounter.tc_frequency = curcpu()->ci_cpu_freq; + + rid = 0; + irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 5, 5, 1, RF_ACTIVE); + if (irq == NULL) { + device_printf(dev, "failed to allocate irq\n"); + return (ENXIO); + } + error = bus_setup_intr(dev, irq, INTR_TYPE_CLK, r4k_clock_intr, NULL, + NULL); + if (error != 0) { + device_printf(dev, "bus_setup_intr returned %d\n", error); + return (error); + } + tc_init(&r4k_timecounter); - cpu_establish_hardintr(5, r4k_clock_intr, NULL); mips_wr_compare(mips_rd_count() + curcpu()->ci_cycles_per_hz); return (0); } ==== //depot/projects/mips/sys/mips/mips/cpu.c#5 (text+ko) ==== @@ -29,13 +29,14 @@ #include <sys/systm.h> #include <sys/bus.h> #include <sys/kernel.h> +#include <sys/rman.h> #include <vm/vm.h> #include <vm/vm_page.h> #include <machine/cache.h> #include <machine/cpufunc.h> -#include <machine/hwfunc.h> +#include <machine/intr.h> #include <machine/locore.h> #include <machine/pte.h> #include <machine/tlb.h> @@ -185,23 +186,30 @@ printf("XXX should print cache identification here\n"); } +static struct rman cpu_hardirq_rman; + static devclass_t cpu_devclass; /* * Device methods */ static int cpu_probe(device_t); +static int cpu_attach(device_t); +static struct resource *cpu_alloc_resource(device_t, device_t, int, int *, + u_long, u_long, u_long, u_int); +static int cpu_setup_intr(device_t, device_t, struct resource *, int, + driver_intr_t *, void *, void **); static device_method_t cpu_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cpu_probe), - DEVMETHOD(device_attach, bus_generic_attach), + DEVMETHOD(device_attach, cpu_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), - /* XXXJM TODO DONGS ETC. Allocate hard/soft intrs off this. */ /* Bus interface */ - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_alloc_resource, cpu_alloc_resource), + DEVMETHOD(bus_setup_intr, cpu_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), { 0, 0 } @@ -235,4 +243,68 @@ } return (0); } + +static int +cpu_attach(device_t dev) +{ + int error; + + cpu_hardirq_rman.rm_start = 0; + cpu_hardirq_rman.rm_end = 5; + cpu_hardirq_rman.rm_type = RMAN_ARRAY; + cpu_hardirq_rman.rm_descr = "CPU Hard Interrupts"; + + error = rman_init(&cpu_hardirq_rman); + if (error != 0) { + device_printf(dev, "failed to initialize irq resources\n"); + return (error); + } + /* XXX rman_manage_all. */ + error = rman_manage_region(&cpu_hardirq_rman, + cpu_hardirq_rman.rm_start, + cpu_hardirq_rman.rm_end); + if (error != 0) { + device_printf(dev, "failed to manage irq resources\n"); + return (error); + } + + return (bus_generic_attach(dev)); +} + +/* + * XXX this routing should be horribly complex and use a resource list and + * make us add a CPU softc! + */ +static struct resource * +cpu_alloc_resource(device_t dev, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct resource *res; + + if (type != SYS_RES_IRQ) + return (NULL); + res = rman_reserve_resource(&cpu_hardirq_rman, start, end, count, 0, + child); + return (res); +} + +static int +cpu_setup_intr(device_t dev, device_t child, struct resource *res, int flags, + driver_intr_t *handler, void *arg, void **cookiep) +{ + int error; + int intr; + + error = rman_activate_resource(res); + if (error != 0) { + device_printf(child, "could not activate irq\n"); + return (error); + } + intr = res->r_start; + + cpu_establish_hardintr(intr, handler, arg); + device_printf(child, "established CPU interrupt %d\n", intr); + return (0); +} + DRIVER_MODULE(cpu, root, cpu_driver, cpu_devclass, 0, 0);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406160000.i5G00fFr014900>