PERFORCE change 55053 for review
Juli Mallett
jmallett at FreeBSD.org
Wed Jun 16 00:01:51 GMT 2004
http://perforce.freebsd.org/chv.cgi?CH=55053
Change 55053 by jmallett at 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);
More information about the p4-projects
mailing list