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