From owner-p4-projects@FreeBSD.ORG Mon Jun 14 01:20:35 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E36C416A4D1; Mon, 14 Jun 2004 01:20:34 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B8E7816A4CE for ; Mon, 14 Jun 2004 01:20:34 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9EDC343D54 for ; Mon, 14 Jun 2004 01:20:34 +0000 (GMT) (envelope-from jmallett@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id i5E1KVgg022809 for ; Mon, 14 Jun 2004 01:20:31 GMT (envelope-from jmallett@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id i5E1KUub022806 for perforce@freebsd.org; Mon, 14 Jun 2004 01:20:30 GMT (envelope-from jmallett@freebsd.org) Date: Mon, 14 Jun 2004 01:20:30 GMT Message-Id: <200406140120.i5E1KUub022806@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jmallett@freebsd.org using -f From: Juli Mallett To: Perforce Change Reviews Subject: PERFORCE change 54880 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Jun 2004 01:20:35 -0000 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 #include +#include #include #include +#include #include +#include #include 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