Date: Mon, 14 Jun 2004 01:20:30 GMT From: Juli Mallett <jmallett@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 54880 for review Message-ID: <200406140120.i5E1KUub022806@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=54880 Change 54880 by jmallett@jmallett_oingo on 2004/06/14 01:20:09 Handle CPU-level interrupts (soft and hard) and move the clock intr handler to the clock code. XXX all of this is generic MIPS, but I'm not comfortable with it being there, so it's with the SGI port for now. Ideally we'd have a "cpu" bus with CPU interrupts off it and we'd establish interrupts with that, and it would do the same as the hardintr/softintr stuff here. And off the cpu would hang the normal mips clock, which here is being called SGI IP22 solely because of its calls to the (abstracted) code for getting cycles per hz, which right now only works on the IP22. Affected files ... .. //depot/projects/mips/sys/mips/include/cpuregs.h#16 edit .. //depot/projects/mips/sys/mips/sgimips/clock.c#8 edit .. //depot/projects/mips/sys/mips/sgimips/intr.h#5 edit .. //depot/projects/mips/sys/mips/sgimips/machdep_sgimips.c#32 edit Differences ... ==== //depot/projects/mips/sys/mips/include/cpuregs.h#16 (text+ko) ==== @@ -210,30 +210,18 @@ * The interrupt masks. * If a bit in the mask is 1 then the interrupt is enabled (or pending). */ -#define MIPS_INT_MASKX 0xff00 +#define MIPS_INT_MASK 0xff00 #define MIPS_INT_MASK_5 0x8000 #define MIPS_INT_MASK_4 0x4000 #define MIPS_INT_MASK_3 0x2000 #define MIPS_INT_MASK_2 0x1000 #define MIPS_INT_MASK_1 0x0800 #define MIPS_INT_MASK_0 0x0400 -#define MIPS_HARD_INT_MASKX 0xfc00 +#define MIPS_HARD_INT_MASK 0xfc00 #define MIPS_SOFT_INT_MASK_1 0x0200 #define MIPS_SOFT_INT_MASK_0 0x0100 /* - * mips3 CPUs have on-chip timer at INT_MASK_5. Each platform can - * choose to enable this interrupt. - */ -#if defined(MIPS_ENABLE_CLOCK_INTR) -#define MIPS_INT_MASK MIPS_INT_MASKX -#define MIPS_HARD_INT_MASK MIPS_HARD_INT_MASKX -#else -#define MIPS_INT_MASK (MIPS_INT_MASKX & ~MIPS_INT_MASK_5) -#define MIPS_HARD_INT_MASK (MIPS_HARD_INT_MASKX & ~MIPS_INT_MASK_5) -#endif - -/* * The bits in the context register. * * XXX XContext ==== //depot/projects/mips/sys/mips/sgimips/clock.c#8 (text+ko) ==== @@ -33,10 +33,13 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/proc.h> #include <sys/time.h> #include <sys/timetc.h> +#include <machine/cpu.h> #include <machine/cpuinfo.h> +#include <platform/intr.h> #include <platform/models.h> static unsigned @@ -51,9 +54,28 @@ ~0, 0, "Uninitialized SGIMIPS", - 1000 + 800 }; +static void +sgimips_clock5_intr(void *arg) +{ + struct clockframe cf; + struct trapframe *tf; + + if (curthread == NULL) + return; + + /* + * Set next clock edge. + */ + tf = curthread->td_frame; + cf.sr = tf->tf_regs[TF_SR]; + cf.pc = tf->tf_regs[TF_EPC]; + hardclock(&cf); + mips_wr_compare(mips_rd_count() + curcpu()->ci_cycles_per_hz); +} + void cpu_initclocks(void) { @@ -67,8 +89,7 @@ } tc_init(&sgimips_timecounter); mips_wr_compare(mips_rd_count() + curcpu()->ci_cycles_per_hz); - /* XXX intr_establish? */ - mips_wr_status(mips_rd_status() | MIPS_INT_MASK_5); + platform_establish_hardintr(5, sgimips_clock5_intr, NULL); } void ==== //depot/projects/mips/sys/mips/sgimips/intr.h#5 (text+ko) ==== @@ -23,14 +23,13 @@ * 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#4 $ + * $P4: //depot/projects/mips/sys/mips/sgimips/intr.h#5 $ */ #ifndef _SGIMIPS_INTR_H_ #define _SGIMIPS_INTR_H_ -/* - * Nothing to see here. - */ +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/machdep_sgimips.c#32 (text+ko) ==== @@ -51,7 +51,7 @@ #include "opt_model.h" -struct machine_type { +static struct machine_type { const char *identifier; void (*init)(void); int type; @@ -62,6 +62,13 @@ { 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; @@ -168,26 +175,72 @@ } 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]; + 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]; + 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); - if (cause & MIPS_INT_MASK_5) { - struct clockframe cf; - - /* - * Set next clock edge. - */ - cf.sr = tf->tf_regs[TF_SR]; - cf.pc = tf->tf_regs[TF_EPC]; - hardclock(&cf); - mips_wr_compare(mips_rd_count() + - curcpu()->ci_cycles_per_hz); - } else { - printf("stray intr cause %lx\n", 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")); } void
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406140120.i5E1KUub022806>