diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2007-12-19 22:05:07 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2007-12-19 22:05:07 +0000 |
commit | 0255bd8fe63cfd7bd3bf0506db8c29a1a9e02e66 (patch) | |
tree | e28de156abef3976ff7eb288c1b1b697a2e523a2 /sys | |
parent | d746971c0c409e53e144c6c06e07d8594cd805ec (diff) |
Overhaul interrupt handling, in order to make it (arguably) simpler and
more board design-independent.
The main changes are:
- define logical interrupt sources, which match the on-board devices as
well as the seven VME interrupt sources. Use these whenever possible
when registering interrupts in the drivers, so that the actual interrupt
mask layouts are hidden.
- make the on-board and VME interrupt handlers separate. On-board interrupt
handlers are not really associated to an interrupt vector, only to a
given interrupt source, and only one handler can be registered for a
logical interrupt source. On the other hand, VME interrupts come with a
vector number, and can be shared. This allows VME devices to really use
the whole 256 vectors space, starting at vector zero.
- update the real interrupt masks upon interrupt handler registration and
removal, so that only interrupt sources for which a handler exists may
be enabled.
- update the VME interrupt allocation logic to allow exclusive vector
allocation.
- move the Z8536 clock routines to their own file, since they are not
AV400-specific; while there, calibrate the delay constant upon startup
for more accurate delay().
The vme driver is the only one left with AV400 tentacles left, to be fixed
very soon.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/aviion/aviion/av400_machdep.c | 367 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/cio_clock.c | 373 | ||||
-rw-r--r-- | sys/arch/aviion/aviion/machdep.c | 120 | ||||
-rw-r--r-- | sys/arch/aviion/conf/files.aviion | 12 | ||||
-rw-r--r-- | sys/arch/aviion/dev/dart_syscon.c | 16 | ||||
-rw-r--r-- | sys/arch/aviion/dev/if_le_syscon.c | 9 | ||||
-rw-r--r-- | sys/arch/aviion/dev/if_le_vme.c | 9 | ||||
-rw-r--r-- | sys/arch/aviion/dev/syscon.c | 82 | ||||
-rw-r--r-- | sys/arch/aviion/dev/sysconreg.h | 45 | ||||
-rw-r--r-- | sys/arch/aviion/dev/sysconvar.h | 23 | ||||
-rw-r--r-- | sys/arch/aviion/dev/vme.c | 168 | ||||
-rw-r--r-- | sys/arch/aviion/dev/vmevar.h | 29 | ||||
-rw-r--r-- | sys/arch/aviion/include/av400.h | 41 | ||||
-rw-r--r-- | sys/arch/aviion/include/avcommon.h | 15 | ||||
-rw-r--r-- | sys/arch/aviion/include/board.h | 32 | ||||
-rw-r--r-- | sys/arch/aviion/include/cpu.h | 23 | ||||
-rw-r--r-- | sys/arch/aviion/include/intr.h | 4 |
17 files changed, 881 insertions, 487 deletions
diff --git a/sys/arch/aviion/aviion/av400_machdep.c b/sys/arch/aviion/aviion/av400_machdep.c index 7d7271f1a69..08b16fd7d33 100644 --- a/sys/arch/aviion/aviion/av400_machdep.c +++ b/sys/arch/aviion/aviion/av400_machdep.c @@ -1,6 +1,6 @@ -/* $OpenBSD: av400_machdep.c,v 1.11 2007/12/19 21:53:36 miod Exp $ */ +/* $OpenBSD: av400_machdep.c,v 1.12 2007/12/19 22:05:04 miod Exp $ */ /* - * Copyright (c) 2006, Miodrag Vallat. + * Copyright (c) 2006, 2007, Miodrag Vallat. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -137,12 +137,14 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/device.h> #include <sys/errno.h> #include <uvm/uvm_extern.h> #include <machine/asm_macro.h> #include <machine/board.h> +#include <machine/bus.h> #include <machine/cmmu.h> #include <machine/cpu.h> #include <machine/reg.h> @@ -154,7 +156,8 @@ #include <machine/av400.h> #include <machine/prom.h> -#include <aviion/dev/sysconreg.h> +#include <aviion/dev/sysconvar.h> +#include <aviion/dev/vmevar.h> u_int safe_level(u_int mask, u_int curlevel); @@ -175,10 +178,11 @@ const struct board board_av400 = { av400_memsize, av400_startup, av400_intr, - av400_init_clocks, + cio_init_clocks, av400_getipl, av400_setipl, av400_raiseipl, + av400_intsrc, av400_ptable }; @@ -199,19 +203,12 @@ u_int32_t int_mask_reg[] = { 0, 0, 0, 0 }; u_int av400_curspl[] = { IPL_HIGH, IPL_HIGH, IPL_HIGH, IPL_HIGH }; +#ifdef MULTIPROCESSOR /* - * external interrupt masks per spl. + * Interrupts allowed on secondary processors. */ -u_int32_t int_mask_val[INT_LEVEL] = { - MASK_LVL_0 & ~IRQ_CIOI, - MASK_LVL_1 & ~IRQ_CIOI, - MASK_LVL_2 & ~IRQ_CIOI, - MASK_LVL_3 & ~IRQ_CIOI, - MASK_LVL_4 & ~IRQ_CIOI, - MASK_LVL_5 & ~IRQ_CIOI, - MASK_LVL_6 & ~IRQ_CIOI, - MASK_LVL_7 & ~IRQ_CIOI -}; +#define SLAVE_MASK 0 /* IRQ_SWI0 | IRQ_SWI1 */ +#endif /* * Figure out how much memory is available, by asking the PROM. @@ -282,11 +279,11 @@ safe_level(u_int mask, u_int curlevel) { int i; - for (i = curlevel; i < INT_LEVEL; i++) + for (i = curlevel; i < NIPLS; i++) if ((int_mask_val[i] & mask) == 0) return i; - return (INT_LEVEL - 1); + return (NIPLS - 1); } u_int @@ -308,7 +305,7 @@ av400_setipl(u_int level) mask = int_mask_val[level]; #ifdef MULTIPROCESSOR if (cpu != master_cpu) - mask &= ~SLAVE_MASK; + mask &= SLAVE_MASK; #endif av400_curspl[cpu] = level; @@ -335,7 +332,7 @@ av400_raiseipl(u_int level) mask = int_mask_val[level]; #ifdef MULTIPROCESSOR if (cpu != master_cpu) - mask &= ~SLAVE_MASK; + mask &= SLAVE_MASK; #endif av400_curspl[cpu] = level; @@ -351,48 +348,77 @@ av400_raiseipl(u_int level) } /* - * Device interrupt handler for AV400 + * Provide the interrupt masks for a given logical interrupt source. */ +u_int64_t +av400_intsrc(int i) +{ + static const u_int32_t intsrc[] = { + 0, + IRQ_ABORT, + IRQ_ACF, + IRQ_SF, + IRQ_CIOI, + IRQ_DI1, + IRQ_DI2, + IRQ_ECI, + 0, + IRQ_SCI, + 0, + IRQ_VME1, + IRQ_VME2, + IRQ_VME3, + IRQ_VME4, + IRQ_VME5, + IRQ_VME6, + IRQ_VME7 + }; + + return ((u_int64_t)intsrc[i]); +} /* - * Hard coded vector table for onboard devices and hardware failure - * interrupts. + * Provide the interrupt source for a given interrupt status bit. */ const u_int obio_vec[32] = { - 0, /* SWI0 */ - 0, /* SWI1 */ + 0, /* SWI0 */ + 0, /* SWI1 */ 0, 0, - 0, /* VME1 */ - SYSCV_SCSI, /* SCI */ - 0, /* VME2 */ + INTSRC_VME, /* VME1 */ + INTSRC_SCSI1, /* SCI */ + INTSRC_VME, /* VME2 */ 0, 0, - 0, /* DVB */ - 0, /* VME3 */ - 0, /* DWP */ - 0, /* VME4 */ - 0, /* DTC */ - 0, /* VME5 */ - SYSCV_LE, /* ECI */ - SYSCV_SCC2, /* DI2 */ - SYSCV_SCC, /* DI1 */ - 0, /* PPI */ - 0, /* VME6 */ - SYSCV_SYSF, /* SF */ - SYSCV_TIMER2, /* CIOI */ - 0, /* KBD */ - 0, /* VME7 */ - 0, /* PAR */ - 0, /* VID */ - 0, /* ZBUF */ + 0, /* DVB */ + INTSRC_VME, /* VME3 */ + 0, /* DWP */ + INTSRC_VME, /* VME4 */ + 0, /* DTC */ + INTSRC_VME, /* VME5 */ + INTSRC_ETHERNET1, /* ECI */ + INTSRC_DUART2, /* DI2 */ + INTSRC_DUART1, /* DI1 */ + 0, /* PPI */ + INTSRC_VME, /* VME6 */ + INTSRC_SYSFAIL, /* SF */ + INTSRC_CIO, /* CIOI */ + 0, /* KBD */ + INTSRC_VME, /* VME7 */ + 0, /* PAR */ + 0, /* VID */ + 0, /* ZBUF */ 0, 0, - 0, /* ARBTO */ /* no vector, but always masked */ - SYSCV_ACF, /* ACF */ - SYSCV_ABRT /* ABORT */ + 0, /* ARBTO */ + INTSRC_ACFAIL, /* ACF */ + INTSRC_ABORT /* ABORT */ }; +/* + * Device interrupt handler for AV400 + */ + #define VME_VECTOR_MASK 0x1ff /* mask into VIACK register */ #define VME_BERR_MASK 0x100 /* timeout during VME IACK cycle */ @@ -406,8 +432,9 @@ av400_intr(u_int v, struct trapframe *eframe) intrhand_t *list; int ret, intbit; vaddr_t ivec; - u_int vec; + u_int intsrc, vec; int unmasked = 0; + int warn; #ifdef DIAGNOSTIC static int problems = 0; #endif @@ -444,22 +471,16 @@ av400_intr(u_int v, struct trapframe *eframe) } /* find the first bit set in the current mask */ + warn = 0; intbit = ff1(cur_mask); - if (OBIO_INTERRUPT_MASK & (1 << intbit)) { - vec = obio_vec[intbit]; - if (vec == 0) { - panic("unknown onboard interrupt: mask = 0x%b", - 1 << intbit, IST_STRING); - } - vec += SYSCON_VECT; - } else if (HW_FAILURE_MASK & (1 << intbit)) { - vec = obio_vec[intbit]; - if (vec == 0) { - panic("unknown hardware failure: mask = 0x%b", - 1 << intbit, IST_STRING); - } - vec += SYSCON_VECT; - } else if (VME_INTERRUPT_MASK & (1 << intbit)) { + intsrc = obio_vec[intbit]; + + if (intsrc == 0) + panic("%s: unexpected interrupt source (bit %d), " + "level %d, mask 0x%b", + __func__, intbit, level, cur_mask, IST_STRING); + + if (intsrc == INTSRC_VME) { ivec = AV400_VIRQLV + (level << 2); vec = *(volatile u_int32_t *)ivec & VME_VECTOR_MASK; if (vec & VME_BERR_MASK) { @@ -471,32 +492,23 @@ av400_intr(u_int v, struct trapframe *eframe) ign_mask |= 1 << intbit; continue; } - if (vec == 0) { - panic("%s: invalid VME interrupt vector, " - "level %d, mask 0x%b", - __func__, level, cur_mask, IST_STRING); - } + list = &vmeintr_handlers[vec]; } else { - panic("%s: unexpected interrupt source, " - "level %d, mask 0x%b", - __func__, level, cur_mask, IST_STRING); + list = &sysconintr_handlers[intsrc]; } - list = &intr_handlers[vec]; if (SLIST_EMPTY(list)) { - printf("%s: spurious interrupt, " - "level %d, vec 0x%x, mask 0x%b\n", - __func__, level, vec, cur_mask, IST_STRING); + warn = 1; ign_mask |= 1 << intbit; } else { /* * Walk through all interrupt handlers in the chain * for the given vector, calling each handler in turn, - * till some handler returns a value != 0. + * until some handler returns a value != 0. */ ret = 0; SLIST_FOREACH(intr, list, ih_link) { - if (intr->ih_wantframe != 0) + if (ISSET(intr->ih_flags, INTR_WANTFRAME)) ret = (*intr->ih_fn)((void *)eframe); else ret = (*intr->ih_fn)(intr->ih_arg); @@ -505,13 +517,25 @@ av400_intr(u_int v, struct trapframe *eframe) break; } } - if (ret == 0) { - panic("%s: unclaimed interrupt, " - "level %d, vec %x, mask 0x%b" - __func__, level, vec, cur_mask, IST_STRING); - ign_mask |= 1 << intbit; - break; - } + if (ret == 0) + warn = 2; + } + + if (warn != 0) { + ign_mask |= 1 << intbit; + + if (intsrc == INTSRC_VME) + printf("%s: %s VME interrupt, " + "level %d, vec 0x%x, mask 0x%b\n", + __func__, + warn > 1 ? "spurious" : "unclaimed", + level, vec, cur_mask, IST_STRING); + else + printf("%s: %s interrupt, " + "level %d, bit %d, mask 0x%b\n", + __func__, + warn > 1 ? "spurious" : "unclaimed", + level, intbit, cur_mask, IST_STRING); } } while (((cur_mask = ISR_GET_CURRENT_MASK(cpu)) & ~ign_mask) != 0); @@ -537,176 +561,3 @@ out: */ set_psr(get_psr() | PSR_IND); } - -/* - * Clock routines - */ - -void av400_cio_init(u_int); -u_int read_cio(int); -void write_cio(int, u_int); - -struct intrhand clock_ih; - -int av400_clockintr(void *); - -struct simplelock av400_cio_lock; - -#define CIO_LOCK simple_lock(&av400_cio_lock) -#define CIO_UNLOCK simple_unlock(&av400_cio_lock) - -/* - * Statistics clock interval and variance, in usec. Variance must be a - * power of two. Since this gives us an even number, not an odd number, - * we discard one case and compensate. That is, a variance of 4096 would - * give us offsets in [0..4095]. Instead, we take offsets in [1..4095]. - * This is symmetric about the point 2048, or statvar/2, and thus averages - * to that value (assuming uniform random numbers). - */ -int statvar = 8192; -int statmin; /* statclock interval - 1/2*variance */ - -/* - * Notes on the AV400 clock usage: - * - * Unlike the MVME188 design, we only have access to three counter/timers - * in the Zilog Z8536 (since we can not receive the DUART timer interrupts). - * - * Clock is run on a Z8536 counter, kept in counter mode and retriggered - * every interrupt (when using the Z8536 in timer mode, it _seems_ that it - * resets at 0xffff instead of the initial count value...) - * - * It should be possible to run statclock on the Z8536 counter #2, but - * this would make interrupt handling more tricky, in the case both - * counters interrupt at the same time... - */ - -void -av400_init_clocks(void) -{ - int s; - - simple_lock_init(&av400_cio_lock); - -#ifdef DIAGNOSTIC - if (1000000 % hz) { - printf("cannot get %d Hz clock; using 100 Hz\n", hz); - hz = 100; - } -#endif - tick = 1000000 / hz; - - av400_cio_init(tick); - - stathz = 0; - - clock_ih.ih_fn = av400_clockintr; - clock_ih.ih_arg = 0; - clock_ih.ih_wantframe = 1; - clock_ih.ih_ipl = IPL_CLOCK; - sysconintr_establish(SYSCV_TIMER2, &clock_ih, "clock"); - - /* unmask CIOI interrupt */ - for (s = IPL_NONE; s < IPL_CLOCK; s++) - int_mask_val[s] |= IRQ_CIOI; -} - -int -av400_clockintr(void *eframe) -{ - CIO_LOCK; - write_cio(CIO_CSR1, CIO_GCB | CIO_CIP); /* Ack the interrupt */ - - /* restart counter */ - write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); - CIO_UNLOCK; - - hardclock(eframe); - - return (1); -} - -/* Write CIO register */ -void -write_cio(int reg, u_int val) -{ - int s; - volatile int i; - volatile u_int32_t * cio_ctrl = (volatile u_int32_t *)CIO_CTRL; - - s = splclock(); - CIO_LOCK; - - i = *cio_ctrl; /* goto state 1 */ - *cio_ctrl = 0; /* take CIO out of RESET */ - i = *cio_ctrl; /* reset CIO state machine */ - - *cio_ctrl = (reg & 0xff); /* select register */ - *cio_ctrl = (val & 0xff); /* write the value */ - - CIO_UNLOCK; - splx(s); -} - -/* Read CIO register */ -u_int -read_cio(int reg) -{ - int c, s; - volatile int i; - volatile u_int32_t * cio_ctrl = (volatile u_int32_t *)CIO_CTRL; - - s = splclock(); - CIO_LOCK; - - /* select register */ - *cio_ctrl = (reg & 0xff); - /* delay for a short time to allow 8536 to settle */ - for (i = 0; i < 100; i++) - ; - /* read the value */ - c = *cio_ctrl; - CIO_UNLOCK; - splx(s); - return (c & 0xff); -} - -/* - * Initialize the CTC (8536) - * Only the counter/timers are used - the IO ports are un-comitted. - */ -void -av400_cio_init(u_int period) -{ - volatile int i; - - CIO_LOCK; - - /* Start by forcing chip into known state */ - read_cio(CIO_MICR); - write_cio(CIO_MICR, CIO_MICR_RESET); /* Reset the CTC */ - for (i = 0; i < 1000; i++) /* Loop to delay */ - ; - - /* Clear reset and start init seq. */ - write_cio(CIO_MICR, 0x00); - - /* Wait for chip to come ready */ - while ((read_cio(CIO_MICR) & CIO_MICR_RJA) == 0) - ; - - /* Initialize the 8536 for real */ - write_cio(CIO_MICR, - CIO_MICR_MIE /* | CIO_MICR_NV */ | CIO_MICR_RJA | CIO_MICR_DLC); - write_cio(CIO_CTMS1, CIO_CTMS_CSC); /* Continuous count */ - write_cio(CIO_PDCB, 0xff); /* set port B to input */ - - period <<= 1; /* CT#1 runs at PCLK/2, hence 2MHz */ - write_cio(CIO_CT1MSB, period >> 8); - write_cio(CIO_CT1LSB, period); - /* enable counter #1 */ - write_cio(CIO_MCCR, CIO_MCCR_CT1E | CIO_MCCR_PBE); - write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); - - CIO_UNLOCK; -} diff --git a/sys/arch/aviion/aviion/cio_clock.c b/sys/arch/aviion/aviion/cio_clock.c new file mode 100644 index 00000000000..38fa20edb6a --- /dev/null +++ b/sys/arch/aviion/aviion/cio_clock.c @@ -0,0 +1,373 @@ +/* $OpenBSD: cio_clock.c,v 1.1 2007/12/19 22:05:04 miod Exp $ */ +/* + * Copyright (c) 2006, 2007, Miodrag Vallat. + * + * 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 AUTHOR ``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 AUTHOR 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. + */ +/* + * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr. + * Copyright (c) 1996 Nivas Madhur + * All rights reserved. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Nivas Madhur. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + */ +/* + * Copyright (c) 1999 Steve Murphree, Jr. + * Copyright (c) 1995 Theo de Raadt + * + * 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 AUTHOR ``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 AUTHOR 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. + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 1995 Nivas Madhur + * Copyright (c) 1994 Gordon W. Ross + * Copyright (c) 1993 Adam Glass + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratory. + * + * 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * @(#)clock.c 8.1 (Berkeley) 6/11/93 + */ +/* + * Mach Operating System + * Copyright (c) 1993-1991 Carnegie Mellon University + * Copyright (c) 1991 OMRON Corporation + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/errno.h> + +#include <uvm/uvm_extern.h> + +#include <machine/asm_macro.h> +#include <machine/board.h> +#include <machine/cmmu.h> +#include <machine/cpu.h> +#include <machine/reg.h> +#include <machine/trap.h> + +#include <machine/m88100.h> +#include <machine/m8820x.h> +#include <machine/avcommon.h> +#include <machine/prom.h> + +#include <aviion/dev/sysconvar.h> + +/* + * Z8536 (CIO) Clock routines + */ + +void cio_clock_init(u_int); +u_int read_cio(int); +void write_cio(int, u_int); + +struct intrhand clock_ih; + +int cio_clockintr(void *); +int cio_calibrateintr(void *); + +volatile int cio_calibrate_phase = 0; +extern u_int aviion_delay_const; + +struct simplelock cio_clock_lock; + +#define CIO_LOCK simple_lock(&acio_clock_lock) +#define CIO_UNLOCK simple_unlock(&cio_clock__lock) + +/* + * Statistics clock interval and variance, in usec. Variance must be a + * power of two. Since this gives us an even number, not an odd number, + * we discard one case and compensate. That is, a variance of 4096 would + * give us offsets in [0..4095]. Instead, we take offsets in [1..4095]. + * This is symmetric about the point 2048, or statvar/2, and thus averages + * to that value (assuming uniform random numbers). + */ +int statvar = 8192; +int statmin; /* statclock interval - 1/2*variance */ + +/* + * Notes on the AV400 clock usage: + * + * Unlike the MVME188 design, we only have access to three counter/timers + * in the Zilog Z8536 (since we can not receive the DUART timer interrupts). + * + * Clock is run on a Z8536 counter, kept in counter mode and retriggered + * every interrupt (when using the Z8536 in timer mode, it _seems_ that it + * resets at 0xffff instead of the initial count value...) + * + * It should be possible to run statclock on the Z8536 counter #2, but + * this would make interrupt handling more tricky, in the case both + * counters interrupt at the same time... + */ + +void +cio_init_clocks(void) +{ + u_int iter, divisor; + u_int32_t psr; + + psr = get_psr(); + set_psr(psr | PSR_IND); + + simple_lock_init(&cio_clock_lock); + +#ifdef DIAGNOSTIC + if (1000000 % hz) { + printf("cannot get %d Hz clock; using 100 Hz\n", hz); + hz = 100; + } +#endif + tick = 1000000 / hz; + + cio_clock_init(tick); + + stathz = 0; + + /* + * Calibrate delay const. + */ + clock_ih.ih_fn = cio_calibrateintr; + clock_ih.ih_arg = 0; + clock_ih.ih_flags = INTR_WANTFRAME; + clock_ih.ih_ipl = IPL_CLOCK; + sysconintr_establish(INTSRC_CIO, &clock_ih, "clock"); + + aviion_delay_const = 1; + set_psr(psr); + while (cio_calibrate_phase == 0) + ; + + iter = 0; + while (cio_calibrate_phase == 1) { + delay(10000); + iter++; + } + + divisor = 1000000 / 10000; + aviion_delay_const = (iter * hz + divisor - 1) / divisor; + + set_psr(psr | PSR_IND); + + sysconintr_disestablish(INTSRC_CIO, &clock_ih); + clock_ih.ih_fn = cio_clockintr; + sysconintr_establish(INTSRC_CIO, &clock_ih, "clock"); + + set_psr(psr); +} + +int +cio_calibrateintr(void *eframe) +{ + CIO_LOCK; + write_cio(CIO_CSR1, CIO_GCB | CIO_CIP); /* Ack the interrupt */ + + /* restart counter */ + write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); + CIO_UNLOCK; + + cio_calibrate_phase++; + + return (1); +} + +int +cio_clockintr(void *eframe) +{ + CIO_LOCK; + write_cio(CIO_CSR1, CIO_GCB | CIO_CIP); /* Ack the interrupt */ + + /* restart counter */ + write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); + CIO_UNLOCK; + + hardclock(eframe); + + return (1); +} + +/* Write CIO register */ +void +write_cio(int reg, u_int val) +{ + int s; + volatile int i; + volatile u_int32_t * cio_ctrl = (volatile u_int32_t *)CIO_CTRL; + + s = splclock(); + CIO_LOCK; + + i = *cio_ctrl; /* goto state 1 */ + *cio_ctrl = 0; /* take CIO out of RESET */ + i = *cio_ctrl; /* reset CIO state machine */ + + *cio_ctrl = (reg & 0xff); /* select register */ + *cio_ctrl = (val & 0xff); /* write the value */ + + CIO_UNLOCK; + splx(s); +} + +/* Read CIO register */ +u_int +read_cio(int reg) +{ + int c, s; + volatile int i; + volatile u_int32_t * cio_ctrl = (volatile u_int32_t *)CIO_CTRL; + + s = splclock(); + CIO_LOCK; + + /* select register */ + *cio_ctrl = (reg & 0xff); + /* delay for a short time to allow 8536 to settle */ + for (i = 0; i < 100; i++) + ; + /* read the value */ + c = *cio_ctrl; + CIO_UNLOCK; + splx(s); + return (c & 0xff); +} + +/* + * Initialize the CTC (8536) + * Only the counter/timers are used - the IO ports are un-comitted. + */ +void +cio_clock_init(u_int period) +{ + volatile int i; + + CIO_LOCK; + + /* Start by forcing chip into known state */ + read_cio(CIO_MICR); + write_cio(CIO_MICR, CIO_MICR_RESET); /* Reset the CTC */ + for (i = 0; i < 1000; i++) /* Loop to delay */ + ; + + /* Clear reset and start init seq. */ + write_cio(CIO_MICR, 0x00); + + /* Wait for chip to come ready */ + while ((read_cio(CIO_MICR) & CIO_MICR_RJA) == 0) + ; + + /* Initialize the 8536 for real */ + write_cio(CIO_MICR, + CIO_MICR_MIE /* | CIO_MICR_NV */ | CIO_MICR_RJA | CIO_MICR_DLC); + write_cio(CIO_CTMS1, CIO_CTMS_CSC); /* Continuous count */ + write_cio(CIO_PDCB, 0xff); /* set port B to input */ + + period <<= 1; /* CT#1 runs at PCLK/2, hence 2MHz */ + write_cio(CIO_CT1MSB, period >> 8); + write_cio(CIO_CT1LSB, period); + /* enable counter #1 */ + write_cio(CIO_MCCR, CIO_MCCR_CT1E | CIO_MCCR_PBE); + write_cio(CIO_CSR1, CIO_GCB | CIO_TCB | CIO_IE); + + CIO_UNLOCK; +} diff --git a/sys/arch/aviion/aviion/machdep.c b/sys/arch/aviion/aviion/machdep.c index d80ed3bde3e..9f72bf20f15 100644 --- a/sys/arch/aviion/aviion/machdep.c +++ b/sys/arch/aviion/aviion/machdep.c @@ -1,4 +1,20 @@ -/* $OpenBSD: machdep.c,v 1.19 2007/12/19 21:53:36 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.20 2007/12/19 22:05:04 miod Exp $ */ +/* + * Copyright (c) 2007 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ /* * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -65,11 +81,14 @@ #include <sys/extent.h> #include <sys/core.h> #include <sys/kcore.h> +#include <sys/device.h> #include <machine/asm.h> #include <machine/asm_macro.h> #include <machine/autoconf.h> +#include <machine/avcommon.h> #include <machine/board.h> +#include <machine/bus.h> #include <machine/cmmu.h> #include <machine/cpu.h> #include <machine/kcore.h> @@ -80,6 +99,8 @@ #include <machine/m88100.h> #endif +#include <aviion/dev/vmevar.h> + #include <dev/cons.h> #include <uvm/uvm_extern.h> @@ -104,8 +125,6 @@ void savectx(struct pcb *); void secondary_main(void); vaddr_t secondary_pre_main(void); -intrhand_t intr_handlers[NVMEINTR]; - int physmem; /* available physical memory, in pages */ struct vm_map *exec_map = NULL; @@ -144,10 +163,12 @@ char bootargs[256]; /* local copy */ u_int bootdev, bootunit, bootpart; /* set in locore.S */ int cputyp; /* set in locore.S */ -int cpuspeed = 20; /* safe guess */ int avtyp; const struct board *platform; +/* multiplication factor for delay() */ +u_int aviion_delay_const = 33; + vaddr_t first_addr; vaddr_t last_addr; @@ -157,6 +178,12 @@ vaddr_t virtual_avail, virtual_end; extern struct user *proc0paddr; /* + * Interrupt masks, one per IPL level. + */ +u_int32_t int_mask_val[NIPLS]; +u_int32_t ext_int_mask_val[NIPLS]; + +/* * This is to fake out the console routines, while booting. * We could use directly the bugtty console, but we want to be able to * configure a kernel without bugtty since we do not necessarily need a @@ -197,11 +224,6 @@ consinit() void identifycpu() { -#if 0 - /* XXX FILL ME */ - cpuspeed = getcpuspeed(&brdid); -#endif - strlcpy(cpu_model, platform->descr, sizeof cpu_model); } @@ -299,12 +321,6 @@ cpu_startup() bufinit(); /* - * Set up interrupt handlers. - */ - for (i = 0; i < NVMEINTR; i++) - SLIST_INIT(&intr_handlers[i]); - - /* * Configure the system. */ if (boothowto & RB_CONFIG) { @@ -630,42 +646,6 @@ secondary_main() #endif /* MULTIPROCESSOR */ -/* - * Try to insert ihand in the list of handlers for vector vec. - */ -int -intr_establish(int vec, struct intrhand *ihand, const char *name) -{ - struct intrhand *intr; - intrhand_t *list; - - if (vec < 0 || vec >= NVMEINTR) { -#ifdef DIAGNOSTIC - printf("intr_establish: vec (0x%x) not between 0x00 and 0xff\n", - vec); -#endif /* DIAGNOSTIC */ - return (EINVAL); - } - - list = &intr_handlers[vec]; - if (!SLIST_EMPTY(list)) { - intr = SLIST_FIRST(list); - if (intr->ih_ipl != ihand->ih_ipl) { -#ifdef DIAGNOSTIC - printf("intr_establish: there are other handlers with " - "vec (0x%x) at ipl %x, but you want it at %x\n", - vec, intr->ih_ipl, ihand->ih_ipl); -#endif /* DIAGNOSTIC */ - return (EINVAL); - } - } - - evcount_attach(&ihand->ih_count, name, (void *)&ihand->ih_ipl, - &evcount_intr); - SLIST_INSERT_HEAD(list, ihand, ih_link); - return (0); -} - void nmihand(void *frame) { @@ -925,6 +905,44 @@ raiseipl(int level) return (int)platform->raiseipl((u_int)level); } +void +intsrc_enable(u_int intsrc, int ipl) +{ + u_int32_t psr; + u_int64_t intmask = platform->intsrc(intsrc); + int i; + + psr = get_psr(); + set_psr(psr | PSR_IND); + + for (i = IPL_NONE; i < ipl; i++) { + int_mask_val[i] |= (u_int32_t)intmask; + ext_int_mask_val[i] |= (u_int32_t)(intmask >> 32); + } + setipl(getipl()); + + set_psr(psr); +} + +void +intsrc_disable(u_int intsrc) +{ + u_int32_t psr; + u_int64_t intmask = platform->intsrc(intsrc); + int i; + + psr = get_psr(); + set_psr(psr | PSR_IND); + + for (i = 0; i < NIPLS; i++) { + int_mask_val[i] &= ~((u_int32_t)intmask); + ext_int_mask_val[i] &= ~((u_int32_t)(intmask >> 32)); + } + setipl(getipl()); + + set_psr(psr); +} + u_char hostaddr[6]; void diff --git a/sys/arch/aviion/conf/files.aviion b/sys/arch/aviion/conf/files.aviion index 46973bad806..ff0b53cda0a 100644 --- a/sys/arch/aviion/conf/files.aviion +++ b/sys/arch/aviion/conf/files.aviion @@ -1,12 +1,10 @@ -# $OpenBSD: files.aviion,v 1.4 2007/12/19 21:51:29 miod Exp $ +# $OpenBSD: files.aviion,v 1.5 2007/12/19 22:05:06 miod Exp $ # maxpartitions 16 device mainbus {[addr = -1]} attach mainbus at root - -device ile: ether, ifnet, ifmedia -file arch/aviion/dev/if_ile.c ile +file arch/aviion/dev/mainbus.c # # On-board devices @@ -28,6 +26,9 @@ file arch/aviion/dev/dart_syscon.c dart_syscon attach le at syscon with le_syscon file arch/aviion/dev/if_le_syscon.c le_syscon +device ile: ether, ifnet, ifmedia +file arch/aviion/dev/if_ile.c ile + attach ile at syscon with ile_syscon file arch/aviion/dev/if_ile_syscon.c ile_syscon @@ -67,8 +68,9 @@ file arch/aviion/aviion/av400_machdep.c av400 file arch/aviion/aviion/av530_machdep.c av530 file arch/aviion/aviion/av5000_machdep.c av5000 file arch/aviion/aviion/av6280_machdep.c av6280 +file arch/aviion/aviion/cio_clock.c av400 | av530 | + av5000 | av6280 file arch/aviion/aviion/m8820x.c m88100 file arch/aviion/aviion/mem.c file arch/aviion/aviion/pmap_table.c file arch/aviion/aviion/prom.c -file arch/aviion/dev/mainbus.c diff --git a/sys/arch/aviion/dev/dart_syscon.c b/sys/arch/aviion/dev/dart_syscon.c index d44fd619473..a237480a251 100644 --- a/sys/arch/aviion/dev/dart_syscon.c +++ b/sys/arch/aviion/dev/dart_syscon.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dart_syscon.c,v 1.2 2007/12/19 21:52:46 miod Exp $ */ +/* $OpenBSD: dart_syscon.c,v 1.3 2007/12/19 22:05:06 miod Exp $ */ /* * Copyright (c) 2006, Miodrag Vallat * @@ -29,11 +29,11 @@ #include <sys/device.h> #include <machine/autoconf.h> +#include <machine/board.h> #include <machine/cpu.h> #include <machine/avcommon.h> - -#include <aviion/dev/sysconreg.h> +#include <aviion/dev/sysconvar.h> #include <aviion/dev/dartvar.h> int dart_syscon_match(struct device *parent, void *self, void *aux); @@ -70,7 +70,7 @@ dart_syscon_attach(struct device *parent, struct device *self, void *aux) struct dartsoftc *sc = (struct dartsoftc *)self; struct confargs *ca = aux; bus_space_handle_t ioh; - u_int vec; + u_int intsrc; if (ca->ca_ipl < 0) ca->ca_ipl = IPL_TTY; @@ -83,21 +83,21 @@ dart_syscon_attach(struct device *parent, struct device *self, void *aux) sc->sc_ioh = ioh; if (ca->ca_paddr == CONSOLE_DART_BASE) { - vec = SYSCV_SCC; + intsrc = INTSRC_DUART1; sc->sc_console = 1; /* XXX for now */ printf(": console"); } else { - vec = SYSCV_SCC2; + intsrc = INTSRC_DUART2; sc->sc_console = 0; } /* enable interrupts */ sc->sc_ih.ih_fn = dartintr; sc->sc_ih.ih_arg = sc; - sc->sc_ih.ih_wantframe = 0; + sc->sc_ih.ih_flags = 0; sc->sc_ih.ih_ipl = ca->ca_ipl; - sysconintr_establish(vec, &sc->sc_ih, self->dv_xname); + sysconintr_establish(intsrc, &sc->sc_ih, self->dv_xname); dart_common_attach(sc); } diff --git a/sys/arch/aviion/dev/if_le_syscon.c b/sys/arch/aviion/dev/if_le_syscon.c index e49f34bc1fe..78cfea22782 100644 --- a/sys/arch/aviion/dev/if_le_syscon.c +++ b/sys/arch/aviion/dev/if_le_syscon.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_le_syscon.c,v 1.3 2007/12/19 21:51:29 miod Exp $ */ +/* $OpenBSD: if_le_syscon.c,v 1.4 2007/12/19 22:05:06 miod Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -55,9 +55,10 @@ #include <net/if_media.h> #include <machine/autoconf.h> +#include <machine/board.h> #include <machine/cpu.h> -#include <aviion/dev/sysconreg.h> +#include <aviion/dev/sysconvar.h> #include <dev/ic/am7990reg.h> #include <dev/ic/am7990var.h> @@ -210,8 +211,8 @@ le_syscon_attach(parent, self, aux) lesc->sc_ih.ih_fn = am7990_intr; lesc->sc_ih.ih_arg = sc; - lesc->sc_ih.ih_wantframe = 0; + lesc->sc_ih.ih_flags = 0; lesc->sc_ih.ih_ipl = ca->ca_ipl; - sysconintr_establish(SYSCV_LE, &lesc->sc_ih, self->dv_xname); + sysconintr_establish(INTSRC_ETHERNET1, &lesc->sc_ih, self->dv_xname); } diff --git a/sys/arch/aviion/dev/if_le_vme.c b/sys/arch/aviion/dev/if_le_vme.c index 658ec2ddd16..ec1d710fce7 100644 --- a/sys/arch/aviion/dev/if_le_vme.c +++ b/sys/arch/aviion/dev/if_le_vme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_le_vme.c,v 1.1 2006/05/09 18:24:32 miod Exp $ */ +/* $OpenBSD: if_le_vme.c,v 1.2 2007/12/19 22:05:06 miod Exp $ */ /*- * Copyright (c) 1982, 1992, 1993 @@ -305,11 +305,12 @@ le_vme_attach(parent, self, aux) /* * Allocate an interrupt vector. */ - if (vmeintr_allocate(1, VMEINTR_ANY, &lesc->sc_vec) != 0) { + lesc->sc_ipl = vaa->vaa_ipl == 0 ? IPL_NET : vaa->vaa_ipl; + if (vmeintr_allocate(1, VMEINTR_ANY | VMEINTR_SHARED, lesc->sc_ipl, + &lesc->sc_vec) != 0) { printf(": no more interrupts!\n"); return; } - lesc->sc_ipl = vaa->vaa_ipl == 0 ? IPL_NET : vaa->vaa_ipl; /* * Map the dual-ported memory. @@ -367,7 +368,7 @@ le_vme_attach(parent, self, aux) /* connect the interrupt */ lesc->sc_ih.ih_fn = le_vme_intr; lesc->sc_ih.ih_arg = sc; - lesc->sc_ih.ih_wantframe = 0; + lesc->sc_ih.ih_flags = 0; lesc->sc_ih.ih_ipl = lesc->sc_ipl; vmeintr_establish(lesc->sc_vec, &lesc->sc_ih, self->dv_xname); diff --git a/sys/arch/aviion/dev/syscon.c b/sys/arch/aviion/dev/syscon.c index b52b4631ec1..85d0c0e9376 100644 --- a/sys/arch/aviion/dev/syscon.c +++ b/sys/arch/aviion/dev/syscon.c @@ -1,4 +1,20 @@ -/* $OpenBSD: syscon.c,v 1.3 2006/11/16 23:21:56 miod Exp $ */ +/* $OpenBSD: syscon.c,v 1.4 2007/12/19 22:05:06 miod Exp $ */ +/* + * Copyright (c) 2007 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -31,10 +47,11 @@ #include <sys/device.h> #include <machine/autoconf.h> +#include <machine/board.h> #include <machine/cpu.h> #include <machine/avcommon.h> -#include <aviion/dev/sysconreg.h> +#include <aviion/dev/sysconvar.h> struct sysconsoftc { struct device sc_dev; @@ -52,7 +69,6 @@ int syscon_scan(struct device *, void *, void *); int sysconabort(void *); int sysconacfail(void *); int sysconsysfail(void *); -int sysconav400(void *); struct cfattach syscon_ca = { sizeof(struct sysconsoftc), sysconmatch, sysconattach @@ -72,35 +88,39 @@ void sysconattach(struct device *parent, struct device *self, void *args) { struct sysconsoftc *sc = (struct sysconsoftc *)self; + int i; printf("\n"); /* - * Clear SYSFAIL if lit. + * Set up interrupt handlers. */ - *(volatile u_int32_t *)AV_UCSR |= UCSR_DRVSFBIT; + for (i = 0; i < INTSRC_VME; i++) + SLIST_INIT(&sysconintr_handlers[i]); /* - * pseudo driver, abort interrupt handler + * Clear SYSFAIL if lit. */ + *(volatile u_int32_t *)AV_UCSR |= UCSR_DRVSFBIT; + sc->sc_abih.ih_fn = sysconabort; sc->sc_abih.ih_arg = 0; - sc->sc_abih.ih_wantframe = 1; + sc->sc_abih.ih_flags = INTR_WANTFRAME; sc->sc_abih.ih_ipl = IPL_ABORT; sc->sc_acih.ih_fn = sysconacfail; sc->sc_acih.ih_arg = 0; - sc->sc_acih.ih_wantframe = 1; + sc->sc_acih.ih_flags = INTR_WANTFRAME; sc->sc_acih.ih_ipl = IPL_ABORT; sc->sc_sfih.ih_fn = sysconsysfail; sc->sc_sfih.ih_arg = 0; - sc->sc_sfih.ih_wantframe = 1; + sc->sc_sfih.ih_flags = INTR_WANTFRAME; sc->sc_sfih.ih_ipl = IPL_ABORT; - sysconintr_establish(SYSCV_ABRT, &sc->sc_abih, "abort"); - sysconintr_establish(SYSCV_ACF, &sc->sc_acih, "acfail"); - sysconintr_establish(SYSCV_SYSF, &sc->sc_sfih, "sysfail"); + sysconintr_establish(INTSRC_ABORT, &sc->sc_abih, "abort"); + sysconintr_establish(INTSRC_ACFAIL, &sc->sc_acih, "acfail"); + sysconintr_establish(INTSRC_SYSFAIL, &sc->sc_sfih, "sysfail"); config_search(syscon_scan, self, args); } @@ -139,17 +159,45 @@ syscon_print(void *args, const char *pnp) return (UNCONF); } +/* + * Interrupt related code + */ + +intrhand_t sysconintr_handlers[INTSRC_VME]; + int -sysconintr_establish(u_int vec, struct intrhand *ih, const char *name) +sysconintr_establish(u_int intsrc, struct intrhand *ih, const char *name) { + intrhand_t *list; + + list = &sysconintr_handlers[intsrc]; + if (!SLIST_EMPTY(list)) { #ifdef DIAGNOSTIC - if (vec < 0 || vec >= SYSCON_NVEC) { - printf("sysconintr_establish: illegal vector 0x%x\n", vec); + printf("%s: interrupt source %u already registered\n", + __func__, intsrc); +#endif return (EINVAL); } -#endif - return (intr_establish(SYSCON_VECT + vec, ih, name)); + evcount_attach(&ih->ih_count, name, (void *)&ih->ih_ipl, + &evcount_intr); + SLIST_INSERT_HEAD(list, ih, ih_link); + + intsrc_enable(intsrc, ih->ih_ipl); + + return (0); +} + +void +sysconintr_disestablish(u_int intsrc, struct intrhand *ih) +{ + intrhand_t *list; + + list = &sysconintr_handlers[intsrc]; + evcount_detach(&ih->ih_count); + SLIST_REMOVE(list, ih, intrhand, ih_link); + + intsrc_disable(intsrc); } int diff --git a/sys/arch/aviion/dev/sysconreg.h b/sys/arch/aviion/dev/sysconreg.h deleted file mode 100644 index 56292778a12..00000000000 --- a/sys/arch/aviion/dev/sysconreg.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $OpenBSD: sysconreg.h,v 1.1 2006/04/26 14:24:54 miod Exp $ */ - -/* - * Copyright (c) 2004, Miodrag Vallat. - * Copyright (c) 1999 Steve Murphree, Jr. - * All rights reserved. - * - * 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 AUTHOR ``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 AUTHOR 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. - */ - -/* - * SYSCON interrupt vectors (reserved for non-VME interrupt sources) - */ -#define SYSCON_VECT 0x50 -#define SYSCON_NVEC 0x10 - -#define SYSCV_ABRT 0x02 /* abort button */ -#define SYSCV_SYSF 0x03 /* SYSFAIL */ -#define SYSCV_ACF 0x04 /* ACFAIL */ -#define SYSCV_SCC 0x05 /* dart(4) serial interrupts */ -#define SYSCV_TIMER2 0x06 /* profiling clock */ -#define SYSCV_SCC2 0x08 /* second dart(4) instance */ -#define SYSCV_LE 0x09 /* onboard ethernet */ -#define SYSCV_SCSI 0x0a /* onboard SCSI */ - -int sysconintr_establish(u_int, struct intrhand *, const char *); diff --git a/sys/arch/aviion/dev/sysconvar.h b/sys/arch/aviion/dev/sysconvar.h new file mode 100644 index 00000000000..f9d09534d3a --- /dev/null +++ b/sys/arch/aviion/dev/sysconvar.h @@ -0,0 +1,23 @@ +/* $OpenBSD: sysconvar.h,v 1.1 2007/12/19 22:05:06 miod Exp $ */ + +/* + * Copyright (c) 2007 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +extern intrhand_t sysconintr_handlers[INTSRC_VME]; + +int sysconintr_establish(u_int, struct intrhand *, const char *); +void sysconintr_disestablish(u_int, struct intrhand *); diff --git a/sys/arch/aviion/dev/vme.c b/sys/arch/aviion/dev/vme.c index 6f73e319469..456e2e7b9cb 100644 --- a/sys/arch/aviion/dev/vme.c +++ b/sys/arch/aviion/dev/vme.c @@ -1,6 +1,6 @@ -/* $OpenBSD: vme.c,v 1.3 2006/05/21 12:22:02 miod Exp $ */ +/* $OpenBSD: vme.c,v 1.4 2007/12/19 22:05:06 miod Exp $ */ /* - * Copyright (c) 2006, Miodrag Vallat. + * Copyright (c) 2006, 2007, Miodrag Vallat. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,6 +37,7 @@ #include <sys/proc.h> #include <sys/uio.h> +#include <machine/board.h> #include <machine/bus.h> #include <machine/conf.h> @@ -45,8 +46,7 @@ #include <aviion/dev/vmevar.h> #include <machine/avcommon.h> -#include <machine/av400.h> -#include <aviion/dev/sysconreg.h> +#include <machine/av400.h> /* XXX */ struct vmesoftc { struct device sc_dev; @@ -60,11 +60,11 @@ int vmematch(struct device *, void *, void *); void vmeattach(struct device *, struct device *, void *); struct cfattach vme_ca = { - sizeof(struct vmesoftc), vmematch, vmeattach + sizeof(struct vmesoftc), vmematch, vmeattach }; struct cfdriver vme_cd = { - NULL, "vme", DV_DULL + NULL, "vme", DV_DULL }; int vme16_map(bus_addr_t, bus_size_t, int, bus_space_handle_t *); @@ -83,13 +83,11 @@ void vme_unmap(struct extent *, vme_addr_t, vaddr_t, bus_size_t); int vmeprint(void *, const char *); int vmescan(struct device *, void *, void *); -u_int vmevecbase; - int vmematch(struct device *parent, void *vcf, void *aux) { /* XXX no VME on AV100/AV200/AV300, though */ - return (1); + return (vme_cd.cd_ndevs == 0); } void @@ -97,10 +95,17 @@ vmeattach(struct device *parent, struct device *self, void *aux) { struct vmesoftc *sc = (struct vmesoftc *)self; u_int32_t ucsr; + int i; printf("\n"); /* + * Set up interrupt handlers. + */ + for (i = 0; i < NVMEINTR; i++) + SLIST_INIT(&vmeintr_handlers[i]); + + /* * Initialize extents */ sc->sc_ext_a16 = extent_create("vme a16", 0, 1 << (16 - PAGE_SHIFT), @@ -110,8 +115,6 @@ vmeattach(struct device *parent, struct device *self, void *aux) sc->sc_ext_a32 = extent_create("vme a32", 0, 1 << (32 - PAGE_SHIFT), M_DEVBUF, NULL, 0, EX_NOWAIT); - vmevecbase = 0x80; /* Hard coded */ - /* * Force a reasonable timeout for VME data transfers. * We can not disable this, this would cause autoconf to hang @@ -188,46 +191,150 @@ vmeprint(void *aux, const char *pnp) * Interrupt related code */ -/* allocate interrupt vectors */ +intrhand_t vmeintr_handlers[NVMEINTR]; + int -vmeintr_allocate(u_int count, int flags, u_int *array) +vmeintr_allocate(u_int count, int flags, int ipl, u_int *array) { u_int vec, v; + struct intrhand *ih; + + if (count > 1 && ISSET(flags, VMEINTR_CONTIGUOUS)) { + /* + * Try to find a range of count unused vectors first. + * If there isn't, it is not possible to provide exclusive + * contiguous vectors. + */ + for (vec = 0; vec <= NVMEINTR - count; vec++) { + for (v = count; v != 0; v--) + if (!SLIST_EMPTY(&vmeintr_handlers[vec + v - 1])) + break; - if ((flags & VMEINTR_CONTIGUOUS) == 0) { - for (vec = vmevecbase; vec <= NVMEINTR - count; vec++) { - if (SLIST_EMPTY(&intr_handlers[vec])) { - *array++ = vec; - if (--count == 0) - return (0); + if (v == 0) { + for (v = 0; v < count; v++) + *array++ = vec++; + return (0); } } - } else { - for (vec = vmevecbase; vec <= NVMEINTR - count; vec++) { - /* do we have count contiguous unassigned vectors? */ - for (v = count; v != 0; v--) - if (!SLIST_EMPTY(&intr_handlers[vec + v - 1])) + if (ISSET(flags, VMEINTR_EXCLUSIVE)) + return (EPERM); + + /* + * Try to find a range of count contiguous vectors, + * sharing the level we intend to register at. If there + * isn't, it is not possible to provide shared contiguous + * vectors. + */ + for (vec = 0; vec <= NVMEINTR - count; vec++) { + for (v = count; v != 0; v--) { + ih = SLIST_FIRST(&vmeintr_handlers[vec + v - 1]); + if (ih == NULL) + continue; + if (ih->ih_ipl != ipl || + ISSET(ih->ih_flags, INTR_EXCLUSIVE)) break; + } if (v == 0) { - *array = vec; + for (v = 0; v < count; v++) + *array++ = vec++; return (0); } } + return (EPERM); } + /* + * Pick as many unused vectors as possible. + */ + for (vec = 0; vec < NVMEINTR; vec++) { + if (SLIST_EMPTY(&vmeintr_handlers[vec])) { + *array++ = vec; + if (--count == 0) + return (0); + } + } + + /* + * There are not enough free vectors, so we'll have to share. + */ + for (vec = 0; vec < NVMEINTR; vec++) { + ih = SLIST_FIRST(&vmeintr_handlers[vec]); + if (ih->ih_ipl == ipl && !ISSET(ih->ih_flags, INTR_EXCLUSIVE)) { + *array++ = vec; + if (--count == 0) + return (0); + } + } + + /* + * There are not enough vectors to share. + */ return (EPERM); } -/* enable and establish interrupt */ int vmeintr_establish(u_int vec, struct intrhand *ih, const char *name) { + struct intrhand *intr; + intrhand_t *list; + + list = &vmeintr_handlers[vec]; + intr = SLIST_FIRST(list); + if (intr != NULL) { + if (intr->ih_ipl != ih->ih_ipl) { +#ifdef DIAGNOSTIC + printf("%s: can't use ipl %d for vector %x," + " it uses ipl %d\n", + __func__, ih->ih_ipl, vec, intr->ih_ipl); +#endif + return (EINVAL); + } + if (ISSET(intr->ih_flags, INTR_EXCLUSIVE) || + ISSET(ih->ih_flags, INTR_EXCLUSIVE)) { +#ifdef DIAGNOSTIC + printf("%s: can't share vector %x\n", __func__, vec); +#endif + return (EINVAL); + } + } + + evcount_attach(&ih->ih_count, name, (void *)&ih->ih_ipl, + &evcount_intr); + SLIST_INSERT_HEAD(list, ih, ih_link); + + /* + * Enable VME interrupt source for this level. + */ + intsrc_enable(INTSRC_VME + (ih->ih_ipl - 1), ih->ih_ipl); + + return (0); +} + +void +vmeintr_disestablish(u_int vec, struct intrhand *ih) +{ + struct intrhand *intr; + intrhand_t *list; + + list = &vmeintr_handlers[vec]; + evcount_detach(&ih->ih_count); + SLIST_REMOVE(list, ih, intrhand, ih_link); + + if (!SLIST_EMPTY(list)) + return; + /* - * No need to enable the VME interrupt source in the interrupt - * controller, as they are enabled by default. + * Walk the interrupts table to check if this level needs + * to be disabled. */ - return intr_establish(vec, ih, name); + for (vec = 0; vec < NVMEINTR; vec++) { + intr = SLIST_FIRST(&vmeintr_handlers[vec]); + if (intr != NULL && intr->ih_ipl == ih->ih_ipl) + break; + } + if (vec == NVMEINTR) + intsrc_disable(INTSRC_VME + (ih->ih_ipl - 1)); } /* @@ -279,7 +386,6 @@ vme_map(struct extent *ext, paddr_t paddr, bus_addr_t addr, bus_size_t size, psize_t len; vaddr_t ova, va; u_int pg; - extern vaddr_t pmap_map(vaddr_t, paddr_t, paddr_t, vm_prot_t, u_int); pa = trunc_page(paddr); len = round_page(paddr + size) - pa; @@ -299,7 +405,7 @@ vme_map(struct extent *ext, paddr_t paddr, bus_addr_t addr, bus_size_t size, *ret = (bus_space_handle_t)va; - for (pg = atop(len); pg !=0; pg--) { + for (pg = atop(len); pg != 0; pg--) { pmap_kenter_pa(va, pa, UVM_PROT_RW); va += PAGE_SIZE; pa += PAGE_SIZE; diff --git a/sys/arch/aviion/dev/vmevar.h b/sys/arch/aviion/dev/vmevar.h index 207271ff9fe..9098585ce8c 100644 --- a/sys/arch/aviion/dev/vmevar.h +++ b/sys/arch/aviion/dev/vmevar.h @@ -1,6 +1,6 @@ -/* $OpenBSD: vmevar.h,v 1.2 2006/05/21 12:22:02 miod Exp $ */ +/* $OpenBSD: vmevar.h,v 1.3 2007/12/19 22:05:06 miod Exp $ */ /* - * Copyright (c) 2006, Miodrag Vallat + * Copyright (c) 2006, 2007, Miodrag Vallat * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -44,11 +44,32 @@ struct vme_attach_args { u_int vaa_ipl; }; -int vmeintr_allocate(u_int, int, u_int *); -#define VMEINTR_ANY 0x00 +/* + * There are 256 possible vectors for VME devices. + * One or more vectors may be allocated by vmeintr_allocate(), and then + * each vector is setup with vmeintr_establish(). Nothing is done to + * prevent the vector to be used in-between, so make sure no interrupt + * can occur between the vector allocation and the interrupt handler + * registration. + */ +#define NVMEINTR 256 +extern intrhand_t vmeintr_handlers[NVMEINTR]; + +int vmeintr_allocate(u_int, int, int, u_int *); +#define VMEINTR_ANY 0x00 /* any vector will do */ #define VMEINTR_CONTIGUOUS 0x01 /* allocate a contiguous range */ +#define VMEINTR_SHARED 0x00 /* sharing is ok */ +#define VMEINTR_EXCLUSIVE 0x02 /* do not share this vector */ +void vmeintr_disestablish(u_int, struct intrhand *); int vmeintr_establish(u_int, struct intrhand *, const char *); +/* + * VME device drivers need to obtain their bus_space_tag_t with + * vmebus_get_bst(), specifying the address and data width to use for + * bus accesses. + * Resources associated to the tag can be released with vmebus_release_bst() + * when bus accesses are no longer necessary. + */ int vmebus_get_bst(struct device *, u_int, u_int, bus_space_tag_t *); #define VME_A32 0x04 /* 100..000 */ #define VME_A24 0x03 /* 011..000 */ diff --git a/sys/arch/aviion/include/av400.h b/sys/arch/aviion/include/av400.h index e156daf1fbc..5e3e6c6adb6 100644 --- a/sys/arch/aviion/include/av400.h +++ b/sys/arch/aviion/include/av400.h @@ -1,4 +1,4 @@ -/* $OpenBSD: av400.h,v 1.4 2007/12/19 21:52:47 miod Exp $ */ +/* $OpenBSD: av400.h,v 1.5 2007/12/19 22:05:06 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -135,45 +135,6 @@ "\20ECI\17IRQ5\16DTC\15IRQ4\14DWP\13IRQ3\12DVB" \ "\7IRQ2\6SCI\5IRQ1\2SWI1\1SWI0" -/* groups by function */ - -/* hardware irq bits */ -#define HW_FAILURE_MASK (IRQ_ABORT | IRQ_ACF | IRQ_ARBTO | IRQ_SF | \ - IRQ_PAR) -/* software irq bits */ -#define SOFT_INTERRUPT_MASK (IRQ_SWI1 | IRQ_SWI0) -/* VME irq bits */ -#define VME_INTERRUPT_MASK (IRQ_VME7 | IRQ_VME6 | IRQ_VME5 | IRQ_VME4 | \ - IRQ_VME3 | IRQ_VME2 | IRQ_VME1) -/* on-board irq bits */ -#define OBIO_INTERRUPT_MASK (IRQ_ZBUF | IRQ_VID | IRQ_KBD | IRQ_CIOI | \ - IRQ_PPI | IRQ_DI1 | IRQ_DI2 | IRQ_ECI | \ - IRQ_DTC | IRQ_DWP | IRQ_DVB | IRQ_SCI) - -/* groups by interrupt levels */ -/* we do not enable and define levels yet for: ZBUF, VID, KBD, PPI, SCI, DMA */ - -#define LVL7 (IRQ_ABORT | IRQ_ACF | IRQ_VME7 | IRQ_SF) -#define LVL6 (IRQ_VME6) -#define LVL5 (IRQ_VME5 | IRQ_CIOI) -#define LVL4 (IRQ_VME4) -#define LVL3 (IRQ_VME3 | IRQ_DI1 | IRQ_DI2) -#define LVL2 (IRQ_VME2) /* | IRQ_SCI */ -#define LVL1 (IRQ_VME1 | IRQ_ECI ) -#define LVL0 (0x0) - -/* interrupts we want to process on the master CPU only */ -#define SLAVE_MASK (HW_FAILURE_MASK | OBIO_INTERRUPT_MASK) - -#define MASK_LVL_0 (LVL7 | LVL6 | LVL5 | LVL4 | LVL3 | LVL2 | LVL1) -#define MASK_LVL_1 (LVL7 | LVL6 | LVL5 | LVL4 | LVL3 | LVL2) -#define MASK_LVL_2 (LVL7 | LVL6 | LVL5 | LVL4 | LVL3) -#define MASK_LVL_3 (LVL7 | LVL6 | LVL5 | LVL4) -#define MASK_LVL_4 (LVL7 | LVL6 | LVL5) -#define MASK_LVL_5 (LVL7 | LVL6) -#define MASK_LVL_6 (LVL7) -#define MASK_LVL_7 (IRQ_ABORT) - /* * CMMU addresses */ diff --git a/sys/arch/aviion/include/avcommon.h b/sys/arch/aviion/include/avcommon.h index 32b391e958e..f2a7f5b4e41 100644 --- a/sys/arch/aviion/include/avcommon.h +++ b/sys/arch/aviion/include/avcommon.h @@ -1,4 +1,4 @@ -/* $OpenBSD: avcommon.h,v 1.3 2007/12/19 21:52:47 miod Exp $ */ +/* $OpenBSD: avcommon.h,v 1.4 2007/12/19 22:05:06 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -62,7 +62,6 @@ #define AV_IST 0xfff84040 /* interrupt status register */ -#define INT_LEVEL 8 /* # of interrupt level + 1 */ #define ISR_GET_CURRENT_MASK(cpu) \ (*(volatile u_int *)AV_IST & int_mask_reg[cpu]) @@ -184,4 +183,16 @@ #define CONSOLE_DART_BASE 0xfff82000 +#if defined(_KERNEL) && !defined(_LOCORE) + +#include <machine/intr.h> + +/* + * Interrupt masks, one per IPL level. + */ +extern u_int32_t int_mask_val[NIPLS]; +extern u_int32_t ext_int_mask_val[NIPLS]; + +#endif + #endif /* __MACHINE_AVCOMMON_H__ */ diff --git a/sys/arch/aviion/include/board.h b/sys/arch/aviion/include/board.h index 68f1c4055a8..2a7c0993851 100644 --- a/sys/arch/aviion/include/board.h +++ b/sys/arch/aviion/include/board.h @@ -1,6 +1,6 @@ -/* $OpenBSD: board.h,v 1.2 2006/05/21 12:22:03 miod Exp $ */ +/* $OpenBSD: board.h,v 1.3 2007/12/19 22:05:06 miod Exp $ */ /* - * Copyright (c) 2006, Miodrag Vallat + * Copyright (c) 2006, 2007, Miodrag Vallat * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,6 +43,8 @@ struct board { u_int (*setipl)(u_int); u_int (*raiseipl)(u_int); + u_int64_t (*intsrc)(int); + pmap_table_t ptable; }; @@ -57,14 +59,38 @@ void av##b##_intr(u_int, struct trapframe *); \ void av##b##_init_clocks(void); \ u_int av##b##_getipl(void); \ u_int av##b##_setipl(u_int); \ -u_int av##b##_raiseipl(u_int); +u_int av##b##_raiseipl(u_int); \ +u_int64_t av##b##_intsrc(int); DECLARE_BOARD(400); DECLARE_BOARD(530); DECLARE_BOARD(5000); DECLARE_BOARD(6280); +/* + * Logical values for interrupt sources. + * When adding new sources, keep INTSRC_VME as the last item - syscon + * depends on this. + */ + +#define INTSRC_ABORT 1 /* abort button */ +#define INTSRC_ACFAIL 2 /* AC failure */ +#define INTSRC_SYSFAIL 3 /* system failure */ +#define INTSRC_CIO 4 /* Z8536 */ +#define INTSRC_DUART1 5 /* console MC68692 */ +#define INTSRC_DUART2 6 /* secondary MC68692 */ +#define INTSRC_ETHERNET1 7 /* first on-board Ethernet */ +#define INTSRC_ETHERNET2 8 /* second on-board Ethernet */ +#define INTSRC_SCSI1 9 /* first on-board SCSI controller */ +#define INTSRC_SCSI2 10 /* second on-board SCSI controller */ +#define INTSRC_VME 11 /* seven VME interrupt levels */ + +void intsrc_enable(u_int, int); +void intsrc_disable(u_int); + extern const struct board *platform;/* just to have people confuse both names */ +void cio_init_clocks(void); + #endif /* _LOCORE */ #endif /* _MACHINE_BOARD_H_ */ diff --git a/sys/arch/aviion/include/cpu.h b/sys/arch/aviion/include/cpu.h index f24ae82aab0..fc813dc299e 100644 --- a/sys/arch/aviion/include/cpu.h +++ b/sys/arch/aviion/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.2 2006/05/20 12:04:54 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.3 2007/12/19 22:05:06 miod Exp $ */ /* * Copyright (c) 1996 Nivas Madhur * Copyright (c) 1992, 1993 @@ -40,31 +40,26 @@ #ifndef _AVIION_CPU_H_ #define _AVIION_CPU_H_ -#include <sys/evcount.h> #include <m88k/cpu.h> #ifdef _KERNEL +#include <sys/evcount.h> + +/* + * Generic interrupt handler structure. Handlers may be chained. + */ struct intrhand { SLIST_ENTRY(intrhand) ih_link; int (*ih_fn)(void *); void *ih_arg; int ih_ipl; - int ih_wantframe; + int ih_flags; +#define INTR_WANTFRAME 0x01 +#define INTR_EXCLUSIVE 0x02 struct evcount ih_count; }; - -int intr_establish(int, struct intrhand *, const char *); - -/* - * There are 256 possible vectors on a aviion platform (including - * onboard and VME vectors. Use intr_establish() to register a - * handler for the given vector. vector number is used to index - * into the intr_handlers[] table. - */ -#define NVMEINTR 256 typedef SLIST_HEAD(, intrhand) intrhand_t; -extern intrhand_t intr_handlers[NVMEINTR]; void doboot(void); void nmihand(void *); diff --git a/sys/arch/aviion/include/intr.h b/sys/arch/aviion/include/intr.h index dbd1ed4057c..68a8bfc4f0b 100644 --- a/sys/arch/aviion/include/intr.h +++ b/sys/arch/aviion/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.1 2006/05/09 18:19:31 miod Exp $ */ +/* $OpenBSD: intr.h,v 1.2 2007/12/19 22:05:06 miod Exp $ */ /* * Copyright (C) 2000 Steve Murphree, Jr. * All rights reserved. @@ -50,6 +50,8 @@ #define IPL_NMI 7 #define IPL_ABORT 7 +#define NIPLS 8 + #include <m88k/intr.h> #endif /* _AVIION_INTR_H_ */ |