From 126f6cf9bcfb8d3163f5b16e23c7d85de22fb1ca Mon Sep 17 00:00:00 2001 From: briggs Date: Sat, 17 Aug 2002 16:42:20 +0000 Subject: [PATCH] Add a new option EVBARM_BOARDTYPE to differentiate between different evbarm ports. Inline _splraise/_spllower/splx for i80321 and iq80310 for more performance. --- sys/arch/arm/xscale/i80321_icu.c | 126 ++++++++++++++--------- sys/arch/arm/xscale/i80321_intr.h | 124 ++++++++++++++++++++++ sys/arch/evbarm/conf/IQ80321 | 7 +- sys/arch/evbarm/conf/TEAMASA_NPWR | 6 +- sys/arch/evbarm/conf/files.evbarm | 3 +- sys/arch/evbarm/conf/std.integrator | 6 +- sys/arch/evbarm/conf/std.iq80310 | 4 +- sys/arch/evbarm/conf/std.iq80321 | 4 +- sys/arch/evbarm/conf/std.ixm1200 | 4 +- sys/arch/evbarm/include/cpu.h | 13 ++- sys/arch/evbarm/include/intr.h | 66 +++++++++++- sys/arch/evbarm/iq80310/iq80310_intr.c | 117 +++++++++++---------- sys/arch/evbarm/iq80310/iq80310_intr.h | 137 +++++++++++++++++++++++++ sys/arch/evbarm/ixm1200/ixm1200_intr.h | 46 +++++++++ 14 files changed, 542 insertions(+), 121 deletions(-) create mode 100644 sys/arch/arm/xscale/i80321_intr.h create mode 100644 sys/arch/evbarm/iq80310/iq80310_intr.h create mode 100644 sys/arch/evbarm/ixm1200/ixm1200_intr.h diff --git a/sys/arch/arm/xscale/i80321_icu.c b/sys/arch/arm/xscale/i80321_icu.c index eb544983bea9..470760c8d021 100644 --- a/sys/arch/arm/xscale/i80321_icu.c +++ b/sys/arch/arm/xscale/i80321_icu.c @@ -1,4 +1,4 @@ -/* $NetBSD: i80321_icu.c,v 1.4 2002/08/14 19:47:18 thorpej Exp $ */ +/* $NetBSD: i80321_icu.c,v 1.5 2002/08/17 16:42:20 briggs Exp $ */ /* * Copyright (c) 2001, 2002 Wasabi Systems, Inc. @@ -57,13 +57,13 @@ struct intrq intrq[NIRQ]; /* Interrupts to mask at each level. */ -static int imask[NIPL]; +int i80321_imask[NIPL]; /* Current interrupt priority level. */ __volatile int current_spl_level; /* Interrupts pending. */ -static __volatile int ipending; +__volatile int i80321_ipending; /* Software copy of the IRQs we have enabled. */ __volatile uint32_t intr_enabled; @@ -155,14 +155,17 @@ i80321_iintsrc_read(void) return (iintsrc & intr_enabled); } +#if defined(EVBARM_SPL_NOINLINE) static __inline void i80321_set_intrmask(void) { + extern __volatile uint32_t intr_enabled; __asm __volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (intr_enabled & ICU_INT_HWMASK)); } +#endif static __inline void i80321_set_intrsteer(void) @@ -217,76 +220,76 @@ i80321_intr_calculate_masks(void) if (intrq[irq].iq_levels & (1U << ipl)) irqs |= (1U << irq); } - imask[ipl] = irqs; + i80321_imask[ipl] = irqs; } - imask[IPL_NONE] = 0; + i80321_imask[IPL_NONE] = 0; /* * Initialize the soft interrupt masks to block themselves. */ - imask[IPL_SOFT] = SI_TO_IRQBIT(SI_SOFT); - imask[IPL_SOFTCLOCK] = SI_TO_IRQBIT(SI_SOFTCLOCK); - imask[IPL_SOFTNET] = SI_TO_IRQBIT(SI_SOFTNET); - imask[IPL_SOFTSERIAL] = SI_TO_IRQBIT(SI_SOFTSERIAL); + i80321_imask[IPL_SOFT] = SI_TO_IRQBIT(SI_SOFT); + i80321_imask[IPL_SOFTCLOCK] = SI_TO_IRQBIT(SI_SOFTCLOCK); + i80321_imask[IPL_SOFTNET] = SI_TO_IRQBIT(SI_SOFTNET); + i80321_imask[IPL_SOFTSERIAL] = SI_TO_IRQBIT(SI_SOFTSERIAL); /* * splsoftclock() is the only interface that users of the * generic software interrupt facility have to block their * soft intrs, so splsoftclock() must also block IPL_SOFT. */ - imask[IPL_SOFTCLOCK] |= imask[IPL_SOFT]; + i80321_imask[IPL_SOFTCLOCK] |= i80321_imask[IPL_SOFT]; /* * splsoftnet() must also block splsoftclock(), since we don't * want timer-driven network events to occur while we're * processing incoming packets. */ - imask[IPL_SOFTNET] |= imask[IPL_SOFTCLOCK]; + i80321_imask[IPL_SOFTNET] |= i80321_imask[IPL_SOFTCLOCK]; /* * Enforce a heirarchy that gives "slow" device (or devices with * limited input buffer space/"real-time" requirements) a better * chance at not dropping data. */ - imask[IPL_BIO] |= imask[IPL_SOFTNET]; - imask[IPL_NET] |= imask[IPL_BIO]; - imask[IPL_SOFTSERIAL] |= imask[IPL_NET]; - imask[IPL_TTY] |= imask[IPL_SOFTSERIAL]; + i80321_imask[IPL_BIO] |= i80321_imask[IPL_SOFTNET]; + i80321_imask[IPL_NET] |= i80321_imask[IPL_BIO]; + i80321_imask[IPL_SOFTSERIAL] |= i80321_imask[IPL_NET]; + i80321_imask[IPL_TTY] |= i80321_imask[IPL_SOFTSERIAL]; /* * splvm() blocks all interrupts that use the kernel memory * allocation facilities. */ - imask[IPL_IMP] |= imask[IPL_TTY]; + i80321_imask[IPL_IMP] |= i80321_imask[IPL_TTY]; /* * Audio devices are not allowed to perform memory allocation * in their interrupt routines, and they have fairly "real-time" * requirements, so give them a high interrupt priority. */ - imask[IPL_AUDIO] |= imask[IPL_IMP]; + i80321_imask[IPL_AUDIO] |= i80321_imask[IPL_IMP]; /* * splclock() must block anything that uses the scheduler. */ - imask[IPL_CLOCK] |= imask[IPL_AUDIO]; + i80321_imask[IPL_CLOCK] |= i80321_imask[IPL_AUDIO]; /* * No separate statclock on the IQ80310. */ - imask[IPL_STATCLOCK] |= imask[IPL_CLOCK]; + i80321_imask[IPL_STATCLOCK] |= i80321_imask[IPL_CLOCK]; /* * splhigh() must block "everything". */ - imask[IPL_HIGH] |= imask[IPL_STATCLOCK]; + i80321_imask[IPL_HIGH] |= i80321_imask[IPL_STATCLOCK]; /* * XXX We need serial drivers to run at the absolute highest priority * in order to avoid overruns, so serial > high. */ - imask[IPL_SERIAL] |= imask[IPL_HIGH]; + i80321_imask[IPL_SERIAL] |= i80321_imask[IPL_HIGH]; /* * Now compute which IRQs must be blocked when servicing any @@ -299,12 +302,12 @@ i80321_intr_calculate_masks(void) i80321_enable_irq(irq); for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL; ih = TAILQ_NEXT(ih, ih_list)) - irqs |= imask[ih->ih_ipl]; + irqs |= i80321_imask[ih->ih_ipl]; iq->iq_mask = irqs; } } -static void +__inline void i80321_do_pending(void) { static __cpu_simple_lock_t processing = __SIMPLELOCK_UNLOCKED; @@ -318,9 +321,9 @@ i80321_do_pending(void) oldirqstate = disable_interrupts(I32_bit); #define DO_SOFTINT(si) \ - if ((ipending & ~new) & SI_TO_IRQBIT(si)) { \ - ipending &= ~SI_TO_IRQBIT(si); \ - current_spl_level |= imask[si_to_ipl[(si)]]; \ + if ((i80321_ipending & ~new) & SI_TO_IRQBIT(si)) { \ + i80321_ipending &= ~SI_TO_IRQBIT(si); \ + current_spl_level |= i80321_imask[si_to_ipl[(si)]]; \ restore_interrupts(oldirqstate); \ softintr_dispatch(si); \ oldirqstate = disable_interrupts(I32_bit); \ @@ -337,16 +340,7 @@ i80321_do_pending(void) restore_interrupts(oldirqstate); } -int -_splraise(int ipl) -{ - int old; - - old = current_spl_level; - current_spl_level |= imask[ipl]; - - return (old); -} +#if defined(EVBARM_SPL_NOINLINE) __inline void splx(int new) @@ -355,12 +349,7 @@ splx(int new) current_spl_level = new; - /* - * If there are pending HW interrupts which are being - * unmasked, then enable them in the INTCTL register. - * This will cause them to come flooding in. - */ - hwpend = (ipending & ICU_INT_HWMASK) & ~new; + hwpend = (i80321_ipending & ICU_INT_HWMASK) & ~new; if (hwpend != 0) { oldirqstate = disable_interrupts(I32_bit); intr_enabled |= hwpend; @@ -368,31 +357,66 @@ splx(int new) restore_interrupts(oldirqstate); } - /* If there are software interrupts to process, do it. */ - if ((ipending & INT_SWMASK) & ~new) + if ((i80321_ipending & INT_SWMASK) & ~new) i80321_do_pending(); } +int +_splraise(int ipl) +{ + int old; + + old = current_spl_level; + current_spl_level |= i80321_imask[ipl]; + + return (old); +} + int _spllower(int ipl) { int old = current_spl_level; - splx(imask[ipl]); - return (old); + splx(i80321_imask[ipl]); + return(old); } +#else /* EVBARM_SPL_NOINLINE */ + +#undef splx +__inline void +splx(int new) +{ + i80321_splx(new); +} + +#undef _spllower +int +_spllower(int ipl) +{ + return i80321_spllower(ipl); +} + +#undef _splraise +int +_splraise(int ipl) +{ + return i80321_splraise(ipl); +} + +#endif /* else EVBARM_SPL_NOINLINE */ + void _setsoftintr(int si) { int oldirqstate; oldirqstate = disable_interrupts(I32_bit); - ipending |= SI_TO_IRQBIT(si); + i80321_ipending |= SI_TO_IRQBIT(si); restore_interrupts(oldirqstate); /* Process unmasked pending soft interrupts. */ - if ((ipending & INT_SWMASK) & ~current_spl_level) + if ((i80321_ipending & INT_SWMASK) & ~current_spl_level) i80321_do_pending(); } @@ -521,11 +545,11 @@ i80321_intr_dispatch(struct clockframe *frame) * IRQ is masked; mark it as pending and check * the next one. Note: the IRQ is already disabled. */ - ipending |= ibit; + i80321_ipending |= ibit; continue; } - ipending &= ~ibit; + i80321_ipending &= ~ibit; iq = &intrq[irq]; iq->iq_ev.ev_count++; @@ -546,7 +570,7 @@ i80321_intr_dispatch(struct clockframe *frame) } /* Check for pendings soft intrs. */ - if ((ipending & INT_SWMASK) & ~current_spl_level) { + if ((i80321_ipending & INT_SWMASK) & ~current_spl_level) { oldirqstate = enable_interrupts(I32_bit); i80321_do_pending(); restore_interrupts(oldirqstate); diff --git a/sys/arch/arm/xscale/i80321_intr.h b/sys/arch/arm/xscale/i80321_intr.h new file mode 100644 index 000000000000..16b605d8a670 --- /dev/null +++ b/sys/arch/arm/xscale/i80321_intr.h @@ -0,0 +1,124 @@ +/* $NetBSD: i80321_intr.h,v 1.1 2002/08/17 16:42:20 briggs Exp $ */ + +/* + * Copyright (c) 2001, 2002 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * 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 for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC + * 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. + */ + +#ifndef _I80321_INTR_H_ +#define _I80321_INTR_H_ + +#include +#include + +#include + +#if !defined(EVBARM_SPL_NOINLINE) +static __inline void +i80321_set_intrmask(void) +{ + extern __volatile uint32_t intr_enabled; + + __asm __volatile("mcr p6, 0, %0, c0, c0, 0" + : + : "r" (intr_enabled & ICU_INT_HWMASK)); +} + +#define INT_SWMASK \ + ((1U << ICU_INT_bit26) | (1U << ICU_INT_bit22) | \ + (1U << ICU_INT_bit5) | (1U << ICU_INT_bit4)) + +static __inline void +i80321_splx(int new) +{ + extern __volatile uint32_t intr_enabled; + extern __volatile int current_spl_level; + extern __volatile int i80321_ipending; + extern void i80321_do_pending(void); + int oldirqstate, hwpend; + + current_spl_level = new; + + hwpend = (i80321_ipending & ICU_INT_HWMASK) & ~new; + if (hwpend != 0) { + oldirqstate = disable_interrupts(I32_bit); + intr_enabled |= hwpend; + i80321_set_intrmask(); + restore_interrupts(oldirqstate); + } + + if ((i80321_ipending & INT_SWMASK) & ~new) + i80321_do_pending(); +} + +static __inline int +i80321_splraise(int ipl) +{ + extern __volatile int current_spl_level; + extern int i80321_imask[]; + int old; + + old = current_spl_level; + current_spl_level |= i80321_imask[ipl]; + + return (old); +} + +static __inline int +i80321_spllower(int ipl) +{ + extern __volatile int current_spl_level; + extern int i80321_imask[]; + int old = current_spl_level; + + i80321_splx(i80321_imask[ipl]); + return(old); +} + +#define splx(new) i80321_splx(new) +#define _spllower(ipl) i80321_spllower(ipl) +#define _splraise(ipl) i80321_splraise(ipl) +void _setsoftintr(int); + +#undef INT_SWMASK + +#else /* !EVBARM_SPL_NOINTR */ + +int _splraise(int); +int _spllower(int); +void splx(int); +void _setsoftintr(int); + +#endif /* else !EVBARM_SPL_NOINTR */ + +#endif _I80321_INTR_H_ diff --git a/sys/arch/evbarm/conf/IQ80321 b/sys/arch/evbarm/conf/IQ80321 index 6ee466178162..6fbcd494b8bb 100644 --- a/sys/arch/evbarm/conf/IQ80321 +++ b/sys/arch/evbarm/conf/IQ80321 @@ -1,4 +1,4 @@ -# $NetBSD: IQ80321,v 1.9 2002/08/07 03:41:43 thorpej Exp $ +# $NetBSD: IQ80321,v 1.10 2002/08/17 16:42:21 briggs Exp $ # # IQ80321 -- Intel IQ80321 Evaluation Board Kernel # @@ -23,6 +23,9 @@ options CPU_XSCALE_80321 # Support the XScale core makeoptions COPTS="-O2 -mcpu=xscale" # Architecture options +options PERFCTRS +options XSCALE_CACHE_READ_WRITE_ALLOCATE +options HZ=512 # File systems @@ -68,6 +71,7 @@ options INET6 # IPV6 #options PPP_DEFLATE # Deflate compression support for PPP #options PPP_FILTER # Active filter support for PPP (requires bpf) #options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG +options SOSEND_LOAN options NFS_BOOT_BOOTP options NFS_BOOT_DHCP @@ -176,6 +180,7 @@ pseudo-device vnd 4 # disk-like interface to files # network pseudo-devices pseudo-device bpfilter 4 # Berkeley packet filter pseudo-device loop # network loopback +pseudo-device kttcp # network loopback # miscellaneous pseudo-devices pseudo-device pty # pseudo-terminals diff --git a/sys/arch/evbarm/conf/TEAMASA_NPWR b/sys/arch/evbarm/conf/TEAMASA_NPWR index 7523f21d17fe..4acc51bf46df 100644 --- a/sys/arch/evbarm/conf/TEAMASA_NPWR +++ b/sys/arch/evbarm/conf/TEAMASA_NPWR @@ -1,4 +1,4 @@ -# $NetBSD: TEAMASA_NPWR,v 1.17 2002/08/07 03:40:01 thorpej Exp $ +# $NetBSD: TEAMASA_NPWR,v 1.18 2002/08/17 16:42:21 briggs Exp $ # # TEAMASA_NPWR -- Team ASA, Inc. Npwr -- XScale/IOP310-based # server appliance. @@ -26,6 +26,8 @@ makeoptions COPTS="-O2 -mcpu=xscale" options XSCALE_CCLKCFG=7 # 600MHz # Architecture options +options PERFCTRS +options XSCALE_CACHE_READ_WRITE_ALLOCATE # File systems @@ -71,6 +73,7 @@ options INET6 # IPV6 #options PPP_DEFLATE # Deflate compression support for PPP #options PPP_FILTER # Active filter support for PPP (requires bpf) #options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG +options SOSEND_LOAN options NFS_BOOT_BOOTP options NFS_BOOT_DHCP @@ -192,6 +195,7 @@ pseudo-device raid 4 # RAIDframe devices # network pseudo-devices pseudo-device bpfilter 4 # Berkeley packet filter pseudo-device loop # network loopback +pseudo-device kttcp # miscellaneous pseudo-devices pseudo-device pty # pseudo-terminals diff --git a/sys/arch/evbarm/conf/files.evbarm b/sys/arch/evbarm/conf/files.evbarm index 2f059fa28ae1..e5c495398259 100644 --- a/sys/arch/evbarm/conf/files.evbarm +++ b/sys/arch/evbarm/conf/files.evbarm @@ -1,4 +1,4 @@ -# $NetBSD: files.evbarm,v 1.13 2002/07/20 03:09:04 ichiro Exp $ +# $NetBSD: files.evbarm,v 1.14 2002/08/17 16:42:21 briggs Exp $ # # First try for arm-specific configuration info # @@ -66,6 +66,7 @@ include "dev/cardbus/files.cardbus" # CARDBus device # # ARM evaluation board specific devices # +defparam opt_evbarm_boardtype.h EVBARM_BOARDTYPE # We need to define the Integrator's "plcom" device here since # it we need to generate a "plcom.h" header file for conf.c diff --git a/sys/arch/evbarm/conf/std.integrator b/sys/arch/evbarm/conf/std.integrator index 5d9dace4d03a..4fa4af88fb10 100644 --- a/sys/arch/evbarm/conf/std.integrator +++ b/sys/arch/evbarm/conf/std.integrator @@ -1,6 +1,6 @@ -# $NetBSD: std.integrator,v 1.5 2002/01/30 03:59:40 thorpej Exp $ +# $NetBSD: std.integrator,v 1.6 2002/08/17 16:42:22 briggs Exp $ # -# standard NetBSD/netwinder options +# standard NetBSD/integrator options machine evbarm arm @@ -19,3 +19,5 @@ options __OLD_INTERRUPT_CODE # XXX for now makeoptions LOADADDRESS="0xa0100000" makeoptions LINKENTRY="-e 0x10000" makeoptions BOARDTYPE="integrator" + +options EVBARM_BOARDTYPE=EVBARM_BOARDTYPE_INTEGRATOR diff --git a/sys/arch/evbarm/conf/std.iq80310 b/sys/arch/evbarm/conf/std.iq80310 index f7ec7ff40567..60de66df8813 100644 --- a/sys/arch/evbarm/conf/std.iq80310 +++ b/sys/arch/evbarm/conf/std.iq80310 @@ -1,4 +1,4 @@ -# $NetBSD: std.iq80310,v 1.11 2002/04/25 01:50:01 briggs Exp $ +# $NetBSD: std.iq80310,v 1.12 2002/08/17 16:42:22 briggs Exp $ # # standard NetBSD/evbarm for IQ80310 options @@ -17,5 +17,7 @@ options ARM32 makeoptions LOADADDRESS="0xa0200000" makeoptions BOARDTYPE="iq80310" +options EVBARM_BOARDTYPE=EVBARM_BOARDTYPE_IQ80310 + # We need to configure the PCI bus. options PCI_NETBSD_CONFIGURE diff --git a/sys/arch/evbarm/conf/std.iq80321 b/sys/arch/evbarm/conf/std.iq80321 index 3449743f1fcf..1a8c29550683 100644 --- a/sys/arch/evbarm/conf/std.iq80321 +++ b/sys/arch/evbarm/conf/std.iq80321 @@ -1,4 +1,4 @@ -# $NetBSD: std.iq80321,v 1.2 2002/04/25 01:47:56 briggs Exp $ +# $NetBSD: std.iq80321,v 1.3 2002/08/17 16:42:22 briggs Exp $ # # standard NetBSD/evbarm for IQ80321 options @@ -17,5 +17,7 @@ options ARM32 makeoptions LOADADDRESS="0xa0200000" makeoptions BOARDTYPE="iq80321" +options EVBARM_BOARDTYPE=EVBARM_BOARDTYPE_I80321 + # We need to configure the PCI bus. options PCI_NETBSD_CONFIGURE diff --git a/sys/arch/evbarm/conf/std.ixm1200 b/sys/arch/evbarm/conf/std.ixm1200 index f47d8c5362a3..d3f2fe091b17 100644 --- a/sys/arch/evbarm/conf/std.ixm1200 +++ b/sys/arch/evbarm/conf/std.ixm1200 @@ -1,4 +1,4 @@ -# $NetBSD: std.ixm1200,v 1.1 2002/07/15 17:13:31 ichiro Exp $ +# $NetBSD: std.ixm1200,v 1.2 2002/08/17 16:42:22 briggs Exp $ # # standard NetBSD/evbarm for IXM1200 options @@ -17,6 +17,8 @@ options ARM32 makeoptions LOADADDRESS="0xC0200000" makeoptions BOARDTYPE="ixm1200" +options EVBARM_BOARDTYPE=EVBARM_BOARDTYPE_IXM1200 + # We need to configure the PCI bus. options PCI_NETBSD_CONFIGURE #options __OLD_INTERRUPT_CODE # XXX XXX for now diff --git a/sys/arch/evbarm/include/cpu.h b/sys/arch/evbarm/include/cpu.h index d456a54182b0..4d88b938c3c5 100644 --- a/sys/arch/evbarm/include/cpu.h +++ b/sys/arch/evbarm/include/cpu.h @@ -1,3 +1,14 @@ -/* $NetBSD: cpu.h,v 1.1 2001/11/25 15:56:03 thorpej Exp $ */ +/* $NetBSD: cpu.h,v 1.2 2002/08/17 16:42:22 briggs Exp $ */ + +#if defined(_KERNEL) && !defined(_LKM) + +#include "opt_evbarm_boardtype.h" + +#define EVBARM_BOARDTYPE_INTEGRATOR 1 +#define EVBARM_BOARDTYPE_IQ80310 2 +#define EVBARM_BOARDTYPE_I80321 3 +#define EVBARM_BOARDTYPE_IXM1200 4 + +#endif #include diff --git a/sys/arch/evbarm/include/intr.h b/sys/arch/evbarm/include/intr.h index ba859176c70d..f02c413f24f7 100644 --- a/sys/arch/evbarm/include/intr.h +++ b/sys/arch/evbarm/include/intr.h @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.7 2002/01/30 03:59:41 thorpej Exp $ */ +/* $NetBSD: intr.h,v 1.8 2002/08/17 16:42:22 briggs Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -85,10 +85,66 @@ #include #include -int _splraise(int); /* provided by BSP */ -int _spllower(int); /* provided by BSP */ -void splx(int); /* provided by BSP */ -void _setsoftintr(int); /* provided by BSP */ +#if defined(_LKM) + +int _splraise(int); +int _spllower(int); +void splx(int); +void _setsoftintr(int); + +#else /* _LKM */ + +#if defined(EVBARM_BOARDTYPE) + +#include + +/* + * Each board needs to define the following functions: + * + * int _splraise(int); + * int _spllower(int); + * void splx(int); + * void _setsoftintr(int); + * + * These may be defined as functions, static __inline functions, or macros, + * but there must be a _spllower() and splx() defined as functions callable + * from assembly language (for cpu_switch()). However, since it's quite + * useful to be able to inline splx(), you could do something like the + * following: + * + * in _intr.h: + * static __inline int + * boardtype_splx(int spl) + * {...} + * + * #define splx(nspl) boardtype_splx(nspl) + * ... + * and in boardtype's machdep code: + * + * ... + * #undef splx + * int + * splx(int spl) + * { + * return boardtype_splx(spl); + * } + */ + +#if EVBARM_BOARDTYPE == EVBARM_BOARDTYPE_IQ80310 +#include +#elif EVBARM_BOARDTYPE == EVBARM_BOARDTYPE_I80321 +#include +#elif EVBARM_BOARDTYPE == EVBARM_BOARDTYPE_IXM1200 +#include +#endif + +#else /* EVBARM_BOARDTYPE */ + +#error EVBARM_BOARDTYPE not defined. + +#endif /* else EVBARM_BOARDTYPE */ + +#endif /* else _LKM */ #define splhigh() _splraise(IPL_HIGH) #define splsoft() _splraise(IPL_SOFT) diff --git a/sys/arch/evbarm/iq80310/iq80310_intr.c b/sys/arch/evbarm/iq80310/iq80310_intr.c index 715c3892d16a..bb88f6b6a654 100644 --- a/sys/arch/evbarm/iq80310/iq80310_intr.c +++ b/sys/arch/evbarm/iq80310/iq80310_intr.c @@ -1,4 +1,4 @@ -/* $NetBSD: iq80310_intr.c,v 1.16 2002/08/14 19:48:04 thorpej Exp $ */ +/* $NetBSD: iq80310_intr.c,v 1.17 2002/08/17 16:42:23 briggs Exp $ */ /* * Copyright (c) 2001, 2002 Wasabi Systems, Inc. @@ -57,37 +57,17 @@ #include #include -#if defined(IOP310_TEAMASA_NPWR) -/* - * We have 5 interrupt source bits -- all in XINT3. All interrupts - * can be masked in the CPLD. - */ -#define IRQ_BITS 0x1f -#define IRQ_BITS_ALWAYS_ON 0x00 -#else /* Default to stock IQ80310 */ -/* - * We have 8 interrupt source bits -- 5 in the XINT3 register, and 3 - * in the XINT0 register (the upper 3). Note that the XINT0 IRQs - * (SPCI INTA, INTB, and INTC) are always enabled, since they can not - * be masked out in the CPLD (it provides only status, not masking, - * for those interrupts). - */ -#define IRQ_BITS 0xff -#define IRQ_BITS_ALWAYS_ON 0xe0 -#define IRQ_READ_XINT0 1 /* XXX only if board rev >= F */ -#endif /* list of IQ80310-based designs */ - /* Interrupt handler queues. */ struct intrq intrq[NIRQ]; /* Interrupts to mask at each level. */ -static int imask[NIPL]; +int iq80310_imask[NIPL]; /* Current interrupt priority level. */ __volatile int current_spl_level; /* Interrupts pending. */ -static __volatile int ipending; +__volatile int iq80310_ipending; /* Software copy of the IRQs we have enabled. */ uint32_t intr_enabled; @@ -182,76 +162,76 @@ iq80310_intr_calculate_masks(void) if (intrq[irq].iq_levels & (1U << ipl)) irqs |= (1U << irq); } - imask[ipl] = irqs; + iq80310_imask[ipl] = irqs; } - imask[IPL_NONE] = 0; + iq80310_imask[IPL_NONE] = 0; /* * Initialize the soft interrupt masks to block themselves. */ - imask[IPL_SOFT] = SI_TO_IRQBIT(SI_SOFT); - imask[IPL_SOFTCLOCK] = SI_TO_IRQBIT(SI_SOFTCLOCK); - imask[IPL_SOFTNET] = SI_TO_IRQBIT(SI_SOFTNET); - imask[IPL_SOFTSERIAL] = SI_TO_IRQBIT(SI_SOFTSERIAL); + iq80310_imask[IPL_SOFT] = SI_TO_IRQBIT(SI_SOFT); + iq80310_imask[IPL_SOFTCLOCK] = SI_TO_IRQBIT(SI_SOFTCLOCK); + iq80310_imask[IPL_SOFTNET] = SI_TO_IRQBIT(SI_SOFTNET); + iq80310_imask[IPL_SOFTSERIAL] = SI_TO_IRQBIT(SI_SOFTSERIAL); /* * splsoftclock() is the only interface that users of the * generic software interrupt facility have to block their * soft intrs, so splsoftclock() must also block IPL_SOFT. */ - imask[IPL_SOFTCLOCK] |= imask[IPL_SOFT]; + iq80310_imask[IPL_SOFTCLOCK] |= iq80310_imask[IPL_SOFT]; /* * splsoftnet() must also block splsoftclock(), since we don't * want timer-driven network events to occur while we're * processing incoming packets. */ - imask[IPL_SOFTNET] |= imask[IPL_SOFTCLOCK]; + iq80310_imask[IPL_SOFTNET] |= iq80310_imask[IPL_SOFTCLOCK]; /* * Enforce a heirarchy that gives "slow" device (or devices with * limited input buffer space/"real-time" requirements) a better * chance at not dropping data. */ - imask[IPL_BIO] |= imask[IPL_SOFTNET]; - imask[IPL_NET] |= imask[IPL_BIO]; - imask[IPL_SOFTSERIAL] |= imask[IPL_NET]; - imask[IPL_TTY] |= imask[IPL_SOFTSERIAL]; + iq80310_imask[IPL_BIO] |= iq80310_imask[IPL_SOFTNET]; + iq80310_imask[IPL_NET] |= iq80310_imask[IPL_BIO]; + iq80310_imask[IPL_SOFTSERIAL] |= iq80310_imask[IPL_NET]; + iq80310_imask[IPL_TTY] |= iq80310_imask[IPL_SOFTSERIAL]; /* * splvm() blocks all interrupts that use the kernel memory * allocation facilities. */ - imask[IPL_IMP] |= imask[IPL_TTY]; + iq80310_imask[IPL_IMP] |= iq80310_imask[IPL_TTY]; /* * Audio devices are not allowed to perform memory allocation * in their interrupt routines, and they have fairly "real-time" * requirements, so give them a high interrupt priority. */ - imask[IPL_AUDIO] |= imask[IPL_IMP]; + iq80310_imask[IPL_AUDIO] |= iq80310_imask[IPL_IMP]; /* * splclock() must block anything that uses the scheduler. */ - imask[IPL_CLOCK] |= imask[IPL_AUDIO]; + iq80310_imask[IPL_CLOCK] |= iq80310_imask[IPL_AUDIO]; /* * No separate statclock on the IQ80310. */ - imask[IPL_STATCLOCK] |= imask[IPL_CLOCK]; + iq80310_imask[IPL_STATCLOCK] |= iq80310_imask[IPL_CLOCK]; /* * splhigh() must block "everything". */ - imask[IPL_HIGH] |= imask[IPL_STATCLOCK]; + iq80310_imask[IPL_HIGH] |= iq80310_imask[IPL_STATCLOCK]; /* * XXX We need serial drivers to run at the absolute highest priority * in order to avoid overruns, so serial > high. */ - imask[IPL_SERIAL] |= imask[IPL_HIGH]; + iq80310_imask[IPL_SERIAL] |= iq80310_imask[IPL_HIGH]; /* * Now compute which IRQs must be blocked when servicing any @@ -264,12 +244,12 @@ iq80310_intr_calculate_masks(void) iq80310_enable_irq(irq); for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL; ih = TAILQ_NEXT(ih, ih_list)) - irqs |= imask[ih->ih_ipl]; + irqs |= iq80310_imask[ih->ih_ipl]; iq->iq_mask = irqs; } } -static void +void iq80310_do_soft(void) { static __cpu_simple_lock_t processing = __SIMPLELOCK_UNLOCKED; @@ -283,9 +263,9 @@ iq80310_do_soft(void) oldirqstate = disable_interrupts(I32_bit); #define DO_SOFTINT(si) \ - if ((ipending & ~new) & SI_TO_IRQBIT(si)) { \ - ipending &= ~SI_TO_IRQBIT(si); \ - current_spl_level |= imask[si_to_ipl[(si)]]; \ + if ((iq80310_ipending & ~new) & SI_TO_IRQBIT(si)) { \ + iq80310_ipending &= ~SI_TO_IRQBIT(si); \ + current_spl_level |= iq80310_imask[si_to_ipl[(si)]]; \ restore_interrupts(oldirqstate); \ softintr_dispatch(si); \ oldirqstate = disable_interrupts(I32_bit); \ @@ -302,13 +282,14 @@ iq80310_do_soft(void) restore_interrupts(oldirqstate); } +#if defined(EVBARM_SPL_NOINLINE) int _splraise(int ipl) { int old; old = current_spl_level; - current_spl_level |= imask[ipl]; + current_spl_level |= iq80310_imask[ipl]; return (old); } @@ -322,7 +303,7 @@ splx(int new) current_spl_level = new; /* If there are software interrupts to process, do it. */ - if ((ipending & ~IRQ_BITS) & ~new) + if ((iq80310_ipending & ~IRQ_BITS) & ~new) iq80310_do_soft(); /* @@ -335,7 +316,7 @@ splx(int new) * XXX be unblocked, because we currently lose if we * XXX get nested interrupts, and I don't know why yet. */ - if ((new & IRQ_BITS) == 0 && (ipending & IRQ_BITS)) + if ((new & IRQ_BITS) == 0 && (iq80310_ipending & IRQ_BITS)) i80200_intr_enable(INTCTL_IM | INTCTL_PM); } @@ -344,21 +325,45 @@ _spllower(int ipl) { int old = current_spl_level; - splx(imask[ipl]); + iq80310_splx(iq80310_imask[ipl]); return (old); } +#else + +#undef _splraise +int +_splraise(int ipl) +{ + return iq80310_splraise(ipl); +} + +#undef splx +__inline void +splx(int new) +{ + return iq80310_splx(new); +} + +#undef _spllower +int +_spllower(int ipl) +{ + return iq80310_spllower(ipl); +} +#endif + void _setsoftintr(int si) { int oldirqstate; oldirqstate = disable_interrupts(I32_bit); - ipending |= SI_TO_IRQBIT(si); + iq80310_ipending |= SI_TO_IRQBIT(si); restore_interrupts(oldirqstate); /* Process unmasked pending soft interrupts. */ - if ((ipending & ~IRQ_BITS) & ~current_spl_level) + if ((iq80310_ipending & ~IRQ_BITS) & ~current_spl_level) iq80310_do_soft(); } @@ -473,11 +478,11 @@ iq80310_intr_dispatch(struct clockframe *frame) * the next one. Note: external IRQs are already * disabled. */ - ipending |= ibit; + iq80310_ipending |= ibit; continue; } - ipending &= ~ibit; + iq80310_ipending &= ~ibit; rv = 0; iq = &intrq[irq]; @@ -505,7 +510,7 @@ iq80310_intr_dispatch(struct clockframe *frame) #endif /* Check for pendings soft intrs. */ - if ((ipending & ~IRQ_BITS) & ~current_spl_level) { + if ((iq80310_ipending & ~IRQ_BITS) & ~current_spl_level) { oldirqstate = enable_interrupts(I32_bit); iq80310_do_soft(); restore_interrupts(oldirqstate); @@ -515,6 +520,6 @@ iq80310_intr_dispatch(struct clockframe *frame) * If no hardware interrupts are masked, re-enable external * interrupts. */ - if ((ipending & IRQ_BITS) == 0) + if ((iq80310_ipending & IRQ_BITS) == 0) i80200_intr_enable(INTCTL_IM | INTCTL_PM); } diff --git a/sys/arch/evbarm/iq80310/iq80310_intr.h b/sys/arch/evbarm/iq80310/iq80310_intr.h new file mode 100644 index 000000000000..d7b308f9b8d7 --- /dev/null +++ b/sys/arch/evbarm/iq80310/iq80310_intr.h @@ -0,0 +1,137 @@ +/* $NetBSD: iq80310_intr.h,v 1.1 2002/08/17 16:42:23 briggs Exp $ */ + +/* + * Copyright (c) 2001, 2002 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * 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 for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC + * 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. + */ + +#ifndef _IQ80310_INTR_H_ +#define _IQ80310_INTR_H_ + +#include "opt_iop310.h" + +#include +#include + +#include +#include + +#if defined(IOP310_TEAMASA_NPWR) +/* + * We have 5 interrupt source bits -- all in XINT3. All interrupts + * can be masked in the CPLD. + */ +#define IRQ_BITS 0x1f +#define IRQ_BITS_ALWAYS_ON 0x00 +#else /* Default to stock IQ80310 */ +/* + * We have 8 interrupt source bits -- 5 in the XINT3 register, and 3 + * in the XINT0 register (the upper 3). Note that the XINT0 IRQs + * (SPCI INTA, INTB, and INTC) are always enabled, since they can not + * be masked out in the CPLD (it provides only status, not masking, + * for those interrupts). + */ +#define IRQ_BITS 0xff +#define IRQ_BITS_ALWAYS_ON 0xe0 +#define IRQ_READ_XINT0 1 /* XXX only if board rev >= F */ +#endif /* list of IQ80310-based designs */ + +void iq80310_do_soft(void); + +#if !defined(EVBARM_SPL_NOINLINE) +static __inline int +iq80310_splraise(int ipl) +{ + extern __volatile int current_spl_level; + extern int iq80310_imask[]; + int old; + + old = current_spl_level; + current_spl_level |= iq80310_imask[ipl]; + + return (old); +} + +static __inline void +iq80310_splx(int new) +{ + extern __volatile int iq80310_ipending; + extern __volatile int current_spl_level; + int old; + + old = current_spl_level; + current_spl_level = new; + + /* If there are software interrupts to process, do it. */ + if ((iq80310_ipending & ~IRQ_BITS) & ~new) + iq80310_do_soft(); + + /* + * If there are pending hardware interrupts (i.e. the + * external interrupt is disabled in the ICU), and all + * hardware interrupts are being unblocked, then re-enable + * the external hardware interrupt. + * + * XXX We have to wait for ALL hardware interrupts to + * XXX be unblocked, because we currently lose if we + * XXX get nested interrupts, and I don't know why yet. + */ + if ((new & IRQ_BITS) == 0 && (iq80310_ipending & IRQ_BITS)) + i80200_intr_enable(INTCTL_IM | INTCTL_PM); +} + +static __inline int +iq80310_spllower(int ipl) +{ + extern __volatile int current_spl_level; + extern int iq80310_imask[]; + int old = current_spl_level; + + iq80310_splx(iq80310_imask[ipl]); + return (old); +} + +#define _splraise(ipl) iq80310_splraise(ipl) +#define _spllower(ipl) iq80310_spllower(ipl) +#define splx(spl) iq80310_splx(spl) +void _setsoftintr(int); +#else + +int _splraise(int); +int _spllower(int); +void splx(int); +void _setsoftintr(int); + +#endif + +#endif /* _IQ80310_INTR_H_ */ diff --git a/sys/arch/evbarm/ixm1200/ixm1200_intr.h b/sys/arch/evbarm/ixm1200/ixm1200_intr.h new file mode 100644 index 000000000000..845a52bb8a12 --- /dev/null +++ b/sys/arch/evbarm/ixm1200/ixm1200_intr.h @@ -0,0 +1,46 @@ +/* $NetBSD: ixm1200_intr.h,v 1.1 2002/08/17 16:42:23 briggs Exp $ */ + +/* + * Copyright (c) 2002 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Allen Briggs for Wasabi Systems, Inc. + * + * 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 for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC + * 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. + */ + +#ifndef _IXM1200_INTR_H_ +#define _IXM1200_INTR_H_ + +int _splraise(int); +int _spllower(int); +void splx(int); +void _setsoftintr(int); + +#endif /* _IXM1200_INTR_H_ */