summaryrefslogtreecommitdiffstats
path: root/sys/alpha/pci
diff options
context:
space:
mode:
authorgallatin <gallatin@FreeBSD.org>2000-05-28 02:52:54 +0000
committergallatin <gallatin@FreeBSD.org>2000-05-28 02:52:54 +0000
commit8baedda6af2ad29558fc1f25013bd148b4d488f0 (patch)
treecf76a38da402f4b41fd903ea6456290aeeff83ed /sys/alpha/pci
parent11726c37b143029cf62f48d93100f88af3039ca5 (diff)
downloadFreeBSD-src-8baedda6af2ad29558fc1f25013bd148b4d488f0.zip
FreeBSD-src-8baedda6af2ad29558fc1f25013bd148b4d488f0.tar.gz
Add AlphaServer 2000 (demi-sable), 2100 (sable), and 2100A (lynx) support.
Only PCI and on-board ISA peripherials are supported at this time. This support has been only lightly tested due to a lack of response to my call for testers on the freebsd-alpha mailing list. It works quite well on the one AS2100 on which it has been tested, but it may not work on an AS2100A and should therefore be regarded as experimental.
Diffstat (limited to 'sys/alpha/pci')
-rw-r--r--sys/alpha/pci/t2.c658
-rw-r--r--sys/alpha/pci/t2_pci.c87
-rw-r--r--sys/alpha/pci/t2reg.h172
3 files changed, 917 insertions, 0 deletions
diff --git a/sys/alpha/pci/t2.c b/sys/alpha/pci/t2.c
new file mode 100644
index 0000000..554fc48
--- /dev/null
+++ b/sys/alpha/pci/t2.c
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2000 Andrew Gallatin & 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * T2 CBUS to PCI bridge
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <alpha/pci/t2reg.h>
+#include <alpha/pci/t2var.h>
+#include <alpha/pci/pcibus.h>
+#include <alpha/isa/isavar.h>
+#include <machine/intr.h>
+#include <machine/resource.h>
+#include <machine/intrcnt.h>
+#include <machine/cpuconf.h>
+#include <machine/swiz.h>
+#include <machine/sgmap.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa + t2_csr_base)
+
+vm_offset_t t2_csr_base = 0UL;
+
+static devclass_t t2_devclass;
+static device_t t2_0; /* XXX only one for now */
+
+struct t2_softc {
+ int junk;
+};
+
+#define T2_SOFTC(dev) (struct t2_softc*) device_get_softc(dev)
+
+static alpha_chipset_inb_t t2_inb;
+static alpha_chipset_inw_t t2_inw;
+static alpha_chipset_inl_t t2_inl;
+static alpha_chipset_outb_t t2_outb;
+static alpha_chipset_outw_t t2_outw;
+static alpha_chipset_outl_t t2_outl;
+static alpha_chipset_readb_t t2_readb;
+static alpha_chipset_readw_t t2_readw;
+static alpha_chipset_readl_t t2_readl;
+static alpha_chipset_writeb_t t2_writeb;
+static alpha_chipset_writew_t t2_writew;
+static alpha_chipset_writel_t t2_writel;
+static alpha_chipset_maxdevs_t t2_maxdevs;
+static alpha_chipset_cfgreadb_t t2_cfgreadb;
+static alpha_chipset_cfgreadw_t t2_cfgreadw;
+static alpha_chipset_cfgreadl_t t2_cfgreadl;
+static alpha_chipset_cfgwriteb_t t2_cfgwriteb;
+static alpha_chipset_cfgwritew_t t2_cfgwritew;
+static alpha_chipset_cfgwritel_t t2_cfgwritel;
+static alpha_chipset_addrcvt_t t2_cvt_dense;
+static alpha_chipset_read_hae_t t2_read_hae;
+static alpha_chipset_write_hae_t t2_write_hae;
+
+static alpha_chipset_t t2_chipset = {
+ t2_inb,
+ t2_inw,
+ t2_inl,
+ t2_outb,
+ t2_outw,
+ t2_outl,
+ t2_readb,
+ t2_readw,
+ t2_readl,
+ t2_writeb,
+ t2_writew,
+ t2_writel,
+ t2_maxdevs,
+ t2_cfgreadb,
+ t2_cfgreadw,
+ t2_cfgreadl,
+ t2_cfgwriteb,
+ t2_cfgwritew,
+ t2_cfgwritel,
+ t2_cvt_dense,
+ NULL,
+ t2_read_hae,
+ t2_write_hae,
+};
+
+static u_int8_t
+t2_inb(u_int32_t port)
+{
+ alpha_mb();
+ return SPARSE_READ_BYTE(KV(T2_PCI_SIO), port);
+}
+
+static u_int16_t
+t2_inw(u_int32_t port)
+{
+ alpha_mb();
+ return SPARSE_READ_WORD(KV(T2_PCI_SIO), port);
+}
+
+static u_int32_t
+t2_inl(u_int32_t port)
+{
+ alpha_mb();
+ return SPARSE_READ_LONG(KV(T2_PCI_SIO), port);
+}
+
+static void
+t2_outb(u_int32_t port, u_int8_t data)
+{
+ SPARSE_WRITE_BYTE(KV(T2_PCI_SIO), port, data);
+ alpha_wmb();
+}
+
+static void
+t2_outw(u_int32_t port, u_int16_t data)
+{
+ SPARSE_WRITE_WORD(KV(T2_PCI_SIO), port, data);
+ alpha_wmb();
+}
+
+static void
+t2_outl(u_int32_t port, u_int32_t data)
+{
+ SPARSE_WRITE_LONG(KV(T2_PCI_SIO), port, data);
+ alpha_wmb();
+}
+
+static u_int32_t t2_hae_mem;
+
+#define REG1 (1UL << 24)
+
+static __inline void
+t2_set_hae_mem(u_int32_t *pa)
+{
+ int s;
+ u_int32_t msb;
+
+ if(*pa >= REG1){
+ msb = *pa & 0xf8000000;
+ *pa -= msb;
+ msb >>= 27; /* t2 puts high bits in the bottom of the register */
+ s = splhigh();
+ if (msb != t2_hae_mem) {
+ t2_hae_mem = msb;
+ REGVAL(T2_HAE0_1) = t2_hae_mem;
+ alpha_mb();
+ t2_hae_mem = REGVAL(T2_HAE0_1);
+ }
+ splx(s);
+ }
+}
+
+static u_int8_t
+t2_readb(u_int32_t pa)
+{
+ alpha_mb();
+ t2_set_hae_mem(&pa);
+ return SPARSE_READ_BYTE(KV(T2_PCI_SPARSE), pa);
+}
+
+static u_int16_t
+t2_readw(u_int32_t pa)
+{
+ alpha_mb();
+ t2_set_hae_mem(&pa);
+ return SPARSE_READ_WORD(KV(T2_PCI_SPARSE), pa);
+}
+
+static u_int32_t
+t2_readl(u_int32_t pa)
+{
+ alpha_mb();
+ t2_set_hae_mem(&pa);
+ return SPARSE_READ_LONG(KV(T2_PCI_SPARSE), pa);
+}
+
+static void
+t2_writeb(u_int32_t pa, u_int8_t data)
+{
+ t2_set_hae_mem(&pa);
+ SPARSE_WRITE_BYTE(KV(T2_PCI_SPARSE), pa, data);
+ alpha_wmb();
+}
+
+static void
+t2_writew(u_int32_t pa, u_int16_t data)
+{
+ t2_set_hae_mem(&pa);
+ SPARSE_WRITE_WORD(KV(T2_PCI_SPARSE), pa, data);
+ alpha_wmb();
+}
+
+static void
+t2_writel(u_int32_t pa, u_int32_t data)
+{
+ t2_set_hae_mem(&pa);
+ SPARSE_WRITE_LONG(KV(T2_PCI_SPARSE), pa, data);
+ alpha_wmb();
+}
+
+static int
+t2_maxdevs(u_int b)
+{
+ return 12; /* XXX */
+}
+
+
+
+/* XXX config space access? */
+
+static vm_offset_t
+t2_cvt_dense(vm_offset_t addr)
+{
+ addr &= 0xffffffffUL;
+ return (addr | T2_PCI_DENSE);
+
+}
+
+static u_int64_t
+t2_read_hae(void)
+{
+ return t2_hae_mem << 27;
+}
+
+static void
+t2_write_hae(u_int64_t hae)
+{
+ u_int32_t pa = hae;
+ t2_set_hae_mem(&pa);
+}
+
+#define T2_CFGOFF(b, s, f, r) \
+ ((b) ? (((b) << 16) | ((s) << 11) | ((f) << 8) | (r)) \
+ : ((1 << ((s) + 11)) | ((f) << 8) | (r)))
+
+#define T2_TYPE1_SETUP(b,s,old_hae3) if((b)) { \
+ do { \
+ (s) = splhigh(); \
+ (old_hae3) = REGVAL(T2_HAE0_3); \
+ alpha_mb(); \
+ REGVAL(T2_HAE0_3) = (old_hae3) | (1<<30); \
+ alpha_mb(); \
+ } while(0); \
+}
+
+#define T2_TYPE1_TEARDOWN(b,s,old_hae3) if((b)) { \
+ do { \
+ alpha_mb(); \
+ REGVAL(T2_HAE0_3) = (old_hae3); \
+ alpha_mb(); \
+ splx((s)); \
+ } while(0); \
+}
+
+#define SWIZ_CFGREAD(b, s, f, r, width, type) \
+ type val = ~0; \
+ int ipl = 0; \
+ u_int32_t old_hae3 = 0; \
+ vm_offset_t off = T2_CFGOFF(b, s, f, r); \
+ vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(T2_PCI_CONF), off); \
+ alpha_mb(); \
+ T2_TYPE1_SETUP(b,ipl,old_hae3); \
+ if (!badaddr((caddr_t)kv, sizeof(type))) { \
+ val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
+ } \
+ T2_TYPE1_TEARDOWN(b,ipl,old_hae3); \
+ return val;
+
+#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) \
+ int ipl = 0; \
+ u_int32_t old_hae3 = 0; \
+ vm_offset_t off = T2_CFGOFF(b, s, f, r); \
+ vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(T2_PCI_CONF), off); \
+ alpha_mb(); \
+ T2_TYPE1_SETUP(b,ipl,old_hae3); \
+ if (!badaddr((caddr_t)kv, sizeof(type))) { \
+ SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \
+ alpha_wmb(); \
+ } \
+ T2_TYPE1_TEARDOWN(b,ipl,old_hae3); \
+ return;
+
+static u_int8_t
+t2_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
+{
+ SWIZ_CFGREAD(b, s, f, r, BYTE, u_int8_t);
+}
+
+static u_int16_t
+t2_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
+{
+ SWIZ_CFGREAD(b, s, f, r, WORD, u_int16_t);
+}
+
+static u_int32_t
+t2_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
+{
+ SWIZ_CFGREAD(b, s, f, r, LONG, u_int32_t);
+}
+
+static void
+t2_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
+{
+ SWIZ_CFGWRITE(b, s, f, r, data, BYTE, u_int8_t);
+}
+
+static void
+t2_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
+{
+ SWIZ_CFGWRITE(b, s, f, r, data, WORD, u_int16_t);
+}
+
+static void
+t2_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
+{
+ SWIZ_CFGWRITE(b, s, f, r, data, LONG, u_int32_t);
+}
+
+static int t2_probe(device_t dev);
+static int t2_attach(device_t dev);
+static int t2_setup_intr(device_t dev, device_t child,
+ struct resource *irq, int flags,
+ void *intr, void *arg, void **cookiep);
+static int t2_teardown_intr(device_t dev, device_t child,
+ struct resource *irq, void *cookie);
+static void
+t2_dispatch_intr(void *frame, unsigned long vector);
+static void
+t2_machine_check(unsigned long mces, struct trapframe *framep,
+ unsigned long vector, unsigned long param);
+
+
+static device_method_t t2_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, t2_probe),
+ DEVMETHOD(device_attach, t2_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
+ DEVMETHOD(bus_release_resource, pci_release_resource),
+ DEVMETHOD(bus_activate_resource, pci_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, t2_setup_intr),
+ DEVMETHOD(bus_teardown_intr, t2_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t t2_driver = {
+ "t2",
+ t2_methods,
+ sizeof(struct t2_softc),
+};
+
+
+#define T2_SGMAP_BASE (8*1024*1024)
+#define T2_SGMAP_SIZE (8*1024*1024)
+
+static void
+t2_sgmap_invalidate(void)
+{
+ u_int64_t val;
+
+ alpha_mb();
+ val = REGVAL64(T2_IOCSR);
+ val |= T2_IOCSRL_ITLB;
+ REGVAL64(T2_IOCSR) = val;
+ alpha_mb();
+ alpha_mb();
+ val = REGVAL64(T2_IOCSR);
+ val &= ~T2_IOCSRL_ITLB;
+ REGVAL64(T2_IOCSR) = val;
+ alpha_mb();
+ alpha_mb();
+}
+
+static void
+t2_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa)
+{
+ u_int64_t *sgtable = arg;
+ int index = alpha_btop(ba - T2_SGMAP_BASE);
+
+ if (pa) {
+ if (pa > (1L<<32))
+ panic("t2_sgmap_map: can't map address 0x%lx", pa);
+ sgtable[index] = ((pa >> 13) << 1) | 1;
+ } else {
+ sgtable[index] = 0;
+ }
+ alpha_mb();
+ t2_sgmap_invalidate();
+}
+
+
+static void
+t2_init_sgmap(void)
+{
+ void *sgtable;
+
+ /*
+ * First setup Window 2 to map 8Mb to 16Mb with an
+ * sgmap. Allocate the map aligned to a 32 boundary.
+ *
+ * bits 31..20 of WBASE represent the pci start address
+ * (in units of 1Mb), and bits 11..0 represent the pci
+ * end address
+ */
+ REGVAL(T2_WBASE2) = T2_WSIZE_8M|T2_WINDOW_ENABLE|T2_WINDOW_SG
+ | ((T2_SGMAP_BASE >> 20) << 20)
+ | ((T2_SGMAP_BASE + T2_SGMAP_SIZE) >> 20);
+ REGVAL(T2_WMASK2) = T2_WMASK_8M;
+ alpha_mb();
+
+ sgtable = contigmalloc(8192, M_DEVBUF, M_NOWAIT,
+ 0, (1L<<34),
+ 32*1024, (1L<<34));
+ if (!sgtable)
+ panic("t2_init_sgmap: can't allocate page table");
+
+ REGVAL(T2_TBASE2) =
+ (pmap_kextract((vm_offset_t) sgtable) >> T2_TBASE_SHIFT);
+
+ chipset.sgmap = sgmap_map_create(T2_SGMAP_BASE,
+ T2_SGMAP_BASE + T2_SGMAP_SIZE,
+ t2_sgmap_map, sgtable);
+}
+
+/*
+ * Perform basic chipset init/fixup. Called by various early
+ * consumers to ensure that the system will work before the
+ * bus methods are invoked.
+ *
+ */
+
+void
+t2_init()
+{
+ static int initted = 0;
+
+ if (initted) return;
+ initted = 1;
+
+ chipset = t2_chipset;
+}
+
+static int
+t2_probe(device_t dev)
+{
+ device_t child;
+
+ if (t2_0)
+ return ENXIO;
+ t2_0 = dev;
+ device_set_desc(dev, "T2 Core Logic chipset");
+
+ pci_init_resources();
+
+ /*
+ * initialize the DMA windows
+ */
+
+ REGVAL(T2_WBASE1) = T2_WSIZE_1G|T2_WINDOW_ENABLE|T2_WINDOW_DIRECT|0x7ff;
+ REGVAL(T2_WMASK1) = T2_WMASK_1G;
+ REGVAL(T2_TBASE1) = 0;
+
+ REGVAL(T2_WBASE2) = 0x0;
+
+
+ /*
+ * enable the PCI "Hole" for ISA devices which use memory in
+ * the 512k - 1MB range
+ */
+ REGVAL(T2_HBASE) = 1 << 13;
+ t2_init_sgmap();
+
+
+ /* initialize the HAEs */
+ REGVAL(T2_HAE0_1) = 0x0;
+ alpha_mb();
+ REGVAL(T2_HAE0_2) = 0x0;
+ alpha_mb();
+ REGVAL(T2_HAE0_3) = 0x0;
+ alpha_mb();
+
+ child = device_add_child(dev, "pcib", 0);
+ device_set_ivars(child, 0);
+
+ return 0;
+}
+
+static int
+t2_attach(device_t dev)
+{
+ t2_init();
+
+ platform.mcheck_handler = t2_machine_check;
+ set_iointr(t2_dispatch_intr);
+ platform.isa_setup_intr = t2_setup_intr;
+ platform.isa_teardown_intr = t2_teardown_intr;
+
+ snprintf(chipset_type, sizeof(chipset_type), "t2");
+
+ bus_generic_attach(dev);
+
+ return 0;
+}
+
+/*
+ * magical mystery table partly obtained from Linux
+ * at least some of their values for PCI masks
+ * were incorrect, and I've filled in my own extrapolations
+ * XXX this needs more testers
+ */
+
+unsigned long t2_shadow_mask = -1L;
+static const char irq_to_mask[40] = {
+ -1, 6, -1, 8, 15, 12, 7, 9, /* ISA 0-7 */
+ -1, 16, 17, 18, 3, -1, 21, 22, /* ISA 8-15 */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* ?? EISA XXX */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* ?? EISA XXX */
+ 0, 1, 2, 3, 4, 5, 6, 7 /* PCI 0-7 XXX */
+};
+
+static int
+t2_setup_intr(device_t dev, device_t child,
+ struct resource *irq, int flags,
+ void *intr, void *arg, void **cookiep)
+{
+ int error, mask, vector;
+
+ mask = irq_to_mask[irq->r_start];
+ vector = 0x800 + (mask << 4);
+
+ error = rman_activate_resource(irq);
+ if (error)
+ return error;
+
+ error = alpha_setup_intr(vector,
+ intr, arg, cookiep,
+ &intrcnt[irq->r_start]);
+ if (error)
+ return error;
+
+ /* Enable interrupt */
+
+ t2_shadow_mask &= ~(1UL << mask);
+
+ if (mask <= 7)
+ outb(SLAVE0_ICU, t2_shadow_mask);
+ else if (mask <= 15)
+ outb(SLAVE1_ICU, t2_shadow_mask >> 8);
+ else
+ outb(SLAVE2_ICU, t2_shadow_mask >> 16);
+
+ device_printf(child, "interrupting at T2 irq %d\n",
+ (int) irq->r_start);
+
+ return 0;
+}
+
+static int
+t2_teardown_intr(device_t dev, device_t child,
+ struct resource *irq, void *cookie)
+{
+ int mask;
+
+ mask = irq_to_mask[irq->r_start];
+
+ /* Disable interrupt */
+
+ t2_shadow_mask |= (1UL << mask);
+
+ if (mask <= 7)
+ outb(SLAVE0_ICU, t2_shadow_mask);
+ else if (mask <= 15)
+ outb(SLAVE1_ICU, t2_shadow_mask >> 8);
+ else
+ outb(SLAVE2_ICU, t2_shadow_mask >> 16);
+
+ alpha_teardown_intr(cookie);
+ return rman_deactivate_resource(irq);
+}
+
+static void
+t2_ack_intr(unsigned long vector)
+{
+ int mask = (vector - 0x800) >> 4;
+
+ switch (mask) {
+ case 0 ... 7:
+ outb(SLAVE0_ICU-1, (0xe0 | (mask)));
+ outb(MASTER_ICU-1, (0xe0 | 1));
+ break;
+ case 8 ... 15:
+ outb(SLAVE1_ICU-1, (0xe0 | (mask - 8)));
+ outb(MASTER_ICU-1, (0xe0 | 3));
+ break;
+ case 16 ... 24:
+ outb(SLAVE2_ICU-1, (0xe0 | (mask - 16)));
+ outb(MASTER_ICU-1, (0xe0 | 4));
+ break;
+ }
+}
+
+
+static void
+t2_dispatch_intr(void *frame, unsigned long vector)
+{
+ alpha_dispatch_intr(frame, vector);
+ t2_ack_intr(vector);
+}
+
+static void
+t2_machine_check(unsigned long mces, struct trapframe *framep,
+ unsigned long vector, unsigned long param)
+{
+ int expected;
+
+ expected = mc_expected;
+ machine_check(mces, framep, vector, param);
+ /* for some reason the alpha_pal_wrmces() doesn't clear all
+ pending machine checks & we may take another */
+ mc_expected = expected;
+}
+
+DRIVER_MODULE(t2, root, t2_driver, t2_devclass, 0, 0);
diff --git a/sys/alpha/pci/t2_pci.c b/sys/alpha/pci/t2_pci.c
new file mode 100644
index 0000000..2213bb3
--- /dev/null
+++ b/sys/alpha/pci/t2_pci.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2000 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, SPELCAL, 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <pci/pcivar.h>
+
+static devclass_t pcib_devclass;
+
+static int
+t2_pcib_probe(device_t dev)
+{
+ device_t child;
+
+ device_set_desc(dev, "T2 PCI host bus adapter");
+
+ child = device_add_child(dev, "pci", 0);
+ device_set_ivars(child, 0);
+
+ return 0;
+}
+
+static int
+t2_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
+{
+ if (which == PCIB_IVAR_HOSE) {
+ *result = 0;
+ return 0;
+ }
+ return ENOENT;
+}
+
+static device_method_t t2_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, t2_pcib_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_read_ivar, t2_pcib_read_ivar),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t t2_pcib_driver = {
+ "pcib",
+ t2_pcib_methods,
+ 1,
+};
+
+DRIVER_MODULE(pcib, t2, t2_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/alpha/pci/t2reg.h b/sys/alpha/pci/t2reg.h
new file mode 100644
index 0000000..339c4e1
--- /dev/null
+++ b/sys/alpha/pci/t2reg.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2000 Doug Rabson & Andrew Gallatin
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+
+
+/*
+ * Registers in the T2 CBUS-to-PCI bridge as used in the SABLE
+ * systems.
+ */
+
+#define REGVAL(r) (*(volatile int32_t *) \
+ ALPHA_PHYS_TO_K0SEG(r + t2_csr_base))
+#define REGVAL64(r) (*(volatile int64_t *) \
+ ALPHA_PHYS_TO_K0SEG(r + t2_csr_base))
+
+#define SABLE_BASE 0x0UL /* offset of SABLE CSRs */
+#define LYNX_BASE 0x8000000000UL /* offset of LYNX CSRs */
+
+#define CBUS_BASE 0x380000000 /* CBUS CSRs */
+#define T2_PCI_SIO 0x3a0000000 /* PCI sparse I/O space */
+#define T2_PCI_CONF 0x390000000 /* PCI configuration space */
+#define T2_PCI_SPARSE 0x200000000 /* PCI sparse memory space */
+#define T2_PCI_DENSE 0x3c0000000 /* PCI dense memory space */
+
+#define T2_IOCSR (CBUS_BASE + 0xe000000)
+ /* Low word */
+#define T2_IOCSRL_EL 0x00000002UL /* loopback enable */
+#define T2_IOCSRL_ESMV 0x00000004UL /* enable state machine visibility */
+#define T2_IOCSRL_PDBP 0x00000008UL /* PCI drive bad parity */
+#define T2_IOCSRL_SLOT0 0x00000030UL /* PCI slot 0 present bits */
+#define T2_IOCSRL_PINT 0x00000040UL /* PCI interrupt */
+#define T2_IOCSRL_ENTLBEC 0x00000080UL /* enable TLB error check */
+#define T2_IOCSRL_ENCCDMA 0x00000100UL /* enable CXACK for DMA */
+#define T2_IOCSRL_ENXXCHG 0x00000400UL /* enable exclusive exchange for EV5 */
+#define T2_IOCSRL_CAWWP0 0x00001000UL /* CBUS command/address write wrong parity 0 */
+#define T2_IOCSRL_CAWWP2 0x00002000UL /* CBUS command/address write wrong parity 2 */
+#define T2_IOCSRL_CDWWPE 0x00004000UL /* CBUS data write wrong parity even */
+#define T2_IOCSRL_SLOT2 0x00008000UL /* PCI slot 2 present bit */
+#define T2_IOCSRL_PSERR 0x00010000UL /* power supply error */
+#define T2_IOCSRL_MBA7 0x00020000UL /* MBA7 asserted */
+#define T2_IOCSRL_SLOT1 0x000c0000UL /* PCI slot 1 present bits */
+#define T2_IOCSRL_PDWWP1 0x00100000UL /* PCI DMA write wrong parity HW1 */
+#define T2_IOCSRL_PDWWP0 0x00200000UL /* PCI DMA write wrong parity HW0 */
+#define T2_IOCSRL_PBR 0x00400000UL /* PCI bus reset */
+#define T2_IOCSRL_PIR 0x00800000UL /* PCI interface reset */
+#define T2_IOCSRL_ENCOI 0x01000000UL /* enable NOACK, CUCERR and out-of-sync int */
+#define T2_IOCSRL_EPMS 0x02000000UL /* enable PCI memory space */
+#define T2_IOCSRL_ETLB 0x04000000UL /* enable TLB */
+#define T2_IOCSRL_EACC 0x08000000UL /* enable atomic CBUS cycles */
+#define T2_IOCSRL_ITLB 0x10000000UL /* flush TLB */
+#define T2_IOCSRL_ECPC 0x20000000UL /* enable CBUS parity check */
+#define T2_IOCSRL_CIR 0x40000000UL /* CBUS interface reset */
+#define T2_IOCSRL_EPL 0x80000000UL /* enable PCI lock */
+ /* High word */
+#define T2_IOCSRH_CBBCE 0x00000001UL /* CBUS back-to-back cycle enable */
+#define T2_IOCSRH_TM 0x0000000eUL /* T2 revision number */
+#define T2_IOCSRH_SMVL 0x00000070UL /* state machine visibility select */
+#define T2_IOCSRH_SLOT2 0x00000080UL /* PCI slot 2 present bit */
+#define T2_IOCSRH_EPR 0x00000100UL /* enable passive release */
+#define T2_IOCSRH_CAWWP1 0x00001000UL /* cbus command/address write wrong parity 1 */
+#define T2_IOCSRH_CAWWP3 0x00002000UL /* cbus command/address write wrong parity 3 */
+#define T2_IOCSRH_DWWPO 0x00004000UL /* CBUS data write wrong parity odd */
+#define T2_IOCSRH_PRM 0x00100000UL /* PCI read multiple */
+#define T2_IOCSRH_PWM 0x00200000UL /* PCI write multiple */
+#define T2_IOCSRH_FPRDPED 0x00400000UL /* force PCI RDPE detect */
+#define T2_IOCSRH_PFAPED 0x00800000UL /* force PCI APE detect */
+#define T2_IOCSRH_FPWDPED 0x01000000UL /* force PCI WDPE detect */
+#define T2_IOCSRH_EPNMI 0x02000000UL /* enable PCI NMI */
+#define T2_IOCSRH_EPDTI 0x04000000UL /* enable PCI DTI */
+#define T2_IOCSRH_EPSEI 0x08000000UL /* enable PCI SERR interrupt */
+#define T2_IOCSRH_EPPEI 0x10000000UL /* enable PCI PERR interrupt */
+#define T2_IOCSRH_ERDPC 0x20000000UL /* enable PCI RDP interrupt */
+#define T2_IOCSRH_EADPC 0x40000000UL /* enable PCI AP interrupt */
+#define T2_IOCSRH_EWDPC 0x80000000UL /* enable PCI WDP interrupt */
+
+#define T2_CERR1 (CBUS_BASE + 0xe000020)
+#define T2_CERR2 (CBUS_BASE + 0xe000040)
+#define T2_CERR3 (CBUS_BASE + 0xe000060)
+#define T2_PERR1 (CBUS_BASE + 0xe000080)
+#define T2_PERR1_PWDPE 0x00000001 /* PCI write data parity error */
+#define T2_PERR1_PAPE 0x00000002 /* PCI address parity error */
+#define T2_PERR1_PRDPE 0x00000004 /* PCI read data parity error */
+#define T2_PERR1_PPE 0x00000008 /* PCI parity error */
+#define T2_PERR1_PSE 0x00000010 /* PCI system error */
+#define T2_PERR1_PDTE 0x00000020 /* PCI device timeout error */
+#define T2_PERR1_NMI 0x00000040 /* PCI NMI */
+
+#define T2_PERR2 (CBUS_BASE + 0xe0000a0)
+#define T2_PSCR (CBUS_BASE + 0xe0000c0)
+#define T2_HAE0_1 (CBUS_BASE + 0xe0000e0)
+#define T2_HAE0_2 (CBUS_BASE + 0xe000100)
+#define T2_HBASE (CBUS_BASE + 0xe000120)
+#define T2_WBASE1 (CBUS_BASE + 0xe000140)
+#define T2_WMASK1 (CBUS_BASE + 0xe000160)
+#define T2_TBASE1 (CBUS_BASE + 0xe000180)
+#define T2_WBASE2 (CBUS_BASE + 0xe0001a0)
+#define T2_WMASK2 (CBUS_BASE + 0xe0001c0)
+#define T2_TBASE2 (CBUS_BASE + 0xe0001e0)
+#define T2_TLBBR (CBUS_BASE + 0xe000200)
+#define T2_HAE0_3 (CBUS_BASE + 0xe000240)
+#define T2_HAE0_4 (CBUS_BASE + 0xe000280)
+
+/*
+ * DMA window constants, section 5.2.1.1.1 of the
+ * Sable I/O Specification
+ */
+
+#define T2_WINDOW_ENABLE 0x00080000
+#define T2_WINDOW_DISABLE 0x00000000
+#define T2_WINDOW_SG 0x00040000
+#define T2_WINDOW_DIRECT 0x00000000
+
+#define T2_WMASK_2G 0x7ff00000
+#define T2_WMASK_1G 0x3ff00000
+#define T2_WMASK_512M 0x1ff00000
+#define T2_WMASK_256M 0x0ff00000
+#define T2_WMASK_128M 0x07f00000
+#define T2_WMASK_64M 0x03f00000
+#define T2_WMASK_32M 0x01f00000
+#define T2_WMASK_16M 0x00f00000
+#define T2_WMASK_8M 0x00700000
+#define T2_WMASK_4M 0x00300000
+#define T2_WMASK_2M 0x00100000
+#define T2_WMASK_1M 0x00000000
+
+
+#define T2_WSIZE_2G 0x80000000
+#define T2_WSIZE_1G 0x40000000
+#define T2_WSIZE_512M 0x20000000
+#define T2_WSIZE_256M 0x10000000
+#define T2_WSIZE_128M 0x08000000
+#define T2_WSIZE_64M 0x04000000
+#define T2_WSIZE_32M 0x02000000
+#define T2_WSIZE_16M 0x01000000
+#define T2_WSIZE_8M 0x00800000
+#define T2_WSIZE_4M 0x00400000
+#define T2_WSIZE_2M 0x00200000
+#define T2_WSIZE_1M 0x00100000
+#define T2_WSIZE_0M 0x00000000
+
+#define T2_TBASE_SHIFT 1
+
+#define MASTER_ICU 0x535
+#define SLAVE0_ICU 0x537
+#define SLAVE1_ICU 0x53b
+#define SLAVE2_ICU 0x53d
+#define SLAVE3_ICU 0x53f
OpenPOWER on IntegriCloud