Misc minor cleanup for arc interrupt handlers:

- always enable options MIPS3_ENABLE_CLOCK_INTR and just clear the compare
  register in cpu_intr() to make CLKF_BASE() works
  properly
- prepare only possible number of cpu_inttab
- use macro for interrupt priority number passed to arc_set_intr()
  to avoid confusion
- merge arc_hardware_intr() into cpu_intr()
- check independent timer interrupt first in cpu_intr()
- tweak MIPS_SR_INT_IE before calling hardclock timer handlers so that
  spllowersoftclock(9) will be invoked properly in hardclock(9)
- reenable interrupt for timer in cpu_intr() rather than each timer handlers

okay'ed by soda.

Note the real fix is to make CLKF_BASE() check all independent
interrupt sources including jazz and isa devices.
This commit is contained in:
tsutsui 2006-06-24 03:50:38 +00:00
parent 648df6ea96
commit 2a8a21a021
11 changed files with 88 additions and 73 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: arc_trap.c,v 1.32 2006/06/17 14:11:16 tsutsui Exp $ */
/* $NetBSD: arc_trap.c,v 1.33 2006/06/24 03:50:38 tsutsui Exp $ */
/* $OpenBSD: trap.c,v 1.22 1999/05/24 23:08:59 jason Exp $ */
/*
@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: arc_trap.c,v 1.32 2006/06/17 14:11:16 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: arc_trap.c,v 1.33 2006/06/24 03:50:38 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -95,43 +95,14 @@ __KERNEL_RCSID(0, "$NetBSD: arc_trap.c,v 1.32 2006/06/17 14:11:16 tsutsui Exp $"
#include <arc/jazz/pica.h>
#include <arc/jazz/rd94.h>
uint32_t arc_hardware_intr(uint32_t, uint32_t, uint32_t, uint32_t);
#define MIPS_INT_LEVELS 8
struct {
struct cpu_inttab {
uint32_t int_mask;
uint32_t (*int_hand)(uint32_t, struct clockframe *);
} cpu_int_tab[MIPS_INT_LEVELS];
};
static struct cpu_inttab cpu_int_tab[ARC_NINTPRI];
uint32_t cpu_int_mask; /* External cpu interrupt mask */
uint32_t
arc_hardware_intr(uint32_t status, uint32_t cause, uint32_t pc,
uint32_t ipending)
{
int i;
struct clockframe cf;
cf.pc = pc;
cf.sr = status;
/*
* Check off all enabled interrupts. Called interrupt routine
* returns mask of interrupts to reenable.
*/
for (i = 0; i < MIPS_INT_LEVELS; i++) {
if (cpu_int_tab[i].int_mask & ipending) {
cause &= (*cpu_int_tab[i].int_hand)(ipending, &cf);
}
}
/*
* Reenable all non served hardware levels.
*/
return cause;
}
/*
* Set up handler for external interrupt events.
* Events are checked in priority order.
@ -141,7 +112,7 @@ arc_set_intr(uint32_t mask, uint32_t (*int_hand)(uint32_t, struct clockframe *),
int prio)
{
if (prio > MIPS_INT_LEVELS)
if (prio >= ARC_NINTPRI)
panic("arc_set_intr: too high priority");
if (cpu_int_tab[prio].int_mask != 0 &&
@ -162,23 +133,66 @@ arc_set_intr(uint32_t mask, uint32_t (*int_hand)(uint32_t, struct clockframe *),
void
cpu_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending)
{
uint32_t handled;
struct clockframe cf;
struct cpu_inttab *inttab;
u_int i;
uvmexp.intrs++;
cf.pc = pc;
cf.sr = status;
/* check MIPS3 internal clock interrupt */
if (ipending & MIPS_INT_MASK_5) {
/*
* Writing a value to the Compare register,
* as a side effect, clears the timer interrupt request.
*/
mips3_cp0_compare_write(mips3_cp0_count_read());
mips3_cp0_compare_write(0);
cause &= ~MIPS_INT_MASK_5;
}
_splset((status & MIPS_INT_MASK_5) | MIPS_SR_INT_IE);
uvmexp.intrs++;
handled = cause;
/* real device interrupt */
if (ipending & MIPS3_HARD_INT_MASK) {
handled = arc_hardware_intr(status, cause, pc, ipending);
/*
* If there is an independent timer interrupt handler, call it first.
* Called interrupt routine returns mask of interrupts to be reenabled.
*/
inttab = &cpu_int_tab[ARC_INTPRI_TIMER_INT];
if (inttab->int_mask & ipending) {
if ((ipending & MIPS_INT_MASK & ~inttab->int_mask) == 0) {
/*
* If all interrupts were enabled and there is no
* pending interrupts, set MIPS_SR_INT_IE so that
* spllowerclock() in hardclock() works properly.
*/
#if 0 /* MIPS_SR_INT_IE is enabled above */
_splset(MIPS_SR_INT_IE);
#endif
} else {
/*
* If there are any pending interrputs, clear
* MIPS_SR_INT_IE in cf.sr so that spllowerclock()
* in hardclock() will not happen.
*/
cf.sr &= ~MIPS_SR_INT_IE;
}
cause &= (*inttab->int_hand)(ipending, &cf);
}
_splset((status & ~handled & MIPS3_HARD_INT_MASK) | MIPS_SR_INT_IE);
_splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
inttab++;
/*
* Check off all other enabled interrupts.
* Called handlers return mask of interrupts to be reenabled.
*/
for (i = ARC_INTPRI_TIMER_INT + 1; i < ARC_NINTPRI; i++) {
if (inttab->int_mask & ipending) {
cause &= (*inttab->int_hand)(ipending, &cf);
}
inttab++;
}
_splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
/* software interrupts */
ipending &= (MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: c_magnum.c,v 1.13 2005/12/11 12:16:37 christos Exp $ */
/* $NetBSD: c_magnum.c,v 1.14 2006/06/24 03:50:38 tsutsui Exp $ */
/* $OpenBSD: machdep.c,v 1.36 1999/05/22 21:22:19 weingart Exp $ */
/*
@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: c_magnum.c,v 1.13 2005/12/11 12:16:37 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: c_magnum.c,v 1.14 2006/06/24 03:50:38 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -174,9 +174,6 @@ timer_magnum_intr(uint32_t mask, struct clockframe *cf)
hardclock(cf);
timer_jazzio_ev.ev_count++;
/* Re-enable clock interrupts */
splx(MIPS_INT_MASK_4 | MIPS_SR_INT_IE);
return ~MIPS_INT_MASK_4; /* Keep clock interrupts enabled */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: c_nec_jazz.c,v 1.11 2005/12/11 12:16:37 christos Exp $ */
/* $NetBSD: c_nec_jazz.c,v 1.12 2006/06/24 03:50:38 tsutsui Exp $ */
/*-
* Copyright (C) 2000 Shuichiro URATA. All rights reserved.
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: c_nec_jazz.c,v 1.11 2005/12/11 12:16:37 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: c_nec_jazz.c,v 1.12 2006/06/24 03:50:38 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -72,9 +72,6 @@ timer_nec_jazz_intr(uint32_t mask, struct clockframe *cf)
hardclock(cf);
timer_jazzio_ev.ev_count++;
/* Re-enable clock interrupts */
splx(MIPS_INT_MASK_3 | MIPS_SR_INT_IE);
return ~MIPS_INT_MASK_3; /* Keep clock interrupts enabled */
}

View File

@ -1,4 +1,4 @@
# $NetBSD: std.arc,v 1.20 2005/12/11 12:16:38 christos Exp $
# $NetBSD: std.arc,v 1.21 2006/06/24 03:50:38 tsutsui Exp $
# standard arc info
machine arc mips
@ -11,6 +11,7 @@ cpu* at mainbus0
# set CPU architecture level for kernel target
#options MIPS1 # R2000/R3000 support
options MIPS3 # R4000/R4400 support
options MIPS3_ENABLE_CLOCK_INTR
# arc port use wired map for device space
options ENABLE_MIPS3_WIRED_MAP

View File

@ -1,4 +1,4 @@
/* $NetBSD: arcsisabr.c,v 1.2 2006/06/12 15:06:32 tsutsui Exp $ */
/* $NetBSD: arcsisabr.c,v 1.3 2006/06/24 03:50:38 tsutsui Exp $ */
/* $OpenBSD: isabus.c,v 1.15 1998/03/16 09:38:46 pefo Exp $ */
/* NetBSD: isa.c,v 1.33 1995/06/28 04:30:51 cgd Exp */
@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: arcsisabr.c,v 1.2 2006/06/12 15:06:32 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: arcsisabr.c,v 1.3 2006/06/24 03:50:38 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -116,7 +116,7 @@ arcsisabrattach(struct device *parent, struct device *self, void *aux)
struct isabr_softc *sc = (struct isabr_softc *)self;
isadma_bounce_tag_init(&sc->sc_dmat);
(*platform->set_intr)(MIPS_INT_MASK_2, isabr_iointr, 2);
(*platform->set_intr)(MIPS_INT_MASK_2, isabr_iointr, ARC_INTPRI_PCIISA);
isabrattach(sc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: tyneisabr.c,v 1.9 2006/04/15 08:49:47 tsutsui Exp $ */
/* $NetBSD: tyneisabr.c,v 1.10 2006/06/24 03:50:38 tsutsui Exp $ */
/* $OpenBSD: isabus.c,v 1.15 1998/03/16 09:38:46 pefo Exp $ */
/* NetBSD: isa.c,v 1.33 1995/06/28 04:30:51 cgd Exp */
@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tyneisabr.c,v 1.9 2006/04/15 08:49:47 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: tyneisabr.c,v 1.10 2006/06/24 03:50:38 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -117,7 +117,7 @@ tyneisabrattach(struct device *parent, struct device *self, void *aux)
struct isabr_softc *sc = (struct isabr_softc *)self;
_bus_dma_tag_init(&sc->sc_dmat); /* XXX dedicated bounce mem */
(*platform->set_intr)(MIPS_INT_MASK_2, isabr_iointr, 2);
(*platform->set_intr)(MIPS_INT_MASK_2, isabr_iointr, ARC_INTPRI_PCIISA);
isabrattach(sc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.15 2006/06/17 14:10:28 tsutsui Exp $ */
/* $NetBSD: intr.h,v 1.16 2006/06/24 03:50:38 tsutsui Exp $ */
/*-
* Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@ -117,6 +117,12 @@ struct clockframe;
void arc_set_intr(uint32_t, uint32_t (*)(uint32_t, struct clockframe *), int);
extern uint32_t cpu_int_mask;
/* priority order to handle each CPU INT line specified via set_intr() */
#define ARC_INTPRI_TIMER_INT 0 /* independent CPU INT for timer */
#define ARC_INTPRI_JAZZ 1 /* CPU INT for JAZZ local bus */
#define ARC_INTPRI_PCIISA 2 /* CPU INT for PCI/EISA/ISA */
#define ARC_NINTPRI 3 /* number of total used CPU INTs */
#endif /* !_LOCORE */
#endif /* _KERNEL */

View File

@ -1,4 +1,4 @@
/* $NetBSD: jazzio.c,v 1.16 2006/04/15 08:49:47 tsutsui Exp $ */
/* $NetBSD: jazzio.c,v 1.17 2006/06/24 03:50:38 tsutsui Exp $ */
/* $OpenBSD: picabus.c,v 1.11 1999/01/11 05:11:10 millert Exp $ */
/* NetBSD: tc.c,v 1.2 1995/03/08 00:39:05 cgd Exp */
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: jazzio.c,v 1.16 2006/04/15 08:49:47 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: jazzio.c,v 1.17 2006/06/24 03:50:38 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -131,7 +131,7 @@ jazzioattach(struct device *parent, struct device *self, void *aux)
}
/* set up interrupt handlers */
(*platform->set_intr)(MIPS_INT_MASK_1, jazzio_intr, 2);
(*platform->set_intr)(MIPS_INT_MASK_1, jazzio_intr, ARC_INTPRI_JAZZ);
sc->sc_bus.ab_dv = (struct device *)sc;

View File

@ -1,4 +1,4 @@
/* $NetBSD: jazzisabr.c,v 1.10 2006/04/15 08:49:47 tsutsui Exp $ */
/* $NetBSD: jazzisabr.c,v 1.11 2006/06/24 03:50:38 tsutsui Exp $ */
/* $OpenBSD: isabus.c,v 1.15 1998/03/16 09:38:46 pefo Exp $ */
/* NetBSD: isa.c,v 1.33 1995/06/28 04:30:51 cgd Exp */
@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: jazzisabr.c,v 1.10 2006/04/15 08:49:47 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: jazzisabr.c,v 1.11 2006/06/24 03:50:38 tsutsui Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -117,7 +117,7 @@ jazzisabrattach(struct device *parent, struct device *self, void *aux)
struct isabr_softc *sc = (struct isabr_softc *)self;
jazz_bus_dma_tag_init(&sc->sc_dmat);
(*platform->set_intr)(MIPS_INT_MASK_2, isabr_iointr, 3);
(*platform->set_intr)(MIPS_INT_MASK_2, isabr_iointr, ARC_INTPRI_PCIISA);
isabrattach(sc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: timer_jazzio.c,v 1.8 2005/12/11 12:16:39 christos Exp $ */
/* $NetBSD: timer_jazzio.c,v 1.9 2006/06/24 03:50:38 tsutsui Exp $ */
/* $OpenBSD: clock.c,v 1.6 1998/10/15 21:30:15 imp Exp $ */
/*
@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: timer_jazzio.c,v 1.8 2005/12/11 12:16:39 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: timer_jazzio.c,v 1.9 2006/06/24 03:50:38 tsutsui Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -146,7 +146,7 @@ timer_jazzio_attach(struct device *parent, struct device *self, void *aux)
evcnt_attach_static(&timer_jazzio_ev);
(*platform->set_intr)(timer_jazzio_conf->tjc_intr_mask,
timer_jazzio_conf->tjc_intr, 1);
timer_jazzio_conf->tjc_intr, ARC_INTPRI_TIMER_INT);
timerattach(&sc->sc_dev, &timerfns_jazzio);

View File

@ -1,4 +1,4 @@
/* $NetBSD: necpb.c,v 1.27 2006/04/16 07:10:45 tsutsui Exp $ */
/* $NetBSD: necpb.c,v 1.28 2006/06/24 03:50:38 tsutsui Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: necpb.c,v 1.27 2006/04/16 07:10:45 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: necpb.c,v 1.28 2006/06/24 03:50:38 tsutsui Exp $");
#include "opt_pci.h"
@ -259,7 +259,7 @@ necpbattach(struct device *parent, struct device *self, void *aux)
for (i = 0; i < 4; i++)
necpb_inttbl[i] = NULL;
(*platform->set_intr)(MIPS_INT_MASK_2, necpb_intr, 3);
(*platform->set_intr)(MIPS_INT_MASK_2, necpb_intr, ARC_INTPRI_PCIISA);
pba.pba_iot = &sc->sc_ncp->nc_iot;
pba.pba_memt = &sc->sc_ncp->nc_memt;