Overhaul the interrupt system to use hardware interrupts directly.

This commit is contained in:
eeh 2001-11-08 23:28:13 +00:00
parent 4da598993d
commit d0f2652711
6 changed files with 64 additions and 144 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: WALNUT,v 1.5 2001/08/29 17:37:48 briggs Exp $
# $NetBSD: WALNUT,v 1.6 2001/11/08 23:28:13 eeh Exp $
#
# GENERIC -- everything that's currently supported
#
@ -38,7 +38,7 @@ options DEBUG # expensive debugging checks/support
options DDB # in-kernel debugger
options DDB_HISTORY_SIZE=512 # enable history editing in DDB
options TRAP_PANICWAIT
options SYMTAB_SPACE=180000 # size for embedded symbol table
options SYMTAB_SPACE=230000 # size for embedded symbol table
makeoptions DEBUG="-g" # compile full symbol table
@ -101,6 +101,7 @@ options PFIL_HOOKS # pfil(9) packet filter hooks
options IPFILTER_LOG # ipmon(8) log support
#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG
options NMBCLUSTERS=1024
options NEW_PIPE
# These options enable verbose messages for several subsystems.
# Warning, these may compile large string tables into the kernel!
@ -127,11 +128,11 @@ mainbus0 at root
cpu0 at mainbus0
# UARTs
com0 at mainbus? addr 0xef600300 irq 5 # UIC IRQ 0
com1 at mainbus? addr 0xef600400 irq 6 # UIC IRQ 1
com0 at mainbus? addr 0xef600300 irq 0 # UIC IRQ 0
com1 at mainbus? addr 0xef600400 irq 1 # UIC IRQ 1
# Ethernet Media Access Controller
emac0 at mainbus? addr 0xef600800 irq 9 # UIC IRQ 15
emac0 at mainbus? addr 0xef600800 irq 15 # UIC IRQ 15
# RTC
dsrtc0 at mainbus? addr 0xf0000000
@ -252,3 +253,4 @@ pseudo-device gif 4 # IPv[46] over IPv[46] tunnel (RFC1933)
pseudo-device vlan # IEEE 802.1q encapsulation
pseudo-device pty # pseudo-terminals
pseudo-device rnd # /dev/random and in-kernel generator
pseudo-device wsmux 2 # ick

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.2 2001/11/06 01:26:47 simonb Exp $ */
/* $NetBSD: intr.h,v 1.3 2001/11/08 23:28:14 eeh Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -157,19 +157,26 @@ set_sint(pending)
#define ICU_LEN 32
#define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN)
#define IRQ_TO_MASK(x) (0x80000000UL >> (x))
#define SINT_NET 0x20000000
#define SINT_CLOCK 0x40000000
#define SINT_SERIAL 0x80000000
#define SPL_CLOCK 0x00000001
/*
* Interrupts 19-24 are not used by hardware and therefore useable
* by us for softints.
*/
#define HWINT_MASK ~0x1fc0
#define CNT_SINT_NET 19
#define CNT_SINT_CLOCK 20
#define CNT_SINT_SERIAL 21
#define CNT_CLOCK 22
#define CNT_STATCLOCK 23
#define SINT_NET IRQ_TO_MASK(CNT_SINT_NET)
#define SINT_CLOCK IRQ_TO_MASK(CNT_SINT_CLOCK)
#define SINT_SERIAL IRQ_TO_MASK(CNT_SINT_SERIAL)
#define SPL_CLOCK IRQ_TO_MASK(CNT_CLOCK)
#define SINT_MASK (SINT_CLOCK|SINT_NET|SINT_SERIAL)
#define CNT_SINT_NET 29
#define CNT_SINT_CLOCK 30
#define CNT_SINT_SERIAL 31
#define CNT_CLOCK 0
#define CNT_STATCLOCK 32 /* note: make sure locore.S has enough space for it */
#define splbio() splraise(imask[IPL_BIO])
#define splnet() splraise(imask[IPL_NET])
#define spltty() splraise(imask[IPL_TTY])

View File

@ -1,4 +1,4 @@
/* $NetBSD: pci_machdep.c,v 1.4 2001/10/29 23:38:35 thorpej Exp $ */
/* $NetBSD: pci_machdep.c,v 1.5 2001/11/08 23:28:15 eeh Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -171,13 +171,20 @@ pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
goto bad;
}
/*
* We need to map the interrupt pin to the interrupt bit in the UIC
* associated with it. This is highly machine-dependent.
*/
switch(dev) {
case 1: *ihp = 4; break; /* Slot 3 Ext IRQ 3 */
case 2: *ihp = 3; break; /* Slot 2 Ext IRQ 4 */
case 3: *ihp = 2; break; /* Slot 1 Ext IRQ 5 */
case 4: *ihp = 1; break; /* Slot 0 Ext IRQ 6 */
case 1:
case 2:
case 3:
case 4:
*ihp = 27 + dev;
break;
default:
printf("Hmm.. PCI device %d should not exist on this board\n", dev);
printf("Hmm.. PCI device %d should not exist on this board\n",
dev);
goto bad;
}
return 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: clock.c,v 1.1 2001/06/13 06:02:00 simonb Exp $ */
/* $NetBSD: clock.c,v 1.2 2001/11/08 23:28:15 eeh Exp $ */
/* $OpenBSD: clock.c,v 1.3 1997/10/13 13:42:53 pefo Exp $ */
/*
@ -101,7 +101,6 @@ decr_intr(struct clockframe *frame)
lasttb = tick - xticks;
intrcnt[CNT_CLOCK]++;
pri = splclock();
if (pri & SPL_CLOCK) {
tickspending += nticks;
@ -131,7 +130,6 @@ decr_intr(struct clockframe *frame)
void
cpu_initclocks(void)
{
ticks_per_intr = ticks_per_sec / hz;
stathz = profhz = ticks_per_sec / (1<<PERIOD_POWER);
printf("Setting PIT to %ld/%d = %ld\n", ticks_per_sec, hz, ticks_per_intr);

View File

@ -1,4 +1,4 @@
/* $NetBSD: extintr.c,v 1.3 2001/11/06 01:26:48 simonb Exp $ */
/* $NetBSD: extintr.c,v 1.4 2001/11/08 23:28:15 eeh Exp $ */
/* $OpenBSD: isabus.c,v 1.1 1997/10/11 11:53:00 pefo Exp $ */
/*
@ -87,48 +87,6 @@
#include <powerpc/spr.h>
#include <powerpc/ibm4xx/dcr.h>
#define GALAXY_INTR(x) (0x80000000U >> x)
/*
* Galaxy interrupt list
*/
#define GALAXY_INTR_UART0 GALAXY_INTR(0)
#define GALAXY_INTR_UART1 GALAXY_INTR(1)
#define GALAXY_INTR_IIC GALAXY_INTR(2)
#define GALAXY_INTR_EMI GALAXY_INTR(3)
#define GALAXY_INTR_PCI GALAXY_INTR(4)
#define GALAXY_INTR_DMA0 GALAXY_INTR(5)
#define GALAXY_INTR_DMA1 GALAXY_INTR(6)
#define GALAXY_INTR_DMA2 GALAXY_INTR(7)
#define GALAXY_INTR_DMA3 GALAXY_INTR(8)
#define GALAXY_INTR_EWOL GALAXY_INTR(9)
#define GALAXY_INTR_MSERR GALAXY_INTR(10)
#define GALAXY_INTR_MTXE GALAXY_INTR(11)
#define GALAXY_INTR_MRXE GALAXY_INTR(12)
#define GALAXY_INTR_MTXD GALAXY_INTR(13)
#define GALAXY_INTR_MRXD GALAXY_INTR(14)
#define GALAXY_INTR_ETH GALAXY_INTR(15)
#define GALAXY_INTR_PCISERR GALAXY_INTR(16)
#define GALAXY_INTR_ECC GALAXY_INTR(17)
#define GALAXY_INTR_PCIPM GALAXY_INTR(18)
#define GALAXY_INTR_IRQ0 GALAXY_INTR(25)
#define GALAXY_INTR_IRQ1 GALAXY_INTR(26)
#define GALAXY_INTR_IRQ2 GALAXY_INTR(27)
#define GALAXY_INTR_IRQ3 GALAXY_INTR(28)
#define GALAXY_INTR_IRQ4 GALAXY_INTR(29)
#define GALAXY_INTR_IRQ5 GALAXY_INTR(30)
#define GALAXY_INTR_IRQ6 GALAXY_INTR(31)
#define WALNUT_INTR_FPGA GALAXY_INTR_IRQ0
#define WALNUT_INTR_SMI GALAXY_INTR_IRQ1
#define WALNUT_INTR_PCI_S3 GALAXY_INTR_IRQ3
#define WALNUT_INTR_PCI_S2 GALAXY_INTR_IRQ4
#define WALNUT_INTR_PCI_S1 GALAXY_INTR_IRQ5
#define WALNUT_INTR_PCI_S0 GALAXY_INTR_IRQ6
static inline void galaxy_disable_irq(int irq);
static inline void galaxy_enable_irq(int irq);
static void intr_calculatemasks(void);
@ -144,31 +102,6 @@ u_long imask[NIPL];
static int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
static struct intrhand *intrhand[ICU_LEN];
/* SW irq# -> hw interrupt bitmask */
static unsigned int galaxy_intr_map[] = {
~0U, /* Reserved for clock interrupts */
WALNUT_INTR_PCI_S0, /* PCI dev 1 irq1 */
WALNUT_INTR_PCI_S1, /* PCI dev 2 irq2 */
WALNUT_INTR_PCI_S2, /* PCI dev 3 irq3 */
WALNUT_INTR_PCI_S3, /* PCI dev 4 irq4 */
GALAXY_INTR_UART0, /* com0 irq5 */
GALAXY_INTR_UART1, /* com1 irq6 */
GALAXY_INTR_IIC, /* iic irq7 */
~0U, /* irq8 - unused */
GALAXY_INTR_EWOL, /* emac irq9 .. 15 */
GALAXY_INTR_MSERR,
GALAXY_INTR_MTXE,
GALAXY_INTR_MRXE,
GALAXY_INTR_MTXD,
GALAXY_INTR_MRXD,
GALAXY_INTR_ETH,
WALNUT_INTR_FPGA, /* keyboard irq16 */
WALNUT_INTR_SMI /* mouse irq17 */
};
#define GALAXY_INTR_SIZE (sizeof (galaxy_intr_map) / sizeof (galaxy_intr_map[0]))
static uint32_t hwirq_mask; /* Mask sw interrupts in use */
static int hw2swirq[32]; /* map MSR bit into sw irq#. */
static inline int
@ -193,18 +126,7 @@ fakeintr(void *arg)
void
intr_init(void)
{
int i;
hwirq_mask = 0;
for (i = 0; i < 32; i++)
hw2swirq[i] = -1;
for (i = 0; i < GALAXY_INTR_SIZE; i++) {
if (galaxy_intr_map[i] == ~0U)
continue;
hwirq_mask |= (1 << i);
hw2swirq[31 - cntlzw(galaxy_intr_map[i])] = i;
}
}
/*
@ -213,7 +135,7 @@ intr_init(void)
void
ext_intr(void)
{
int i, irq, bits_to_clear;
int i, bits_to_clear;
int r_imen, msr;
int pcpl;
struct intrhand *ih;
@ -226,25 +148,19 @@ ext_intr(void)
bits_to_clear = int_state;
while (int_state) {
i = 31 - cntlzw(int_state);
int_state &= ~(1 << i);
i = cntlzw(int_state);
int_state &= ~IRQ_TO_MASK(i);
irq = hw2swirq[i];
if (irq == -1) {
printf("Unexpected interrupt %d\n",i);
continue;
}
r_imen = 1 << irq;
r_imen = IRQ_TO_MASK(i);
if ((pcpl & r_imen) != 0) {
ipending |= r_imen; /* Masked! Mark this as pending */
galaxy_disable_irq(irq);
galaxy_disable_irq(i);
} else {
splraise(intrmask[irq]);
splraise(intrmask[i]);
asm volatile ("mtmsr %0" :: "r"(msr | PSL_EE));
KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
ih = intrhand[irq];
ih = intrhand[i];
while (ih) {
(*ih->ih_fun)(ih->ih_arg);
ih = ih->ih_next;
@ -253,7 +169,7 @@ ext_intr(void)
asm volatile ("mtmsr %0" :: "r"(msr));
cpl = pcpl;
uvmexp.intrs++;
intrcnt[irq]++;
intrcnt[i]++;
}
}
mtdcr(DCR_UIC0_SR, bits_to_clear); /* Acknowledge all pending interrupts */
@ -268,13 +184,8 @@ galaxy_disable_irq(int irq)
{
int mask, omask;
if (irq >= GALAXY_INTR_SIZE)
return;
if (galaxy_intr_map[irq] == ~0U)
return;
mask = omask = mfdcr(DCR_UIC0_ER);
mask &= ~galaxy_intr_map[irq];
mask &= ~IRQ_TO_MASK(irq);
if (mask == omask)
return;
mtdcr(DCR_UIC0_ER, mask);
@ -288,13 +199,8 @@ galaxy_enable_irq(int irq)
{
int mask, omask;
if (irq >= GALAXY_INTR_SIZE)
return;
if (galaxy_intr_map[irq] == ~0U)
return;
mask = omask = mfdcr(DCR_UIC0_ER);
mask |= galaxy_intr_map[irq];
mask |= IRQ_TO_MASK(irq);
if (mask == omask)
return;
mtdcr(DCR_UIC0_ER, mask);
@ -380,7 +286,7 @@ intr_establish(int irq, int type, int level, int (*ih_fun)(void *), void *ih_arg
ih->ih_irq = irq;
*p = ih;
#ifdef IRQ_DEBUG
printf("intr_establish: irq%d h=%p arg=%p\n",irq, ih_fun, ih_arg);
printf("***** intr_establish: irq%d h=%p arg=%p\n",irq, ih_fun, ih_arg);
#endif
return (ih);
}
@ -441,7 +347,7 @@ intr_calculatemasks(void)
register int irqs = 0;
for (irq = 0; irq < ICU_LEN; irq++)
if (intrlevel[irq] & (1 << level))
irqs |= 1 << irq;
irqs |= IRQ_TO_MASK(irq);
imask[level] = irqs | SINT_MASK;
}
@ -502,7 +408,7 @@ intr_calculatemasks(void)
/* And eventually calculate the complete masks. */
for (irq = 0; irq < ICU_LEN; irq++) {
register int irqs = 1 << irq;
register int irqs = IRQ_TO_MASK(irq);
for (q = intrhand[irq]; q; q = q->ih_next)
irqs |= imask[q->ih_level];
intrmask[irq] = irqs;
@ -535,11 +441,11 @@ do_pending_int(void)
pcpl = cpl; /* Turn off all */
again:
while ((hwpend = ipending & ~pcpl & hwirq_mask)) {
irq = 31 - cntlzw(hwpend);
while ((hwpend = ipending & ~pcpl & HWINT_MASK)) {
irq = cntlzw(hwpend);
galaxy_enable_irq(irq);
ipending &= ~(1 << irq);
ipending &= ~IRQ_TO_MASK(irq);
splraise(intrmask[irq]);
asm volatile("mtmsr %0" :: "r"(emsr));

View File

@ -1,4 +1,4 @@
/* $NetBSD: mainbus.c,v 1.5 2001/10/29 01:37:29 simonb Exp $ */
/* $NetBSD: mainbus.c,v 1.6 2001/11/08 23:28:15 eeh Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -94,14 +94,14 @@ const struct ppc405gp_dev {
bus_addr_t addr;
int irq;
} ppc405gp_devs [] = {
{ "com", UART0_BASE, 5 },
{ "com", UART1_BASE, 6 },
{ "com", UART0_BASE, 0 },
{ "com", UART1_BASE, 1 },
{ "dsrtc", NVRAM_BASE, -1 },
{ "emac", EMAC0_BASE, 9 }, /* XXX: really irq 9..15 */
{ "emac", EMAC0_BASE, 15 }, /* XXX: really irq 9..15 */
{ "gpio", GPIO0_BASE, -1 },
{ "i2c", IIC0_BASE, -1 },
{ "wdog", -1, -1 },
{ "pckbc", KEY_MOUSE_BASE, 16 }, /* XXX: really irq x..x+1 */
{ "pckbc", KEY_MOUSE_BASE, 10 }, /* XXX: really irq x..x+1 */
{ NULL }
};