Date: Tue, 15 Jun 2004 14:42:06 GMT From: Juli Mallett <jmallett@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 55026 for review Message-ID: <200406151442.i5FEg622081626@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=55026 Change 55026 by jmallett@jmallett_oingo on 2004/06/15 14:41:17 Move CPU interrupt establishment to a file with the idea that: o) The CPU bus will provide access for other busses and devices to raw interrupts by way of a "fast" style call. o) CPU interrupts are few(#) and short between, and usually map to something else or MUST be handled fast, i.e. bus reset or clock tick. o) You can jam on the ithreads at the layer they're needed (I will probably add an intr_machdep.c for this purpose later.) o) Soft interrutps on the CPU need to go through a magic API anyway. Does FreeBSD even have anything to really use them? Might be a fun way to fake a real interrupty console with ARCS. o) Nothing should request a hard interrupt without going through the bus layer. This is just the mechanical separation and fixup of wrong includes of <platform/intr.h> directly. Also moves interrupt processing out of the trap() path, since it is not owned by the platform anymore. It is now done in cpu_intr() in interrupt.c, which was like platform_intr(), except it can pass on the trapframe. XXX A big caveat to doing the bussification of interrupts will be the mapped interrupt stuff. I think I have a good model of that in my head for hanging off "mainbus" - it's why I killed the local0 and whatnot in NetBSD at first anyway, but I brought them back because I needed to go down that road soon :( Meta-XXX note that by "hanging off" I do not mean a device attached to mainbus, that'd just be tricky. I mean it would have carnal knowledge of the machine and be able to figure out how to map interrupts. This actually seems reasonable to me. Either that or do a nexus down at that level. Affected files ... .. //depot/projects/mips/sys/conf/files.mips#40 edit .. //depot/projects/mips/sys/mips/include/intr.h#3 edit .. //depot/projects/mips/sys/mips/mips/clock_r4k.c#2 edit .. //depot/projects/mips/sys/mips/mips/exception.S#30 edit .. //depot/projects/mips/sys/mips/mips/interrupt.c#1 add .. //depot/projects/mips/sys/mips/mips/trap.c#25 edit .. //depot/projects/mips/sys/mips/sgimips/clock.c#12 edit .. //depot/projects/mips/sys/mips/sgimips/imc/imc.c#10 edit .. //depot/projects/mips/sys/mips/sgimips/intr.h#7 edit .. //depot/projects/mips/sys/mips/sgimips/ip22.c#10 edit .. //depot/projects/mips/sys/mips/sgimips/machdep_sgimips.c#37 edit .. //depot/projects/mips/sys/mips/sgimips/mainbus.c#2 edit Differences ... ==== //depot/projects/mips/sys/conf/files.mips#40 (text+ko) ==== @@ -19,6 +19,7 @@ mips/mips/elf_machdep.c standard mips/mips/exception.S standard mips/mips/in_cksum.c optional inet +mips/mips/interrupt.c standard mips/mips/locore.S standard no-obj mips/mips/machdep.c standard mips/mips/pmap.c standard ==== //depot/projects/mips/sys/mips/include/intr.h#3 (text+ko) ==== @@ -23,15 +23,21 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/mips/sys/mips/include/intr.h#2 $ + * $P4: //depot/projects/mips/sys/mips/include/intr.h#3 $ */ #ifndef _MACHINE_INTR_H_ #define _MACHINE_INTR_H_ +struct trapframe; + /* * Include the platform-specific MD interrupt header. */ #include <platform/intr.h> +void cpu_establish_hardintr(int, void (*)(void *), void *); +void cpu_establish_softintr(int, void (*)(void *), void *); +void cpu_intr(struct trapframe *); + #endif /* !_MACHINE_INTR_H_ */ ==== //depot/projects/mips/sys/mips/mips/clock_r4k.c#2 (text+ko) ==== @@ -36,7 +36,7 @@ #include <machine/clock.h> #include <machine/cpu.h> #include <machine/cpuinfo.h> -#include <platform/intr.h> +#include <machine/intr.h> static unsigned r4k_get_timecount(struct timecounter *); @@ -112,7 +112,7 @@ { r4k_timecounter.tc_frequency = curcpu()->ci_cpu_freq; tc_init(&r4k_timecounter); - platform_establish_hardintr(5, r4k_clock_intr, NULL); + 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/exception.S#30 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/mips/sys/mips/mips/exception.S#29 $ + * $P4: //depot/projects/mips/sys/mips/mips/exception.S#30 $ */ #include "opt_ddb.h" @@ -125,15 +125,36 @@ mtc0 t0, MIPS_COP_0_STATUS /* + * If this is an interrupt, call cpu_intr() with the arguments: + * trapframe + * + * Otherwise, go to trap(). Trapframe is set to a0 from k1 in the + * BDslot here. + */ + mfc0 a1, MIPS_COP_0_CAUSE + and k0, a1, MIPS_CR_EXC_CODE + bnez k0, 1f + move a0, k1 + + jal cpu_intr + nop + + b 2f + nop + + /* * Call trap() with arguments: * trapframe, cause, badvaddr. * - * The trapframe is copied from k1 to a0 in the BDslot. + * The trapframe is copied from k1 to a0 in the BDslot above. + * Cause is set up above when computing the code. */ +1: mfc0 a1, MIPS_COP_0_CAUSE dmfc0 a2, MIPS_COP_0_BAD_VADDR jal trap - move a0, k1 + nop +2: /* * Make sure interrupts are disabled for the purposes of ==== //depot/projects/mips/sys/mips/mips/trap.c#25 (text+ko) ==== @@ -117,12 +117,6 @@ /* XXX Kernel only. */ tlb_modified(badvaddr); goto done; - case TrInt: - /*platform_trap_exit();*/ - critical_enter(); - platform_intr(tf); - critical_exit(); - goto done; case TrAdEL: case TrDBE: if (trap_error == -1/* && trap_addr == badvaddr*/) { ==== //depot/projects/mips/sys/mips/sgimips/clock.c#12 (text+ko) ==== @@ -34,7 +34,7 @@ #include <machine/clock.h> #include <machine/cpu.h> #include <machine/cpuinfo.h> -#include <platform/intr.h> +#include <machine/intr.h> #include <platform/models.h> void ==== //depot/projects/mips/sys/mips/sgimips/imc/imc.c#10 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/mips/sys/mips/sgimips/imc/imc.c#9 $ + * $P4: //depot/projects/mips/sys/mips/sgimips/imc/imc.c#10 $ */ #include <sys/cdefs.h> @@ -36,9 +36,9 @@ #include <sys/bus.h> #include <machine/bus.h> +#include <machine/intr.h> #include <platform/models.h> #include <platform/imc/imcreg.h> -#include <platform/intr.h> static devclass_t imc_devclass; @@ -128,7 +128,7 @@ /* Clear error status and set up bus error handler. */ imc_reset(dev); - platform_establish_hardintr(4, imc_reset, dev); + cpu_establish_hardintr(4, imc_reset, dev); /* * Enable parity reporting on GIO/main memory transactions. ==== //depot/projects/mips/sys/mips/sgimips/intr.h#7 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/mips/sys/mips/sgimips/intr.h#6 $ + * $P4: //depot/projects/mips/sys/mips/sgimips/intr.h#7 $ */ #ifndef _SGIMIPS_INTR_H_ @@ -31,7 +31,4 @@ #define NINTR 32 -void platform_establish_hardintr(int, void (*)(void *), void *); -void platform_establish_softintr(int, void (*)(void *), void *); - #endif /* _SGIMIPS_INTR_H_ */ ==== //depot/projects/mips/sys/mips/sgimips/ip22.c#10 (text+ko) ==== @@ -44,9 +44,9 @@ #include <machine/bus.h> #include <machine/cpuinfo.h> +#include <machine/intr.h> #include <platform/int2reg.h> #include <platform/int2var.h> -#include <platform/intr.h> #include <platform/models.h> #include <platform/sysconf.h> #include <platform/timerreg.h> @@ -121,8 +121,8 @@ unsigned long cps; unsigned long ctrdiff[3]; - platform_establish_hardintr(0, int_local0_intr, NULL); - platform_establish_hardintr(1, int_local1_intr, NULL); + cpu_establish_hardintr(0, int_local0_intr, NULL); + cpu_establish_hardintr(1, int_local1_intr, NULL); /* calibrate timer */ int_cal_timer(); ==== //depot/projects/mips/sys/mips/sgimips/machdep_sgimips.c#37 (text+ko) ==== @@ -43,7 +43,7 @@ #include <machine/pmap.h> #include <machine/trap.h> -#include <platform/intr.h> +#include <machine/intr.h> #include <platform/models.h> #include <platform/sysconf.h> @@ -62,13 +62,6 @@ { NULL, NULL, 0 } }; -struct intrhand { - void (*handler)(void *); - void *arg; -}; -static struct intrhand intrhard[6]; -static struct intrhand intrsoft[2]; - int arcsmem, availmem, lpmem; int mach_type, mach_subtype, mach_boardrev; @@ -174,79 +167,6 @@ ctob(availmem) / (1024 * 1024)); } -void -platform_establish_hardintr(int intr, void (*handler)(void *), void *arg) -{ - struct intrhand *ih; - - if (intr < 0 || intr > 5) - panic("%s called for unknown hard intr %d", __func__, intr); - ih = &intrhard[intr]; - if (ih->handler != NULL && ih->handler != handler) - panic("%s cannot share hard intr %d", __func__, intr); - ih->handler = handler; - ih->arg = arg; - - /* Route above the 2 lower software interrupt bits. */ - mips_wr_status(mips_rd_status() | (((1 << intr) << 8) << 2)); -} - -void -platform_establish_softintr(int intr, void (*handler)(void *), void *arg) -{ - struct intrhand *ih; - - if (intr < 0 || intr > 1) - panic("%s called for unknown soft intr %d", __func__, intr); - ih = &intrsoft[intr]; - if (ih->handler != NULL && ih->handler != handler) - panic("%s cannot share soft intr %d", __func__, intr); - ih->handler = handler; - ih->arg = arg; - - mips_wr_status(mips_rd_status() | ((1 << intr) << 8)); -} - -void -platform_intr(struct trapframe *tf) -{ - struct intrhand *ih; - register_t cause; - int hard; - int intr; - int i; - - cause = mips_rd_cause(); - intr = (cause & MIPS_INT_MASK) >> 8; - cause &= ~MIPS_INT_MASK; - mips_wr_cause(cause); - - 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; - ih = &intrsoft[i]; - break; - default: - /* Hardware interrupt. */ - i -= 2; /* Trim software interrupt bits. */ - i--; /* Get a 0-offset interrupt. */ - hard = 1; - ih = &intrhard[i]; - break; - } - if (ih->handler != NULL) - (*ih->handler)(ih->arg); - else - printf("stray %s interrupt %d\n", - hard ? "hard" : "soft", i); - } - KASSERT(i == 0, ("all interrupts handled")); -} - /* * XXX Maybe return the state of the watchdog in enter, and pass it to * exit? Like spl(). ==== //depot/projects/mips/sys/mips/sgimips/mainbus.c#2 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/mips/sys/mips/sgimips/mainbus.c#1 $ + * $P4: //depot/projects/mips/sys/mips/sgimips/mainbus.c#2 $ */ #include <sys/cdefs.h> @@ -36,8 +36,8 @@ #include <sys/bus.h> #include <machine/bus.h> +#include <machine/intr.h> #include <platform/models.h> -#include <platform/intr.h> static devclass_t mainbus_devclass;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406151442.i5FEg622081626>