summaryrefslogtreecommitdiffstats
path: root/sys/alpha/tlsb
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1998-06-10 10:57:29 +0000
committerdfr <dfr@FreeBSD.org>1998-06-10 10:57:29 +0000
commit224577d6cf4d0daf37dddd81b9f9c646ad2be083 (patch)
tree345e0ea224736af311f2e28c0acb268d809bff9c /sys/alpha/tlsb
parent2e6fba7d51b32033eec1fc27efaa0f8e840825fe (diff)
downloadFreeBSD-src-224577d6cf4d0daf37dddd81b9f9c646ad2be083.zip
FreeBSD-src-224577d6cf4d0daf37dddd81b9f9c646ad2be083.tar.gz
Add initial support for the FreeBSD/alpha kernel. This is very much a
work in progress and has never booted a real machine. Initial development and testing was done using SimOS (see http://simos.stanford.edu for details). On the SimOS simulator, this port successfully reaches single-user mode and has been tested with loads as high as one copy of /bin/ls :-). Obtained from: partly from NetBSD/alpha
Diffstat (limited to 'sys/alpha/tlsb')
-rw-r--r--sys/alpha/tlsb/dwlpx.c291
-rw-r--r--sys/alpha/tlsb/dwlpxreg.h237
-rw-r--r--sys/alpha/tlsb/gbus.c155
-rw-r--r--sys/alpha/tlsb/gbusreg.h46
-rw-r--r--sys/alpha/tlsb/gbusvar.h64
-rw-r--r--sys/alpha/tlsb/kftxx.c192
-rw-r--r--sys/alpha/tlsb/kftxxreg.h74
-rw-r--r--sys/alpha/tlsb/kftxxvar.h59
-rw-r--r--sys/alpha/tlsb/mcclock_tlsb.c126
-rw-r--r--sys/alpha/tlsb/tlsb.c329
-rw-r--r--sys/alpha/tlsb/tlsbmem.c91
-rw-r--r--sys/alpha/tlsb/tlsbreg.h318
-rw-r--r--sys/alpha/tlsb/tlsbvar.h75
-rw-r--r--sys/alpha/tlsb/zs_tlsb.c473
-rw-r--r--sys/alpha/tlsb/zsreg.h30
15 files changed, 2560 insertions, 0 deletions
diff --git a/sys/alpha/tlsb/dwlpx.c b/sys/alpha/tlsb/dwlpx.c
new file mode 100644
index 0000000..e9f2aa5
--- /dev/null
+++ b/sys/alpha/tlsb/dwlpx.c
@@ -0,0 +1,291 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * 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 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+#include "opt_simos.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <alpha/tlsb/dwlpxreg.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+
+#include <alpha/tlsb/kftxxvar.h>
+
+#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
+#define DWLPX_BASE(n, h) ((((u_long)(n) - 4) << 36) \
+ | ((u_long)(h) << 34) \
+ | (1L << 39))
+
+static devclass_t dwlpx_devclass;
+static device_t dwlpx0; /* XXX only one for now */
+
+struct dwlpx_softc {
+ vm_offset_t dmem_base; /* dense memory */
+ vm_offset_t smem_base; /* sparse memory */
+ vm_offset_t io_base; /* sparse i/o */
+ vm_offset_t cfg_base; /* sparse pci config */
+};
+
+#define DWLPX_SOFTC(dev) (struct dwlpx_softc*) device_get_softc(dev)
+
+#define SPARSE_READ(o) (*(u_int32_t*) (o))
+#define SPARSE_WRITE(o, d) (*(u_int32_t*) (o) = (d))
+
+#define SPARSE_BYTE_OFFSET(o) (((o) << 5) | ((o) & 3))
+#define SPARSE_WORD_OFFSET(o) (((o) << 5) | ((o) & 2) | 0x8)
+#define SPARSE_LONG_OFFSET(o) (((o) << 5) | 0x18)
+
+#define SPARSE_BYTE_EXTRACT(o, d) ((d) >> (8*((o) & 3)))
+#define SPARSE_WORD_EXTRACT(o, d) ((d) >> (8*((o) & 2)))
+
+#define SPARSE_BYTE_INSERT(o, d) ((d) << (8*((o) & 3)))
+#define SPARSE_WORD_INSERT(o, d) ((d) << (8*((o) & 2)))
+
+#define SPARSE_READ_BYTE(base, o) \
+ SPARSE_BYTE_EXTRACT(o, SPARSE_READ(base + SPARSE_BYTE_OFFSET(o)))
+
+#define SPARSE_READ_WORD(base, o) \
+ SPARSE_WORD_EXTRACT(o, SPARSE_READ(base + SPARSE_WORD_OFFSET(o)))
+
+#define SPARSE_READ_LONG(base, o) \
+ SPARSE_READ(base + SPARSE_LONG_OFFSET(o))
+
+#define SPARSE_WRITE_BYTE(base, o, d) \
+ SPARSE_WRITE(base + SPARSE_BYTE_OFFSET(o), SPARSE_BYTE_INSERT(o, d))
+
+#define SPARSE_WRITE_WORD(base, o, d) \
+ SPARSE_WRITE(base + SPARSE_WORD_OFFSET(o), SPARSE_WORD_INSERT(o, d))
+
+#define SPARSE_WRITE_LONG(base, o, d) \
+ SPARSE_WRITE(base + SPARSE_LONG_OFFSET(o), d)
+
+static alpha_chipset_inb_t dwlpx_inb;
+static alpha_chipset_inw_t dwlpx_inw;
+static alpha_chipset_inl_t dwlpx_inl;
+static alpha_chipset_outb_t dwlpx_outb;
+static alpha_chipset_outw_t dwlpx_outw;
+static alpha_chipset_outl_t dwlpx_outl;
+static alpha_chipset_maxdevs_t dwlpx_maxdevs;
+static alpha_chipset_cfgreadb_t dwlpx_cfgreadb;
+static alpha_chipset_cfgreadw_t dwlpx_cfgreadw;
+static alpha_chipset_cfgreadl_t dwlpx_cfgreadl;
+static alpha_chipset_cfgwriteb_t dwlpx_cfgwriteb;
+static alpha_chipset_cfgwritew_t dwlpx_cfgwritew;
+static alpha_chipset_cfgwritel_t dwlpx_cfgwritel;
+
+static alpha_chipset_t dwlpx_chipset = {
+ dwlpx_inb,
+ dwlpx_inw,
+ dwlpx_inl,
+ dwlpx_outb,
+ dwlpx_outw,
+ dwlpx_outl,
+ dwlpx_maxdevs,
+ dwlpx_cfgreadb,
+ dwlpx_cfgreadw,
+ dwlpx_cfgreadl,
+ dwlpx_cfgwriteb,
+ dwlpx_cfgwritew,
+ dwlpx_cfgwritel,
+};
+
+/*
+ * For supporting multiple busses, we will encode the dwlpx unit number into
+ * the port address as Linux does.
+ */
+
+static u_int8_t
+dwlpx_inb(u_int32_t port)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ return SPARSE_READ_BYTE(sc->io_base, port);
+}
+
+static u_int16_t
+dwlpx_inw(u_int32_t port)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ return SPARSE_READ_WORD(sc->io_base, port);
+}
+
+static u_int32_t
+dwlpx_inl(u_int32_t port)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ return SPARSE_READ_LONG(sc->io_base, port);
+}
+
+static void
+dwlpx_outb(u_int32_t port, u_int8_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ SPARSE_WRITE_BYTE(sc->io_base, port, data);
+}
+
+static void
+dwlpx_outw(u_int32_t port, u_int16_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ SPARSE_WRITE_WORD(sc->io_base, port, data);
+}
+
+static void
+dwlpx_outl(u_int32_t port, u_int32_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ SPARSE_WRITE_LONG(sc->io_base, port, data);
+}
+
+static int
+dwlpx_maxdevs(u_int b)
+{
+ return 12; /* XXX */
+}
+
+/* XXX only support bus 0 */
+
+#define DWLPX_CFGOFF(b, s, f, r) \
+ (((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
+
+static u_int8_t
+dwlpx_cfgreadb(u_int b, u_int s, u_int f, u_int r)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 1)) return ~0;
+ return SPARSE_READ_BYTE(sc->cfg_base, off);
+}
+
+static u_int16_t
+dwlpx_cfgreadw(u_int b, u_int s, u_int f, u_int r)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 2)) return ~0;
+ return SPARSE_READ_WORD(sc->cfg_base, off);
+}
+
+static u_int32_t
+dwlpx_cfgreadl(u_int b, u_int s, u_int f, u_int r)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 4)) return ~0;
+ return SPARSE_READ_LONG(sc->cfg_base, off);
+}
+
+static void
+dwlpx_cfgwriteb(u_int b, u_int s, u_int f, u_int r, u_int8_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 1)) return;
+ SPARSE_WRITE_BYTE(sc->cfg_base, off, data);
+}
+
+static void
+dwlpx_cfgwritew(u_int b, u_int s, u_int f, u_int r, u_int16_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 2)) return;
+ SPARSE_WRITE_WORD(sc->cfg_base, off, data);
+}
+
+static void
+dwlpx_cfgwritel(u_int b, u_int s, u_int f, u_int r, u_int32_t data)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dwlpx0);
+ vm_offset_t off = DWLPX_CFGOFF(b, s, f, r);
+ if (badaddr((caddr_t)(sc->cfg_base + off), 4)) return;
+ SPARSE_WRITE_LONG(sc->cfg_base, off, data);
+}
+
+static driver_probe_t dwlpx_probe;
+static driver_attach_t dwlpx_attach;
+static driver_intr_t dwlpx_intr;
+
+static driver_t dwlpx_driver = {
+ "dwlpx",
+ dwlpx_probe,
+ dwlpx_attach,
+ NULL,
+ NULL,
+ DRIVER_TYPE_MISC,
+ sizeof(struct dwlpx_softc),
+ NULL,
+};
+
+
+static int
+dwlpx_probe(bus_t bus, device_t dev)
+{
+ if (dwlpx0)
+ return ENXIO;
+ device_set_desc(dev, "DWLPA or DWLPB PCI adapter");
+ return 0;
+}
+
+static int
+dwlpx_attach(bus_t bus, device_t dev)
+{
+ struct dwlpx_softc* sc = DWLPX_SOFTC(dev);
+ vm_offset_t regs;
+ dwlpx0 = dev;
+
+ chipset = dwlpx_chipset;
+
+ regs = KV(DWLPX_BASE(kft_get_node(dev), kft_get_hosenum(dev)));
+ sc->dmem_base = regs + (0L << 32);
+ sc->smem_base = regs + (1L << 32);
+ sc->io_base = regs + (2L << 32);
+ sc->cfg_base = regs + (3L << 32);
+
+ *(u_int32_t*) (regs + PCIA_CTL(0)) = 1; /* Type1 config cycles */
+
+ bus_map_intr(bus, dev, dwlpx_intr, 0);
+
+ return 0;
+}
+
+static void
+dwlpx_intr(void* arg)
+{
+#ifdef SIMOS
+ extern void simos_intr(int);
+ simos_intr(0);
+#endif
+}
+
+DRIVER_MODULE(dwlpx, kft, dwlpx_driver, dwlpx_devclass, 0, 0);
+
diff --git a/sys/alpha/tlsb/dwlpxreg.h b/sys/alpha/tlsb/dwlpxreg.h
new file mode 100644
index 0000000..cafadc4
--- /dev/null
+++ b/sys/alpha/tlsb/dwlpxreg.h
@@ -0,0 +1,237 @@
+/* $NetBSD: dwlpxreg.h,v 1.9 1998/03/21 22:02:42 mjacob Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * Taken from combinations of:
+ *
+ * ``DWLPA and DWLPB PCI Adapter Technical Manual,
+ * Order Number: EK-DWLPX-TM.A01''
+ *
+ * and
+ *
+ * ``AlphaServer 8200/8400 System Technical Manual,
+ * Order Number EK-T8030-TM. A01''
+ */
+
+#define REGVAL(r) (*(volatile int32_t *)ALPHA_PHYS_TO_K0SEG(r))
+
+/*
+ * There are (potentially) 4 I/O hoses, and there are three
+ * (electrically distinct) PCI busses per DWLPX (which appear
+ * as one logical PCI bus).
+ *
+ * A CPU to PCI Address Mapping looks (roughly) like this:
+ *
+ * 39 38........36 35.34 33.....32 31....................5 4.........3 2...0
+ * --------------------------------------------------------------------------
+ * |1| I/O NodeID |Hose#|PCI Space|Byte Aligned I/O <26:0>|Byte Length|0 0 0|
+ * --------------------------------------------------------------------------
+ *
+ * I/O Node is the TLSB Node ID minus 4. Don't ask.
+ */
+
+#define NHPC 3
+
+/*
+ * Address Space Cookies
+ *
+ * (lacking I/O Node ID and Hose Numbers)
+ */
+
+#define DWLPX_PCI_DENSE 0x000000000LL
+#define DWLPX_PCI_SPARSE 0x100000000LL
+#define DWLPX_PCI_IOSPACE 0x200000000LL
+#define DWLPX_PCI_CONF 0x300000000LL
+
+/*
+ * PCIA Interface Adapter Register Addresses (Offsets from Node Address)
+ *
+ *
+ * Addresses are for Hose #0, PCI bus #0. Macros below will offset
+ * per bus. I/O Hose and TLSB Node I/D offsets must be added separately.
+ */
+
+#define _PCIA_CTL 0x380000000LL /* PCI 0 Bus Control */
+#define _PCIA_MRETRY 0x380000080LL /* PCI 0 Master Retry Limit */
+#define _PCIA_GPR 0x380000100LL /* PCI 0 General Purpose */
+#define _PCIA_ERR 0x380000180LL /* PCI 0 Error Summary */
+#define _PCIA_FADR 0x380000200LL /* PCI 0 Failing Address */
+#define _PCIA_IMASK 0x380000280LL /* PCI 0 Interrupt Mask */
+#define _PCIA_DIAG 0x380000300LL /* PCI 0 Diagnostic */
+#define _PCIA_IPEND 0x380000380LL /* PCI 0 Interrupt Pending */
+#define _PCIA_IPROG 0x380000400LL /* PCI 0 Interrupt in Progress */
+#define _PCIA_WMASK_A 0x380000480LL /* PCI 0 Window Mask A */
+#define _PCIA_WBASE_A 0x380000500LL /* PCI 0 Window Base A */
+#define _PCIA_TBASE_A 0x380000580LL /* PCI 0 Window Translated Base A */
+#define _PCIA_WMASK_B 0x380000600LL /* PCI 0 Window Mask B */
+#define _PCIA_WBASE_B 0x380000680LL /* PCI 0 Window Base B */
+#define _PCIA_TBASE_B 0x380000700LL /* PCI 0 Window Translated Base B */
+#define _PCIA_WMASK_C 0x380000780LL /* PCI 0 Window Mask C */
+#define _PCIA_WBASE_C 0x380000800LL /* PCI 0 Window Base C */
+#define _PCIA_TBASE_C 0x380000880LL /* PCI 0 Window Translated Base C */
+#define _PCIA_ERRVEC 0x380000900LL /* PCI 0 Error Interrupt Vector */
+#define _PCIA_DEVVEC 0x380001000LL /* PCI 0 Device Interrupt Vector */
+
+
+#define PCIA_CTL(hpc) (_PCIA_CTL + (0x200000 * (hpc)))
+#define PCIA_MRETRY(hpc) (_PCIA_MRETRY + (0x200000 * (hpc)))
+#define PCIA_GPR(hpc) (_PCIA_GPR + (0x200000 * (hpc)))
+#define PCIA_ERR(hpc) (_PCIA_ERR + (0x200000 * (hpc)))
+#define PCIA_FADR(hpc) (_PCIA_FADR + (0x200000 * (hpc)))
+#define PCIA_IMASK(hpc) (_PCIA_IMASK + (0x200000 * (hpc)))
+#define PCIA_DIAG(hpc) (_PCIA_DIAG + (0x200000 * (hpc)))
+#define PCIA_IPEND(hpc) (_PCIA_IPEND + (0x200000 * (hpc)))
+#define PCIA_IPROG(hpc) (_PCIA_IPROG + (0x200000 * (hpc)))
+#define PCIA_WMASK_A(hpc) (_PCIA_WMASK_A + (0x200000 * (hpc)))
+#define PCIA_WBASE_A(hpc) (_PCIA_WBASE_A + (0x200000 * (hpc)))
+#define PCIA_TBASE_A(hpc) (_PCIA_TBASE_A + (0x200000 * (hpc)))
+#define PCIA_WMASK_B(hpc) (_PCIA_WMASK_B + (0x200000 * (hpc)))
+#define PCIA_WBASE_B(hpc) (_PCIA_WBASE_B + (0x200000 * (hpc)))
+#define PCIA_TBASE_B(hpc) (_PCIA_TBASE_B + (0x200000 * (hpc)))
+#define PCIA_WMASK_C(hpc) (_PCIA_WMASK_C + (0x200000 * (hpc)))
+#define PCIA_WBASE_C(hpc) (_PCIA_WBASE_C + (0x200000 * (hpc)))
+#define PCIA_TBASE_C(hpc) (_PCIA_TBASE_C + (0x200000 * (hpc)))
+#define PCIA_ERRVEC(hpc) (_PCIA_ERRVEC + (0x200000 * (hpc)))
+
+#define PCIA_DEVVEC(hpc, subslot, ipin) \
+ (_PCIA_DEVVEC + (0x200000 * (hpc)) + ((subslot) * 0x200) + ((ipin-1) * 0x80))
+
+#define PCIA_SCYCLE 0x380002000LL /* PCI Special Cycle */
+#define PCIA_IACK 0x380002080LL /* PCI Interrupt Acknowledge */
+
+#define PCIA_PRESENT 0x380800000LL /* PCI Slot Present */
+#define PCIA_TBIT 0x380A00000LL /* PCI TBIT */
+#define PCIA_MCTL 0x380C00000LL /* PCI Module Control */
+#define PCIA_IBR 0x380E00000LL /* PCI Information Base Repair */
+
+/*
+ * Bits in PCIA_CTL register
+ */
+#define PCIA_CTL_SG32K (0<<25) /* 32K SGMAP entries */
+#define PCIA_CTL_SG64K (1<<25) /* 64K SGMAP entries */
+#define PCIA_CTL_SG128K (3<<25) /* 128K SGMAP entries */
+#define PCIA_CTL_SG0K (2<<25) /* disable SGMAP in HPC */
+#define PCIA_CTL_4UP (0<<23) /* 4 Up Hose buffers */
+#define PCIA_CTL_1UP (1<<23) /* 1 "" */
+#define PCIA_CTL_2UP (2<<23) /* 2 "" */
+#define PCIA_CTL_3UP (3<<23) /* 3 "" (normal) */
+#define PCIA_CTL_RMM4X (1<<22) /* Read Multiple 2X -> 4X */
+#define PCIA_CTL_RMMENA (1<<21) /* Read Multiple Enable */
+#define PCIA_CTL_RMMARB (1<<20) /* RMM Multiple Arb */
+#define PCIA_CTL_HAEDIS (1<<19) /* Hardware Address Ext. Disable */
+#define PCIA_CTL_MHAE(x) ((x&0x1f)<<14) /* Memory Hardware Address Extension */
+#define PCIA_CTL_IHAE(x) ((x&0x1f)<<9) /* I/O Hardware Address Extension */
+#define PCIA_CTL_CUTENA (1<<8) /* PCI Cut Through */
+#define PCIA_CTL_CUT(x) ((x&0x7)<<4) /* PCI Cut Through Size */
+#define PCIA_CTL_PRESET (1<<3) /* PCI Reset */
+#define PCIA_CTL_DTHROT (1<<2) /* DMA downthrottle */
+#define PCIA_CTL_T1CYC (1<<0) /* Type 1 Configuration Cycle */
+
+/*
+ * Bits in PCIA_ERR. All are "Write 1 to clear".
+ */
+#define PCIA_ERR_SERR_L (1<<18) /* PCI device asserted SERR_L */
+#define PCIA_ERR_ILAT (1<<17) /* Incremental Latency Exceeded */
+#define PCIA_ERR_SGPRTY (1<<16) /* CPU access of SG RAM Parity Error */
+#define PCIA_ERR_ILLCSR (1<<15) /* Illegal CSR Address Error */
+#define PCIA_ERR_PCINXM (1<<14) /* Nonexistent PCI Address Error */
+#define PCIA_ERR_DSCERR (1<<13) /* PCI Target Disconnect Error */
+#define PCIA_ERR_ABRT (1<<12) /* PCI Target Abort Error */
+#define PCIA_ERR_WPRTY (1<<11) /* PCI Write Parity Error */
+#define PCIA_ERR_DPERR (1<<10) /* PCI Data Parity Error */
+#define PCIA_ERR_APERR (1<<9) /* PCI Address Parity Error */
+#define PCIA_ERR_DFLT (1<<8) /* SG Map RAM Invalid Entry Error */
+#define PCIA_ERR_DPRTY (1<<7) /* DMA access of SG RAM Parity Error */
+#define PCIA_ERR_DRPERR (1<<6) /* DMA Read Return Parity Error */
+#define PCIA_ERR_MABRT (1<<5) /* PCI Master Abort Error */
+#define PCIA_ERR_CPRTY (1<<4) /* CSR Parity Error */
+#define PCIA_ERR_COVR (1<<3) /* CSR Overrun Error */
+#define PCIA_ERR_MBPERR (1<<2) /* Mailbox Parity Error */
+#define PCIA_ERR_MBILI (1<<1) /* Mailbox Illegal Length Error */
+#define PCIA_ERR_ERROR (1<<0) /* Summary Error */
+#define PCIA_ERR_ALLERR ((1<<19) - 1)
+
+/*
+ * Bits in PCIA_PRESENT.
+ */
+#define PCIA_PRESENT_REVSHIFT 25 /* shift by this to get revision */
+#define PCIA_PRESENT_REVMASK 0xf
+#define PCIA_PRESENT_STDIO 0x01000000 /* STD I/O bridge present */
+#define PCIA_PRESENT_SLOTSHIFT(hpc, slot) \
+ (((hpc) << 3) + ((slot) << 1))
+#define PCIA_PRESENT_SLOT_MASK 0x3
+#define PCIA_PRESENT_SLOT_NONE 0x0
+#define PCIA_PRESENT_SLOT_25W 0x1
+#define PCIA_PRESENT_SLOT_15W 0x2
+#define PCIA_PRESENT_SLOW_7W 0x3
+
+/*
+ * Location of the DWLPx SGMAP page table SRAM.
+ */
+#define PCIA_SGMAP_PT 0x381000000UL
+
+/*
+ * Values for PCIA_WMASK_x
+ */
+#define PCIA_WMASK_MASK 0xffff0000 /* mask of valid bits */
+#define PCIA_WMASK_64K 0x00000000
+#define PCIA_WMASK_128K 0x00010000
+#define PCIA_WMASK_256K 0x00030000
+#define PCIA_WMASK_512K 0x00070000
+#define PCIA_WMASK_1M 0x000f0000
+#define PCIA_WMASK_2M 0x001f0000
+#define PCIA_WMASK_4M 0x003f0000
+#define PCIA_WMASK_8M 0x007f0000
+#define PCIA_WMASK_16M 0x00ff0000
+#define PCIA_WMASK_32M 0x01ff0000
+#define PCIA_WMASK_64M 0x03ff0000
+#define PCIA_WMASK_128M 0x07ff0000
+#define PCIA_WMASK_256M 0x0fff0000
+#define PCIA_WMASK_512M 0x1fff0000
+#define PCIA_WMASK_1G 0x3fff0000
+#define PCIA_WMASK_2G 0x7fff0000
+#define PCIA_WMASK_4G 0xffff0000
+
+/*
+ * Values for PCIA_WBASE_x
+ */
+#define PCIA_WBASE_MASK 0xffff0000 /* mask of valid bits in address */
+#define PCIA_WBASE_W_EN 0x00000002 /* window enable */
+#define PCIA_WBASE_SG_EN 0x00000001 /* SGMAP enable */
+
+/*
+ * Values for PCIA_TBASE_x
+ *
+ * NOTE: Translated Base is only used on direct-mapped DMA on the DWLPx!!
+ */
+#define PCIA_TBASE_MASK 0x00fffffe
+#define PCIA_TBASE_SHIFT 15
diff --git a/sys/alpha/tlsb/gbus.c b/sys/alpha/tlsb/gbus.c
new file mode 100644
index 0000000..5235284
--- /dev/null
+++ b/sys/alpha/tlsb/gbus.c
@@ -0,0 +1,155 @@
+/* $Id */
+/* $NetBSD: gbus.c,v 1.8 1998/05/13 22:13:35 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * Autoconfiguration and support routines for the Gbus: the internal
+ * bus on AlphaServer CPU modules.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/rpb.h>
+#include <machine/pte.h>
+
+#include <alpha/tlsb/gbusreg.h>
+#include <alpha/tlsb/gbusvar.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+
+extern int cputype;
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+
+/*
+ * The structure used to attach devices to the Gbus.
+ */
+struct gbus_device {
+ const char* gd_name;
+ int gd_offset;
+};
+
+#define DEVTOGBUS(dev) ((struct gbus_device*) device_get_ivars(dev))
+
+struct gbus_device gbus_children[] = {
+ { "zsc", GBUS_DUART0_OFFSET },
+/* { "zsc", GBUS_DUART1_OFFSET },*/
+ { "mcclock", GBUS_CLOCK_OFFSET },
+ { NULL, 0 },
+};
+
+static devclass_t gbus_devclass;
+
+/*
+ * Bus handlers.
+ */
+static bus_print_device_t gbus_print_device;
+static bus_read_ivar_t gbus_read_ivar;
+
+static bus_ops_t gbus_bus_ops = {
+ gbus_print_device,
+ gbus_read_ivar,
+ null_write_ivar,
+ null_map_intr,
+};
+
+static void
+gbus_print_device(bus_t bus, device_t dev)
+{
+ struct gbus_device* gdev = DEVTOGBUS(dev);
+ device_t gbusdev = bus_get_device(bus);
+
+ printf(" at %s%d offset 0x%lx",
+ device_get_name(gbusdev), device_get_unit(gbusdev),
+ gdev->gd_offset);
+}
+
+static int
+gbus_read_ivar(bus_t bus, device_t dev,
+ int index, u_long* result)
+{
+ struct gbus_device* gdev = DEVTOGBUS(dev);
+
+ switch (index) {
+ case GBUS_IVAR_OFFSET:
+ *result = gdev->gd_offset;
+ break;
+ }
+ return ENOENT;
+}
+
+static driver_probe_t gbus_bus_probe;
+
+static driver_t gbus_bus_driver = {
+ "gbus",
+ gbus_bus_probe,
+ bus_generic_attach,
+ bus_generic_detach,
+ bus_generic_shutdown,
+ DRIVER_TYPE_MISC,
+ sizeof(struct bus),
+ NULL,
+};
+
+/*
+ * At 'probe' time, we add all the devices which we know about to the
+ * bus. The generic attach routine will probe and attach them if they
+ * are alive.
+ */
+static int
+gbus_bus_probe(bus_t parent, device_t dev)
+{
+ bus_t bus = device_get_softc(dev);
+ struct gbus_device *gdev;
+
+ /*
+ * Make sure we're looking for a Gbus.
+ * Right now, only Gbus could be a
+ * child of a TLSB CPU Node.
+ */
+ if (!TLDEV_ISCPU(tlsb_get_dtype(dev)))
+ return ENXIO;
+
+ bus_init(bus, dev, &gbus_bus_ops);
+
+ for (gdev = gbus_children; gdev->gd_name; gdev++)
+ bus_add_device(bus, gdev->gd_name, -1, gdev);
+
+ return 0;
+}
+
+DRIVER_MODULE(gbus, tlsb, gbus_bus_driver, gbus_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/gbusreg.h b/sys/alpha/tlsb/gbusreg.h
new file mode 100644
index 0000000..4e75854
--- /dev/null
+++ b/sys/alpha/tlsb/gbusreg.h
@@ -0,0 +1,46 @@
+/* $NetBSD: gbusreg.h,v 1.1 1998/05/13 02:50:29 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Register definitions for the Gbus found on TurboLaser CPU modules.
+ */
+
+#define GBUS_DUART0_OFFSET 0x10000000 /* duart 0 */
+#define GBUS_DUART1_OFFSET 0x11000000 /* duart 1 */
+#define GBUS_CLOCK_OFFSET 0x20000000 /* clock */
diff --git a/sys/alpha/tlsb/gbusvar.h b/sys/alpha/tlsb/gbusvar.h
new file mode 100644
index 0000000..1652619
--- /dev/null
+++ b/sys/alpha/tlsb/gbusvar.h
@@ -0,0 +1,64 @@
+/* $NetBSD: gbusvar.h,v 1.1 1998/05/13 02:50:29 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Autoconfiguration definitions for the Gbus found on TurboLaser CPU modules.
+ */
+
+/* #include <machine/bus.h> */
+
+enum gbus_device_ivars {
+ GBUS_IVAR_OFFSET /* offset from Gbus base */
+};
+
+/*
+ * Simplified accessors for gbus devices
+ */
+
+#define GBUS_ACCESSOR(A, B, T) \
+ \
+static __inline T gbus_get_ ## A(device_t dev) \
+{ \
+ u_long v; \
+ bus_read_ivar(device_get_parent(dev), dev, GBUS_IVAR_ ## B, &v); \
+ return (T) v; \
+}
+
+GBUS_ACCESSOR(offset, OFFSET, u_int32_t)
+
diff --git a/sys/alpha/tlsb/kftxx.c b/sys/alpha/tlsb/kftxx.c
new file mode 100644
index 0000000..9f41b62
--- /dev/null
+++ b/sys/alpha/tlsb/kftxx.c
@@ -0,0 +1,192 @@
+/* $Id$ */
+/* $NetBSD: kftxx.c,v 1.9 1998/05/14 00:01:32 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * KFTIA and KFTHA Bus Adapter Node for I/O hoses
+ * found on AlphaServer 8200 and 8400 systems.
+ *
+ * i.e., handler for all TLSB I/O nodes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/rpb.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+#include <alpha/tlsb/kftxxreg.h>
+#include <alpha/tlsb/kftxxvar.h>
+
+struct kft_softc {
+ struct bus sc_bus; /* bus common */
+ int sc_node; /* TLSB node */
+ u_int16_t sc_dtype; /* device type */
+};
+
+/*
+ * Instance variables for kft devices.
+ */
+struct kft_device {
+ char * kd_name; /* name */
+ int kd_node; /* node number */
+ u_int16_t kd_dtype; /* device type */
+ u_int16_t kd_hosenum; /* hose number */
+};
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+
+static devclass_t kft_devclass;
+
+/*
+ * Bus handlers.
+ */
+static bus_print_device_t kft_print_device;
+static bus_read_ivar_t kft_read_ivar;
+
+static bus_ops_t kft_bus_ops = {
+ kft_print_device,
+ kft_read_ivar,
+ null_write_ivar,
+ null_map_intr,
+};
+
+static void
+kft_print_device(bus_t bus, device_t dev)
+{
+ struct kft_device *kd = (struct kft_device*) device_get_ivars(dev);
+ device_t busdev = bus_get_device(bus);
+
+ printf(" at %s%d hose %d",
+ device_get_name(busdev), device_get_unit(busdev),
+ kd->kd_hosenum);
+}
+
+static int
+kft_read_ivar(bus_t bus, device_t dev,
+ int index, u_long* result)
+{
+ struct kft_device *kd = (struct kft_device*) device_get_ivars(dev);
+
+ switch (index) {
+ case KFT_IVAR_NAME:
+ *result = (u_long) kd->kd_name;
+ return 0;
+
+ case KFT_IVAR_NODE:
+ *result = (u_long) kd->kd_node;
+ return 0;
+
+ case KFT_IVAR_DTYPE:
+ *result = (u_long) kd->kd_dtype;
+ return 0;
+
+ case KFT_IVAR_HOSENUM:
+ *result = (u_long) kd->kd_hosenum;
+ return 0;
+
+ default:
+ return ENOENT;
+ }
+}
+
+static driver_probe_t kft_bus_probe;
+
+static driver_t kft_bus_driver = {
+ "kft",
+ kft_bus_probe,
+ bus_generic_attach,
+ bus_generic_detach,
+ bus_generic_shutdown,
+ DRIVER_TYPE_MISC,
+ sizeof(struct kft_softc),
+ NULL,
+};
+
+static int
+kft_bus_probe(bus_t parent, device_t dev)
+{
+ struct kft_softc *sc = (struct kft_softc *) device_get_softc(dev);
+ struct kft_device* kd;
+ int hoseno;
+
+ if (!TLDEV_ISIOPORT(tlsb_get_dtype(dev)))
+ return ENXIO;
+
+ bus_init(&sc->sc_bus, dev, &kft_bus_ops);
+
+ sc->sc_node = tlsb_get_node(dev);
+ sc->sc_dtype = tlsb_get_dtype(dev);
+
+ for (hoseno = 0; hoseno < MAXHOSE; hoseno++) {
+ u_int32_t value =
+ TLSB_GET_NODEREG(sc->sc_node, KFT_IDPNSEX(hoseno));
+ if (value & 0x0E000000) {
+ printf("%s%d: Hose %d IDPNSE has %x\n",
+ device_get_name(dev), device_get_unit(dev),
+ hoseno, value);
+ continue;
+ }
+ if ((value & 0x1) != 0x0) {
+ printf("%s%d: Hose %d has a Bad Cable (0x%x)\n",
+ device_get_name(dev), device_get_unit(dev),
+ hoseno, value);
+ continue;
+ }
+ if ((value & 0x6) != 0x6) {
+ if (value)
+ printf("%s%d: Hose %d is missing PWROK (0x%x)\n",
+ device_get_name(dev), device_get_unit(dev),
+ hoseno, value);
+ continue;
+ }
+
+ kd = (struct kft_device*) malloc(sizeof(struct kft_device),
+ M_DEVBUF, M_NOWAIT);
+ if (!kd) continue;
+
+ kd->kd_name = "dwlpx";
+ kd->kd_node = sc->sc_node;
+ kd->kd_dtype = sc->sc_dtype;
+ kd->kd_hosenum = hoseno;
+ bus_add_device(&sc->sc_bus, kd->kd_name, -1, kd);
+ }
+
+ return 0;
+}
+
+DRIVER_MODULE(kft, tlsb, kft_bus_driver, kft_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/kftxxreg.h b/sys/alpha/tlsb/kftxxreg.h
new file mode 100644
index 0000000..0f45fdd
--- /dev/null
+++ b/sys/alpha/tlsb/kftxxreg.h
@@ -0,0 +1,74 @@
+/* $NetBSD: kftxxreg.h,v 1.4 1997/06/04 01:47:15 cgd Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * Registers and values specific to KFTIA or KFTHA nodes.
+ */
+
+/*
+ * Taken from combinations of:
+ *
+ * ``DWLPA and DWLPB PCI Adapter Technical Manual,
+ * Order Number: EK-DWLPX-TM.A01''
+ *
+ * and
+ *
+ * ``AlphaServer 8200/8400 System Technical Manual,
+ * Order Number EK-T8030-TM. A01''
+ */
+
+#define REGVAL(r) (*(volatile int32_t *)ALPHA_PHYS_TO_K0SEG(r))
+
+/*
+ * There are (potentially) 4 I/O hoses per I/O node.
+ *
+ * A CPU to Hose Address Mapping looks (roughly) like this:
+ *
+ * 39 38........36 35.34 33.................0
+ * -------------------------------------------
+ * |1|TLSB NodeID |Hose#|Hose Module Specific|
+ * -------------------------------------------
+ *
+ */
+
+#define HOSE_SIZE 0x400000000L
+
+#define MAXHOSE 4
+/*
+ * Hose Specific I/O registers (offsets from base of I/O Board)
+ */
+
+#define KFT_IDPNSEX(hose) ((hose)? (0x2040 + (0x100 * (hose))) : 0x2A40)
+
+#define KFT_ICCNSE 0x2040
+#define KFT_ICCWTR 0x2100
+#define KFT_IDPMSR 0x2B80
diff --git a/sys/alpha/tlsb/kftxxvar.h b/sys/alpha/tlsb/kftxxvar.h
new file mode 100644
index 0000000..d0b3f40
--- /dev/null
+++ b/sys/alpha/tlsb/kftxxvar.h
@@ -0,0 +1,59 @@
+/* $NetBSD: kftxxvar.h,v 1.3 1997/04/06 20:08:38 cgd Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * Instance vars for children of a KFTIA or KFTHA node.
+ */
+enum kft_dev_ivars {
+ KFT_IVAR_NAME,
+ KFT_IVAR_NODE,
+ KFT_IVAR_DTYPE,
+ KFT_IVAR_HOSENUM
+};
+
+/*
+ * Simplified accessors for kft devices
+ */
+
+#define KFT_ACCESSOR(A, B, T) \
+ \
+static __inline T kft_get_ ## A(device_t dev) \
+{ \
+ u_long v; \
+ bus_read_ivar(device_get_parent(dev), dev, KFT_IVAR_ ## B, &v); \
+ return (T) v; \
+}
+
+KFT_ACCESSOR(name, NAME, const char*)
+KFT_ACCESSOR(node, NODE, int)
+KFT_ACCESSOR(dtype, DTYPE, u_int16_t)
+KFT_ACCESSOR(hosenum, HOSENUM, u_int16_t)
diff --git a/sys/alpha/tlsb/mcclock_tlsb.c b/sys/alpha/tlsb/mcclock_tlsb.c
new file mode 100644
index 0000000..15974fc
--- /dev/null
+++ b/sys/alpha/tlsb/mcclock_tlsb.c
@@ -0,0 +1,126 @@
+/* $Id$ */
+/* $NetBSD: mcclock_tlsb.c,v 1.8 1998/05/13 02:50:29 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <dev/dec/clockvar.h>
+#include <dev/dec/mcclockvar.h>
+
+#include <alpha/tlsb/gbusvar.h>
+
+#include <alpha/tlsb/tlsbreg.h> /* XXX */
+
+#include <dev/dec/mc146818reg.h>
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+/*
+ * Registers are 64 bytes apart (and 1 byte wide)
+ */
+#define REGSHIFT 6
+
+struct mcclock_tlsb_softc {
+ struct mcclock_softc sc_mcclock;
+ unsigned long regbase;
+};
+
+static int mcclock_tlsb_probe(bus_t, device_t);
+static int mcclock_tlsb_attach(bus_t, device_t);
+
+static devclass_t mcclock_devclass;
+
+driver_t mcclock_tlsb_driver = {
+ "mcclock",
+ mcclock_tlsb_probe,
+ mcclock_tlsb_attach,
+ NULL,
+ NULL,
+ DRIVER_TYPE_MISC,
+ sizeof(struct mcclock_tlsb_softc),
+ NULL,
+};
+
+static void mcclock_tlsb_write __P((struct mcclock_softc *, u_int, u_int));
+static u_int mcclock_tlsb_read __P((struct mcclock_softc *, u_int));
+
+const struct mcclock_busfns mcclock_tlsb_busfns = {
+ mcclock_tlsb_write, mcclock_tlsb_read,
+};
+
+int
+mcclock_tlsb_probe(bus_t bus, device_t dev)
+{
+ device_set_desc(dev, "MC146818A real time clock");
+ return 0;
+}
+
+int
+mcclock_tlsb_attach(bus_t bus, device_t dev)
+{
+ struct mcclock_tlsb_softc *sc = device_get_softc(dev);
+
+ /* XXX Should be bus.h'd, so we can accomodate the kn7aa. */
+
+ sc->sc_mcclock.sc_dev = dev;
+ sc->regbase = TLSB_GBUS_BASE + gbus_get_offset(dev);
+
+ mcclock_attach(&sc->sc_mcclock, &mcclock_tlsb_busfns);
+ return 0;
+}
+
+static void
+mcclock_tlsb_write(mcsc, reg, val)
+ struct mcclock_softc *mcsc;
+ u_int reg, val;
+{
+ struct mcclock_tlsb_softc *sc = (struct mcclock_tlsb_softc *)mcsc;
+ unsigned char *ptr = (unsigned char *)
+ KV(sc->regbase + (reg << REGSHIFT));
+ *ptr = val;
+}
+
+static u_int
+mcclock_tlsb_read(mcsc, reg)
+ struct mcclock_softc *mcsc;
+ u_int reg;
+{
+ struct mcclock_tlsb_softc *sc = (struct mcclock_tlsb_softc *)mcsc;
+ unsigned char *ptr = (unsigned char *)
+ KV(sc->regbase + (reg << REGSHIFT));
+ return *ptr;
+}
+
+DRIVER_MODULE(mcclock_tlsb, gbus, mcclock_tlsb_driver, mcclock_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/tlsb.c b/sys/alpha/tlsb/tlsb.c
new file mode 100644
index 0000000..7b778ac
--- /dev/null
+++ b/sys/alpha/tlsb/tlsb.c
@@ -0,0 +1,329 @@
+/* $Id */
+/* $NetBSD: tlsb.c,v 1.10 1998/05/14 00:01:32 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Based in part upon a prototype version by Jason Thorpe
+ * Copyright (c) 1996 by Jason Thorpe.
+ *
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * Autoconfiguration and support routines for the TurboLaser System Bus
+ * found on AlphaServer 8200 and 8400 systems.
+ */
+
+#include "opt_simos.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+
+#include <machine/rpb.h>
+#include <machine/cpuconf.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+
+/* #include "locators.h" */
+
+extern int cputype;
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+
+/*
+ * The structure used to attach devices to the TurboLaser.
+ */
+struct tlsb_device {
+ int td_node; /* node number */
+ u_int16_t td_dtype; /* device type */
+ u_int8_t td_swrev; /* software revision */
+ u_int8_t td_hwrev; /* hardware revision */
+};
+#define DEVTOTLSB(dev) ((struct tlsb_device*) device_get_ivars(dev))
+
+struct intr_mapping {
+ STAILQ_ENTRY(intr_mapping) queue;
+ driver_intr_t* intr;
+ void* arg;
+};
+
+struct tlsb_softc {
+ struct bus bus;
+ STAILQ_HEAD(, intr_mapping) intr_handlers;
+};
+
+static char *tlsb_node_type_str(u_int32_t);
+static void tlsb_intr(void* frame, u_long vector);
+
+/* There can be only one. */
+static int tlsb_found;
+static struct tlsb_softc* tlsb0_softc;
+
+/*
+ * Bus handlers.
+ */
+static bus_print_device_t tlsb_print_device;
+static bus_read_ivar_t tlsb_read_ivar;
+static bus_map_intr_t tlsb_map_intr;
+
+static bus_ops_t tlsb_bus_ops = {
+ tlsb_print_device,
+ tlsb_read_ivar,
+ null_write_ivar,
+ tlsb_map_intr,
+};
+
+static void
+tlsb_print_device(bus_t bus, device_t dev)
+{
+ device_t busdev = bus_get_device(bus);
+ struct tlsb_device* tdev = DEVTOTLSB(dev);
+
+ printf(" at %s%d node %d",
+ device_get_name(busdev),
+ device_get_unit(busdev),
+ tdev->td_node);
+}
+
+static int
+tlsb_read_ivar(bus_t bus, device_t dev,
+ int index, u_long* result)
+{
+ struct tlsb_device* tdev = DEVTOTLSB(dev);
+
+ switch (index) {
+ case TLSB_IVAR_NODE:
+ *result = tdev->td_node;
+ break;
+
+ case TLSB_IVAR_DTYPE:
+ *result = tdev->td_dtype;
+ break;
+
+ case TLSB_IVAR_SWREV:
+ *result = tdev->td_swrev;
+ break;
+
+ case TLSB_IVAR_HWREV:
+ *result = tdev->td_hwrev;
+ break;
+ }
+ return ENOENT;
+}
+
+static int
+tlsb_map_intr(bus_t bus, device_t dev, driver_intr_t *intr, void *arg)
+{
+ struct tlsb_softc* sc = (struct tlsb_softc*) bus;
+ struct intr_mapping* i;
+ i = malloc(sizeof(struct intr_mapping), M_DEVBUF, M_NOWAIT);
+ if (!i)
+ return ENOMEM;
+ i->intr = intr;
+ i->arg = arg;
+ STAILQ_INSERT_TAIL(&sc->intr_handlers, i, queue);
+
+ return 0;
+}
+
+static driver_probe_t tlsb_bus_probe;
+static devclass_t tlsb_devclass;
+
+static driver_t tlsb_bus_driver = {
+ "tlsb",
+ tlsb_bus_probe,
+ bus_generic_attach,
+ bus_generic_detach,
+ bus_generic_shutdown,
+ DRIVER_TYPE_MISC,
+ sizeof(struct tlsb_softc),
+ NULL,
+};
+
+/*
+ * At 'probe' time, we add all the devices which we know about to the
+ * bus. The generic attach routine will probe and attach them if they
+ * are alive.
+ */
+static int
+tlsb_bus_probe(bus_t parent, device_t dev)
+{
+ struct tlsb_softc* sc = device_get_softc(dev);
+ struct tlsb_device *tdev;
+ u_int32_t tldev;
+ u_int8_t vid;
+ int node;
+ device_t subdev;
+
+ device_set_desc(dev, "TurboLaser bus");
+ bus_init(&sc->bus, dev, &tlsb_bus_ops);
+ STAILQ_INIT(&sc->intr_handlers);
+ tlsb0_softc = sc;
+
+ set_iointr(tlsb_intr);
+
+ printf("Probing for devices on the TurboLaser bus:\n");
+
+ tlsb_found = 1;
+
+ /*
+ * Attempt to find all devices on the bus, including
+ * CPUs, memory modules, and I/O modules.
+ */
+
+ /*
+ * Sigh. I would like to just start off nicely,
+ * but I need to treat I/O modules differently-
+ * The highest priority I/O node has to be in
+ * node #8, and I want to find it *first*, since
+ * it will have the primary disks (most likely)
+ * on it.
+ */
+ /*
+ * XXX dfr: I don't see why I need to do this
+ */
+ for (node = 0; node <= TLSB_NODE_MAX; ++node) {
+ /*
+ * Check for invalid address. This may not really
+ * be necessary, but what the heck...
+ */
+ if (badaddr(TLSB_NODE_REG_ADDR(node, TLDEV), sizeof(u_int32_t)))
+ continue;
+ tldev = TLSB_GET_NODEREG(node, TLDEV);
+#ifdef SIMOS
+ if (node != 0 && node != 8)
+ continue;
+#endif
+ if (tldev == 0) {
+ /* Nothing at this node. */
+ continue;
+ }
+#if 0
+ if (TLDEV_ISIOPORT(tldev))
+ continue; /* not interested right now */
+#endif
+
+ tdev = (struct tlsb_device*)
+ malloc(sizeof(struct tlsb_device),
+ M_DEVBUF, M_NOWAIT);
+
+ if (!tdev)
+ continue;
+
+ tdev->td_node = node;
+#ifdef SIMOS
+ if (node == 0)
+ tdev->td_dtype = TLDEV_DTYPE_SCPU4;
+ else if (node == 8)
+ tdev->td_dtype = TLDEV_DTYPE_KFTIA;
+#else
+ tdev->td_dtype = TLDEV_DTYPE(tldev);
+#endif
+ tdev->td_swrev = TLDEV_SWREV(tldev);
+ tdev->td_hwrev = TLDEV_HWREV(tldev);
+
+ subdev = bus_add_device(&sc->bus, NULL, -1, tdev);
+ device_set_desc(subdev, tlsb_node_type_str(tdev->td_dtype));
+
+ /*
+ * Deal with hooking CPU instances to TurboLaser nodes.
+ */
+ if (TLDEV_ISCPU(tldev)) {
+ printf("%s%d node %d: %s",
+ device_get_name(dev), device_get_unit(dev),
+ node, tlsb_node_type_str(tldev));
+
+ /*
+ * Hook in the first CPU unit.
+ */
+ vid = (TLSB_GET_NODEREG(node, TLVID) &
+ TLVID_VIDA_MASK) >> TLVID_VIDA_SHIFT;
+ printf(", VID %d\n", vid);
+ TLSB_PUT_NODEREG(node, TLCPUMASK, (1<<vid));
+ }
+ }
+
+ return 0;
+}
+
+static void
+tlsb_intr(void* frame, u_long vector)
+{
+ struct tlsb_softc* sc = tlsb0_softc;
+ struct intr_mapping* i;
+
+ /*
+ * XXX for SimOS, broadcast the interrupt. A real implementation
+ * will decode the vector to extract node and host etc.
+ */
+ for (i = STAILQ_FIRST(&sc->intr_handlers);
+ i; i = STAILQ_NEXT(i, queue))
+ i->intr(i->arg);
+}
+
+DRIVER_MODULE(tlsb, root, tlsb_bus_driver, tlsb_devclass, 0, 0);
+
+static char *
+tlsb_node_type_str(u_int32_t dtype)
+{
+ static char tlsb_line[64];
+
+ switch (dtype & TLDEV_DTYPE_MASK) {
+ case TLDEV_DTYPE_KFTHA:
+ return ("KFTHA I/O interface");
+
+ case TLDEV_DTYPE_KFTIA:
+ return ("KFTIA I/O interface");
+
+ case TLDEV_DTYPE_MS7CC:
+ return ("MS7CC Memory Module");
+
+ case TLDEV_DTYPE_SCPU4:
+ return ("Single CPU, 4MB cache");
+
+ case TLDEV_DTYPE_SCPU16:
+ return ("Single CPU, 16MB cache");
+
+ case TLDEV_DTYPE_DCPU4:
+ return ("Dual CPU, 4MB cache");
+
+ case TLDEV_DTYPE_DCPU16:
+ return ("Dual CPU, 16MB cache");
+
+ default:
+ bzero(tlsb_line, sizeof(tlsb_line));
+ sprintf(tlsb_line, "unknown, dtype 0x%x", dtype);
+ return (tlsb_line);
+ }
+ /* NOTREACHED */
+}
diff --git a/sys/alpha/tlsb/tlsbmem.c b/sys/alpha/tlsb/tlsbmem.c
new file mode 100644
index 0000000..c46306c
--- /dev/null
+++ b/sys/alpha/tlsb/tlsbmem.c
@@ -0,0 +1,91 @@
+/* $NetBSD: tlsbmem.c,v 1.6 1998/01/12 10:21:25 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * Dummy Node for TLSB Memory Modules found on
+ * AlphaServer 8200 and 8400 systems.
+ */
+
+#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
+
+__KERNEL_RCSID(0, "$NetBSD: tlsbmem.c,v 1.6 1998/01/12 10:21:25 thorpej Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/autoconf.h>
+#include <machine/rpb.h>
+#include <machine/pte.h>
+
+#include <alpha/tlsb/tlsbreg.h>
+#include <alpha/tlsb/tlsbvar.h>
+
+struct tlsbmem_softc {
+ struct device sc_dv;
+ int sc_node; /* TLSB node */
+ u_int16_t sc_dtype; /* device type */
+};
+
+static int tlsbmemmatch __P((struct device *, struct cfdata *, void *));
+static void tlsbmemattach __P((struct device *, struct device *, void *));
+struct cfattach tlsbmem_ca = {
+ sizeof (struct tlsbmem_softc), tlsbmemmatch, tlsbmemattach
+};
+
+static int
+tlsbmemmatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct tlsb_dev_attach_args *ta = aux;
+ if (TLDEV_ISMEM(ta->ta_dtype))
+ return (1);
+ return (0);
+}
+
+static void
+tlsbmemattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct tlsb_dev_attach_args *ta = aux;
+ struct tlsbmem_softc *sc = (struct tlsbmem_softc *)self;
+
+ sc->sc_node = ta->ta_node;
+ sc->sc_dtype = ta->ta_dtype;
+
+ printf("\n");
+}
diff --git a/sys/alpha/tlsb/tlsbreg.h b/sys/alpha/tlsb/tlsbreg.h
new file mode 100644
index 0000000..37b58de
--- /dev/null
+++ b/sys/alpha/tlsb/tlsbreg.h
@@ -0,0 +1,318 @@
+/* $NetBSD: tlsbreg.h,v 1.3 1997/04/06 20:08:40 cgd Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Based in part upon a prototype version by Jason Thorpe
+ * Copyright (c) 1996 by Jason Thorpe.
+ *
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * Definitions for the TurboLaser System Bus found on
+ * AlphaServer 8200/8400 systems.
+ */
+
+/*
+ * There are 9 TurboLaser nodes, 0 though 8. Their uses are defined as
+ * follows:
+ *
+ * Node Module
+ * ---- ------
+ * 0 CPU, Memory
+ * 1 CPU, Memory
+ * 2 CPU, Memory
+ * 3 CPU, Memory
+ * 4 CPU, Memory, I/O
+ * 5 CPU, Memory, I/O
+ * 6 CPU, Memory, I/O
+ * 7 CPU, Memory, I/O
+ * 8 I/O
+ *
+ * A node occurs every 0x00400000 bytes.
+ *
+ * Note, the AlphaServer 8200 only has nodes 4 though 8.
+ */
+
+#define TLSB_NODE_BASE 0x000000ff88000000 /* Dense */
+#define TLSB_NODE_SIZE 0x00400000
+#define TLSB_NODE_MAX 8
+
+/* Translate a node number to an address. */
+#define TLSB_NODE_ADDR(_node) \
+ (long)(TLSB_NODE_BASE + ((_node) * TLSB_NODE_SIZE))
+
+#define TLSB_NODE_REG_ADDR(_node, _reg) \
+ KV((long)TLSB_NODE_ADDR((_node)) + (_reg))
+
+/* Access the specified register on the specified node. */
+#define TLSB_GET_NODEREG(_node, _reg) \
+ *(volatile u_int32_t *)(TLSB_NODE_REG_ADDR((_node), (_reg)))
+#define TLSB_PUT_NODEREG(_node, _reg, _val) \
+ *(volatile u_int32_t *)(TLSB_NODE_REG_ADDR((_node), (_reg))) = (_val)
+
+/*
+ * Some registers are shared by all TurboLaser nodes, and appear in
+ * the TurboLaser Broadcast space.
+ */
+#define TLSB_BCAST_BASE 0x000000ff8e000000 /* Dense */
+
+#define TLSB_BCAST_REG_ADDR(_reg) KV((long)(TLSB_BCASE_BASE + (_reg)))
+
+/* Access the specified register in the broadcast space. */
+#define TLSB_GET_BCASTREG(_reg) \
+ *(volatile u_int32_t *)(TLSB_BCAST_REG_ADDR + (_reg))
+#define TLSB_PUT_BCASTREG(_reg, _val) \
+ *(volatile u_int32_t *)(TLSB_BCAST_REG_ADDR + (_reg)) = (_val)
+
+/*
+ * Location of the Gbus, the per-CPU bus containing the clock and
+ * console hardware.
+ */
+#define TLSB_GBUS_BASE 0x000000ff90000000 /* Dense */
+
+/*
+ * Note that not every module type supports each TurboLaser register.
+ * The following defines the keys used to denote module support for
+ * a given register:
+ *
+ * C Supported by CPU module
+ * M Supported by Memory module
+ * I Supported by I/O module
+ */
+
+/*
+ * Per-node TurboLaser System Bus registers, offsets from the
+ * base of the node.
+ */
+#define TLDEV 0x0000 /* CMI: Device Register */
+#define TLBER 0x0040 /* CMI: Bus Error Register */
+#define TLCNR 0x0080 /* CMI: Congfiguration Register */
+#define TLVID 0x00c0 /* CM: Virtual ID Register */
+#define TLMMR0 0x0200 /* CM: Memory Mapping Register 0 */
+#define TLMMR1 0x0240 /* CM: Memory Mapping Register 1 */
+#define TLMMR2 0x0280 /* CM: Memory Mapping Register 2 */
+#define TLMMR3 0x02c0 /* CM: Memory Mapping Register 3 */
+#define TLMMR4 0x0300 /* CM: Memory Mapping Register 4 */
+#define TLMMR5 0x0340 /* CM: Memory Mapping Register 5 */
+#define TLMMR6 0x0380 /* CM: Memory Mapping Register 6 */
+#define TLMMR7 0x03c0 /* CM: Memory Mapping Register 7 */
+#define TLFADR0 0x0600 /* MI: Failing Address Register 0 */
+#define TLFADR1 0x0640 /* MI: Failing Address Register 1 */
+#define TLESR0 0x0680 /* CMI: Error Syndrome Register 0 */
+#define TLESR1 0x06c0 /* CMI: Error Syndrome Register 1 */
+#define TLESR2 0x0700 /* CMI: Error Syndrome Register 2 */
+#define TLESR3 0x0740 /* CMI: Error Syndrome Register 3 */
+#define TLILID0 0x0a00 /* I: Int. Level 0 IDENT Register */
+#define TLILID1 0x0a40 /* I: Int. Level 1 IDENT Register */
+#define TLILID2 0x0a80 /* I: Int. Level 2 IDENT Register */
+#define TLILID3 0x0ac0 /* I: Int. Level 3 IDENT Register */
+#define TLCPUMASK 0x0b00 /* I: CPU Interrupt Mask Register */
+#define TLMBPTR 0x0c00 /* I: Mailbox Pointer Register */
+#define TLEPAERR 0x1500 /* C: ADG error register */
+
+/*
+ * Registers shared between TurboLaser nodes, offsets from the
+ * TurboLaser Broadcast Base.
+ */
+#define TLPRIVATE 0x0000 /* CMI: private "global" space */
+#define TLIPINTR 0x0040 /* C: Interprocessor Int. Register */
+#define TLIOINTR4 0x0100 /* C: I/O Interrupt Register 4 */
+#define TLIOINTR5 0x0140 /* C: I/O Interrupt Register 5 */
+#define TLIOINTR6 0x0180 /* C: I/O Interrupt Register 6 */
+#define TLIOINTR7 0x01c0 /* C: I/O Interrupt Register 7 */
+#define TLIOINTR8 0x0200 /* C: I/O Interrupt Register 8 */
+#define TLWSDQR4 0x0400 /* C: Win Spc Dcr Que Ctr Reg 4 */
+#define TLWSDQR5 0x0440 /* C: Win Spc Dcr Que Ctr Reg 5 */
+#define TLWSDQR6 0x0480 /* C: Win Spc Dcr Que Ctr Reg 6 */
+#define TLWSDQR7 0x04c0 /* C: Win Spc Dcr Que Ctr Reg 7 */
+#define TLWSDQR8 0x0500 /* C: Win Spc Dcr Que Ctr Reg 8 */
+#define TLRMDQRX 0x0600 /* C: Mem Chan Dcr Que Ctr Reg X */
+#define TLRMDQR8 0x0640 /* C: Mem Chan Dcr Que Ctr Reg 8 */
+#define TLRDRD 0x0800 /* C: CSR Read Data Rtn Data Reg */
+#define TLRDRE 0x0840 /* C: CSR Read Data Rtn Error Reg */
+#define TLMCR 0x1880 /* M: Memory Control Register */
+
+/*
+ * TLDEV - Device Register
+ *
+ * Access: R/W
+ *
+ * Notes:
+ * Register is loaded during initialization with information
+ * that identifies a node. A zero value indicates a non-initialized
+ * (slot empty) node.
+ *
+ * Bits 0-15 contain the hardware device type, bits 16-23
+ * the board's software revision, and bits 24-31 the board's
+ * hardware revision.
+ *
+ * The device type portion is laid out as follows:
+ *
+ * Bit 15: identifies a CPU
+ * Bit 14: identifies a memory board
+ * Bit 13: identifies an I/O board
+ * Bits 0-7: specify the ID of a node type
+ */
+#define TLDEV_DTYPE_MASK 0x0000ffff
+#define TLDEV_DTYPE_KFTHA 0x2000 /* KFTHA board, I/O */
+#define TLDEV_DTYPE_KFTIA 0x2020 /* KFTIA board, I/O */
+#define TLDEV_DTYPE_MS7CC 0x5000 /* Memory board */
+#define TLDEV_DTYPE_SCPU4 0x8011 /* 1 CPU, 4mb cache */
+#define TLDEV_DTYPE_SCPU16 0x8012 /* 1 CPU, 16mb cache */
+#define TLDEV_DTYPE_DCPU4 0x8014 /* 2 CPU, 4mb cache */
+#define TLDEV_DTYPE_DCPU16 0x8015 /* 2 CPU, 16mb cache */
+
+#define TLDEV_DTYPE(_val) ((_val) & TLDEV_DTYPE_MASK)
+# define TLDEV_ISCPU(_val) (TLDEV_DTYPE(_val) & 0x8000)
+# define TLDEV_ISMEM(_val) (TLDEV_DTYPE(_val) & 0x4000)
+# define TLDEV_ISIOPORT(_val) (TLDEV_DTYPE(_val) & 0x2000)
+#define TLDEV_SWREV(_val) (((_val) >> 16) & 0xff)
+#define TLDEV_HWREV(_val) (((_val) >> 24) & 0xff)
+
+/*
+ * TLBER - Bus Error Register
+ *
+ * Access: R/W
+ *
+ * Notes:
+ * This register contains information about TLSB errors detected by
+ * nodes on the TLSB. The register will become locked when:
+ *
+ * * Any error occurs and the "lock on first error"
+ * bit of the Configuration Register is set.
+ *
+ * * Any bit other than 20-23 (DS0-DS3) becomes set.
+ *
+ * and will remain locked until either:
+ *
+ * * All bits in the TLBER are cleared.
+ *
+ * * The "lock on first error" bit is cleared.
+ *
+ * TLBER locking is intended for diagnosic purposes only, and
+ * not for general use.
+ */
+#define TLBER_ATCE 0x00000001 /* Addr Transmit Ck Error */
+#define TLBER_APE 0x00000002 /* Addr Parity Error */
+#define TLBER_BAE 0x00000004 /* Bank Avail Violation Error */
+#define TLBER_LKTO 0x00000008 /* Bank Lock Timeout */
+#define TLBER_NAE 0x00000010 /* No Ack Error */
+#define TLBER_RTCE 0x00000020 /* Read Transmit Ck Error */
+#define TLBER_ACKTCE 0x00000040 /* Ack Transmit Ck Error */
+#define TLBER_MMRE 0x00000080 /* Mem Mapping Register Error */
+#define TLBER_FNAE 0x00000100 /* Fatal No Ack Error */
+#define TLBER_REQDE 0x00000200 /* Request Deassertion Error */
+#define TLBER_ATDE 0x00000400 /* Addredd Transmitter During Error */
+#define TLBER_UDE 0x00010000 /* Uncorrectable Data Error */
+#define TLBER_CWDE 0x00020000 /* Correctable Write Data Error */
+#define TLBER_CRDE 0x00040000 /* Correctable Read Data Error */
+#define TLBER_CRDE2 0x00080000 /* ...ditto... */
+#define TLBER_DS0 0x00100000 /* Data Synd 0 */
+#define TLBER_DS1 0x00200000 /* Data Synd 1 */
+#define TLBER_DS2 0x00400000 /* Data Synd 2 */
+#define TLBER_DS3 0x00800000 /* Data Synd 3 */
+#define TLBER_DTDE 0x01000000 /* Data Transmitter During Error */
+#define TLBER_FDTCE 0x02000000 /* Fatal Data Transmit Ck Error */
+#define TLBER_UACKE 0x04000000 /* Unexpected Ack Error */
+#define TLBER_ABTCE 0x08000000 /* Addr Bus Transmit Error */
+#define TLBER_DCTCE 0x10000000 /* Data Control Transmit Ck Error */
+#define TLBER_SEQE 0x20000000 /* Sequence Error */
+#define TLBER_DSE 0x40000000 /* Data Status Error */
+#define TLBER_DTO 0x80000000 /* Data Timeout Error */
+
+/*
+ * TLCNR - Configuration Register
+ *
+ * Access: R/W
+ */
+#define TLCNR_CWDD 0x00000001 /* Corr Write Data Err INTR Dis */
+#define TLCNR_CRDD 0x00000002 /* Corr Read Data Err INTR Dis */
+#define TLCNR_LKTOD 0x00000004 /* Bank Lock Timeout Disable */
+#define TLCNR_DTOD 0x00000008 /* Data Timeout Disable */
+#define TLCNR_STF_A 0x00001000 /* Self-Test Fail A */
+#define TLCNR_STF_B 0x00002000 /* Self-Test Fail B */
+#define TLCNR_HALT_A 0x00100000 /* Halt A */
+#define TLCNR_HALT_B 0x00200000 /* Halt B */
+#define TLCNR_RSTSTAT 0x10000000 /* Reset Status */
+#define TLCNR_NRST 0x40000000 /* Node Reset */
+#define TLCNR_LOFE 0x80000000 /* Lock On First Error */
+
+#define TLCNR_NODE_MASK 0x000000f0 /* Node ID mask */
+#define TLCNR_NODE_SHIFT 4
+
+#define TLCNR_VCNT_MASK 0x00000f00 /* VCNT mask */
+#define TLCNR_VCNT_SHIFT 8
+
+/*
+ * TLVID - Virtual ID Register
+ *
+ * Access: R/W
+ *
+ * Notes:
+ * Virtual units can be CPUs or Memory boards. The units are
+ * are addressed using virtual IDs. These virtual IDs are assigned
+ * by writing to the TLVID register. The upper 24 bits of this
+ * register are reserved and must be written as `0'.
+ */
+#define TLVID_VIDA_MASK 0x0000000f /* Virtual ID for unit 0 */
+#define TLVID_VIDA_SHIFT 0
+
+#define TLVID_VIDB_MASK 0x000000f0 /* Virtual ID for unit 1 */
+#define TLVID_VIDB_SHIFT 4
+
+/*
+ * TLMMRn - Memory Mapping Registers
+ *
+ * Access: W
+ *
+ * Notes:
+ * Contains mapping information for doing a bank-decode.
+ */
+#define TLMMR_INTMASK 0x00000003 /* Valid bits in Interleave */
+#define TLMMR_ADRMASK 0x000000f0 /* Valid bits in Address */
+#define TLMMR_SBANK 0x00000800 /* Single-bank indicator */
+#define TLMMR_VALID 0x80000000 /* Indicated mapping is valid */
+
+#define TLMMR_INTLV_MASK 0x00000700 /* Mask for interleave value */
+#define TLMMR_INTLV_SHIFT 8
+
+#define TLMMR_ADDRESS_MASK 0x03fff000 /* Mask for address value */
+#define TLMMR_ADDRESS_SHIFT 12
+
+/*
+ * TLFADRn - Failing Address Registers
+ *
+ * Access: R/W
+ *
+ * Notes:
+ * These registers contain status information for a failed address.
+ * Not all nodes preserve this information. The validation bits
+ * indicate the validity of a given field.
+ */
+
diff --git a/sys/alpha/tlsb/tlsbvar.h b/sys/alpha/tlsb/tlsbvar.h
new file mode 100644
index 0000000..bfb24ed
--- /dev/null
+++ b/sys/alpha/tlsb/tlsbvar.h
@@ -0,0 +1,75 @@
+/* $Id$ */
+/* $NetBSD: tlsbvar.h,v 1.5 1998/05/13 23:23:23 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center.
+ * All rights reserved.
+ *
+ * Based in part upon a prototype version by Jason Thorpe
+ * Copyright (c) 1996 by Jason Thorpe.
+ *
+ * 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 immediately at the beginning of the file, without modification,
+ * 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. 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 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 AUTHOR 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.
+ */
+
+/*
+ * Definitions for the TurboLaser System Bus found on
+ * AlphaServer 8200/8400 systems.
+ */
+
+enum tlsb_device_instvars {
+ TLSB_IVAR_NODE,
+ TLSB_IVAR_DTYPE,
+ TLSB_IVAR_SWREV,
+ TLSB_IVAR_HWREV
+};
+
+/*
+ * Simplified accessors for turbolaser devices
+ */
+
+#define TLSB_ACCESSOR(A, B, T) \
+ \
+static __inline T tlsb_get_ ## A(device_t dev) \
+{ \
+ u_long v; \
+ bus_read_ivar(device_get_parent(dev), dev, TLSB_IVAR_ ## B, &v); \
+ return v; \
+}
+
+TLSB_ACCESSOR(node, NODE, int)
+TLSB_ACCESSOR(dtype, DTYPE, u_int16_t)
+TLSB_ACCESSOR(hwrev, HWREV, u_int8_t)
+TLSB_ACCESSOR(swrev, SWREV, u_int8_t)
+
+/*
+ * Bus-dependent structure for CPUs. This is dynamically allocated
+ * for each CPU on the TurboLaser, and glued into the cpu_softc
+ * as sc_busdep (when there is a cpu_softc to do this to).
+ */
+struct tlsb_cpu_busdep {
+ u_int8_t tcpu_vid; /* virtual ID of CPU */
+ int tcpu_node; /* TurboLaser node */
+};
diff --git a/sys/alpha/tlsb/zs_tlsb.c b/sys/alpha/tlsb/zs_tlsb.c
new file mode 100644
index 0000000..8532ed3
--- /dev/null
+++ b/sys/alpha/tlsb/zs_tlsb.c
@@ -0,0 +1,473 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * 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 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+/*
+ * This driver is a hopeless hack to get the SimOS console working. A real
+ * driver would use the zs driver source from NetBSD.
+ */
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/tty.h>
+#include <sys/proc.h>
+#include <sys/ucred.h>
+#include <machine/cons.h>
+#include <machine/clock.h>
+
+#include <alpha/tlsb/gbusvar.h>
+#include <alpha/tlsb/tlsbreg.h> /* XXX */
+#include <alpha/tlsb/zsreg.h>
+
+#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
+
+static int zsc_get_channel(device_t dev);
+static caddr_t zsc_get_base(device_t dev);
+
+struct zs_softc {
+ struct tty tty;
+ int channel;
+ caddr_t base;
+};
+#define ZS_SOFTC(unit) \
+ ((struct zs_softc*)devclass_get_softc(zs_devclass, (unit)))
+
+static d_open_t zsopen;
+static d_close_t zsclose;
+static d_read_t zsread;
+static d_write_t zswrite;
+static d_ioctl_t zsioctl;
+static d_stop_t zsstop;
+static d_devtotty_t zsdevtotty;
+
+#define CDEV_MAJOR 97
+static struct cdevsw zs_cdevsw = {
+ zsopen, zsclose, zsread, zswrite,
+ zsioctl, zsstop, noreset, zsdevtotty,
+ ttpoll, nommap, NULL, "zs",
+ NULL, -1,
+};
+
+static void zsstart __P((struct tty *));
+static int zsparam __P((struct tty *, struct termios *));
+
+/*
+ * Helpers for console support.
+ */
+
+static int zs_cngetc __P((dev_t));
+static void zs_cnputc __P((dev_t, int));
+static void zs_cnpollc __P((dev_t, int));
+
+struct consdev zs_cons = {
+ NULL, NULL, zs_cngetc, NULL, zs_cnputc,
+ NULL, makedev(CDEV_MAJOR, 0), CN_NORMAL,
+};
+
+static caddr_t zs_console_addr;
+static int zs_console;
+
+static int zs_probe(bus_t, device_t);
+static int zs_attach(bus_t, device_t);
+
+static devclass_t zs_devclass;
+static devclass_t zsc_devclass;
+
+driver_t zs_driver = {
+ "zs",
+ zs_probe,
+ zs_attach,
+ NULL,
+ NULL,
+ DRIVER_TYPE_MISC,
+ sizeof(struct zs_softc),
+ NULL,
+};
+
+static int
+zs_probe(bus_t bus, device_t dev)
+{
+ return 0;
+}
+
+static int
+zs_attach(bus_t bus, device_t dev)
+{
+ struct zs_softc *sc = device_get_softc(dev);
+
+ sc->channel = zsc_get_channel(dev);
+ sc->base = zsc_get_base(dev);
+
+ return 0;
+}
+
+static int
+zs_get_status(caddr_t base)
+{
+ return (*(u_int32_t*) (base + ZSC_STATUS)) & 0xff;
+}
+
+static void
+zs_put_status(caddr_t base, int v)
+{
+ *(u_int32_t*) (base + ZSC_STATUS) = v;
+ alpha_mb();
+}
+
+static int
+zs_get_rr3(caddr_t base)
+{
+ zs_put_status(base, 3);
+ return zs_get_status(base);
+}
+
+static int
+zs_get_data(caddr_t base)
+{
+ return (*(u_int32_t*) (base + ZSC_DATA)) & 0xff;
+}
+
+static void
+zs_put_data(caddr_t base, int v)
+{
+ *(u_int32_t*) (base + ZSC_DATA) = v;
+ alpha_mb();
+}
+
+static int
+zs_getc(caddr_t base)
+{
+ while (!(zs_get_status(base) & 1))
+ DELAY(5);
+ return zs_get_data(base);
+}
+
+static void
+zs_putc(caddr_t base, int c)
+{
+ while (!(zs_get_status(base) & 4))
+ DELAY(5);
+ zs_put_data(base, c);
+}
+
+extern struct consdev* cn_tab;
+
+int
+zs_cnattach(vm_offset_t base, vm_offset_t offset)
+{
+ zs_console_addr = (caddr_t) ALPHA_PHYS_TO_K0SEG(base + offset);
+ zs_console = 1;
+
+ cn_tab = &zs_cons;
+ return 0;
+}
+
+static int
+zs_cngetc(dev_t dev)
+{
+ int s = spltty();
+ int c = zs_getc(zs_console_addr);
+ splx(s);
+ return c;
+}
+
+static void
+zs_cnputc(dev_t dev, int c)
+{
+ int s = spltty();
+ zs_putc(zs_console_addr, c);
+ splx(s);
+}
+
+static void
+zs_cnpollc(dev_t dev, int onoff)
+{
+}
+
+
+static int
+zsopen(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct zs_softc* sc = ZS_SOFTC(minor(dev));
+ struct tty *tp;
+ int s;
+ int error = 0;
+
+ if (!sc)
+ return ENXIO;
+
+ s = spltty();
+
+ tp = &sc->tty;
+
+ tp->t_oproc = zsstart;
+ tp->t_param = zsparam;
+ tp->t_dev = dev;
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_CARR_ON;
+ ttychars(tp);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = 9600;
+ ttsetwater(tp);
+ } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return EBUSY;
+ }
+
+ splx(s);
+
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+
+ return error;
+}
+
+static int
+zsclose(dev_t dev, int flag, int mode, struct proc *p)
+{
+ struct tty *tp = &ZS_SOFTC(minor(dev))->tty;
+
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+ return 0;
+}
+
+static int
+zsread(dev_t dev, struct uio *uio, int flag)
+{
+ struct tty *tp = &ZS_SOFTC(minor(dev))->tty;
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+static int
+zswrite(dev_t dev, struct uio *uio, int flag)
+{
+ struct tty *tp = &ZS_SOFTC(minor(dev))->tty;
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+static int
+zsioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct tty *tp = &ZS_SOFTC(minor(dev))->tty;
+ int error;
+
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error != ENOIOCTL)
+ return error;
+ error = ttioctl(tp, cmd, data, flag);
+ if (error != ENOIOCTL)
+ return error;
+
+ return ENOTTY;
+}
+
+static int
+zsparam(struct tty *tp, struct termios *t)
+{
+
+ return 0;
+}
+
+static void
+zsstart(struct tty *tp)
+{
+ struct zs_softc* sc = (struct zs_softc*) tp;
+ int s;
+
+ s = spltty();
+
+ if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
+ ttwwakeup(tp);
+ splx(s);
+ return;
+ }
+
+ tp->t_state |= TS_BUSY;
+ while (tp->t_outq.c_cc != 0)
+ zs_putc(sc->base, getc(&tp->t_outq));
+ tp->t_state &= ~TS_BUSY;
+
+ ttwwakeup(tp);
+ splx(s);
+}
+
+/*
+ * Stop output on a line.
+ */
+static void
+zsstop(struct tty *tp, int flag)
+{
+ int s;
+
+ s = spltty();
+ if (tp->t_state & TS_BUSY)
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ splx(s);
+}
+
+static struct tty *
+zsdevtotty(dev_t dev)
+{
+ struct zs_softc* sc = ZS_SOFTC(minor(dev));
+ if (!sc)
+ return (NULL);
+ return (&sc->tty);
+}
+
+CDEV_DRIVER_MODULE(zs, zsc, zs_driver, zs_devclass,
+ CDEV_MAJOR, zs_cdevsw, 0, 0);
+
+/*
+ * The zsc bus holds two zs devices, one for channel A, one for channel B.
+ */
+
+struct zsc_softc {
+ struct bus bus;
+ caddr_t base;
+ struct zs_softc* sc_a;
+ struct zs_softc* sc_b;
+};
+
+static driver_probe_t zsc_tlsb_probe;
+static driver_attach_t zsc_tlsb_attach;
+static driver_intr_t zsc_tlsb_intr;
+static bus_print_device_t zsc_tlsb_print_device;
+
+driver_t zsc_tlsb_driver = {
+ "zsc",
+ zsc_tlsb_probe,
+ zsc_tlsb_attach,
+ NULL,
+ NULL,
+ DRIVER_TYPE_MISC,
+ sizeof(struct zsc_softc),
+ NULL,
+};
+
+
+static bus_ops_t zsc_tlsb_ops = {
+ zsc_tlsb_print_device,
+ null_read_ivar,
+ null_write_ivar,
+ null_map_intr,
+};
+
+static int
+zsc_get_channel(device_t dev)
+{
+ return (long) device_get_ivars(dev);
+}
+
+static caddr_t
+zsc_get_base(device_t dev)
+{
+ device_t busdev = bus_get_device(device_get_parent(dev));
+ struct zsc_softc* sc = device_get_softc(busdev);
+ return sc->base;
+}
+
+static void
+zsc_tlsb_print_device(bus_t bus, device_t dev)
+{
+ device_t busdev = bus_get_device(bus);
+
+ printf(" at %s%d channel %c",
+ device_get_name(busdev), device_get_unit(busdev),
+ 'A' + (device_get_unit(dev) & 1));
+}
+
+static int
+zsc_tlsb_probe(bus_t parent, device_t dev)
+{
+ struct zsc_softc* sc = device_get_softc(dev);
+
+ device_set_desc(dev, "Z8530 uart");
+
+ bus_init(&sc->bus, dev, &zsc_tlsb_ops);
+
+ sc->base = (caddr_t) ALPHA_PHYS_TO_K0SEG(TLSB_GBUS_BASE
+ + gbus_get_offset(dev));
+
+ /*
+ * Add channel A for now.
+ */
+ bus_add_device(&sc->bus, "zs", -1, (void*) 0);
+
+ return 0;
+}
+
+static int
+zsc_tlsb_attach(bus_t parent, device_t dev)
+{
+ struct zsc_softc* sc = device_get_softc(dev);
+
+ bus_generic_attach(parent, dev);
+
+ /* XXX */
+ sc->sc_a = ZS_SOFTC(0);
+
+ bus_map_intr(parent, dev, zsc_tlsb_intr, sc);
+
+ return 0;
+}
+
+
+static void
+zsc_tlsb_intr(void* arg)
+{
+ struct zsc_softc* sc = arg;
+ caddr_t base = sc->base;
+
+ /* XXX only allow for zs0 at zsc0 */
+ int rr3 = zs_get_rr3(base);
+ if (rr3 & 0x20) {
+ struct tty* tp = &sc->sc_a->tty;
+ int c;
+
+ while (zs_get_status(base) & 1) {
+ c = zs_get_data(base);
+#ifdef DDB
+ if (c == CTRL('\\'))
+ Debugger("manual escape to debugger");
+#endif
+ if (tp->t_state & TS_ISOPEN)
+ (*linesw[tp->t_line].l_rint)(c, tp);
+ DELAY(5);
+ }
+ }
+}
+
+DRIVER_MODULE(zsc_tlsb, gbus, zsc_tlsb_driver, zsc_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/zsreg.h b/sys/alpha/tlsb/zsreg.h
new file mode 100644
index 0000000..68e567d
--- /dev/null
+++ b/sys/alpha/tlsb/zsreg.h
@@ -0,0 +1,30 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * 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 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+#define ZSC_STATUS 0x80
+#define ZSC_DATA 0xc0
OpenPOWER on IntegriCloud