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
This commit is contained in:
parent
3a550d746a
commit
8e6e666e7a
@ -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 "universal" comm boards
|
||||
# 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
|
||||
|
@ -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_args *pa, pci_intr_handle_t *ihp)
|
||||
#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_handle_t ih,
|
||||
|
||||
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);
|
||||
|
@ -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, void *aux)
|
||||
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, void *aux)
|
||||
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, void *aux)
|
||||
sc->sc_trs->asp_imr = ~0;
|
||||
irr = sc->sc_trs->asp_irr;
|
||||
sc->sc_trs->asp_imr = 0;
|
||||
|
||||
/* Establish the interrupt register. */
|
||||
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);
|
||||
|
||||
/* Establish the interrupt register. */
|
||||
hp700_interrupt_register_establish(&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;
|
||||
|
||||
/* Attach the GSC bus. */
|
||||
ga.ga_ca = *ca; /* clone from us */
|
||||
if (strcmp(parent->dv_xname, "mainbus0") == 0) {
|
||||
|
@ -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 2012/05/23 09:49:56 skrll Exp $");
|
||||
#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, void *aux)
|
||||
|
||||
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, void *aux)
|
||||
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, void *aux)
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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, void *aux)
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
@ -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.35 2012/05/23 10:31:59 skrll Exp $");
|
||||
#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 cfdata, void *aux)
|
||||
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 self, void *aux)
|
||||
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 self, void *aux)
|
||||
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 self, void *aux)
|
||||
/* 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 */
|
||||
|
||||
|
@ -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, void *aux)
|
||||
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 self, void *aux)
|
||||
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 self, void *aux)
|
||||
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 */
|
||||
|
@ -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 1.22 2011/07/01 18:33:09 dyoung Exp $")
|
||||
#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, void *aux)
|
||||
{
|
||||
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, void *aux)
|
||||
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, void *aux)
|
||||
#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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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 1.9 2012/04/03 12:07:26 skrll Exp $");
|
||||
#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 match, void *aux)
|
||||
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_t self, void *aux)
|
||||
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_t self, void *aux)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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, void *aux)
|
||||
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, void *aux)
|
||||
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, void *aux)
|
||||
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;
|
||||
|
@ -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, void *aux)
|
||||
{
|
||||
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, void *aux)
|
||||
/* 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;
|
||||
|
@ -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;
|
||||
|
@ -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(void);
|
||||
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)
|
||||
|
@ -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_info, ci_mtx_count)
|
||||
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)
|
||||
|
@ -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.40 2012/05/23 11:04:54 skrll Exp $");
|
||||
#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.40 2012/05/23 11:04:54 skrll Exp $");
|
||||
#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(struct hp700_interrupt_register *ir)
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 (*handler)(void *), void *arg,
|
||||
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 (*handler)(void *), void *arg,
|
||||
* 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 (*handler)(void *), void *arg,
|
||||
ib->ib_handler = handler;
|
||||
ib->ib_arg = arg;
|
||||
|
||||
hp700_intr_calculatemasks(ci);
|
||||
|
||||
return ib;
|
||||
}
|
||||
|
||||
@ -234,32 +201,45 @@ hp700_intr_establish(int ipl, int (*handler)(void *), void *arg,
|
||||
* 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)
|
||||
{
|
||||
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();
|
||||
int eirr;
|
||||
int i;
|
||||
|
||||
#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;
|
||||
shared = ci->ci_ishared;
|
||||
while (shared) {
|
||||
struct hp700_interrupt_register *sir;
|
||||
int sbit, lvl;
|
||||
|
||||
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);
|
||||
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();
|
||||
int ipending_run;
|
||||
u_int old_hppa_intr_depth;
|
||||
int bit_pos;
|
||||
struct hp700_interrupt_bit *ib;
|
||||
void *arg;
|
||||
struct clockframe clkframe;
|
||||
int ipending_run;
|
||||
int bit_pos;
|
||||
void *arg;
|
||||
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, struct trapframe *frame)
|
||||
* 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, struct trapframe *frame)
|
||||
* 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, struct trapframe *frame)
|
||||
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
|
||||
|
@ -1,96 +0,0 @@
|
||||
/* $NetBSD: intr.h,v 1.15 2011/02/01 18:33:25 skrll Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Matthew Fredette.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
/*
|
||||
* The device name for this interrupt register.
|
||||
*/
|
||||
const char *ir_name;
|
||||
|
||||
/*
|
||||
* 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_int_bits. That is, these
|
||||
* bits are ORed to ipending_new in hp700_intr_ipending_new() 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_REG 0xffffff00
|
||||
#define IR_BIT_UNUSED IR_BIT_REG
|
||||
#define IR_BIT_NESTED_P(x) (((x) & ~IR_BIT_UNUSED) != 0)
|
||||
|
||||
/*
|
||||
* The mask of allocatable bit numbers.
|
||||
*/
|
||||
int ir_bits;
|
||||
};
|
||||
|
||||
extern struct hp700_interrupt_register ir_cpu;
|
||||
|
||||
void hp700_intr_bootstrap(void);
|
||||
void hp700_interrupt_register_establish(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 _hp700_intr_ipl_next(void);
|
||||
void hp700_intr_init(void);
|
||||
void hp700_intr_dispatch(int, int, struct trapframe *);
|
@ -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)
|
||||
@ -745,110 +745,6 @@ ENTRY(hp700_intr_schedule,0)
|
||||
mtctl %arg1, %eiem
|
||||
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);
|
||||
*/
|
||||
|
@ -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 1.112 2012/05/23 08:59:36 skrll Exp $");
|
||||
#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.
|
||||
|
@ -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 1.82 2012/04/03 12:07:26 skrll Exp $");
|
||||
#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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user