diff options
-rw-r--r-- | sys/arch/mvme88k/dev/bussw.c | 196 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/busswreg.h | 205 |
2 files changed, 401 insertions, 0 deletions
diff --git a/sys/arch/mvme88k/dev/bussw.c b/sys/arch/mvme88k/dev/bussw.c new file mode 100644 index 00000000000..369382d811f --- /dev/null +++ b/sys/arch/mvme88k/dev/bussw.c @@ -0,0 +1,196 @@ +/* $OpenBSD: bussw.c,v 1.1 2001/12/13 08:59:38 smurph Exp $ */ + +/* + * Copyright (c) 1999 Steve Murphree, Jr. + * + * 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 under OpenBSD by + * Theo de Raadt for Willowglen Singapore. + * 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. + */ + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/ioctl.h> +#include <sys/device.h> +#include <sys/systm.h> +#include <sys/uio.h> +#include <sys/malloc.h> +#include <machine/psl.h> +#include <machine/autoconf.h> +#include <machine/bugio.h> +#include <machine/cpu.h> +#include <machine/mioctl.h> +#include <machine/vmparam.h> + +#include <mvme88k/dev/busswreg.h> +#include <mvme88k/dev/busswfunc.h> + +struct bussw_softc { + struct device sc_dev; + void *sc_paddr; + void *sc_vaddr; + int sc_len; + struct intrhand sc_abih; /* `abort' switch */ + struct bussw_reg *sc_bussw; +}; + +void bussw_attach __P((struct device *, struct device *, void *)); +int bussw_match __P((struct device *, void *, void *)); + +struct cfattach bussw_ca = { + sizeof(struct bussw_softc), bussw_match, bussw_attach +}; + +struct cfdriver bussw_cd = { + NULL, "bussw", DV_DULL, 0 +}; + +int bussw_print __P((void *args, const char *bus)); +int bussw_scan __P((struct device *parent, void *child, void *args)); +int busswabort __P((void *)); + +int +bussw_match(parent, vcf, args) +struct device *parent; +void *vcf, *args; +{ + struct confargs *ca = args; + struct bussw_reg *bussw; + /* Don't match if wrong cpu */ + if (brdtyp != BRD_197) + return (0); /* The only one... */ + + bussw = (struct bussw_reg *)(IIOV(ca->ca_paddr)); + if (badvaddr((vm_offset_t)bussw, 4)) { + printf("==> busswitch: failed address check.\n"); + return (0); + } + return (1); +} + +void +bussw_attach(parent, self, args) +struct device *parent, *self; +void *args; +{ + struct confargs *ca = args; + struct bussw_softc *sc = (struct bussw_softc *)self; + struct bussw_reg *bs; + + sc->sc_vaddr = sc->sc_paddr = ca->ca_paddr; + bs = sc->sc_bussw = (struct bussw_reg *)sc->sc_vaddr; + bs->bs_intr2 |= BS_VECBASE; + bs->bs_gcsr |= BS_GCSR_XIPL; + /* + * pseudo driver, abort interrupt handler + */ + sc->sc_abih.ih_fn = busswabort; + sc->sc_abih.ih_arg = 0; + sc->sc_abih.ih_wantframe = 1; + sc->sc_abih.ih_ipl = IPL_NMI; /* level 8!! */ + busswintr_establish(BS_ABORTIRQ, &sc->sc_abih); + bs->bs_intr1 |= BS_INTR1_ABORT_IEN; + + printf(": rev %d\n", BS_CHIPREV(bs)); + config_search(bussw_scan, self, args); +} + +int +bussw_print(args, bus) +void *args; +const char *bus; +{ + struct confargs *ca = args; + + if (ca->ca_offset != -1) + printf(" offset 0x%x", ca->ca_offset); + if (ca->ca_ipl > 0) + printf(" ipl %d", ca->ca_ipl); + return (UNCONF); +} + +int +bussw_scan(parent, child, args) +struct device *parent; +void *child, *args; +{ + struct cfdata *cf = child; + struct bussw_softc *sc = (struct bussw_softc *)parent; + struct confargs oca; + + if (parent->dv_cfdata->cf_driver->cd_indirect) { + printf(" indirect devices not supported\n"); + return 0; + } + + bzero(&oca, sizeof oca); + oca.ca_offset = cf->cf_loc[0]; + oca.ca_ipl = cf->cf_loc[1]; + if (((int)oca.ca_offset != -1) && ISIIOVA(sc->sc_vaddr + oca.ca_offset)) { + oca.ca_vaddr = sc->sc_vaddr + oca.ca_offset; + oca.ca_paddr = sc->sc_paddr + oca.ca_offset; + } else { + oca.ca_vaddr = (void *)-1; + oca.ca_paddr = (void *)-1; + } + oca.ca_bustype = BUS_BUSSWITCH; + oca.ca_master = (void *)sc->sc_bussw; + oca.ca_name = cf->cf_driver->cd_name; + if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0) + return (0); + config_attach(parent, cf, &oca, bussw_print); + return (1); +} + +int +busswintr_establish(vec, ih) + int vec; + struct intrhand *ih; +{ + if (vec >= BS_NVEC) { + printf("bussw: illegal vector: 0x%x\n", vec); + panic("busswintr_establish"); + } + return (intr_establish(BS_VECBASE+vec, ih)); +} + +int +busswabort(eframe) + void *eframe; +{ + struct frame *frame = eframe; + + struct bussw_softc *sc = (struct bussw_softc *)bussw_cd.cd_devs[0]; + struct bussw_reg *bs = sc->sc_bussw; + + if (bs->bs_intr1 & BS_INTR1_ABORT_INT) { + bs->bs_intr1 |= BS_INTR1_ABORT_ICLR; + nmihand(frame); + return 1; + } + return 0; +} + diff --git a/sys/arch/mvme88k/dev/busswreg.h b/sys/arch/mvme88k/dev/busswreg.h new file mode 100644 index 00000000000..b23960686cb --- /dev/null +++ b/sys/arch/mvme88k/dev/busswreg.h @@ -0,0 +1,205 @@ +/* $OpenBSD: busswreg.h,v 1.1 2001/12/13 08:59:38 smurph Exp $ */ + +/* + * Memory map for BusSwitch chip found in mvme197 boards. + */ +#ifndef BUSSWREG_H +#define BUSSWREG_H +#define BS_BASE 0xFFF00000 + +struct bussw_reg { + volatile u_long bs_gcsr; + volatile u_short bs_iodata; + volatile u_short bs_iodir; + volatile u_short bs_psar1; + volatile u_short bs_pear1; + volatile u_short bs_psar2; + volatile u_short bs_pear2; + volatile u_short bs_psar3; + volatile u_short bs_pear3; + volatile u_short bs_psar4; + volatile u_short bs_pear4; + volatile u_short bs_ptr1; + volatile u_short bs_ptsr1; + volatile u_short bs_ptr2; + volatile u_short bs_ptsr2; + volatile u_short bs_ptr3; + volatile u_short bs_ptsr3; + volatile u_short bs_ptr4; + volatile u_short bs_ptsr4; + volatile u_short bs_ssar1; + volatile u_short bs_sear1; + volatile u_short bs_ssar2; + volatile u_short bs_sear2; + volatile u_short bs_ssar3; + volatile u_short bs_sear3; + volatile u_short bs_ssar4; + volatile u_short bs_sear4; + volatile u_short bs_str1; + volatile u_short bs_stsr1; + volatile u_short bs_str2; + volatile u_short bs_stsr2; + volatile u_short bs_str3; + volatile u_short bs_stsr3; + volatile u_short bs_str4; + volatile u_short bs_stsr4; + volatile u_long bs_par; + volatile u_long bs_sar; + volatile u_long bs_btimer; + volatile u_long bs_pal; + volatile u_long bs_wppa; + volatile u_long bs_wp; + volatile u_long bs_romcr; + volatile u_long bs_lmi; + volatile u_long bs_intr1; + volatile u_long bs_intr2; + volatile u_long bs_tcomp1; + volatile u_long bs_tcount1; + volatile u_long bs_tcomp2; + volatile u_long bs_tcount2; + volatile u_long bs_gpr1; + volatile u_long bs_gpr2; + volatile u_long bs_gpr3; + volatile u_long bs_gpr4; + volatile u_long bs_xctags; + volatile u_long bs_res3; + volatile u_long bs_xccr; + volatile u_long bs_vec1; + volatile u_long bs_vec2; + volatile u_long bs_vec3; + volatile u_long bs_vec4; + volatile u_long bs_vec5; + volatile u_long bs_vec6; + volatile u_long bs_vec7; +}; + +/* GCSR bit definitions */ +#define BS_CHIPID(x) (((x)->bs_gcsr & 0xFF000000) >> 16) +#define BS_CHIPREV(x) (((x)->bs_gcsr & 0x00FF0000) >> 16) +#define BS_GCSR_APRI0 0x00000001 /* Bus Request 0 Priority indicator (CPU0)*/ +#define BS_GCSR_APRI1 0x00000002 /* Bus Request 1 Priority indicator (CPU1)*/ +#define BS_GCSR_APRI2 0x00000003 /* Bus Request 2 Priority indicator (mc88410)*/ +#define BS_GCSR_AMOD 0x00000004 /* Arbitration Mode */ +#define BS_GCSR_BREN 0x00000008 /* Bus Request Enable */ +#define BS_GCSR_CPUID 0x00000010 /* CPU ID */ +#define BS_GCSR_B410 0x00000020 /* BUS410 indicator */ +#define BS_GCSR_INVD 0x00000040 /* Invalidate Decoder */ +#define BS_GCSR_USR 0x00000080 /* User Access Enable */ +#define BS_GCSR_XIPL 0x00000100 /* External IPL Enable */ +#define BS_GCSR_TCPU1 0x00000200 /* Test CPU 1 Registers */ +#define BS_GCSR_XCC 0x00000400 /* External Cache Controller */ +#define BS_GCSR_INCB 0x00000800 /* Increment On Burst */ +#define BS_GCSR_TDPR 0x00002000 /* Test Dual Processor Registers */ +#define BS_GCSR_TBB 0x00004000 /* Test Bus Busy */ +#define BS_GCSR_POR 0x00008000 /* Power On Reset */ + +/* System Attribute Registers bit definitions */ +#define BS_SAR_DEN 0x01 /* Decode Enable */ +#define BS_SAR_INVR 0x04 /* Invalidate On Reads */ +#define BS_SAR_GBL 0x08 /* Global Access */ + +/* Bus Timer Register bit definitions */ +#define BS_BTIMER_PBT8 0x00 /* Processor Bus Timout, 8 usec */ +#define BS_BTIMER_PBT64 0x01 /* Processor Bus Timout, 64 usec */ +#define BS_BTIMER_PBT256 0x02 /* Processor Bus Timout, 256 usec */ +#define BS_BTIMER_PBTD 0x03 /* Processor Bus Timout, disable */ +#define BS_BTIMER_SBT8 (0x00 << 2) /* System Bus Timout, 8 usec */ +#define BS_BTIMER_SBT64 (0x01 << 2) /* System Bus Timout, 64 usec */ +#define BS_BTIMER_SBT256 (0x02 << 2) /* System Bus Timout, 256 usec */ +#define BS_BTIMER_SBTD (0x03 << 2) /* System Bus Timout, disable */ + +/* Prescaler Adjust values */ +#define BS_PADJUST_50 0xCE /* 50 MHz clock */ +#define BS_PADJUST_40 0xD8 /* 40 MHz clock */ +#define BS_PADJUST_33 0xDF /* 33 MHz clock */ +#define BS_PADJUST_25 0xE7 /* 25 MHz clock */ + +/* ROM Control Register bit definitions */ +#define BS_ROMCR_WEN0 0x01000000 +#define BS_ROMCR_WEN1 0x02000000 +#define BS_ROMCR_SGLB 0x04000000 +#define BS_ROMCR_ROM0 0x80000000 + +/* External Cache Control Register bit definitions */ +#define BS_XCC_F0 0x00000001 +#define BS_XCC_F1 0x00000002 +#define BS_XCC_FBSY 0x00000004 +#define BS_XCC_DIAG 0x00000008 + +/* + * INTR1 - Abort Control Register + * Cross Processor Interrupt Register + * Timer Interrupt 1 Register + * Timer Interrupt 2 Register + */ +#define BS_INTR1_ABORT_ICLR 0x08000000 /* abort interrupt clear */ +#define BS_INTR1_ABORT_IEN 0x10000000 /* abort interrupt enable */ +#define BS_INTR1_ABORT_INT 0x20000000 /* abort interrupt received */ +#define BS_INTR1_ABORT_ABT 0x40000000 /* abort interrupt asserted */ + +#define BS_INTR1_CPI_ICLR 0x00080000 /* cpi interrupt clear */ +#define BS_INTR1_CPI_IEN 0x00100000 /* cpi interrupt enable */ +#define BS_INTR1_CPI_INT 0x00200000 /* cpi interrupt received */ +#define BS_INTR1_CPI_STAT 0x00400000 /* cpi interrupt status */ +#define BS_INTR1_CPI_SCPI 0x00800000 /* send cross proc interrupt */ + +#define BS_INTR1_TINT1_ICLR 0x00000800 /* timer 1 interrupt clear */ +#define BS_INTR1_TINT1_IEN 0x00001000 /* timer 1 interrupt enable */ +#define BS_INTR1_TINT1_INT 0x00002000 /* timer 1 interrupt received */ +#define BS_INTR1_TINT1_LM 0x00000700 /* timer 1 level mask */ +#define BS_INTR1_TINT1_LEVEL(x) ((x << 8) & BS_INTR1_TINT1_LM) + +#define BS_INTR1_TINT2_ICLR 0x00000008 /* timer 1 interrupt clear */ +#define BS_INTR1_TINT2_IEN 0x00000010 /* timer 1 interrupt enable */ +#define BS_INTR1_TINT2_INT 0x00000020 /* timer 1 interrupt received */ +#define BS_INTR1_TINT2_LM 0x00000007 /* timer 1 level mask */ +#define BS_INTR1_TINT2_LEVEL(x) (x & BS_INTR1_TINT2_LM) + +/* Vector Base Register (A read upon an interrupt reveals the source) */ +#define BS_VBASE_SRC_TMR1 0x0 +#define BS_VBASE_SRC_TMR2 0x1 +#define BS_VBASE_SRC_WPE 0x2 +#define BS_VBASE_SRC_PAL 0x3 +#define BS_VBASE_SRC_EXT 0x4 /* external interrupt */ +#define BS_VBASE_SRC_SPUR 0x7 /* spurious interrupt */ + +/* + * INTR2 - Write Post Control Register + * Processor Address Log Interrupt Register + * External Interrupt Register + * Vector Base + */ +#define BS_INTR2_WPINT_ICLR 0x08000000 /* WPINT interrupt clear */ +#define BS_INTR2_WPINT_IEN 0x10000000 /* WPINT interrupt enable */ +#define BS_INTR2_WPINT_INT 0x20000000 /* WPINT interrupt received */ +#define BS_INTR2_WPINT_LM 0x07000000 /* WPINT level mask */ +#define BS_INTR2_WPINT_LEVEL(x) ((x << 24) & BS_INTR2_WPINT_LM) + +#define BS_INTR2_PALINT_ICLR 0x00080000 /* PALINT interrupt clear */ +#define BS_INTR2_PALINT_IEN 0x00100000 /* PALINT interrupt enable */ +#define BS_INTR2_PALINT_INT 0x00200000 /* PALINT interrupt received */ +#define BS_INTR2_PALINT_PLTY 0x00800000 /* PALINT polarity */ +#define BS_INTR2_PALINT_LM 0x00070000 /* PALINT level mask */ +#define BS_INTR2_PALINT_LEVEL(x) ((x << 16) & BS_INTR2_PALINT_LM) + +#define BS_INTR2_XINT_ICLR 0x00000800 /* XINT interrupt clear */ +#define BS_INTR2_XINT_IEN 0x00001000 /* XINT interrupt enable */ +#define BS_INTR2_XINT_INT 0x00002000 /* XINT interrupt received */ +#define BS_INTR2_XINT_EL 0x00004000 /* XINT edge/level */ +#define BS_INTR2_XINT_PLTY 0x00008000 /* XINT polarity */ +#define BS_INTR2_XINT_LM 0x00000700 /* XINT level mask */ +#define BS_INTR2_XINT_LEVEL(x) ((x << 24) & BS_INTR2_XINT_LM) + +/* We lock off BusSwitch vectors at 0x40 */ +#define BS_VECBASE 0x40 +#define BS_NVEC 16 + +/* Bottom 4 bits of the vector returned during IACK cycle */ +#define BS_TMR1IRQ 0x01 /* lowest */ +#define BS_TMR2IRQ 0x02 +#define BS_ABORTIRQ 0x03 + +/* Define the Abort vector */ +#define BS_ABORTVEC (BS_VECBASE | BS_ABORTIRQ) + +#endif /* BUSSWREG_H */ |