summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/mvme88k/dev/bussw.c196
-rw-r--r--sys/arch/mvme88k/dev/busswreg.h205
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 */