Module Name:    src
Committed By:   skrll
Date:           Wed May 23 16:11:37 UTC 2012

Modified Files:
        src/sys/arch/hp700/conf: GENERIC
        src/sys/arch/hp700/dev: apic.c asp.c cpu.c dino.c lasi.c mongoose.c
            power.c siop_sgc.c wax.c
        src/sys/arch/hp700/gsc: gscbus.c gscbusvar.h
        src/sys/arch/hp700/hp700: autoconf.c genassym.cf intr.c locore.S
            machdep.c mainbus.c
        src/sys/arch/hp700/include: cpu.h intr.h
Removed Files:
        src/sys/arch/hp700/hp700: intr.h

Log Message:
Rework the hp700 interrupt code to

        - note chip restictions on interrupt in the kernel config
        - allocate interrupts at attach time
        - track per CPU interrupts
        - remove a funciton written in assembly


To generate a diff of this commit:
cvs rdiff -u -r1.113 -r1.114 src/sys/arch/hp700/conf/GENERIC
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/hp700/dev/apic.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/hp700/dev/asp.c
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/hp700/dev/cpu.c
cvs rdiff -u -r1.35 -r1.36 src/sys/arch/hp700/dev/dino.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/hp700/dev/lasi.c \
    src/sys/arch/hp700/dev/mongoose.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/hp700/dev/power.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/hp700/dev/siop_sgc.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/hp700/dev/wax.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/hp700/gsc/gscbus.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/hp700/gsc/gscbusvar.h
cvs rdiff -u -r1.46 -r1.47 src/sys/arch/hp700/hp700/autoconf.c
cvs rdiff -u -r1.33 -r1.34 src/sys/arch/hp700/hp700/genassym.cf
cvs rdiff -u -r1.40 -r1.41 src/sys/arch/hp700/hp700/intr.c
cvs rdiff -u -r1.15 -r0 src/sys/arch/hp700/hp700/intr.h
cvs rdiff -u -r1.60 -r1.61 src/sys/arch/hp700/hp700/locore.S
cvs rdiff -u -r1.112 -r1.113 src/sys/arch/hp700/hp700/machdep.c
cvs rdiff -u -r1.82 -r1.83 src/sys/arch/hp700/hp700/mainbus.c
cvs rdiff -u -r1.69 -r1.70 src/sys/arch/hp700/include/cpu.h
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/hp700/include/intr.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/hp700/conf/GENERIC
diff -u src/sys/arch/hp700/conf/GENERIC:1.113 src/sys/arch/hp700/conf/GENERIC:1.114
--- src/sys/arch/hp700/conf/GENERIC:1.113	Fri Apr  6 12:21:58 2012
+++ src/sys/arch/hp700/conf/GENERIC	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.113 2012/04/06 12:21:58 skrll Exp $
+# $NetBSD: GENERIC,v 1.114 2012/05/23 16:11:37 skrll Exp $
 #
 # GENERIC machine description file
 #
@@ -23,7 +23,7 @@ include 	"arch/hp700/conf/std.hp700"
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 options 	SYSCTL_INCLUDE_DESCR	# Include sysctl descriptions in kernel
 
-#ident 		"GENERIC-$Revision: 1.113 $"
+#ident 		"GENERIC-$Revision: 1.114 $"
 
 maxusers	32		# estimated number of users
 
@@ -229,10 +229,13 @@ power0	at mainbus0		# power/fail manager
 lcd0	at mainbus0		# LCD
 
 # Basic Bus Support
-lasi*	at mainbus0		# LASI host adapter ( LSI PN??? )
-asp*	at mainbus0		# this one comes w/ Viper and leds
+lasi0	at mainbus0 irq 28	# LASI host adapter
+lasi0	at phantomas0 irq 28	# LASI on [AB]*
+lasi0	at uturn? irq 28	# LASI on [CJ]*
+lasi1	at mainbus0 irq 27	# 712 GIO card
+asp*	at mainbus0 irq 28	# this one comes w/ Viper and LEDs
 wax*	at mainbus0		# Wax GSC to GSC Bus Adapter
-mongoose* at mainbus0 irq 17	# EISA Bus Adapter ( i82350 or TI??? )
+mongoose* at mainbus0		# EISA Bus Adapter ( i82350 or TI??? )
 #vmeb*	at mainbus0 irq ?	# VME bus adapter
 phantomas*	at mainbus0	# Phantom PseudoBC GSC+ Port
 
@@ -341,10 +344,10 @@ lpt*	at puc? port ?			# || ports on "uni
 # GSC SCSI controllers
 oosiop*	at gsc?				# NCR 53c700
 osiop*	at gsc? flags 0x00000		# NCR 53c710
-siop*	at gsc? irq 3			# NCR 53c720 (Fast/Wide)
-siop*	at mainbus0 irq 3		# NCR 53c720 (Fast/Wide)
-siop*	at phantomas? irq 3		# NCR 53c720 (Fast/Wide)
-siop*	at uturn? irq 3			# NCR 53c720 (Fast/Wide)
+siop*	at gsc?				# NCR 53c720 (Fast/Wide)
+siop*	at mainbus0			# NCR 53c720 (Fast/Wide)
+siop*	at phantomas?			# NCR 53c720 (Fast/Wide)
+siop*	at uturn? 			# NCR 53c720 (Fast/Wide)
 
 # PCI SCSI controllers
 adv*	at pci? dev ? function ?	# AdvanSys 1200[A,B], 9xx[U,UA] SCSI

Index: src/sys/arch/hp700/dev/apic.c
diff -u src/sys/arch/hp700/dev/apic.c:1.15 src/sys/arch/hp700/dev/apic.c:1.16
--- src/sys/arch/hp700/dev/apic.c:1.15	Mon May 21 20:58:39 2012
+++ src/sys/arch/hp700/dev/apic.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: apic.c,v 1.15 2012/05/21 20:58:39 skrll Exp $	*/
+/*	$NetBSD: apic.c,v 1.16 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: apic.c,v 1.14 2011/05/01 21:59:39 kettenis Exp $	*/
 
@@ -28,8 +28,6 @@
 #include <machine/pdc.h>
 #include <machine/intr.h>
 
-#include <hp700/hp700/intr.h>
-
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcidevs.h>
@@ -127,6 +125,7 @@ int
 apic_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
 {
 	struct elroy_softc *sc = pa->pa_pc->_cookie;
+	struct cpu_info *ci = &cpus[0];
 	pci_chipset_tag_t pc = pa->pa_pc;
 	pcitag_t tag = pa->pa_tag;
 	pcireg_t reg;
@@ -139,7 +138,8 @@ apic_intr_map(const struct pci_attach_ar
 #endif
 	line = PCI_INTERRUPT_LINE(reg);
 	if (sc->sc_irq[line] == 0)
-		sc->sc_irq[line] = hp700_intr_allocate_bit(&ir_cpu);
+		sc->sc_irq[line] = hp700_intr_allocate_bit(&ci->ci_ir, -1);
+	KASSERT(sc->sc_irq[line] != -1);
 	*ihp = (line << APIC_INT_LINE_SHIFT) | sc->sc_irq[line];
 
 	return APIC_INT_IRQ(*ihp) == 0;
@@ -194,7 +194,7 @@ apic_intr_establish(void *v, pci_intr_ha
 
 	biv = apic_intr_list[irq];
 	if (biv == NULL) {
-		iv = hp700_intr_establish(pri, apic_intr, aiv, &ir_cpu, irq);
+		iv = hp700_intr_establish(pri, apic_intr, aiv, &ci->ci_ir, irq);
 		if (iv == NULL) {
 			free(aiv, M_DEVBUF);
 			free(cnt, M_DEVBUF);

Index: src/sys/arch/hp700/dev/asp.c
diff -u src/sys/arch/hp700/dev/asp.c:1.20 src/sys/arch/hp700/dev/asp.c:1.21
--- src/sys/arch/hp700/dev/asp.c:1.20	Wed May 23 10:37:01 2012
+++ src/sys/arch/hp700/dev/asp.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: asp.c,v 1.20 2012/05/23 10:37:01 skrll Exp $	*/
+/*	$NetBSD: asp.c,v 1.21 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: asp.c,v 1.5 2000/02/09 05:04:22 mickey Exp $	*/
 
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: asp.c,v 1.20 2012/05/23 10:37:01 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: asp.c,v 1.21 2012/05/23 16:11:37 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -172,10 +172,6 @@ aspmatch(device_t parent, cfdata_t cf, v
 	    ca->ca_type.iodc_sv_model != HPPA_BHA_ASP)
 		return 0;
 
-	/* Make sure we have an IRQ. */
-	if (ca->ca_irq == HP700CF_IRQ_UNDEF)
-		ca->ca_irq = hp700_intr_allocate_bit(&ir_cpu);
-
 	/*
 	 * Forcibly mask the HPA down to the start of the ASP
 	 * chip address space.
@@ -191,12 +187,19 @@ aspattach(device_t parent, device_t self
 	struct confargs *ca = aux;
 	struct asp_softc *sc = device_private(self);
 	struct gsc_attach_args ga;
+	struct cpu_info *ci = &cpus[0];
 	bus_space_handle_t ioh;
 	uint32_t irr;
 	int s;
 
 	sc->sc_dev = self;
 
+	ca->ca_irq = hp700_intr_allocate_bit(&ci->ci_ir, ca->ca_irq);
+	if (ca->ca_irq == HP700CF_IRQ_UNDEF) {
+		aprint_error_dev(self, ": can't allocate interrupt");
+		return;
+	}
+
 	/*
 	 * Map the ASP interrupt registers.
 	 */
@@ -244,18 +247,19 @@ aspattach(device_t parent, device_t self
 	sc->sc_trs->asp_imr = ~0;
 	irr = sc->sc_trs->asp_irr;
 	sc->sc_trs->asp_imr = 0;
-	splx(s);
-
-	aprint_normal(": %s rev %d, lan %d scsi %d\n",
-	    asp_spus[sc->sc_trs->asp_spu].name, sc->sc_hw->asp_version,
-	    sc->sc_trs->asp_lan, sc->sc_trs->asp_scsi);
 
 	/* Establish the interrupt register. */
-	hp700_interrupt_register_establish(&sc->sc_ir);
+	hp700_interrupt_register_establish(ci, &sc->sc_ir);
 	sc->sc_ir.ir_name = device_xname(self);
 	sc->sc_ir.ir_mask = &sc->sc_trs->asp_imr;
 	sc->sc_ir.ir_req = &sc->sc_trs->asp_irr;
 
+	splx(s);
+
+	aprint_normal(": %s rev %d, lan %d scsi %d\n",
+	    asp_spus[sc->sc_trs->asp_spu].name, sc->sc_hw->asp_version,
+	    sc->sc_trs->asp_lan, sc->sc_trs->asp_scsi);
+
 	/* Attach the GSC bus. */
 	ga.ga_ca = *ca;	/* clone from us */
 	if (strcmp(parent->dv_xname, "mainbus0") == 0) {

Index: src/sys/arch/hp700/dev/cpu.c
diff -u src/sys/arch/hp700/dev/cpu.c:1.26 src/sys/arch/hp700/dev/cpu.c:1.27
--- src/sys/arch/hp700/dev/cpu.c:1.26	Wed May 23 09:49:56 2012
+++ src/sys/arch/hp700/dev/cpu.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.26 2012/05/23 09:49:56 skrll Exp $	*/
+/*	$NetBSD: cpu.c,v 1.27 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: cpu.c,v 1.29 2009/02/08 18:33:28 miod Exp $	*/
 
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.26 2012/05/23 09:49:56 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.27 2012/05/23 16:11:37 skrll Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -47,7 +47,6 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.26
 #include <machine/autoconf.h>
 
 #include <hppa/hppa/cpuvar.h>
-#include <hp700/hp700/intr.h>
 #include <hp700/hp700/machdep.h>
 #include <hp700/dev/cpudevs.h>
 
@@ -92,8 +91,9 @@ cpuattach(device_t parent, device_t self
 
 	struct cpu_softc *sc = device_private(self);
 	struct confargs *ca = aux;
-	struct cpu_info *ci;
 	static const char lvls[4][4] = { "0", "1", "1.5", "2" };
+	struct hp700_interrupt_register *ir;
+	struct cpu_info *ci;
 	u_int mhz = 100 * cpu_ticksnum / cpu_ticksdenom;
 	int cpuno = device_unit(self);
 
@@ -115,6 +115,12 @@ cpuattach(device_t parent, device_t self
 		aprint_normal(" (%s)", hppa_cpu_info->hci_chip_nickname);
 	aprint_normal(" rev %d", cpu_revision);
 
+	/* sanity against luser amongst config editors */
+	if (ca->ca_irq != 31) {
+		aprint_error_dev(self, "bad irq number %d\n", ca->ca_irq);
+		return;
+	}
+
 	/* Print the CPU type, spec, level, category, and speed. */
 	aprint_normal("\n%s: %s, PA-RISC %s", self->dv_xname,
 	    hppa_cpu_info->hci_chip_type,
@@ -156,17 +162,25 @@ cpuattach(device_t parent, device_t self
 	    hppa_mod_info(HPPA_TYPE_FPU, (fpu_version >> 16) & 0x1f),
 	    (fpu_version >> 11) & 0x1f);
 
-	/* sanity against luser amongst config editors */
-	if (ca->ca_irq != 31) {
-		aprint_error_dev(self, "bad irq number %d\n", ca->ca_irq);
-		return;
-	}
-	
+	hp700_intr_initialise(ci);
+
+	ir = &ci->ci_ir;
+	hp700_interrupt_register_establish(ci, ir);
+	ir->ir_iscpu = true;
+	ir->ir_ci = ci;
+	ir->ir_name = device_xname(self);
+
 	sc->sc_ihclk = hp700_intr_establish(IPL_CLOCK, clock_intr,
-	    NULL /*clockframe*/, &ir_cpu, 31);
+	    NULL /*clockframe*/, &ci->ci_ir, 31);
 
-#ifdef MULTIPROCESSOR
+	/*
+	 * Reserve some bits for chips that don't like to be moved
+	 * around, e.g. lasi and asp.
+	 */
+	ir->ir_rbits = ((1 << 28) | (1 << 27));
+	ir->ir_bits &= ~ir->ir_rbits;
 
+#ifdef MULTIPROCESSOR
 	/* Allocate stack for spin up and FPU emulation. */
 	TAILQ_INIT(&mlist);
 	error = uvm_pglistalloc(PAGE_SIZE, 0, -1L, PAGE_SIZE, 0, &mlist, 1, 0);
@@ -191,21 +205,10 @@ cpuattach(device_t parent, device_t self
 		}
 	}
 	hppa_ncpu++;
-
 #endif
-
-	/*
-	 * Set the allocatable bits in the CPU interrupt registers.
-	 * These should only be used by major chipsets, like ASP and
-	 * LASI, and the bits used appear to be important - the
-	 * ASP doesn't seem to like to use interrupt bits above 28
-	 * or below 27.
-	 */
-	ir_cpu.ir_bits =
-		(1 << 28) | (1 << 27) | (1 << 26);
+	KASSERT(ci->ci_cpl == -1);
 }
 
-
 #ifdef MULTIPROCESSOR
 void
 cpu_boot_secondary_processors(void)

Index: src/sys/arch/hp700/dev/dino.c
diff -u src/sys/arch/hp700/dev/dino.c:1.35 src/sys/arch/hp700/dev/dino.c:1.36
--- src/sys/arch/hp700/dev/dino.c:1.35	Wed May 23 10:31:59 2012
+++ src/sys/arch/hp700/dev/dino.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: dino.c,v 1.35 2012/05/23 10:31:59 skrll Exp $ */
+/*	$NetBSD: dino.c,v 1.36 2012/05/23 16:11:37 skrll Exp $ */
 
 /*	$OpenBSD: dino.c,v 1.5 2004/02/13 20:39:31 mickey Exp $	*/
 
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dino.c,v 1.35 2012/05/23 10:31:59 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dino.c,v 1.36 2012/05/23 16:11:37 skrll Exp $");
 
 /* #include "cardbus.h" */
 
@@ -43,7 +43,6 @@ __KERNEL_RCSID(0, "$NetBSD: dino.c,v 1.3
 #include <machine/iomod.h>
 #include <machine/autoconf.h>
 #include <machine/intr.h>
-#include <hp700/hp700/intr.h>
 
 #include <hppa/include/vmparam.h>
 #include <hp700/dev/cpudevs.h>
@@ -1594,10 +1593,6 @@ dinomatch(device_t parent, cfdata_t cfda
 	if (ca->ca_type.iodc_model == 0x78)
 		return 0;
 
-	/* Make sure we have an IRQ. */
-	if (ca->ca_irq == HP700CF_IRQ_UNDEF)
-		ca->ca_irq = hp700_intr_allocate_bit(&ir_cpu);
-
 	return 1;
 }
 
@@ -1617,6 +1612,7 @@ dinoattach(device_t parent, device_t sel
 	sc->sc_bt = ca->ca_iot;
 	sc->sc_dmat = ca->ca_dmatag;
 
+	ca->ca_irq = hp700_intr_allocate_bit(&ci->ci_ir, ca->ca_irq);
 	if (ca->ca_irq == HP700CF_IRQ_UNDEF) {
 		aprint_error_dev(self, ": can't allocate interrupt");
 		return;
@@ -1659,7 +1655,7 @@ dinoattach(device_t parent, device_t sel
 	r->iar0 = ci->ci_hpa | (31 - ca->ca_irq);
 	splx(s);
 	/* Establish the interrupt register. */
-	hp700_interrupt_register_establish(&sc->sc_ir);
+	hp700_interrupt_register_establish(ci, &sc->sc_ir);
 	sc->sc_ir.ir_name = device_xname(self);
 	sc->sc_ir.ir_mask = &r->imr;
 	sc->sc_ir.ir_req = &r->irr0;
@@ -1667,7 +1663,7 @@ dinoattach(device_t parent, device_t sel
 	/* Add the I/O interrupt register. */
 
 	sc->sc_ih = hp700_intr_establish(IPL_NONE, NULL, &sc->sc_ir,
-	    &ir_cpu, ca->ca_irq);
+	    &ci->ci_ir, ca->ca_irq);
 
 	/* TODO establish the bus error interrupt */
 

Index: src/sys/arch/hp700/dev/lasi.c
diff -u src/sys/arch/hp700/dev/lasi.c:1.22 src/sys/arch/hp700/dev/lasi.c:1.23
--- src/sys/arch/hp700/dev/lasi.c:1.22	Tue Apr  3 12:07:26 2012
+++ src/sys/arch/hp700/dev/lasi.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: lasi.c,v 1.22 2012/04/03 12:07:26 skrll Exp $	*/
+/*	$NetBSD: lasi.c,v 1.23 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: lasi.c,v 1.4 2001/06/09 03:57:19 mickey Exp $	*/
 
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lasi.c,v 1.22 2012/04/03 12:07:26 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lasi.c,v 1.23 2012/05/23 16:11:37 skrll Exp $");
 
 #undef LASIDEBUG
 
@@ -132,10 +132,6 @@ lasimatch(device_t parent, cfdata_t cf, 
 	    ca->ca_type.iodc_sv_model != HPPA_BHA_LASI)
 		return 0;
 
-	/* Make sure we have an IRQ. */
-	if (ca->ca_irq == HP700CF_IRQ_UNDEF)
-		ca->ca_irq = hp700_intr_allocate_bit(&ir_cpu);
-
 	/*
 	 * Forcibly mask the HPA down to the start of the LASI
 	 * chip address space.
@@ -181,6 +177,12 @@ lasiattach(device_t parent, device_t sel
 	aprint_normal(": rev %d.%d\n", (sc->sc_hw->lasi_version & 0xf0) >> 4,
 		sc->sc_hw->lasi_version & 0xf);
 
+	ca->ca_irq = hp700_intr_allocate_bit(&ci->ci_ir, ca->ca_irq);
+	if (ca->ca_irq == HP700CF_IRQ_UNDEF) {
+		aprint_error(": can't allocate interrupt\n");
+		return;
+	}
+
 	/* interrupts guts */
 	s = splhigh();
 	sc->sc_trs->lasi_iar = ci->ci_hpa | (31 - ca->ca_irq);
@@ -188,13 +190,13 @@ lasiattach(device_t parent, device_t sel
 	sc->sc_trs->lasi_imr = ~0U;
 	in = sc->sc_trs->lasi_irr;
 	sc->sc_trs->lasi_imr = 0;
-	splx(s);
 
 	/* Establish the interrupt register. */
-	hp700_interrupt_register_establish(&sc->sc_ir);
+	hp700_interrupt_register_establish(ci, &sc->sc_ir);
 	sc->sc_ir.ir_name = device_xname(self);
 	sc->sc_ir.ir_mask = &sc->sc_trs->lasi_imr;
 	sc->sc_ir.ir_req = &sc->sc_trs->lasi_irr;
+	splx(s);
 
 	/* Attach the GSC bus. */
 	ga.ga_ca = *ca;	/* clone from us */
Index: src/sys/arch/hp700/dev/mongoose.c
diff -u src/sys/arch/hp700/dev/mongoose.c:1.22 src/sys/arch/hp700/dev/mongoose.c:1.23
--- src/sys/arch/hp700/dev/mongoose.c:1.22	Fri Jul  1 18:33:09 2011
+++ src/sys/arch/hp700/dev/mongoose.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: mongoose.c,v 1.22 2011/07/01 18:33:09 dyoung Exp $	*/
+/*	$NetBSD: mongoose.c,v 1.23 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: mongoose.c,v 1.19 2010/01/01 20:28:42 kettenis Exp $	*/
 
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mongoose.c,v 1.22 2011/07/01 18:33:09 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mongoose.c,v 1.23 2012/05/23 16:11:37 skrll Exp $");
 
 #define MONGOOSE_DEBUG 9
 
@@ -42,7 +42,6 @@ __KERNEL_RCSID(0, "$NetBSD: mongoose.c,v
 #include <machine/iomod.h>
 #include <machine/autoconf.h>
 
-#include <hp700/hp700/intr.h>
 #include <hp700/dev/cpudevs.h>
 #include <hp700/dev/viper.h>
 
@@ -358,7 +357,7 @@ mg_intr(void *v)
 	int s, irq = 0;
 
 	iv = &sc->sc_iv[irq];
-	s = splraise(imask[iv->iv_pri]);
+	s = splraise(iv->iv_pri);
 	(iv->iv_handler)(iv->iv_arg);
 	splx(s);
 
@@ -594,6 +593,7 @@ mgattach(device_t parent, device_t self,
 {
 	struct confargs *ca = aux;
 	struct mongoose_softc *sc = device_private(self);
+	struct cpu_info *ci = &cpus[0];
 	struct hppa_bus_space_tag *bt;
 	union mongoose_attach_args ea;
 	char brid[EISA_IDSTRINGLEN];
@@ -616,6 +616,13 @@ mgattach(device_t parent, device_t self,
 		    sizeof(struct mongoose_regs));
 		return;
 	}
+
+	ca->ca_irq = hp700_intr_allocate_bit(&ci->ci_ir, ca->ca_irq);
+	if (ca->ca_irq == HP700CF_IRQ_UNDEF) {
+		aprint_error(": can't allocate interrupt\n");
+		return;
+	}
+
 	sc->sc_ctrl = (struct mongoose_ctrl *)ioh;
 
 	viper_eisa_en();
@@ -709,6 +716,6 @@ mgattach(device_t parent, device_t self,
 #undef	R
 
 	/* attach interrupt */
-	sc->sc_ih = hp700_intr_establish(IPL_NONE, mg_intr, sc, &ir_cpu,
+	sc->sc_ih = hp700_intr_establish(IPL_NONE, mg_intr, sc, &ci->ci_ir,
 	    ca->ca_irq);
 }

Index: src/sys/arch/hp700/dev/power.c
diff -u src/sys/arch/hp700/dev/power.c:1.6 src/sys/arch/hp700/dev/power.c:1.7
--- src/sys/arch/hp700/dev/power.c:1.6	Tue Jan  4 10:42:33 2011
+++ src/sys/arch/hp700/dev/power.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: power.c,v 1.6 2011/01/04 10:42:33 skrll Exp $	*/
+/*	$NetBSD: power.c,v 1.7 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*
  * Copyright (c) 2004 Jochen Kunz.
@@ -70,7 +70,6 @@
 #include <machine/autoconf.h>
 
 #include <hp700/dev/cpudevs.h>
-#include <hp700/hp700/intr.h>
 
 #include <dev/sysmon/sysmon_taskq.h>
 #include <dev/sysmon/sysmonvar.h>

Index: src/sys/arch/hp700/dev/siop_sgc.c
diff -u src/sys/arch/hp700/dev/siop_sgc.c:1.9 src/sys/arch/hp700/dev/siop_sgc.c:1.10
--- src/sys/arch/hp700/dev/siop_sgc.c:1.9	Tue Apr  3 12:07:26 2012
+++ src/sys/arch/hp700/dev/siop_sgc.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: siop_sgc.c,v 1.9 2012/04/03 12:07:26 skrll Exp $	*/
+/*	$NetBSD: siop_sgc.c,v 1.10 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: siop_sgc.c,v 1.1 2007/08/05 19:09:52 kettenis Exp $	*/
 
@@ -19,7 +19,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: siop_sgc.c,v 1.9 2012/04/03 12:07:26 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siop_sgc.c,v 1.10 2012/05/23 16:11:37 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -40,7 +40,6 @@ __KERNEL_RCSID(0, "$NetBSD: siop_sgc.c,v
 #include <dev/ic/siopvar.h>
 
 #include <hp700/dev/cpudevs.h>
-#include <hp700/hp700/intr.h>
 
 #define IO_II_INTEN		0x20000000
 #define IO_II_PACKEN		0x10000000
@@ -75,10 +74,6 @@ siop_sgc_match(device_t parent, cfdata_t
 	    ca->ca_type.iodc_sv_model != HPPA_ADMA_FWSCSI)
 		return 0;
 
-	/* Make sure we have an IRQ. */
-	if (ca->ca_irq == HP700CF_IRQ_UNDEF)
-		ca->ca_irq = hp700_intr_allocate_bit(&ir_cpu);
-
 	return 1;
 }
 
@@ -99,6 +94,12 @@ siop_sgc_attach(device_t parent, device_
 		return;
 	}
 
+	ca->ca_irq = hp700_intr_allocate_bit(&ci->ci_ir, ca->ca_irq);
+	if (ca->ca_irq == HP700CF_IRQ_UNDEF) {
+		aprint_error(": can't allocate interrupt\n");
+		return;
+	}
+
 	sgc->sc_bustag = *sgc->sc_iot;
 	sgc->sc_bustag.hbt_r1 = siop_sgc_r1;
 	sgc->sc_bustag.hbt_r2 = siop_sgc_r2;
@@ -135,7 +136,7 @@ siop_sgc_attach(device_t parent, device_
 
 	siop_attach(&sgc->sc_siop);
 
-	(void)hp700_intr_establish(IPL_BIO, siop_intr, sc, &ir_cpu,
+	(void)hp700_intr_establish(IPL_BIO, siop_intr, sc, &ci->ci_ir,
 	    ca->ca_irq);
 }
 

Index: src/sys/arch/hp700/dev/wax.c
diff -u src/sys/arch/hp700/dev/wax.c:1.19 src/sys/arch/hp700/dev/wax.c:1.20
--- src/sys/arch/hp700/dev/wax.c:1.19	Wed May 23 10:31:59 2012
+++ src/sys/arch/hp700/dev/wax.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: wax.c,v 1.19 2012/05/23 10:31:59 skrll Exp $	*/
+/*	$NetBSD: wax.c,v 1.20 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: wax.c,v 1.1 1998/11/23 03:04:10 mickey Exp $	*/
 
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wax.c,v 1.19 2012/05/23 10:31:59 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wax.c,v 1.20 2012/05/23 16:11:37 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -101,11 +101,6 @@ waxmatch(device_t parent, cfdata_t cf, v
 	    ca->ca_type.iodc_sv_model != HPPA_BHA_WAX)
 		return 0;
 
-	/* Make sure we have an IRQ. */
-	if (ca->ca_irq == HP700CF_IRQ_UNDEF) {
-		ca->ca_irq = hp700_intr_allocate_bit(&ir_cpu);
-	}
-
 	return 1;
 }
 
@@ -119,6 +114,7 @@ waxattach(device_t parent, device_t self
 	bus_space_handle_t ioh;
 	int s, in;
 
+	ca->ca_irq = hp700_intr_allocate_bit(&ci->ci_ir, ca->ca_irq);
 	if (ca->ca_irq == HP700CF_IRQ_UNDEF) {
 		aprint_error(": can't allocate interrupt\n");
 		return;
@@ -149,7 +145,7 @@ waxattach(device_t parent, device_t self
 	splx(s);
 
 	/* Establish the interrupt register. */
-	hp700_interrupt_register_establish(&sc->sc_ir);
+	hp700_interrupt_register_establish(ci, &sc->sc_ir);
 	sc->sc_ir.ir_name = device_xname(self);
 	sc->sc_ir.ir_mask = &sc->sc_regs->wax_imr;
 	sc->sc_ir.ir_req = &sc->sc_regs->wax_irr;

Index: src/sys/arch/hp700/gsc/gscbus.c
diff -u src/sys/arch/hp700/gsc/gscbus.c:1.22 src/sys/arch/hp700/gsc/gscbus.c:1.23
--- src/sys/arch/hp700/gsc/gscbus.c:1.22	Tue Feb  1 18:33:24 2011
+++ src/sys/arch/hp700/gsc/gscbus.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: gscbus.c,v 1.22 2011/02/01 18:33:24 skrll Exp $	*/
+/*	$NetBSD: gscbus.c,v 1.23 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: gscbus.c,v 1.13 2001/08/01 20:32:04 miod Exp $	*/
 
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gscbus.c,v 1.22 2011/02/01 18:33:24 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gscbus.c,v 1.23 2012/05/23 16:11:37 skrll Exp $");
 
 #define GSCDEBUG
 
@@ -136,6 +136,7 @@ gscattach(device_t parent, device_t self
 {
 	struct gsc_softc *sc = device_private(self);
 	struct gsc_attach_args *ga = aux;
+	struct cpu_info *ci = &cpus[0];
 
 	sc->sc_dev = self;
 	sc->sc_ga = *ga;
@@ -150,7 +151,7 @@ gscattach(device_t parent, device_t self
 	/* Add the I/O subsystem's interrupt register. */
 	ga->ga_ir->ir_name = device_xname(self);
 	sc->sc_ih = hp700_intr_establish(IPL_NONE, NULL, ga->ga_ir,
-	    &ir_cpu, ga->ga_irq);
+	    &ci->ci_ir, ga->ga_irq);
 
 	ga->ga_ca.ca_nmodules = MAXMODBUS;
 	ga->ga_ca.ca_hpabase = 0;

Index: src/sys/arch/hp700/gsc/gscbusvar.h
diff -u src/sys/arch/hp700/gsc/gscbusvar.h:1.10 src/sys/arch/hp700/gsc/gscbusvar.h:1.11
--- src/sys/arch/hp700/gsc/gscbusvar.h:1.10	Tue Feb  1 18:33:24 2011
+++ src/sys/arch/hp700/gsc/gscbusvar.h	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: gscbusvar.h,v 1.10 2011/02/01 18:33:24 skrll Exp $	*/
+/*	$NetBSD: gscbusvar.h,v 1.11 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: gscbusvar.h,v 1.3 1999/08/16 02:48:39 mickey Exp $	*/
 
@@ -28,7 +28,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <hp700/hp700/intr.h>
+#include <machine/intr.h>
 
 struct gsc_attach_args {
 	struct confargs ga_ca;

Index: src/sys/arch/hp700/hp700/autoconf.c
diff -u src/sys/arch/hp700/hp700/autoconf.c:1.46 src/sys/arch/hp700/hp700/autoconf.c:1.47
--- src/sys/arch/hp700/hp700/autoconf.c:1.46	Wed May 23 11:08:33 2012
+++ src/sys/arch/hp700/hp700/autoconf.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.46 2012/05/23 11:08:33 skrll Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.47 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: autoconf.c,v 1.15 2001/06/25 00:43:10 mickey Exp $	*/
 
@@ -86,7 +86,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.46 2012/05/23 11:08:33 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.47 2012/05/23 16:11:37 skrll Exp $");
 
 #include "opt_kgdb.h"
 #include "opt_useleds.h"
@@ -164,8 +164,6 @@ static void hppa_pdc_system_map_scan(voi
 void
 cpu_configure(void)
 {
-	struct cpu_info *ci = curcpu();
-
 	/*
 	 * Consider stopping for a debugger before
 	 * autoconfiguration.
@@ -184,10 +182,8 @@ cpu_configure(void)
 	if (config_rootfound("mainbus", NULL) == NULL)
 		panic("no mainbus found");
 
-	/* in spl*() we trust */
-	hp700_intr_init();
-	hppa_enable_irq();
-	ci->ci_psw |= PSW_I;
+	/* Allow interrupts - we're trusting spl* here */
+	hp700_intr_enable();
 	spl0();
 
 	if (cold_hook)

Index: src/sys/arch/hp700/hp700/genassym.cf
diff -u src/sys/arch/hp700/hp700/genassym.cf:1.33 src/sys/arch/hp700/hp700/genassym.cf:1.34
--- src/sys/arch/hp700/hp700/genassym.cf:1.33	Wed May 23 11:18:46 2012
+++ src/sys/arch/hp700/hp700/genassym.cf	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.33 2012/05/23 11:18:46 skrll Exp $
+#	$NetBSD: genassym.cf,v 1.34 2012/05/23 16:11:37 skrll Exp $
 
 #	$OpenBSD: genassym.cf,v 1.18 2001/09/20 18:31:14 mickey Exp $
 
@@ -64,8 +64,7 @@ include <machine/frame.h>
 include <machine/pmap.h>
 include <machine/iomod.h>
 include <machine/lock.h>
-
-include <hp700/hp700/intr.h>
+include <machine/intr.h>
 
 include <hppa/hppa/hpt.h>
 
@@ -88,7 +87,6 @@ export	HPPA_BREAK_SET_PSW
 struct	hp700_interrupt_register
 member	IR_REQ			ir_req
 member	IR_BITS_MAP		ir_bits_map
-export	IR_BIT_REG
 
 # struct cpu_info fields
 define	CI_TRAPSAVE		offsetof(struct cpu_info, ci_trapsave)
@@ -96,6 +94,7 @@ define	CI_MTX_COUNT		offsetof(struct cpu
 define	CI_CPL			offsetof(struct cpu_info, ci_cpl)
 define	CI_IPENDING		offsetof(struct cpu_info, ci_ipending)
 #define	CI_INTR_DEPTH		offsetof(struct cpu_info, ci_intr_depth)
+define	CI_IMASK		offsetof(struct cpu_info, ci_imask)
 #define	CI_SOFTLWPS		offsetof(struct cpu_info, ci_softlwps)
 define	CI_PSW			offsetof(struct cpu_info, ci_psw)
 define	CI_FPU_STATE		offsetof(struct cpu_info, ci_fpu_state)

Index: src/sys/arch/hp700/hp700/intr.c
diff -u src/sys/arch/hp700/hp700/intr.c:1.40 src/sys/arch/hp700/hp700/intr.c:1.41
--- src/sys/arch/hp700/hp700/intr.c:1.40	Wed May 23 11:04:54 2012
+++ src/sys/arch/hp700/hp700/intr.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.c,v 1.40 2012/05/23 11:04:54 skrll Exp $	*/
+/*	$NetBSD: intr.c,v 1.41 2012/05/23 16:11:37 skrll Exp $	*/
 /*	$OpenBSD: intr.c,v 1.27 2009/12/31 12:52:35 jsing Exp $	*/
 
 /*
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.40 2012/05/23 11:04:54 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.41 2012/05/23 16:11:37 skrll Exp $");
 
 #define __MUTEX_PRIVATE
 
@@ -50,7 +50,6 @@ __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.4
 #include <machine/intr.h>
 #include <machine/reg.h>
 
-#include <hp700/hp700/intr.h>
 #include <hp700/hp700/machdep.h>
 
 #include <machine/mutex.h>
@@ -59,68 +58,32 @@ __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.4
 #include "opt_lockdebug.h"
 #endif
 
-/* The priority level masks. */
-int imask[NIPL];
-
-/* Shared interrupts */
-int ishared;
+static int hp700_intr_ipl_next(struct cpu_info *);
+void hp700_intr_calculatemasks(struct cpu_info *);
+int hp700_intr_ipending(struct hp700_interrupt_register *, int);
+void hp700_intr_dispatch(int , int , struct trapframe *);
 
 /* The list of all interrupt registers. */
 struct hp700_interrupt_register *hp700_interrupt_registers[HP700_INTERRUPT_BITS];
 
-/*
- * The array of interrupt handler structures, one per bit.
- */
-static struct hp700_interrupt_bit {
-
-	/* The interrupt register this bit is in. */
-	struct hp700_interrupt_register *ib_reg;
-
-	/*
-	 * The priority level associated with this bit, e.g, IPL_BIO, IPL_NET,
-	 * etc.
-	 */
-	int ib_ipl;
-
-	/*
-	 * The spl mask for this bit.  This starts out as the spl bit assigned
-	 * to this particular interrupt, and later gets fleshed out by the mask
-	 * calculator to be the full mask that we need to raise spl to when we
-	 * get this interrupt.
-	 */
-	int ib_spl;
-
-	/* The interrupt name. */
-	char ib_name[16];
-
-	/* The interrupt event count. */
-	struct evcnt ib_evcnt;
-
-	/*
-	 * The interrupt handler and argument for this bit.  If the argument is
-	 * NULL, the handler gets the trapframe.
-	 */
-	int (*ib_handler)(void *);
-	void *ib_arg;
-
-} hp700_interrupt_bits[HP700_INTERRUPT_BITS];
-
-/* The CPU interrupt register. */
-struct hp700_interrupt_register ir_cpu;
 
 /*
  * This establishes a new interrupt register.
  */
 void
-hp700_interrupt_register_establish(struct hp700_interrupt_register *ir)
+hp700_interrupt_register_establish(struct cpu_info *ci, 
+    struct hp700_interrupt_register *ir)
 {
 	int idx;
 
 	/* Initialize the register structure. */
 	memset(ir, 0, sizeof(*ir));
+	ir->ir_ci = ci;
+
 	for (idx = 0; idx < HP700_INTERRUPT_BITS; idx++)
 		ir->ir_bits_map[idx] = IR_BIT_UNUSED;
 
+	ir->ir_bits = ~0;
 	/* Add this structure to the list. */
 	for (idx = 0; idx < HP700_INTERRUPT_BITS; idx++)
 		if (hp700_interrupt_registers[idx] == NULL)
@@ -131,17 +94,16 @@ hp700_interrupt_register_establish(struc
 }
 
 /*
- * This bootstraps interrupts.
+ * This initialise interrupts for a CPU.
  */
 void
-hp700_intr_bootstrap(void)
+hp700_intr_initialise(struct cpu_info *ci)
 {
-	struct cpu_info *ci = curcpu();
 	int i;
 
 	/* Initialize all prority level masks to mask everything. */
 	for (i = 0; i < NIPL; i++)
-		imask[i] = -1;
+		ci->ci_imask[i] = -1;
 
 	/* We are now at the highest priority level. */
 	ci->ci_cpl = -1;
@@ -149,18 +111,14 @@ hp700_intr_bootstrap(void)
 	/* There are no pending interrupts. */
 	ci->ci_ipending = 0;
 
-	/* We are not running an interrupt. */
+	/* We are not running an interrupt handler. */
 	ci->ci_intr_depth = 0;
 
 	/* There are no interrupt handlers. */
-	memset(hp700_interrupt_bits, 0, sizeof(hp700_interrupt_bits));
+	memset(ci->ci_ib, 0, sizeof(ci->ci_ib));
 
 	/* There are no interrupt registers. */
 	memset(hp700_interrupt_registers, 0, sizeof(hp700_interrupt_registers));
-
-	/* Initialize the CPU interrupt register description. */
-	hp700_interrupt_register_establish(&ir_cpu);
-	ir_cpu.ir_name = "cpu0";
 }
 
 /*
@@ -171,6 +129,7 @@ hp700_intr_establish(int ipl, int (*hand
     struct hp700_interrupt_register *ir, int bit_pos)
 {
 	struct hp700_interrupt_bit *ib;
+	struct cpu_info *ci = ir->ir_ci;
 	int idx;
 
 	/* Panic on a bad interrupt bit. */
@@ -182,38 +141,44 @@ hp700_intr_establish(int ipl, int (*hand
 	 * shared interrupts for cascaded registers, e.g. dino and gsc
 	 * XXX This could be improved.
 	 */
-	if (ir->ir_bits_map[31 ^ bit_pos] != IR_BIT_UNUSED &&
-	    !IR_BIT_NESTED_P(ir->ir_bits_map[31 ^ bit_pos]) &&
-	    handler == NULL)
-		panic("%s: int already handled", __func__);
-
+	if (handler != NULL) {
+		if (IR_BIT_USED_P(ir->ir_bits_map[31 ^ bit_pos]))
+			panic("%s: interrupt already handled", __func__);
+	}
+	
 	/*
 	 * If this interrupt bit leads us to another interrupt register,
 	 * simply note that in the mapping for the bit.
 	 */
 	if (handler == NULL) {
-		for (idx = 0; idx < HP700_INTERRUPT_BITS; idx++)
+		for (idx = 1; idx < HP700_INTERRUPT_BITS; idx++)
 			if (hp700_interrupt_registers[idx] == arg)
 				break;
 		if (idx == HP700_INTERRUPT_BITS)
 			panic("%s: unknown int reg", __func__);
-		ir->ir_bits_map[31 ^ bit_pos] = IR_BIT_REG | idx;
 		
+		ir->ir_bits_map[31 ^ bit_pos] = IR_BIT_REG(idx);
+
 		return NULL;
 	}
 
 	/*
 	 * Otherwise, allocate a new bit in the spl.
 	 */
-	idx = _hp700_intr_ipl_next();
+	idx = hp700_intr_ipl_next(ir->ir_ci);
+
 	ir->ir_bits &= ~(1 << bit_pos);
-	if (ir->ir_bits_map[31 ^ bit_pos] == IR_BIT_UNUSED)
+	ir->ir_rbits &= ~(1 << bit_pos);
+	if (!IR_BIT_USED_P(ir->ir_bits_map[31 ^ bit_pos])) {
 		ir->ir_bits_map[31 ^ bit_pos] = 1 << idx;
-	else {
+	} else {
+		int j;
+		
 		ir->ir_bits_map[31 ^ bit_pos] |= 1 << idx;
-		ishared |= ir->ir_bits_map[31 ^ bit_pos];
+		j = (ir - hp700_interrupt_registers[0]);
+		ci->ci_ishared |= (1 << j);
 	}
-	ib = &hp700_interrupt_bits[idx];
+	ib = &ci->ci_ib[idx];
 
 	/* Fill this interrupt bit. */
 	ib->ib_reg = ir;
@@ -226,6 +191,8 @@ hp700_intr_establish(int ipl, int (*hand
 	ib->ib_handler = handler;
 	ib->ib_arg = arg;
 
+	hp700_intr_calculatemasks(ci);
+
 	return ib;
 }
 
@@ -234,32 +201,45 @@ hp700_intr_establish(int ipl, int (*hand
  * It returns the bit position, or -1 if no bits were available.
  */
 int
-hp700_intr_allocate_bit(struct hp700_interrupt_register *ir)
+hp700_intr_allocate_bit(struct hp700_interrupt_register *ir, int irq)
 {
 	int bit_pos;
+	int last_bit;
 	u_int mask;
+	int *bits;
 
-	for (bit_pos = 31, mask = (1 << bit_pos);
-	     bit_pos >= 0;
-	     bit_pos--, mask >>= 1)
-		if (ir->ir_bits & mask)
+	if (irq == -1) {
+		bit_pos = 31;
+		last_bit = 0;
+		bits = &ir->ir_bits;
+	} else {
+		bit_pos = irq;
+		last_bit = irq;
+		bits = &ir->ir_rbits;
+	}
+	for (mask = (1 << bit_pos); bit_pos >= last_bit; bit_pos--) {
+		if (*bits & mask)
 			break;
-	if (bit_pos >= 0)
-		ir->ir_bits &= ~mask;
+		mask >>= 1;
+	}
+	if (bit_pos >= last_bit) {
+		*bits &= ~mask;
+		return bit_pos;
+	}
 
-	return bit_pos;
+	return -1;
 }
 
 /*
- * This returns the next available spl bit.  This is not intended for wide use.
+ * This returns the next available spl bit.
  */
-int
-_hp700_intr_ipl_next(void)
+static int
+hp700_intr_ipl_next(struct cpu_info *ci)
 {
 	int idx;
 
 	for (idx = 0; idx < HP700_INTERRUPT_BITS; idx++)
-		if (hp700_interrupt_bits[idx].ib_reg == NULL)
+		if (ci->ci_ib[idx].ib_reg == NULL)
 			break;
 	if (idx == HP700_INTERRUPT_BITS)
 		panic("%s: too many devices", __func__);
@@ -270,92 +250,74 @@ _hp700_intr_ipl_next(void)
  * This finally initializes interrupts.
  */
 void
-hp700_intr_init(void)
+hp700_intr_calculatemasks(struct cpu_info *ci)
 {
 	struct hp700_interrupt_bit *ib;
 	struct hp700_interrupt_register *ir;
-	struct cpu_info *ci = curcpu();
 	int idx, bit_pos;
 	int mask;
-	int eiem;
+	int ipl;
 
 	/*
 	 * Put together the initial imask for each level.
 	 */
-	memset(imask, 0, sizeof(imask));
+	memset(ci->ci_imask, 0, sizeof(ci->ci_imask));
 	for (bit_pos = 0; bit_pos < HP700_INTERRUPT_BITS; bit_pos++) {
-		ib = hp700_interrupt_bits + bit_pos;
+		ib = &ci->ci_ib[bit_pos];
 		if (ib->ib_reg == NULL)
 			continue;
-		imask[ib->ib_ipl] |= ib->ib_spl;
+		ci->ci_imask[ib->ib_ipl] |= ib->ib_spl;
 	}
 
-	/* The following bits cribbed from i386/isa/isa_machdep.c: */
-
 	/*
 	 * IPL_NONE is used for hardware interrupts that are never blocked,
 	 * and do not block anything else.
 	 */
-	imask[IPL_NONE] = 0;
+	ci->ci_imask[IPL_NONE] = 0;
 
 	/*
 	 * Enforce a hierarchy that gives slow devices a better chance at not
 	 * dropping data.
 	 */
-	imask[IPL_SOFTCLOCK] |= imask[IPL_NONE];
-	imask[IPL_SOFTBIO] |= imask[IPL_SOFTCLOCK];
-	imask[IPL_SOFTNET] |= imask[IPL_SOFTBIO];
-	imask[IPL_SOFTSERIAL] |= imask[IPL_SOFTNET];
-	imask[IPL_VM] |= imask[IPL_SOFTSERIAL];
-	imask[IPL_SCHED] |= imask[IPL_VM];
-	imask[IPL_HIGH] |= imask[IPL_SCHED];
-
-	/* Now go back and flesh out the spl levels on each bit. */
-	for (bit_pos = 0; bit_pos < HP700_INTERRUPT_BITS; bit_pos++) {
-		ib = hp700_interrupt_bits + bit_pos;
-		if (ib->ib_reg == NULL)
-			continue;
-		ib->ib_spl = imask[ib->ib_ipl];
-	}
-
-	/* Print out the levels. */
-	printf("vmmask %08x schedmask %08x highmask %08x\n",
-	    imask[IPL_VM], imask[IPL_SCHED], imask[IPL_HIGH]);
-#if 0
-	for (bit_pos = 0; bit_pos < NIPL; bit_pos++)
-		printf("imask[%d] == %08x\n", bit_pos, imask[bit_pos]);
-#endif
+	for (ipl = NIPL - 1; ipl > 0; ipl--)
+		ci->ci_imask[ipl - 1] |= ci->ci_imask[ipl];
 
 	/*
 	 * Load all mask registers, loading %eiem last.  This will finally
 	 * enable interrupts, but since cpl and ipending should be -1 and 0,
 	 * respectively, no interrupts will get dispatched until the priority
 	 * level is lowered.
-	 *
-	 * Because we're paranoid, we force these values for cpl and ipending,
-	 * even though they should be unchanged since hp700_intr_bootstrap().
 	 */
-	ci->ci_cpl = -1;
-	ci->ci_ipending = 0;
-	eiem = 0;
+	KASSERT(ci->ci_cpl == -1);
+	KASSERT(ci->ci_ipending == 0);
+
 	for (idx = 0; idx < HP700_INTERRUPT_BITS; idx++) {
 		ir = hp700_interrupt_registers[idx];
-		if (ir == NULL)
+		if (ir == NULL || ir->ir_ci != ci)
 			continue;
 		mask = 0;
 		for (bit_pos = 0; bit_pos < HP700_INTERRUPT_BITS; bit_pos++) {
-			if (ir->ir_bits_map[31 ^ bit_pos] !=
-			    IR_BIT_UNUSED)
+			if (IR_BIT_USED_P(ir->ir_bits_map[31 ^ bit_pos]))
 				mask |= (1 << bit_pos);
 		}
-		if (ir == &ir_cpu)
-			eiem = mask;
+		if (ir->ir_iscpu)
+			ir->ir_ci->ci_eiem = mask;
 		else if (ir->ir_mask != NULL)
 			*ir->ir_mask = mask;
 	}
-	mtctl(eiem, CR_EIEM);
 }
 
+void
+hp700_intr_enable(void)
+{
+	struct cpu_info *ci = curcpu();
+
+	mtctl(ci->ci_eiem, CR_EIEM);
+	ci->ci_psw |= PSW_I;
+	hppa_enable_irq();
+}
+
+
 /*
  * Service interrupts.  This doesn't necessarily dispatch them.  This is called
  * with %eiem loaded with zero.  It's named hppa_intr instead of hp700_intr
@@ -364,13 +326,9 @@ hp700_intr_init(void)
 void
 hppa_intr(struct trapframe *frame)
 {
+	struct cpu_info *ci = curcpu();
 	int eirr;
-	int ipending_new;
-	int pending;
 	int i;
-	struct hp700_interrupt_register *ir;
-	int hp700_intr_ipending_new(struct hp700_interrupt_register *, int);
-	struct cpu_info *ci = curcpu();
 
 #ifndef LOCKDEBUG
 	extern char mutex_enter_crit_start[];
@@ -409,36 +367,32 @@ hppa_intr(struct trapframe *frame)
 	mfctl(CR_EIRR, eirr);
 	mtctl(eirr, CR_EIRR);
 
-	ci->ci_ipending |= hp700_intr_ipending_new(&ir_cpu, eirr);
+	ci->ci_ipending |= hp700_intr_ipending(&ci->ci_ir, eirr);
 
+	i = 0;
 	/* If we have interrupts to dispatch, do so. */
-	if (ci->ci_ipending & ~ci->ci_cpl)
+	while (ci->ci_ipending & ~ci->ci_cpl) {
+		int shared;
+		
 		hp700_intr_dispatch(ci->ci_cpl, frame->tf_eiem, frame);
 
-	/* We are done if there are no shared interrupts. */
-	if (ishared == 0)
-		return;
-
-	for (i = 0; i < HP700_INTERRUPT_BITS; i++) {
-		ir = hp700_interrupt_registers[i];
-		if (ir == NULL || ir->ir_level == NULL)
-			continue;
-		/*
-		 * For shared interrupts look if the interrupt line is still
-		 * asserted. If it is, reschedule the corresponding interrupt.
-		 */
-		ipending_new = *ir->ir_level;
-		while (ipending_new != 0) {
-			pending = ffs(ipending_new) - 1;
-			ci->ci_ipending |=
-			    ir->ir_bits_map[31 ^ pending] & ishared;
-			ipending_new &= ~(1 << pending);
+		shared = ci->ci_ishared;
+		while (shared) {
+			struct hp700_interrupt_register *sir;
+			int sbit, lvl;
+
+			sbit = ffs(shared) - 1;
+			sir = hp700_interrupt_registers[sbit];
+			lvl = *sir->ir_level;
+
+			ci->ci_ipending |= hp700_intr_ipending(sir, lvl);
+			shared &= ~(1 << sbit);
 		}
+		i++;
+		KASSERTMSG(i <= 2,
+		    "%s: ci->ipending %08x ci->ci_cpl %08x shared %08x\n",
+		    __func__, ci->ci_ipending, ci->ci_cpl, shared);
 	}
-
-	/* If we still have interrupts to dispatch, do so. */
-	if (ci->ci_ipending & ~ci->ci_cpl)
-		hp700_intr_dispatch(ci->ci_cpl, frame->tf_eiem, frame);
 }
 
 /*
@@ -449,16 +403,18 @@ void
 hp700_intr_dispatch(int ncpl, int eiem, struct trapframe *frame)
 {
 	struct cpu_info *ci = curcpu();
+	struct hp700_interrupt_bit *ib;
+	struct clockframe clkframe;
 	int ipending_run;
-	u_int old_hppa_intr_depth;
 	int bit_pos;
-	struct hp700_interrupt_bit *ib;
 	void *arg;
-	struct clockframe clkframe;
 	int handled;
+	bool locked = false;
 
-	/* Increment our depth, grabbing the previous value. */
-	old_hppa_intr_depth = ci->ci_intr_depth++;
+	/*
+	 * Increment our depth
+	 */
+	ci->ci_intr_depth++;
 
 	/* Loop while we have interrupts to dispatch. */
 	for (;;) {
@@ -475,12 +431,12 @@ hp700_intr_dispatch(int ncpl, int eiem, 
 		 * If this interrupt handler takes the clockframe
 		 * as an argument, conjure one up.
 		 */
-		ib = &hp700_interrupt_bits[bit_pos];
+		ib = &ci->ci_ib[bit_pos];
 		ib->ib_evcnt.ev_count++;
 		arg = ib->ib_arg;
 		if (arg == NULL) {
-			clkframe.cf_flags = (old_hppa_intr_depth ?
-						TFF_INTR : 0);
+			clkframe.cf_flags = (ci->ci_intr_depth ? 
+			    TFF_INTR : 0);
 			clkframe.cf_spl = ncpl;
 			if (frame != NULL) {
 				clkframe.cf_flags |= frame->tf_flags;
@@ -495,9 +451,14 @@ hp700_intr_dispatch(int ncpl, int eiem, 
 		 * and reenable interrupts.
 		 */
 		ci->ci_ipending &= ~(1 << bit_pos);
-		ci->ci_cpl = ncpl | ib->ib_spl;
+		ci->ci_cpl = ncpl | ci->ci_imask[ib->ib_ipl];
 		mtctl(eiem, CR_EIEM);
 
+		if (ib->ib_ipl == IPL_VM) {
+			KERNEL_LOCK(1, NULL);
+			locked = true;
+		}
+
 		/* Count and dispatch the interrupt. */
 		ci->ci_data.cpu_nintr++;
 		handled = (*ib->ib_handler)(arg);
@@ -506,14 +467,43 @@ hp700_intr_dispatch(int ncpl, int eiem, 
 			printf("%s: can't handle interrupt\n",
 				ib->ib_evcnt.ev_name);
 #endif
-
+		if (locked) {
+			KERNEL_UNLOCK_ONE(NULL);
+			locked = false;
+		}
+		
 		/* Disable interrupts and loop. */
 		mtctl(0, CR_EIEM);
 	}
 
 	/* Interrupts are disabled again, restore cpl and the depth. */
 	ci->ci_cpl = ncpl;
-	ci->ci_intr_depth = old_hppa_intr_depth;
+	ci->ci_intr_depth--;
+}
+
+
+int
+hp700_intr_ipending(struct hp700_interrupt_register *ir, int eirr)
+{
+	int pending = 0;
+	int idx;
+
+	for (idx = 31; idx >= 0; idx--) {
+		if ((eirr & (1 << idx)) == 0)
+			continue;
+		if (IR_BIT_NESTED_P(ir->ir_bits_map[31 ^ idx])) {
+			struct hp700_interrupt_register *nir;
+			int reg = ir->ir_bits_map[31 ^ idx] & ~IR_BIT_MASK;
+
+			nir = hp700_interrupt_registers[reg];
+			pending |= hp700_intr_ipending(nir, *(nir->ir_req));
+		} else {
+			pending |= ir->ir_bits_map[31 ^ idx];
+		}
+	}
+
+	
+	return pending;
 }
 
 bool

Index: src/sys/arch/hp700/hp700/locore.S
diff -u src/sys/arch/hp700/hp700/locore.S:1.60 src/sys/arch/hp700/hp700/locore.S:1.61
--- src/sys/arch/hp700/hp700/locore.S:1.60	Fri Apr  6 12:21:59 2012
+++ src/sys/arch/hp700/hp700/locore.S	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.60 2012/04/06 12:21:59 skrll Exp $	*/
+/*	$NetBSD: locore.S,v 1.61 2012/05/23 16:11:37 skrll Exp $	*/
 /*	$OpenBSD: locore.S,v 1.158 2008/07/28 19:08:46 miod Exp $	*/
 
 /*
@@ -64,15 +64,13 @@
 
 #include <sys/errno.h>
 #include <machine/param.h>
-#include <machine/cpu.h>
 #include <machine/asm.h>
 #include <machine/psl.h>
 #include <machine/trap.h>
 #include <machine/iomod.h>
 #include <machine/pdc.h>
-#include <machine/intr.h>
-#include <machine/frame.h>
 #include <machine/reg.h>
+#include <machine/cpu.h>
 
 #include "assym.h"
 
@@ -657,6 +655,8 @@ EXIT(pdc_call)
  */
 LEAF_ENTRY(splraise)
 	GET_CURCPU(%t1)
+	sh2addl	%arg0, %t1, %arg0
+	ldw	CI_IMASK(%arg0), %arg0
 	ldw	CI_CPL(%t1), %ret0
 	or	%ret0, %arg0, %arg0
 	bv	%r0(%rp)
@@ -746,110 +746,6 @@ ENTRY(hp700_intr_schedule,0)
 EXIT(hp700_intr_schedule)
 
 /*
- *
- * int hp700_intr_ipending_new(struct hp700_int_reg *int_reg, int int_req);
- *
- * This assembles the mask of new pending interrupts.
- *
- */
-ENTRY(hp700_intr_ipending_new,HPPA_FRAME_SIZE)
-
-	/* Start stack calling convention. */
-	stw	%rp, HPPA_FRAME_CRP(%sp)
-	copy	%r3, %r1
-	copy	%sp, %r3
-	stw,ma	%r1, HPPA_FRAME_SIZE(%sp)
-
-	/*
-	 * Get this interrupt register's interrupt bits map
-	 * and start with the least significant bit and with
-	 * a zero ipending_new value.
-	 */
-	ldo	IR_BITS_MAP(%arg0), %arg0
-	ldi	31, %arg2
-	copy	%r0, %ret0
-
-	/*
-	 * The top of this loop finds the next set bit in
-	 * the request register.  Note that if the bvb does
-	 * not branch, the addib is nullified, and control
-	 * falls out of the loop.  If the bvb does branch,
-	 * the addib runs with the mtsar in its delay slot.
-	 * If the addib branches, the mtsar is nullified.
-	 */
-L$hp700_inew_loop:
-	mtsar	%arg2
-	bvb,>=,n %arg1, L$hp700_inew_loop
-	addib,<,n -1, %arg2, L$hp700_inew_done
-
-	/*
-	 * If the map entry for this bit has IR_BIT_REG
-	 * set, branch to descend into the next interrupt
-	 * register.  Otherwise, set the bits in our ipending_new
-	 * value and loop.
-	 */
-	ldwx,s  %arg2(%arg0), %t1
-	ldil	L%IR_BIT_REG, %t2
-	ldo	R%IR_BIT_REG(%t2), %t2
-	and	%t1, %t2, %t3
-	combt,=,n	%t2, %t3, L$hp700_inew_descend
-	addib,>= -1, %arg2, L$hp700_inew_loop
-	or	%t1, %ret0, %ret0
-
-L$hp700_inew_done:
-
-	/* End stack calling convention. */
-	ldw	HPPA_FRAME_CRP(%r3), %rp
-	ldo	HPPA_FRAME_SIZE(%r3), %sp
-	bv	%r0(%rp)
-	ldw,mb	-HPPA_FRAME_SIZE(%sp), %r3
-
-L$hp700_inew_descend:
-
-	/*
-	 * If the next interrupt register index is zero,
-	 * this interrupt bit is unused.  (Index zero
-	 * is the CPU interrupt register, which you can
-	 * never descend into since it's the root.)
-	 */
-	andcm,<> %t1, %t2, %t1
-	b,n	L$hp700_inew_unused
-
-	/* Save our state. */
-	stw	%arg0, HPPA_FRAME_ARG(0)(%r3)
-	stw	%arg1, HPPA_FRAME_ARG(1)(%r3)
-	stw	%arg2, HPPA_FRAME_ARG(2)(%r3)
-	stw	%ret0, HPPA_FRAME_ARG(3)(%r3)
-
-	/* Get our new interrupt register. */
-	ldil	L%hp700_interrupt_registers, %arg0
-	ldo	R%hp700_interrupt_registers(%arg0), %arg0
-	sh2add	%t1, %arg0, %arg0
-	ldw	0(%arg0), %arg0
-
-	/*
-	 * Read the interrupt request register and make
-	 * our recursive call.  The read also serves to
-	 * acknowledge the interrupt to the I/O subsystem.
-	 */
-	ldw	IR_REQ(%arg0), %arg1
-	bl	hp700_intr_ipending_new, %rp
-	ldw	0(%arg1), %arg1
-
-	/* Restore our state. */
-	ldw	HPPA_FRAME_ARG(0)(%r3), %arg0
-	ldw	HPPA_FRAME_ARG(1)(%r3), %arg1
-	ldw	HPPA_FRAME_ARG(2)(%r3), %arg2
-	ldw	HPPA_FRAME_ARG(3)(%r3), %ret1
-	or	%ret1, %ret0, %ret0
-
-L$hp700_inew_unused:
-	addib,>= -1, %arg2, L$hp700_inew_loop
-	nop
-	b,n	L$hp700_inew_done
-EXIT(hp700_intr_ipending_new)
-
-/*
  * void cpu_die(void);
  */
 LEAF_ENTRY_NOPROFILE(cpu_die)

Index: src/sys/arch/hp700/hp700/machdep.c
diff -u src/sys/arch/hp700/hp700/machdep.c:1.112 src/sys/arch/hp700/hp700/machdep.c:1.113
--- src/sys/arch/hp700/hp700/machdep.c:1.112	Wed May 23 08:59:36 2012
+++ src/sys/arch/hp700/hp700/machdep.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.112 2012/05/23 08:59:36 skrll Exp $	*/
+/*	$NetBSD: machdep.c,v 1.113 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.112 2012/05/23 08:59:36 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.113 2012/05/23 16:11:37 skrll Exp $");
 
 #include "opt_cputype.h"
 #include "opt_ddb.h"
@@ -121,7 +121,6 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 
 #include <ddb/db_extern.h>
 #endif
 
-#include <hp700/hp700/intr.h>
 #include <hp700/hp700/machdep.h>
 #include <hp700/hp700/pim.h>
 #include <hp700/dev/cpudevs.h>
@@ -588,7 +587,7 @@ do {									\
 
 	DPRINTF(("%s: intr bootstrap\n", __func__));
 	/* Bootstrap interrupt masking and dispatching. */
-	hp700_intr_bootstrap();
+	hp700_intr_initialise(ci);
 
 	/*
 	 * Initialize any debugger.

Index: src/sys/arch/hp700/hp700/mainbus.c
diff -u src/sys/arch/hp700/hp700/mainbus.c:1.82 src/sys/arch/hp700/hp700/mainbus.c:1.83
--- src/sys/arch/hp700/hp700/mainbus.c:1.82	Tue Apr  3 12:07:26 2012
+++ src/sys/arch/hp700/hp700/mainbus.c	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: mainbus.c,v 1.82 2012/04/03 12:07:26 skrll Exp $	*/
+/*	$NetBSD: mainbus.c,v 1.83 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.82 2012/04/03 12:07:26 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.83 2012/05/23 16:11:37 skrll Exp $");
 
 #include "locators.h"
 #include "power.h"
@@ -80,7 +80,6 @@ __KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 
 #include <machine/autoconf.h>
 
 #include <hp700/hp700/machdep.h>
-#include <hp700/hp700/intr.h>
 #include <hp700/dev/cpudevs.h>
 
 #if NLCD > 0
@@ -1474,9 +1473,6 @@ mbprint(void *aux, const char *pnp)
 		}
 		if (!pnp && ca->ca_irq >= 0) {
 			aprint_normal(" irq %d", ca->ca_irq);
-			if (ca->ca_type.iodc_type != HPPA_TYPE_BHA)
-				aprint_normal(" ipl %d",
-				    _hp700_intr_ipl_next());
 		}
 	}
 

Index: src/sys/arch/hp700/include/cpu.h
diff -u src/sys/arch/hp700/include/cpu.h:1.69 src/sys/arch/hp700/include/cpu.h:1.70
--- src/sys/arch/hp700/include/cpu.h:1.69	Thu Apr  5 21:00:29 2012
+++ src/sys/arch/hp700/include/cpu.h	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.69 2012/04/05 21:00:29 skrll Exp $	*/
+/*	$NetBSD: cpu.h,v 1.70 2012/05/23 16:11:37 skrll Exp $	*/
 
 /*	$OpenBSD: cpu.h,v 1.55 2008/07/23 17:39:35 kettenis Exp $	*/
 
@@ -60,6 +60,11 @@
 #include <machine/trap.h>
 #include <machine/frame.h>
 #include <machine/reg.h>
+#include <machine/intrdefs.h>
+
+#ifndef __ASSEMBLER__
+#include <machine/intr.h>
+#endif
 
 #ifndef _LOCORE
 
@@ -243,9 +248,11 @@ int	clock_intr(void *);
 
 #endif /* _KERNEL */
 
+#ifndef __ASSEMBLER__
 #if defined(_KERNEL) || defined(_KMEMUSER)
 
 #include <sys/cpu_data.h>
+#include <sys/evcnt.h>
 
 /*
  * Note that the alignment of ci_trap_save is important since we want to keep
@@ -259,6 +266,11 @@ struct cpu_info {
 	struct cpu_data ci_data;	/* MI per-cpu data */
 
 #ifndef _KMEMUSER
+	hppa_hpa_t	ci_hpa;
+	register_t	ci_psw;		/* Processor Status Word. */
+	paddr_t		ci_fpu_state;	/* LWP FPU state address, or zero. */
+	u_long		ci_itmr;
+
 	int		ci_cpuid;	/* CPU index (see cpus[] array) */
 	int		ci_mtx_count;
 	int		ci_mtx_oldspl;
@@ -267,12 +279,14 @@ struct cpu_info {
 	volatile int	ci_cpl;
 	volatile int	ci_ipending;	/* The pending interrupts. */
 	u_int		ci_intr_depth;	/* Nonzero iff running an interrupt. */
+	u_int		ci_ishared;
+	u_int		ci_eiem;
 
-	hppa_hpa_t	ci_hpa;
-	register_t	ci_psw;		/* Processor Status Word. */
-	paddr_t		ci_fpu_state;	/* LWP FPU state address, or zero. */
-	u_long		ci_itmr;
+	u_int		ci_imask[NIPL];
 
+	struct hp700_interrupt_register	ci_ir;
+	struct hp700_interrupt_bit	ci_ib[HP700_INTERRUPT_BITS];
+	
 #if defined(MULTIPROCESSOR)
 	struct lwp	*ci_curlwp;	/* CPU owner */
 	paddr_t		ci_stack;	/* stack for spin up */
@@ -289,6 +303,7 @@ struct cpu_info {
 } __aligned(64);
 
 #endif /* _KERNEL || _KMEMUSER */
+#endif /* __ASSEMBLER__ */
 
 #if defined(_KERNEL)
 

Index: src/sys/arch/hp700/include/intr.h
diff -u src/sys/arch/hp700/include/intr.h:1.21 src/sys/arch/hp700/include/intr.h:1.22
--- src/sys/arch/hp700/include/intr.h:1.21	Thu Apr  5 21:00:29 2012
+++ src/sys/arch/hp700/include/intr.h	Wed May 23 16:11:37 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.h,v 1.21 2012/04/05 21:00:29 skrll Exp $	*/
+/*	$NetBSD: intr.h,v 1.22 2012/05/23 16:11:37 skrll Exp $	*/
 /*	$OpenBSD: intr.h,v 1.26 2009/12/29 13:11:40 jsing Exp $	*/
 
 /*-
@@ -36,12 +36,113 @@
 #include <machine/psl.h>
 #include <machine/intrdefs.h>
 
+#include <sys/evcnt.h>
+
 #ifndef _LOCORE
 
 #ifdef _KERNEL
 
-/* The priority level masks. */
-extern int imask[NIPL];
+struct cpu_info;
+
+/*
+ * The maximum number of bits in a cpl value/spl mask, the maximum number of
+ * bits in an interrupt request register, and the maximum number of interrupt
+ * registers.
+ */
+#define	HP700_INTERRUPT_BITS	(32)
+#define	CPU_NINTS		HP700_INTERRUPT_BITS	/* Use this one */
+
+/*
+ * This describes one HP700 interrupt register.
+ */
+struct hp700_interrupt_register {
+	bool ir_iscpu;
+	const char *ir_name;		/* name for this intr reg */
+	struct cpu_info *ir_ci;		/* cpu this intr reg  */
+
+	/*
+	 * The virtual address of the mask, request and level
+	 * registers.
+	 */
+	volatile int *ir_mask;
+	volatile int *ir_req;
+	volatile int *ir_level;
+
+	/*
+	 * This array has one entry for each bit in the interrupt request
+	 * register.
+	 *
+	 * If the 24 most significant bits are set, the low 8 bits are the
+	 * index of the hp700_interrupt_register that this interrupt bit leads
+	 * to, with zero meaning that the interrupt bit is unused.
+	 *
+	 * Otherwise these bits correspond to hp700_interrupt_bits. That is,
+	 * these bits are ORed to ipending_new in hp700_intr_ipending() when
+	 * an interrupt happens.
+	 *
+	 * Note that this array is indexed by HP bit number, *not* by "normal"
+	 * bit number.  In other words, the least significant bit in the inter-
+	 * rupt register corresponds to array index 31.
+	 */
+
+	unsigned int ir_bits_map[HP700_INTERRUPT_BITS];
+
+#define	IR_BIT_MASK		0xffffff00
+#define	IR_BIT_REG(x)		(IR_BIT_MASK | (x))
+#define	IR_BIT_UNUSED		IR_BIT_REG(0)
+#define	IR_BIT_USED_P(x)	(((x) & IR_BIT_MASK) != IR_BIT_MASK)
+#define	IR_BIT_NESTED_P(x)	(((x) & IR_BIT_MASK) == IR_BIT_MASK)
+
+	int ir_bits;		/* mask of allocatable bit numbers */
+	int ir_rbits;		/* mask of reserved (for lasi/asp) bit numbers */
+};
+
+struct hp700_interrupt_bit {
+
+	/*
+	 * The interrupt register this bit is in.  Some handlers, e.g
+	 * apic_intr, don't make use of an hp700_interrupt_register, but are
+	 * nested.
+	 */
+	struct hp700_interrupt_register *ib_reg;
+
+	/*
+	 * The priority level associated with this bit, e.g, IPL_BIO, IPL_NET,
+	 * etc.
+	 */
+	int ib_ipl;
+
+	/*
+	 * The spl mask for this bit.  This starts out as the spl bit assigned
+	 * to this particular interrupt, and later gets fleshed out by the mask
+	 * calculator to be the full mask that we need to raise spl to when we
+	 * get this interrupt.
+	 */
+	int ib_spl;
+
+	/* The interrupt name. */
+	char ib_name[16];
+
+	/* The interrupt event count. */
+	struct evcnt ib_evcnt;
+
+	/*
+	 * The interrupt handler and argument for this bit.  If the argument is
+	 * NULL, the handler gets the trapframe.
+	 */
+	int (*ib_handler)(void *);
+	void *ib_arg;
+
+};
+
+void	hp700_intr_bootstrap(void);
+void	hp700_intr_initialise(struct cpu_info *);
+void	hp700_interrupt_register_establish(struct cpu_info *,
+    struct hp700_interrupt_register *);
+void *	hp700_intr_establish(int, int (*)(void *), void *,
+    struct hp700_interrupt_register *, int);
+int	hp700_intr_allocate_bit(struct hp700_interrupt_register *, int);
+void	hp700_intr_enable(void);
 
 /* splraise()/spllower() are in locore.S */
 int splraise(int);
@@ -69,7 +170,7 @@ static inline int
 splraiseipl(ipl_cookie_t icookie)
 {
 
-	return splraise(imask[icookie._ipl]);
+	return splraise(icookie._ipl);
 }
 
 #include <sys/spl.h>

Reply via email to