summaryrefslogtreecommitdiffstats
path: root/sys/alpha/pci
diff options
context:
space:
mode:
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