summaryrefslogtreecommitdiffstats
path: root/sys/alpha/pci
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2000-08-28 21:48:13 +0000
committerdfr <dfr@FreeBSD.org>2000-08-28 21:48:13 +0000
commitdd8b44b3958fa67d802cbbec7c7d82f7fb476229 (patch)
tree61496c144b3ecd15192a2e07e755754e18346bc9 /sys/alpha/pci
parent9ed8ded4d312c58a27de9402fd9802e78a591cb9 (diff)
downloadFreeBSD-src-dd8b44b3958fa67d802cbbec7c7d82f7fb476229.zip
FreeBSD-src-dd8b44b3958fa67d802cbbec7c7d82f7fb476229.tar.gz
* Completely rewrite the alpha busspace to hide the implementation from
the drivers. * Remove legacy inx/outx support from chipset and replace with macros which call busspace. * Rework pci config accesses to route through the pcib device instead of calling a MD function directly. With these changes it is possible to cleanly support machines which have more than one independantly numbered PCI busses. As a bonus, the new busspace implementation should be measurably faster than the old one.
Diffstat (limited to 'sys/alpha/pci')
-rw-r--r--sys/alpha/pci/alphapci_if.m59
-rw-r--r--sys/alpha/pci/apecs.c325
-rw-r--r--sys/alpha/pci/apecs_pci.c115
-rw-r--r--sys/alpha/pci/apecsvar.h5
-rw-r--r--sys/alpha/pci/bwx.c131
-rw-r--r--sys/alpha/pci/cia.c541
-rw-r--r--sys/alpha/pci/cia_pci.c332
-rw-r--r--sys/alpha/pci/dwlpx_pci.c80
-rw-r--r--sys/alpha/pci/irongate.c255
-rw-r--r--sys/alpha/pci/irongate_pci.c127
-rw-r--r--sys/alpha/pci/lca.c252
-rw-r--r--sys/alpha/pci/lca_pci.c111
-rw-r--r--sys/alpha/pci/lcavar.h4
-rw-r--r--sys/alpha/pci/mcpcia_pci.c80
-rw-r--r--sys/alpha/pci/pcibus.c151
-rw-r--r--sys/alpha/pci/pcibus.h2
-rw-r--r--sys/alpha/pci/swiz.c154
-rw-r--r--sys/alpha/pci/t2.c259
-rw-r--r--sys/alpha/pci/t2_pci.c114
-rw-r--r--sys/alpha/pci/t2var.h2
-rw-r--r--sys/alpha/pci/tsunami.c308
-rw-r--r--sys/alpha/pci/tsunami_pci.c271
22 files changed, 1468 insertions, 2210 deletions
diff --git a/sys/alpha/pci/alphapci_if.m b/sys/alpha/pci/alphapci_if.m
new file mode 100644
index 0000000..1525af9
--- /dev/null
+++ b/sys/alpha/pci/alphapci_if.m
@@ -0,0 +1,59 @@
+#
+# 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, 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$
+#
+
+#include <sys/bus.h>
+#include <alpha/pci/pcibus.h>
+
+INTERFACE alphapci;
+
+CODE {
+ static void *null_cvt(device_t dev, vm_offset_t ba)
+ {
+ return 0;
+ }
+};
+
+METHOD void * cvt_dense {
+ device_t dev;
+ vm_offset_t ba;
+} DEFAULT null_cvt;
+
+METHOD void * cvt_bwx {
+ device_t dev;
+ vm_offset_t ba;
+} DEFAULT null_cvt;
+
+METHOD struct alpha_busspace * get_bustag {
+ device_t dev;
+ int type;
+} DEFAULT pci_get_bustag;
+
+METHOD struct rman * get_rman {
+ device_t dev;
+ int type;
+} DEFAULT pci_get_rman;
diff --git a/sys/alpha/pci/apecs.c b/sys/alpha/pci/apecs.c
index d23df8a..e15aee1 100644
--- a/sys/alpha/pci/apecs.c
+++ b/sys/alpha/pci/apecs.c
@@ -94,105 +94,14 @@ struct apecs_softc {
#define APECS_SOFTC(dev) (struct apecs_softc*) device_get_softc(dev)
-static alpha_chipset_inb_t apecs_swiz_inb;
-static alpha_chipset_inw_t apecs_swiz_inw;
-static alpha_chipset_inl_t apecs_swiz_inl;
-static alpha_chipset_outb_t apecs_swiz_outb;
-static alpha_chipset_outw_t apecs_swiz_outw;
-static alpha_chipset_outl_t apecs_swiz_outl;
-static alpha_chipset_readb_t apecs_swiz_readb;
-static alpha_chipset_readw_t apecs_swiz_readw;
-static alpha_chipset_readl_t apecs_swiz_readl;
-static alpha_chipset_writeb_t apecs_swiz_writeb;
-static alpha_chipset_writew_t apecs_swiz_writew;
-static alpha_chipset_writel_t apecs_swiz_writel;
-static alpha_chipset_maxdevs_t apecs_swiz_maxdevs;
-static alpha_chipset_cfgreadb_t apecs_swiz_cfgreadb;
-static alpha_chipset_cfgreadw_t apecs_swiz_cfgreadw;
-static alpha_chipset_cfgreadl_t apecs_swiz_cfgreadl;
-static alpha_chipset_cfgwriteb_t apecs_swiz_cfgwriteb;
-static alpha_chipset_cfgwritew_t apecs_swiz_cfgwritew;
-static alpha_chipset_cfgwritel_t apecs_swiz_cfgwritel;
-static alpha_chipset_addrcvt_t apecs_cvt_dense;
static alpha_chipset_read_hae_t apecs_read_hae;
static alpha_chipset_write_hae_t apecs_write_hae;
static alpha_chipset_t apecs_swiz_chipset = {
- apecs_swiz_inb,
- apecs_swiz_inw,
- apecs_swiz_inl,
- apecs_swiz_outb,
- apecs_swiz_outw,
- apecs_swiz_outl,
- apecs_swiz_readb,
- apecs_swiz_readw,
- apecs_swiz_readl,
- apecs_swiz_writeb,
- apecs_swiz_writew,
- apecs_swiz_writel,
- apecs_swiz_maxdevs,
- apecs_swiz_cfgreadb,
- apecs_swiz_cfgreadw,
- apecs_swiz_cfgreadl,
- apecs_swiz_cfgwriteb,
- apecs_swiz_cfgwritew,
- apecs_swiz_cfgwritel,
- apecs_cvt_dense,
- NULL,
apecs_read_hae,
apecs_write_hae,
};
-static int
-apecs_swiz_maxdevs(u_int b)
-{
- return 12; /* XXX */
-}
-
-
-
-static u_int8_t
-apecs_swiz_inb(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_BYTE(KV(APECS_PCI_SIO), port);
-}
-
-static u_int16_t
-apecs_swiz_inw(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_WORD(KV(APECS_PCI_SIO), port);
-}
-
-static u_int32_t
-apecs_swiz_inl(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_LONG(KV(APECS_PCI_SIO), port);
-}
-
-static void
-apecs_swiz_outb(u_int32_t port, u_int8_t data)
-{
- SPARSE_WRITE_BYTE(KV(APECS_PCI_SIO), port, data);
- alpha_wmb();
-}
-
-static void
-apecs_swiz_outw(u_int32_t port, u_int16_t data)
-{
- SPARSE_WRITE_WORD(KV(APECS_PCI_SIO), port, data);
- alpha_wmb();
-}
-
-static void
-apecs_swiz_outl(u_int32_t port, u_int32_t data)
-{
- SPARSE_WRITE_LONG(KV(APECS_PCI_SIO), port, data);
- alpha_wmb();
-}
-
/*
* Memory functions.
*
@@ -204,14 +113,14 @@ apecs_swiz_outl(u_int32_t port, u_int32_t data)
static u_int32_t apecs_hae_mem;
#define REG1 (1UL << 24)
-static __inline void
-apecs_swiz_set_hae_mem(u_int32_t *pa)
+static u_int32_t
+apecs_set_hae_mem(void *arg, u_int32_t pa)
{
int s;
u_int32_t msb;
- if(*pa >= REG1){
- msb = *pa & 0xf8000000;
- *pa -= msb;
+ if (pa >= REG1){
+ msb = pa & 0xf8000000;
+ pa -= msb;
s = splhigh();
if (msb != apecs_hae_mem) {
apecs_hae_mem = msb;
@@ -221,217 +130,7 @@ apecs_swiz_set_hae_mem(u_int32_t *pa)
}
splx(s);
}
-}
-
-static u_int8_t
-apecs_swiz_readb(u_int32_t pa)
-{
- alpha_mb();
- apecs_swiz_set_hae_mem(&pa);
- return SPARSE_READ_BYTE(KV(APECS_PCI_SPARSE), pa);
-}
-
-static u_int16_t
-apecs_swiz_readw(u_int32_t pa)
-{
- alpha_mb();
- apecs_swiz_set_hae_mem(&pa);
- return SPARSE_READ_WORD(KV(APECS_PCI_SPARSE), pa);
-}
-
-static u_int32_t
-apecs_swiz_readl(u_int32_t pa)
-{
- alpha_mb();
- apecs_swiz_set_hae_mem(&pa);
- return SPARSE_READ_LONG(KV(APECS_PCI_SPARSE), pa);
-}
-
-static void
-apecs_swiz_writeb(u_int32_t pa, u_int8_t data)
-{
- apecs_swiz_set_hae_mem(&pa);
- SPARSE_WRITE_BYTE(KV(APECS_PCI_SPARSE), pa, data);
- alpha_wmb();
-}
-
-static void
-apecs_swiz_writew(u_int32_t pa, u_int16_t data)
-{
- apecs_swiz_set_hae_mem(&pa);
- SPARSE_WRITE_WORD(KV(APECS_PCI_SPARSE), pa, data);
- alpha_wmb();
-}
-
-
-static void
-apecs_swiz_writel(u_int32_t pa, u_int32_t data)
-{
- apecs_swiz_set_hae_mem(&pa);
- SPARSE_WRITE_LONG(KV(APECS_PCI_SPARSE), pa, data);
- alpha_wmb();
-
-}
-
-
-#define APECS_SWIZ_CFGOFF(b, s, f, r) \
- (((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
-
-#define APECS_TYPE1_SETUP(b,s,old_haxr2) if((b)) { \
- do { \
- (s) = splhigh(); \
- (old_haxr2) = REGVAL(EPIC_HAXR2); \
- alpha_mb(); \
- REGVAL(EPIC_HAXR2) = (old_haxr2) | 0x1; \
- alpha_mb(); \
- } while(0); \
-}
-
-#define APECS_TYPE1_TEARDOWN(b,s,old_haxr2) if((b)) { \
- do { \
- alpha_mb(); \
- REGVAL(EPIC_HAXR2) = (old_haxr2); \
- 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_haxr2 = 0; \
- struct apecs_softc* sc = APECS_SOFTC(apecs0); \
- vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r); \
- vm_offset_t kv = SPARSE_##width##_ADDRESS(sc->cfg0_base, off); \
- alpha_mb(); \
- APECS_TYPE1_SETUP(b,ipl,old_haxr2); \
- if (!badaddr((caddr_t)kv, sizeof(type))) { \
- val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
- } \
- APECS_TYPE1_TEARDOWN(b,ipl,old_haxr2); \
- return val;
-
-#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) \
- int ipl = 0; \
- u_int32_t old_haxr2 = 0; \
- struct apecs_softc* sc = APECS_SOFTC(apecs0); \
- vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r); \
- vm_offset_t kv = SPARSE_##width##_ADDRESS(sc->cfg0_base, off); \
- alpha_mb(); \
- APECS_TYPE1_SETUP(b,ipl,old_haxr2); \
- if (!badaddr((caddr_t)kv, sizeof(type))) { \
- SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \
- alpha_wmb(); \
- } \
- APECS_TYPE1_TEARDOWN(b,ipl,old_haxr2); \
- return;
-
-#if 1
-static u_int8_t
-apecs_swiz_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
-apecs_swiz_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
-apecs_swiz_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
-apecs_swiz_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
-apecs_swiz_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
-apecs_swiz_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);
-}
-
-#else
-static u_int8_t
-apecs_swiz_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- struct apecs_softc* sc = APECS_SOFTC(apecs0);
- vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r);
- alpha_mb();
- if (badaddr((caddr_t)(sc->cfg0_base + SPARSE_BYTE_OFFSET(off)), 1)) return ~0;
- return SPARSE_READ_BYTE(sc->cfg0_base, off);
-}
-
-static u_int16_t
-apecs_swiz_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- struct apecs_softc* sc = APECS_SOFTC(apecs0);
- vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r);
- alpha_mb();
- if (badaddr((caddr_t)(sc->cfg0_base + SPARSE_WORD_OFFSET(off)), 2)) return ~0;
- return SPARSE_READ_WORD(sc->cfg0_base, off);
-}
-
-static u_int32_t
-apecs_swiz_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- struct apecs_softc* sc = APECS_SOFTC(apecs0);
- vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r);
- alpha_mb();
- if (badaddr((caddr_t)(sc->cfg0_base + SPARSE_LONG_OFFSET(off)), 4)) return ~0;
- return SPARSE_READ_LONG(sc->cfg0_base, off);
-}
-
-static void
-apecs_swiz_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
-{
- struct apecs_softc* sc = APECS_SOFTC(apecs0);
- vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r);
- if (badaddr((caddr_t)(sc->cfg0_base + SPARSE_BYTE_OFFSET(off)), 1)) return;
- SPARSE_WRITE_BYTE(sc->cfg0_base, off, data);
- alpha_wmb();
-}
-
-static void
-apecs_swiz_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
-{
- struct apecs_softc* sc = APECS_SOFTC(apecs0);
- vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r);
- if (badaddr((caddr_t)(sc->cfg0_base + SPARSE_WORD_OFFSET(off)), 2)) return;
- SPARSE_WRITE_WORD(sc->cfg0_base, off, data);
- alpha_wmb();
-}
-
-static void
-apecs_swiz_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
-{
- struct apecs_softc* sc = APECS_SOFTC(apecs0);
- vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r);
- if (badaddr((caddr_t)(sc->cfg0_base + SPARSE_LONG_OFFSET(off)), 4)) return;
- SPARSE_WRITE_LONG(sc->cfg0_base, off, data);
- alpha_wmb();
-}
-#endif
-
-
-static vm_offset_t
-apecs_cvt_dense(vm_offset_t addr)
-{
- addr &= 0xffffffffUL;
- return (addr | APECS_PCI_DENSE);
-
+ return pa;
}
static u_int64_t
@@ -444,7 +143,7 @@ static void
apecs_write_hae(u_int64_t hae)
{
u_int32_t pa = hae;
- apecs_swiz_set_hae_mem(&pa);
+ apecs_set_hae_mem(0, pa);
}
static int apecs_probe(device_t dev);
@@ -495,7 +194,7 @@ apecs_sgmap_invalidate(void)
}
static void
-apecs_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa)
+apecs_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
{
u_int64_t *sgtable = arg;
int index = alpha_btop(ba - APECS_SGMAP_BASE);
@@ -544,10 +243,18 @@ void
apecs_init()
{
static int initted = 0;
+ static struct swiz_space io_space, mem_space;
if (initted) return;
initted = 1;
+ swiz_init_space(&io_space, KV(APECS_PCI_SIO));
+ swiz_init_space_hae(&mem_space, KV(APECS_PCI_SPARSE),
+ apecs_set_hae_mem, 0);
+
+ busspace_isa_io = (struct alpha_busspace *) &io_space;
+ busspace_isa_mem = (struct alpha_busspace *) &mem_space;
+
chipset = apecs_swiz_chipset;
if (platform.pci_intr_init)
diff --git a/sys/alpha/pci/apecs_pci.c b/sys/alpha/pci/apecs_pci.c
index bb1b8bd..287b2d9 100644
--- a/sys/alpha/pci/apecs_pci.c
+++ b/sys/alpha/pci/apecs_pci.c
@@ -34,6 +34,15 @@
#include <machine/bus.h>
#include <sys/rman.h>
#include <pci/pcivar.h>
+#include <machine/swiz.h>
+
+#include <alpha/pci/apecsreg.h>
+#include <alpha/pci/apecsvar.h>
+
+#include "alphapci_if.h"
+#include "pcib_if.h"
+
+#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
static devclass_t pcib_devclass;
@@ -50,13 +59,109 @@ apecs_pcib_probe(device_t dev)
static int
apecs_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
{
- if (which == PCIB_IVAR_HOSE) {
+ if (which == PCIB_IVAR_BUS) {
*result = 0;
return 0;
}
return ENOENT;
}
+static void *
+apecs_pcib_cvt_dense(device_t dev, vm_offset_t addr)
+{
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | APECS_PCI_DENSE);
+}
+
+static int
+apecs_pcib_maxslots(device_t dev)
+{
+ return 31;
+}
+
+#define APECS_SWIZ_CFGOFF(b, s, f, r) \
+ (((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
+
+#define APECS_TYPE1_SETUP(b,s,old_haxr2) if((b)) { \
+ do { \
+ (s) = splhigh(); \
+ (old_haxr2) = REGVAL(EPIC_HAXR2); \
+ alpha_mb(); \
+ REGVAL(EPIC_HAXR2) = (old_haxr2) | 0x1; \
+ alpha_mb(); \
+ } while(0); \
+}
+
+#define APECS_TYPE1_TEARDOWN(b,s,old_haxr2) if((b)) { \
+ do { \
+ alpha_mb(); \
+ REGVAL(EPIC_HAXR2) = (old_haxr2); \
+ alpha_mb(); \
+ splx((s)); \
+ } while(0); \
+}
+
+#define SWIZ_CFGREAD(b, s, f, r, width, type) do { \
+ type val = ~0; \
+ int ipl = 0; \
+ u_int32_t old_haxr2 = 0; \
+ vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r); \
+ vm_offset_t kv = \
+ SPARSE_##width##_ADDRESS(KV(APECS_PCI_CONF), off); \
+ alpha_mb(); \
+ APECS_TYPE1_SETUP(b,ipl,old_haxr2); \
+ if (!badaddr((caddr_t)kv, sizeof(type))) { \
+ val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
+ } \
+ APECS_TYPE1_TEARDOWN(b,ipl,old_haxr2); \
+ return val; \
+} while (0)
+
+#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) do { \
+ int ipl = 0; \
+ u_int32_t old_haxr2 = 0; \
+ vm_offset_t off = APECS_SWIZ_CFGOFF(b, s, f, r); \
+ vm_offset_t kv = \
+ SPARSE_##width##_ADDRESS(KV(APECS_PCI_CONF), off); \
+ alpha_mb(); \
+ APECS_TYPE1_SETUP(b,ipl,old_haxr2); \
+ if (!badaddr((caddr_t)kv, sizeof(type))) { \
+ SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \
+ alpha_wmb(); \
+ } \
+ APECS_TYPE1_TEARDOWN(b,ipl,old_haxr2); \
+ return; \
+} while (0)
+
+u_int32_t
+apecs_pcib_read_config(device_t dev, int b, int s, int f,
+ int reg, int width)
+{
+ switch (width) {
+ case 1:
+ SWIZ_CFGREAD(b, s, f, reg, BYTE, u_int8_t);
+ case 2:
+ SWIZ_CFGREAD(b, s, f, reg, WORD, u_int16_t);
+ case 4:
+ SWIZ_CFGREAD(b, s, f, reg, LONG, u_int32_t);
+ }
+ return ~0;
+}
+
+static void
+apecs_pcib_write_config(device_t dev, int b, int s, int f,
+ int reg, u_int32_t val, int width)
+{
+ switch (width) {
+ case 1:
+ SWIZ_CFGWRITE(b, s, f, reg, val, BYTE, u_int8_t);
+ case 2:
+ SWIZ_CFGWRITE(b, s, f, reg, val, WORD, u_int16_t);
+ case 4:
+ SWIZ_CFGWRITE(b, s, f, reg, val, LONG, u_int32_t);
+ }
+}
+
static device_method_t apecs_pcib_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, apecs_pcib_probe),
@@ -72,6 +177,14 @@ static device_method_t apecs_pcib_methods[] = {
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ /* alphapci interface */
+ DEVMETHOD(alphapci_cvt_dense, apecs_pcib_cvt_dense),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, apecs_pcib_maxslots),
+ DEVMETHOD(pcib_read_config, apecs_pcib_read_config),
+ DEVMETHOD(pcib_write_config, apecs_pcib_write_config),
+
{ 0, 0 }
};
diff --git a/sys/alpha/pci/apecsvar.h b/sys/alpha/pci/apecsvar.h
index a5fa82e..56ade54 100644
--- a/sys/alpha/pci/apecsvar.h
+++ b/sys/alpha/pci/apecsvar.h
@@ -26,5 +26,8 @@
* $FreeBSD$
*/
-extern void apecs_init(void);
+struct device;
+extern void apecs_init(void);
+u_int32_t apecs_pcib_read_config(struct device *dev, int b, int s, int f,
+ int reg, int width);
diff --git a/sys/alpha/pci/bwx.c b/sys/alpha/pci/bwx.c
new file mode 100644
index 0000000..9dd0e92
--- /dev/null
+++ b/sys/alpha/pci/bwx.c
@@ -0,0 +1,131 @@
+/*-
+ * 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, 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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kobj.h>
+
+#include <machine/bus.h>
+#include <machine/bwx.h>
+
+static u_int8_t
+bwx_read_1(struct alpha_busspace *space, size_t offset)
+{
+ struct bwx_space *bwx = (struct bwx_space *) space;
+ alpha_mb();
+ return ldbu(bwx->base + offset);
+}
+
+static u_int16_t
+bwx_read_2(struct alpha_busspace *space, size_t offset)
+{
+ struct bwx_space *bwx = (struct bwx_space *) space;
+ alpha_mb();
+ return ldwu(bwx->base + offset);
+}
+
+static u_int32_t
+bwx_read_4(struct alpha_busspace *space, size_t offset)
+{
+ struct bwx_space *bwx = (struct bwx_space *) space;
+ alpha_mb();
+ return ldl(bwx->base + offset);
+}
+
+static void
+bwx_write_1(struct alpha_busspace *space, size_t offset, u_int8_t data)
+{
+ struct bwx_space *bwx = (struct bwx_space *) space;
+ stb(bwx->base + offset, data);
+ alpha_mb();
+}
+
+static void
+bwx_write_2(struct alpha_busspace *space, size_t offset, u_int16_t data)
+{
+ struct bwx_space *bwx = (struct bwx_space *) space;
+ stw(bwx->base + offset, data);
+ alpha_mb();
+}
+
+static void
+bwx_write_4(struct alpha_busspace *space, size_t offset, u_int32_t data)
+{
+ struct bwx_space *bwx = (struct bwx_space *) space;
+ stl(bwx->base + offset, data);
+ alpha_mb();
+}
+
+static struct alpha_busspace_ops bwx_space_ops = {
+ bwx_read_1,
+ bwx_read_2,
+ bwx_read_4,
+
+ busspace_generic_read_multi_1,
+ busspace_generic_read_multi_2,
+ busspace_generic_read_multi_4,
+
+ busspace_generic_read_region_1,
+ busspace_generic_read_region_2,
+ busspace_generic_read_region_4,
+
+ bwx_write_1,
+ bwx_write_2,
+ bwx_write_4,
+
+ busspace_generic_write_multi_1,
+ busspace_generic_write_multi_2,
+ busspace_generic_write_multi_4,
+
+ busspace_generic_write_region_1,
+ busspace_generic_write_region_2,
+ busspace_generic_write_region_4,
+
+ busspace_generic_set_multi_1,
+ busspace_generic_set_multi_2,
+ busspace_generic_set_multi_4,
+
+ busspace_generic_set_region_1,
+ busspace_generic_set_region_2,
+ busspace_generic_set_region_4,
+
+ busspace_generic_copy_region_1,
+ busspace_generic_copy_region_2,
+ busspace_generic_copy_region_4,
+
+ busspace_generic_barrier,
+};
+
+void
+bwx_init_space(struct bwx_space *bwx, u_int64_t base)
+{
+ bwx->ops = &bwx_space_ops;
+ bwx->base = base;
+}
+
diff --git a/sys/alpha/pci/cia.c b/sys/alpha/pci/cia.c
index 55a4750..558bad0 100644
--- a/sys/alpha/pci/cia.c
+++ b/sys/alpha/pci/cia.c
@@ -116,6 +116,8 @@
#include <vm/vm.h>
#include <vm/vm_page.h>
+#include "alphapci_if.h"
+
#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
static devclass_t cia_devclass;
@@ -129,533 +131,36 @@ struct cia_softc {
#define CIA_SOFTC(dev) (struct cia_softc*) device_get_softc(dev)
-static alpha_chipset_inb_t cia_bwx_inb, cia_swiz_inb;
-static alpha_chipset_inw_t cia_bwx_inw, cia_swiz_inw;
-static alpha_chipset_inl_t cia_bwx_inl, cia_swiz_inl;
-static alpha_chipset_outb_t cia_bwx_outb, cia_swiz_outb;
-static alpha_chipset_outw_t cia_bwx_outw, cia_swiz_outw;
-static alpha_chipset_outl_t cia_bwx_outl, cia_swiz_outl;
-static alpha_chipset_readb_t cia_bwx_readb, cia_swiz_readb;
-static alpha_chipset_readw_t cia_bwx_readw, cia_swiz_readw;
-static alpha_chipset_readl_t cia_bwx_readl, cia_swiz_readl;
-static alpha_chipset_writeb_t cia_bwx_writeb, cia_swiz_writeb;
-static alpha_chipset_writew_t cia_bwx_writew, cia_swiz_writew;
-static alpha_chipset_writel_t cia_bwx_writel, cia_swiz_writel;
-static alpha_chipset_maxdevs_t cia_bwx_maxdevs, cia_swiz_maxdevs;
-static alpha_chipset_cfgreadb_t cia_bwx_cfgreadb, cia_swiz_cfgreadb;
-static alpha_chipset_cfgreadw_t cia_bwx_cfgreadw, cia_swiz_cfgreadw;
-static alpha_chipset_cfgreadl_t cia_bwx_cfgreadl, cia_swiz_cfgreadl;
-static alpha_chipset_cfgwriteb_t cia_bwx_cfgwriteb, cia_swiz_cfgwriteb;
-static alpha_chipset_cfgwritew_t cia_bwx_cfgwritew, cia_swiz_cfgwritew;
-static alpha_chipset_cfgwritel_t cia_bwx_cfgwritel, cia_swiz_cfgwritel;
-static alpha_chipset_addrcvt_t cia_cvt_dense, cia_cvt_bwx;
static alpha_chipset_read_hae_t cia_read_hae;
static alpha_chipset_write_hae_t cia_write_hae;
static alpha_chipset_t cia_bwx_chipset = {
- cia_bwx_inb,
- cia_bwx_inw,
- cia_bwx_inl,
- cia_bwx_outb,
- cia_bwx_outw,
- cia_bwx_outl,
- cia_bwx_readb,
- cia_bwx_readw,
- cia_bwx_readl,
- cia_bwx_writeb,
- cia_bwx_writew,
- cia_bwx_writel,
- cia_bwx_maxdevs,
- cia_bwx_cfgreadb,
- cia_bwx_cfgreadw,
- cia_bwx_cfgreadl,
- cia_bwx_cfgwriteb,
- cia_bwx_cfgwritew,
- cia_bwx_cfgwritel,
- cia_cvt_dense,
- cia_cvt_bwx,
cia_read_hae,
cia_write_hae,
};
static alpha_chipset_t cia_swiz_chipset = {
- cia_swiz_inb,
- cia_swiz_inw,
- cia_swiz_inl,
- cia_swiz_outb,
- cia_swiz_outw,
- cia_swiz_outl,
- cia_swiz_readb,
- cia_swiz_readw,
- cia_swiz_readl,
- cia_swiz_writeb,
- cia_swiz_writew,
- cia_swiz_writel,
- cia_swiz_maxdevs,
- cia_swiz_cfgreadb,
- cia_swiz_cfgreadw,
- cia_swiz_cfgreadl,
- cia_swiz_cfgwriteb,
- cia_swiz_cfgwritew,
- cia_swiz_cfgwritel,
- cia_cvt_dense,
- NULL,
cia_read_hae,
cia_write_hae,
};
-static u_int8_t
-cia_bwx_inb(u_int32_t port)
-{
- alpha_mb();
- return ldbu(KV(CIA_EV56_BWIO+BWX_EV56_INT1 + port));
-}
-
-static u_int16_t
-cia_bwx_inw(u_int32_t port)
-{
- alpha_mb();
- return ldwu(KV(CIA_EV56_BWIO+BWX_EV56_INT2 + port));
-}
-
-static u_int32_t
-cia_bwx_inl(u_int32_t port)
-{
- alpha_mb();
- return ldl(KV(CIA_EV56_BWIO+BWX_EV56_INT4 + port));
-}
-
-static void
-cia_bwx_outb(u_int32_t port, u_int8_t data)
-{
- stb(KV(CIA_EV56_BWIO+BWX_EV56_INT1 + port), data);
- alpha_wmb();
-}
-
-static void
-cia_bwx_outw(u_int32_t port, u_int16_t data)
-{
- stw(KV(CIA_EV56_BWIO+BWX_EV56_INT2 + port), data);
- alpha_wmb();
-}
-
-static void
-cia_bwx_outl(u_int32_t port, u_int32_t data)
-{
- stl(KV(CIA_EV56_BWIO+BWX_EV56_INT4 + port), data);
- alpha_wmb();
-}
-
-static u_int8_t
-cia_bwx_readb(u_int32_t pa)
-{
- alpha_mb();
- return ldbu(KV(CIA_EV56_BWMEM+BWX_EV56_INT1 + pa));
-}
-
-static u_int16_t
-cia_bwx_readw(u_int32_t pa)
-{
- alpha_mb();
- return ldwu(KV(CIA_EV56_BWMEM+BWX_EV56_INT2 + pa));
-}
-
-static u_int32_t
-cia_bwx_readl(u_int32_t pa)
-{
- alpha_mb();
- return ldl(KV(CIA_EV56_BWMEM+BWX_EV56_INT4 + pa));
-}
-
-static void
-cia_bwx_writeb(u_int32_t pa, u_int8_t data)
-{
- stb(KV(CIA_EV56_BWMEM+BWX_EV56_INT1 + pa), data);
- alpha_wmb();
-}
-
-static void
-cia_bwx_writew(u_int32_t pa, u_int16_t data)
-{
- stw(KV(CIA_EV56_BWMEM+BWX_EV56_INT2 + pa), data);
- alpha_wmb();
-}
-
-static void
-cia_bwx_writel(u_int32_t pa, u_int32_t data)
-{
- stl(KV(CIA_EV56_BWMEM+BWX_EV56_INT4 + pa), data);
- alpha_wmb();
-}
-
-static int
-cia_bwx_maxdevs(u_int b)
-{
- return 12; /* XXX */
-}
-
-static void
-cia_clear_abort(void)
-{
- /*
- * Some (apparently-common) revisions of EB164 and AlphaStation
- * firmware do the Wrong thing with PCI master and target aborts,
- * which are caused by accesing the configuration space of devices
- * that don't exist (for example).
- *
- * To work around this, we clear the CIA error register's PCI
- * master and target abort bits before touching PCI configuration
- * space and check it afterwards. If it indicates a master or target
- * abort, the device wasn't there so we return 0xffffffff.
- */
- REGVAL(CIA_CSR_CIA_ERR) = CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT;
- alpha_mb();
- alpha_pal_draina();
-}
-
-static int
-cia_check_abort(void)
-{
- u_int32_t errbits;
- int ba = 0;
-
- alpha_pal_draina();
- alpha_mb();
- errbits = REGVAL(CIA_CSR_CIA_ERR);
- if (errbits & (CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT))
- ba = 1;
-
- if (errbits) {
- REGVAL(CIA_CSR_CIA_ERR) = errbits;
- alpha_mb();
- alpha_pal_draina();
- }
-
- return ba;
-}
-
-#define CIA_BWX_CFGADDR(b, s, f, r) \
- KV(((b) ? CIA_EV56_BWCONF1 : CIA_EV56_BWCONF0) \
- | ((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
-
-static u_int8_t
-cia_bwx_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- vm_offset_t va = CIA_BWX_CFGADDR(b, s, f, r);
- u_int8_t data;
- cia_clear_abort();
- if (badaddr((caddr_t)va, 1)) {
- cia_check_abort();
- return ~0;
- }
- data = ldbu(va+BWX_EV56_INT1);
- if (cia_check_abort())
- return ~0;
- return data;
-}
-
-static u_int16_t
-cia_bwx_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- vm_offset_t va = CIA_BWX_CFGADDR(b, s, f, r);
- u_int16_t data;
- cia_clear_abort();
- if (badaddr((caddr_t)va, 2)) {
- cia_check_abort();
- return ~0;
- }
- data = ldwu(va+BWX_EV56_INT2);
- if (cia_check_abort())
- return ~0;
- return data;
-}
-
-static u_int32_t
-cia_bwx_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- vm_offset_t va = CIA_BWX_CFGADDR(b, s, f, r);
- u_int32_t data;
- cia_clear_abort();
- if (badaddr((caddr_t)va, 4)) {
- cia_check_abort();
- return ~0;
- }
- data = ldl(va+BWX_EV56_INT4);
- if (cia_check_abort())
- return ~0;
- return data;
-}
-
-static void
-cia_bwx_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
-{
- vm_offset_t va = CIA_BWX_CFGADDR(b, s, f, r);
- cia_clear_abort();
- if (badaddr((caddr_t)va, 1)) return;
- stb(va+BWX_EV56_INT1, data);
- cia_check_abort();
-}
-
-static void
-cia_bwx_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
-{
- vm_offset_t va = CIA_BWX_CFGADDR(b, s, f, r);
- if (badaddr((caddr_t)va, 2)) return;
- stw(va+BWX_EV56_INT2, data);
- cia_check_abort();
-}
-
-static void
-cia_bwx_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
-{
- vm_offset_t va = CIA_BWX_CFGADDR(b, s, f, r);
- if (badaddr((caddr_t)va, 4)) return;
- stl(va+BWX_EV56_INT4, data);
- cia_check_abort();
-}
-
-static u_int8_t
-cia_swiz_inb(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_BYTE(KV(CIA_PCI_SIO1), port);
-}
-
-static u_int16_t
-cia_swiz_inw(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_WORD(KV(CIA_PCI_SIO1), port);
-}
-
static u_int32_t
-cia_swiz_inl(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_LONG(KV(CIA_PCI_SIO1), port);
-}
-
-static void
-cia_swiz_outb(u_int32_t port, u_int8_t data)
-{
- SPARSE_WRITE_BYTE(KV(CIA_PCI_SIO1), port, data);
- alpha_wmb();
-}
-
-static void
-cia_swiz_outw(u_int32_t port, u_int16_t data)
-{
- SPARSE_WRITE_WORD(KV(CIA_PCI_SIO1), port, data);
- alpha_wmb();
-}
-
-static void
-cia_swiz_outl(u_int32_t port, u_int32_t data)
-{
- SPARSE_WRITE_LONG(KV(CIA_PCI_SIO1), port, data);
- alpha_wmb();
-}
-
-static __inline void
-cia_swiz_set_hae_mem(u_int32_t *pa)
+cia_swiz_set_hae_mem(void *arg, u_int32_t pa)
{
/* Only bother with region 1 */
#define REG1 (7 << 29)
- if ((cia_hae_mem & REG1) != (*pa & REG1)) {
+ if ((cia_hae_mem & REG1) != (pa & REG1)) {
/*
* Seems fairly paranoid but this is what Linux does...
*/
- u_int32_t msb = *pa & REG1;
+ u_int32_t msb = pa & REG1;
int s = splhigh();
cia_hae_mem = (cia_hae_mem & ~REG1) | msb;
REGVAL(CIA_CSR_HAE_MEM) = cia_hae_mem;
alpha_mb();
cia_hae_mem = REGVAL(CIA_CSR_HAE_MEM);
splx(s);
- *pa -= msb;
}
-}
-
-static u_int8_t
-cia_swiz_readb(u_int32_t pa)
-{
- alpha_mb();
- cia_swiz_set_hae_mem(&pa);
- return SPARSE_READ_BYTE(KV(CIA_PCI_SMEM1), pa);
-}
-
-static u_int16_t
-cia_swiz_readw(u_int32_t pa)
-{
- alpha_mb();
- cia_swiz_set_hae_mem(&pa);
- return SPARSE_READ_WORD(KV(CIA_PCI_SMEM1), pa);
-}
-
-static u_int32_t
-cia_swiz_readl(u_int32_t pa)
-{
- alpha_mb();
- cia_swiz_set_hae_mem(&pa);
- return SPARSE_READ_LONG(KV(CIA_PCI_SMEM1), pa);
-}
-
-static void
-cia_swiz_writeb(u_int32_t pa, u_int8_t data)
-{
- cia_swiz_set_hae_mem(&pa);
- SPARSE_WRITE_BYTE(KV(CIA_PCI_SMEM1), pa, data);
- alpha_wmb();
-}
-
-static void
-cia_swiz_writew(u_int32_t pa, u_int16_t data)
-{
- cia_swiz_set_hae_mem(&pa);
- SPARSE_WRITE_WORD(KV(CIA_PCI_SMEM1), pa, data);
- alpha_wmb();
-}
-
-static void
-cia_swiz_writel(u_int32_t pa, u_int32_t data)
-{
- cia_swiz_set_hae_mem(&pa);
- SPARSE_WRITE_LONG(KV(CIA_PCI_SMEM1), pa, data);
- alpha_wmb();
-}
-
-static int
-cia_swiz_maxdevs(u_int b)
-{
- return 12; /* XXX */
-}
-
-#define CIA_SWIZ_CFGOFF(b, s, f, r) \
- (((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
-
-/* when doing a type 1 pci configuration space access, we
- * must set a bit in the CIA_CSR_CFG register & clear it
- * when we're done
-*/
-
-#define CIA_TYPE1_SETUP(b,s,old_cfg) if((b)) { \
- do { \
- (s) = splhigh(); \
- (old_cfg) = REGVAL(CIA_CSR_CFG); \
- alpha_mb(); \
- REGVAL(CIA_CSR_CFG) = (old_cfg) | 0x1; \
- alpha_mb(); \
- } while(0); \
-}
-
-#define CIA_TYPE1_TEARDOWN(b,s,old_cfg) if((b)) { \
- do { \
- alpha_mb(); \
- REGVAL(CIA_CSR_CFG) = (old_cfg); \
- alpha_mb(); \
- splx((s)); \
- } while(0); \
-}
-
-/*
- * From NetBSD:
- * Some (apparently-common) revisions of EB164 and AlphaStation
- * firmware do the Wrong thing with PCI master and target aborts,
- * which are caused by accesing the configuration space of devices
- * that don't exist (for example).
- *
- * To work around this, we clear the CIA error register's PCI
- * master and target abort bits before touching PCI configuration
- * space and check it afterwards. If it indicates a master or target
- * abort, the device wasn't there so we return ~0
- */
-
-
-#define SWIZ_CFGREAD(b, s, f, r, width, type) \
- type val = ~0; \
- int ipl = 0; \
- u_int32_t old_cfg = 0, errbits; \
- vm_offset_t off = CIA_SWIZ_CFGOFF(b, s, f, r); \
- vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(CIA_PCI_CONF), off); \
- REGVAL(CIA_CSR_CIA_ERR) = CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT;\
- alpha_mb(); \
- CIA_TYPE1_SETUP(b,ipl,old_cfg); \
- if (!badaddr((caddr_t)kv, sizeof(type))) { \
- val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
- } \
- CIA_TYPE1_TEARDOWN(b,ipl,old_cfg); \
- errbits = REGVAL(CIA_CSR_CIA_ERR); \
- if (errbits & (CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT)) \
- val = ~0; \
- if (errbits) { \
- REGVAL(CIA_CSR_CIA_ERR) = errbits; \
- alpha_mb(); \
- alpha_pal_draina(); \
- } \
- return val;
-
-#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) \
- int ipl = 0; \
- u_int32_t old_cfg = 0; \
- vm_offset_t off = CIA_SWIZ_CFGOFF(b, s, f, r); \
- vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(CIA_PCI_CONF), off); \
- alpha_mb(); \
- CIA_TYPE1_SETUP(b,ipl,old_cfg); \
- if (!badaddr((caddr_t)kv, sizeof(type))) { \
- SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \
- alpha_wmb(); \
- } \
- CIA_TYPE1_TEARDOWN(b,ipl,old_cfg); \
- return;
-
-static u_int8_t
-cia_swiz_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
-cia_swiz_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
-cia_swiz_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
-cia_swiz_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
-cia_swiz_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
-cia_swiz_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);
-}
-
-vm_offset_t
-cia_cvt_dense(vm_offset_t addr)
-{
- addr &= 0xffffffffUL;
- return (addr | CIA_PCI_DENSE);
-
-}
-
-vm_offset_t
-cia_cvt_bwx(vm_offset_t addr)
-{
- addr &= 0xffffffffUL;
- return (addr |= CIA_EV56_BWMEM);
+ return pa & ~REG1;
}
static u_int64_t
@@ -668,7 +173,7 @@ static void
cia_write_hae(u_int64_t hae)
{
u_int32_t pa = hae;
- cia_swiz_set_hae_mem(&pa);
+ cia_swiz_set_hae_mem(0, pa);
}
static int cia_probe(device_t dev);
@@ -756,7 +261,7 @@ cia_sgmap_invalidate_pyxis(void)
}
static void
-cia_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa)
+cia_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
{
u_int64_t *sgtable = arg;
int index = alpha_btop(ba - CIA_SGMAP_BASE);
@@ -842,6 +347,10 @@ void
cia_init()
{
static int initted = 0;
+ static union space {
+ struct bwx_space bwx;
+ struct swiz_space swiz;
+ } io_space, mem_space;
if (initted) return;
initted = 1;
@@ -870,16 +379,22 @@ cia_init()
if (alpha_implver() != ALPHA_IMPLVER_EV5
|| alpha_amask(ALPHA_AMASK_BWX)
- || !(cia_config & CNFG_BWEN))
+ || !(cia_config & CNFG_BWEN)) {
+ swiz_init_space(&io_space.swiz, KV(CIA_PCI_SIO1));
+ swiz_init_space_hae(&mem_space.swiz, KV(CIA_PCI_SMEM1),
+ cia_swiz_set_hae_mem, 0);
+
chipset = cia_swiz_chipset;
- else
+ } else {
+ bwx_init_space(&io_space.bwx, KV(CIA_EV56_BWIO));
+ bwx_init_space(&mem_space.bwx, KV(CIA_EV56_BWMEM));
+
chipset = cia_bwx_chipset;
+ }
cia_hae_mem = REGVAL(CIA_CSR_HAE_MEM);
-#if 0
- chipset = cia_swiz_chipset; /* XXX */
- cia_ispyxis = 0;
-#endif
+ busspace_isa_io = (struct alpha_busspace *) &io_space;
+ busspace_isa_mem = (struct alpha_busspace *) &mem_space;
if (platform.pci_intr_init)
platform.pci_intr_init();
@@ -888,6 +403,8 @@ cia_init()
static int
cia_probe(device_t dev)
{
+ uintptr_t use_bwx = 1;
+
if (cia0)
return ENXIO;
cia0 = dev;
@@ -897,7 +414,13 @@ cia_probe(device_t dev)
isa_init_intr();
cia_init_sgmap();
+ if (alpha_implver() != ALPHA_IMPLVER_EV5
+ || alpha_amask(ALPHA_AMASK_BWX)
+ || !(cia_config & CNFG_BWEN))
+ use_bwx = 0;
+
device_add_child(dev, "pcib", 0);
+ device_set_ivars(dev, (void *)use_bwx);
return 0;
}
diff --git a/sys/alpha/pci/cia_pci.c b/sys/alpha/pci/cia_pci.c
index f9b7268..7b1620b 100644
--- a/sys/alpha/pci/cia_pci.c
+++ b/sys/alpha/pci/cia_pci.c
@@ -25,6 +25,69 @@
*
* $FreeBSD$
*/
+/*-
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
#include <sys/param.h>
#include <sys/systm.h>
@@ -35,6 +98,16 @@
#include <machine/md_var.h>
#include <sys/rman.h>
#include <pci/pcivar.h>
+#include <machine/bwx.h>
+#include <machine/swiz.h>
+
+#include <alpha/pci/ciareg.h>
+#include <alpha/pci/ciavar.h>
+
+#include "alphapci_if.h"
+#include "pcib_if.h"
+
+#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
static devclass_t pcib_devclass;
@@ -51,13 +124,261 @@ cia_pcib_probe(device_t dev)
static int
cia_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
{
- if (which == PCIB_IVAR_HOSE) {
+ switch (which) {
+ case PCIB_IVAR_BUS:
*result = 0;
return 0;
}
return ENOENT;
}
+static void *
+cia_pcib_cvt_dense(device_t dev, vm_offset_t addr)
+{
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | CIA_PCI_DENSE);
+}
+
+static void *
+cia_pcib_cvt_bwx(device_t dev, vm_offset_t addr)
+{
+ if ((uintptr_t) device_get_ivars(dev)) {
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | CIA_EV56_BWMEM);
+ } else {
+ return 0;
+ }
+}
+
+static void
+cia_clear_abort(void)
+{
+ /*
+ * Some (apparently-common) revisions of EB164 and AlphaStation
+ * firmware do the Wrong thing with PCI master and target aborts,
+ * which are caused by accesing the configuration space of devices
+ * that don't exist (for example).
+ *
+ * To work around this, we clear the CIA error register's PCI
+ * master and target abort bits before touching PCI configuration
+ * space and check it afterwards. If it indicates a master or target
+ * abort, the device wasn't there so we return 0xffffffff.
+ */
+ REGVAL(CIA_CSR_CIA_ERR) = CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT;
+ alpha_mb();
+ alpha_pal_draina();
+}
+
+static int
+cia_check_abort(void)
+{
+ u_int32_t errbits;
+ int ba = 0;
+
+ alpha_pal_draina();
+ alpha_mb();
+ errbits = REGVAL(CIA_CSR_CIA_ERR);
+ if (errbits & (CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT))
+ ba = 1;
+
+ if (errbits) {
+ REGVAL(CIA_CSR_CIA_ERR) = errbits;
+ alpha_mb();
+ alpha_pal_draina();
+ }
+
+ return ba;
+}
+
+#define CIA_BWX_CFGADDR(b, s, f, r) \
+ KV(((b) ? CIA_EV56_BWCONF1 : CIA_EV56_BWCONF0) \
+ | ((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
+
+#define BWX_CFGREAD(b, s, f, r, width, type, op) do { \
+ vm_offset_t va = CIA_BWX_CFGADDR(b, s, f, r); \
+ type data; \
+ cia_clear_abort(); \
+ if (badaddr((caddr_t)va, width)) { \
+ cia_check_abort(); \
+ return ~0; \
+ } \
+ data = op(va); \
+ if (cia_check_abort()) \
+ return ~0; \
+ return data; \
+} while (0)
+
+#define BWX_CFGWRITE(b, s, f, r, data, width, type, op) do { \
+ vm_offset_t va = CIA_BWX_CFGADDR(b, s, f, r); \
+ cia_clear_abort(); \
+ if (badaddr((caddr_t)va, width)) return; \
+ op(va, data); \
+ cia_check_abort(); \
+ return; \
+} while (0)
+
+#define CIA_SWIZ_CFGOFF(b, s, f, r) \
+ (((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
+
+/* when doing a type 1 pci configuration space access, we
+ * must set a bit in the CIA_CSR_CFG register & clear it
+ * when we're done
+*/
+
+#define CIA_TYPE1_SETUP(b,s,old_cfg) if((b)) { \
+ do { \
+ (s) = splhigh(); \
+ (old_cfg) = REGVAL(CIA_CSR_CFG); \
+ alpha_mb(); \
+ REGVAL(CIA_CSR_CFG) = (old_cfg) | 0x1; \
+ alpha_mb(); \
+ } while(0); \
+}
+
+#define CIA_TYPE1_TEARDOWN(b,s,old_cfg) if((b)) { \
+ do { \
+ alpha_mb(); \
+ REGVAL(CIA_CSR_CFG) = (old_cfg); \
+ alpha_mb(); \
+ splx((s)); \
+ } while(0); \
+}
+
+/*
+ * From NetBSD:
+ * Some (apparently-common) revisions of EB164 and AlphaStation
+ * firmware do the Wrong thing with PCI master and target aborts,
+ * which are caused by accesing the configuration space of devices
+ * that don't exist (for example).
+ *
+ * To work around this, we clear the CIA error register's PCI
+ * master and target abort bits before touching PCI configuration
+ * space and check it afterwards. If it indicates a master or target
+ * abort, the device wasn't there so we return ~0
+ */
+
+
+#define SWIZ_CFGREAD(b, s, f, r, width, type) do { \
+ type val = ~0; \
+ int ipl = 0; \
+ u_int32_t old_cfg = 0, errbits; \
+ vm_offset_t off = CIA_SWIZ_CFGOFF(b, s, f, r); \
+ vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(CIA_PCI_CONF), off); \
+ REGVAL(CIA_CSR_CIA_ERR) = CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT; \
+ alpha_mb(); \
+ CIA_TYPE1_SETUP(b,ipl,old_cfg); \
+ if (!badaddr((caddr_t)kv, sizeof(type))) { \
+ val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
+ } \
+ CIA_TYPE1_TEARDOWN(b,ipl,old_cfg); \
+ errbits = REGVAL(CIA_CSR_CIA_ERR); \
+ if (errbits & (CIA_ERR_RCVD_MAS_ABT|CIA_ERR_RCVD_TAR_ABT)) \
+ val = ~0; \
+ if (errbits) { \
+ REGVAL(CIA_CSR_CIA_ERR) = errbits; \
+ alpha_mb(); \
+ alpha_pal_draina(); \
+ } \
+ return val; \
+} while (0)
+
+#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) do { \
+ int ipl = 0; \
+ u_int32_t old_cfg = 0; \
+ vm_offset_t off = CIA_SWIZ_CFGOFF(b, s, f, r); \
+ vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(CIA_PCI_CONF), off); \
+ alpha_mb(); \
+ CIA_TYPE1_SETUP(b,ipl,old_cfg); \
+ if (!badaddr((caddr_t)kv, sizeof(type))) { \
+ SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \
+ alpha_wmb(); \
+ } \
+ CIA_TYPE1_TEARDOWN(b,ipl,old_cfg); \
+ return; \
+} while (0)
+
+static u_int32_t
+cia_pcib_swiz_read_config(int b, int s, int f, int reg, int width)
+{
+ switch (width) {
+ case 1:
+ SWIZ_CFGREAD(b, s, f, reg, BYTE, u_int8_t);
+ case 2:
+ SWIZ_CFGREAD(b, s, f, reg, WORD, u_int16_t);
+ case 4:
+ SWIZ_CFGREAD(b, s, f, reg, LONG, u_int32_t);
+ }
+ return ~0;
+}
+
+static void
+cia_pcib_swiz_write_config(int b, int s, int f, int reg,
+ u_int32_t val, int width)
+{
+ switch (width) {
+ case 1:
+ SWIZ_CFGWRITE(b, s, f, reg, val, BYTE, u_int8_t);
+ case 2:
+ SWIZ_CFGWRITE(b, s, f, reg, val, WORD, u_int16_t);
+ case 4:
+ SWIZ_CFGWRITE(b, s, f, reg, val, LONG, u_int32_t);
+ }
+}
+
+static u_int32_t
+cia_pcib_bwx_read_config(int b, int s, int f, int reg, int width)
+{
+ switch (width) {
+ case 1:
+ BWX_CFGREAD(b, s, f, reg, 1, u_int8_t, ldbu);
+ case 2:
+ BWX_CFGREAD(b, s, f, reg, 2, u_int16_t, ldwu);
+ case 4:
+ BWX_CFGREAD(b, s, f, reg, 4, u_int32_t, ldl);
+ }
+ return ~0;
+}
+
+static void
+cia_pcib_bwx_write_config(int b, int s, int f, int reg,
+ u_int32_t val, int width)
+{
+ switch (width) {
+ case 1:
+ BWX_CFGWRITE(b, s, f, reg, val, 1, u_int8_t, stb);
+ case 2:
+ BWX_CFGWRITE(b, s, f, reg, val, 2, u_int16_t, stw);
+ case 4:
+ BWX_CFGWRITE(b, s, f, reg, val, 4, u_int32_t, stl);
+ }
+}
+
+static int
+cia_pcib_maxslots(device_t dev)
+{
+ return 31;
+}
+
+static u_int32_t
+cia_pcib_read_config(device_t dev, int b, int s, int f,
+ int reg, int width)
+{
+ if ((uintptr_t) device_get_ivars(dev))
+ return cia_pcib_bwx_read_config(b, s, f, reg, width);
+ else
+ return cia_pcib_swiz_read_config(b, s, f, reg, width);
+}
+
+static void
+cia_pcib_write_config(device_t dev, int b, int s, int f,
+ int reg, u_int32_t val, int width)
+{
+ if ((uintptr_t) device_get_ivars(dev))
+ cia_pcib_bwx_write_config(b, s, f, reg, val, width);
+ else
+ cia_pcib_swiz_write_config(b, s, f, reg, val, width);
+}
+
static device_method_t cia_pcib_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, cia_pcib_probe),
@@ -73,6 +394,15 @@ static device_method_t cia_pcib_methods[] = {
DEVMETHOD(bus_setup_intr, alpha_platform_pci_setup_intr),
DEVMETHOD(bus_teardown_intr, alpha_platform_pci_teardown_intr),
+ /* alphapci interface */
+ DEVMETHOD(alphapci_cvt_dense, cia_pcib_cvt_dense),
+ DEVMETHOD(alphapci_cvt_bwx, cia_pcib_cvt_bwx),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, cia_pcib_maxslots),
+ DEVMETHOD(pcib_read_config, cia_pcib_read_config),
+ DEVMETHOD(pcib_write_config, cia_pcib_write_config),
+
{ 0, 0 }
};
diff --git a/sys/alpha/pci/dwlpx_pci.c b/sys/alpha/pci/dwlpx_pci.c
deleted file mode 100644
index c852b62..0000000
--- a/sys/alpha/pci/dwlpx_pci.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $FreeBSD$ */
-/*
- * Copyright (c) 2000 Matthew Jacob
- * 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.
- *
- */
-
-#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
-dwlpx_pcib_probe(device_t dev)
-{
- device_set_desc(dev, "DWLPX PCI host bus adapter");
- device_add_child(dev, "pci", device_get_unit(dev) << 4);
- return (0);
-}
-
-static int
-dwlpx_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
-{
- if (which == PCIB_IVAR_HOSE) {
- *result = *(int*) device_get_ivars(dev);
- return 0;
- }
- return ENOENT;
-}
-
-static device_method_t dwlpx_pcib_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, dwlpx_pcib_probe),
- DEVMETHOD(device_attach, bus_generic_attach),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_read_ivar, dwlpx_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 dwlpx_pcib_driver = {
- "pcib", dwlpx_pcib_methods, 1
-};
-
-DRIVER_MODULE(pcib, dwlpx, dwlpx_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/alpha/pci/irongate.c b/sys/alpha/pci/irongate.c
index 296d09d..3983cca 100644
--- a/sys/alpha/pci/irongate.c
+++ b/sys/alpha/pci/irongate.c
@@ -65,242 +65,14 @@ struct irongate_softc {
#define IRONGATE_SOFTC(dev) (struct irongate_softc*) device_get_softc(dev)
-static alpha_chipset_inb_t irongate_inb;
-static alpha_chipset_inw_t irongate_inw;
-static alpha_chipset_inl_t irongate_inl;
-static alpha_chipset_outb_t irongate_outb;
-static alpha_chipset_outw_t irongate_outw;
-static alpha_chipset_outl_t irongate_outl;
-static alpha_chipset_readb_t irongate_readb;
-static alpha_chipset_readw_t irongate_readw;
-static alpha_chipset_readl_t irongate_readl;
-static alpha_chipset_writeb_t irongate_writeb;
-static alpha_chipset_writew_t irongate_writew;
-static alpha_chipset_writel_t irongate_writel;
-static alpha_chipset_maxdevs_t irongate_maxdevs;
-static alpha_chipset_cfgreadb_t irongate_cfgreadb;
-static alpha_chipset_cfgreadw_t irongate_cfgreadw;
-static alpha_chipset_cfgreadl_t irongate_cfgreadl;
-static alpha_chipset_cfgwriteb_t irongate_cfgwriteb;
-static alpha_chipset_cfgwritew_t irongate_cfgwritew;
-static alpha_chipset_cfgwritel_t irongate_cfgwritel;
-static alpha_chipset_addrcvt_t irongate_cvt_dense, irongate_cvt_bwx;
-
static alpha_chipset_read_hae_t irongate_read_hae;
static alpha_chipset_write_hae_t irongate_write_hae;
static alpha_chipset_t irongate_chipset = {
- irongate_inb,
- irongate_inw,
- irongate_inl,
- irongate_outb,
- irongate_outw,
- irongate_outl,
- irongate_readb,
- irongate_readw,
- irongate_readl,
- irongate_writeb,
- irongate_writew,
- irongate_writel,
- irongate_maxdevs,
- irongate_cfgreadb,
- irongate_cfgreadw,
- irongate_cfgreadl,
- irongate_cfgwriteb,
- irongate_cfgwritew,
- irongate_cfgwritel,
- irongate_cvt_dense,
- irongate_cvt_bwx,
irongate_read_hae,
irongate_write_hae,
};
-static u_int8_t
-irongate_inb(u_int32_t port)
-{
- alpha_mb();
- return ldbu(KV(IRONGATE_IO + port));
-}
-
-static u_int16_t
-irongate_inw(u_int32_t port)
-{
- alpha_mb();
- return ldwu(KV(IRONGATE_IO + port));
-}
-
-static u_int32_t
-irongate_inl(u_int32_t port)
-{
- alpha_mb();
- return ldl(KV(IRONGATE_IO + port));
-}
-
-static void
-irongate_outb(u_int32_t port, u_int8_t data)
-{
- stb(KV(IRONGATE_IO + port), data);
- alpha_mb();
-}
-
-static void
-irongate_outw(u_int32_t port, u_int16_t data)
-{
- stw(KV(IRONGATE_IO + port), data);
- alpha_mb();
-}
-
-static void
-irongate_outl(u_int32_t port, u_int32_t data)
-{
- stl(KV(IRONGATE_IO + port), data);
- alpha_mb();
-}
-
-static u_int8_t
-irongate_readb(u_int32_t pa)
-{
- alpha_mb();
- return ldbu(KV(IRONGATE_MEM + pa));
-}
-
-static u_int16_t
-irongate_readw(u_int32_t pa)
-{
- alpha_mb();
- return ldwu(KV(IRONGATE_MEM + pa));
-}
-
-static u_int32_t
-irongate_readl(u_int32_t pa)
-{
- alpha_mb();
- return ldl(KV(IRONGATE_MEM + pa));
-}
-
-static void
-irongate_writeb(u_int32_t pa, u_int8_t data)
-{
- stb(KV(IRONGATE_MEM + pa), data);
- alpha_mb();
-}
-
-static void
-irongate_writew(u_int32_t pa, u_int16_t data)
-{
- stw(KV(IRONGATE_MEM + pa), data);
- alpha_mb();
-}
-
-static void
-irongate_writel(u_int32_t pa, u_int32_t data)
-{
- stl(KV(IRONGATE_MEM + pa), data);
- alpha_mb();
-}
-
-static int
-irongate_maxdevs(u_int b)
-{
- return 12; /* XXX */
-}
-
-static void
-irongate_clear_abort(void)
-{
- alpha_mb();
- alpha_pal_draina();
-}
-
-static int
-irongate_check_abort(void)
-{
- alpha_pal_draina();
- alpha_mb();
-
- return 0;
-}
-
-#define IRONGATE_CFGADDR(b, s, f, r) \
- KV(IRONGATE_CONF | ((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
-
-#define CFGREAD(h, b, s, f, r, op, width, type) \
- vm_offset_t va; \
- type data; \
- va = IRONGATE_CFGADDR(b, s, f, r); \
- irongate_clear_abort(); \
- if (badaddr((caddr_t)va, width)) { \
- irongate_check_abort(); \
- return ~0; \
- } \
- data = ##op##(va); \
- if (irongate_check_abort()) \
- return ~0; \
- return data;
-
-#define CFWRITE(h, b, s, f, r, data, op, width) \
- vm_offset_t va; \
- va = IRONGATE_CFGADDR(b, s, f, r); \
- irongate_clear_abort(); \
- if (badaddr((caddr_t)va, width)) \
- return; \
- ##op##(va, data); \
- irongate_check_abort();
-
-
-
-
-static u_int8_t
-irongate_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(h, b, s, f, r, ldbu, 1, u_int8_t)
-}
-
-static u_int16_t
-irongate_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(h, b, s, f, r, ldwu, 2, u_int16_t)
-}
-
-static u_int32_t
-irongate_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(h, b, s, f, r, ldl, 4, u_int32_t)
-}
-
-static void
-irongate_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
-{
- CFWRITE(h, b, s, f, r, data, stb, 1)
-}
-
-static void
-irongate_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
-{
- CFWRITE(h, b, s, f, r, data, stw, 2)
-}
-
-static void
-irongate_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
-{
- CFWRITE(h, b, s, f, r, data, stl, 4)
-}
-
-
-vm_offset_t
-irongate_cvt_bwx(vm_offset_t addr)
-{
- addr &= 0xffffffffUL;
- return (KV(addr | IRONGATE_MEM));
-}
-
-vm_offset_t
-irongate_cvt_dense(vm_offset_t addr)
-{
- return irongate_cvt_bwx(addr);
-}
-
-
/*
* There doesn't appear to be an hae on this platform
*/
@@ -347,6 +119,7 @@ void
irongate_init()
{
static int initted = 0;
+ struct bwx_space io_space, mem_space;
if (initted) return;
initted = 1;
@@ -354,6 +127,12 @@ irongate_init()
chipset = irongate_chipset;
alpha_XXX_dmamap_or = 0UL;
+ bwx_init_space(&io_space, KV(IRONGATE_IO));
+ bwx_init_space(&mem_space, KV(IRONGATE_MEM));
+
+ busspace_isa_io = (kobj_t) &io_space;
+ busspace_isa_mem = (kobj_t) &mem_space;
+
if (platform.pci_intr_init)
platform.pci_intr_init();
}
@@ -377,10 +156,6 @@ irongate_probe(device_t dev)
static int
irongate_attach(device_t dev)
{
- u_int8_t value;
- pcicfgregs southbridge;
-
-
irongate_init();
if (!platform.iointr) /* XXX */
@@ -395,22 +170,6 @@ irongate_attach(device_t dev)
/* no s/g support in this chipset, must use bounce-buffers */
chipset.sgmap = NULL;
- /*
- * XXX -- The SRM console doesn't properly initialize
- * the AcerLabs M1533C southbridge. We must turn off 32-bit
- * DMA support.
- */
-
- southbridge.hose = 0;
- southbridge.bus = 0;
- southbridge.slot = 7;
- southbridge.func = 0;
- if ((0x153310b9 == pci_cfgread(&southbridge, PCIR_DEVVENDOR, 4))) {
- value = (u_int8_t)pci_cfgread(&southbridge, 0x42, 1);
- value &= ~0x40;
- pci_cfgwrite(&southbridge, 0x42, 0, 1);
- }
-
bus_generic_attach(dev);
return 0;
diff --git a/sys/alpha/pci/irongate_pci.c b/sys/alpha/pci/irongate_pci.c
index e8cf291..3b62716 100644
--- a/sys/alpha/pci/irongate_pci.c
+++ b/sys/alpha/pci/irongate_pci.c
@@ -34,14 +34,19 @@
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/md_var.h>
+#include <machine/bwx.h>
#include <sys/rman.h>
#include <pci/pcivar.h>
+#include <pci/pcireg.h>
#include <alpha/pci/irongatereg.h>
#include <alpha/pci/irongatevar.h>
+#include "alphapci_if.h"
+#include "pcib_if.h"
-static devclass_t pcib_devclass;
+#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
+static devclass_t pcib_devclass;
static int
irongate_pcib_probe(device_t dev)
@@ -49,7 +54,19 @@ irongate_pcib_probe(device_t dev)
device_set_desc(dev, "AMD 751 PCI host bus adapter");
- device_add_child(dev, "pci", -1);
+ device_add_child(dev, "pci", 0);
+
+ /*
+ * XXX -- The SRM console doesn't properly initialize
+ * the AcerLabs M1533C southbridge. We must turn off 32-bit
+ * DMA support.
+ */
+ if ((0x153310b9 == PCIB_READ_CONFIG(dev, 0, 7, 0,
+ PCIR_DEVVENDOR, 4))) {
+ u_int8_t value = PCIB_READ_CONFIG(dev, 0, 7, 0, 0x42, 1);
+ value &= ~0x40;
+ PCIB_WRITE_CONFIG(dev, 0, 7, 0, 0x42, 0, 1);
+ }
return 0;
}
@@ -57,13 +74,107 @@ irongate_pcib_probe(device_t dev)
static int
irongate_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
{
- if (which == PCIB_IVAR_HOSE) {
+ switch (which) {
+ case PCIB_IVAR_BUS:
*result = 0;
return 0;
}
return ENOENT;
}
+static void *
+irongate_pcib_cvt_dense(device_t dev, vm_offset_t addr)
+{
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | IRONGATE_MEM);
+}
+
+static void *
+irongate_pcib_cvt_bwx(device_t dev, vm_offset_t addr)
+{
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | IRONGATE_MEM);
+}
+
+static int
+irongate_pcib_maxslots(device_t dev)
+{
+ return 31;
+}
+
+static void
+irongate_clear_abort(void)
+{
+ alpha_mb();
+ alpha_pal_draina();
+}
+
+static int
+irongate_check_abort(void)
+{
+ alpha_pal_draina();
+ alpha_mb();
+
+ return 0;
+}
+
+#define IRONGATE_CFGADDR(b, s, f, r) \
+ KV(IRONGATE_CONF | ((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
+
+#define CFGREAD(b, s, f, r, width, type, op) do { \
+ vm_offset_t va; \
+ type data; \
+ va = IRONGATE_CFGADDR(b, s, f, r); \
+ irongate_clear_abort(); \
+ if (badaddr((caddr_t)va, width)) { \
+ irongate_check_abort(); \
+ return ~0; \
+ } \
+ data = ##op##(va); \
+ if (irongate_check_abort()) \
+ return ~0; \
+ return data; \
+} while (0)
+
+#define CFGWRITE(b, s, f, r, data, width, op) do { \
+ vm_offset_t va; \
+ va = IRONGATE_CFGADDR(b, s, f, r); \
+ irongate_clear_abort(); \
+ if (badaddr((caddr_t)va, width)) \
+ return; \
+ ##op##(va, data); \
+ irongate_check_abort(); \
+} while (0)
+
+static u_int32_t
+irongate_pcib_read_config(device_t dev, int b, int s, int f,
+ int reg, int width)
+{
+ switch (width) {
+ case 1:
+ CFGREAD(b, s, f, reg, 1, u_int8_t, ldbu);
+ case 2:
+ CFGREAD(b, s, f, reg, 2, u_int16_t, ldwu);
+ case 4:
+ CFGREAD(b, s, f, reg, 4, u_int32_t, ldl);
+ }
+ return ~0;
+}
+
+static void
+irongate_pcib_write_config(device_t dev, int b, int s, int f,
+ int reg, u_int32_t val, int width)
+{
+ switch (width) {
+ case 1:
+ CFGWRITE(b, s, f, reg, val, 1, stb);
+ case 2:
+ CFGWRITE(b, s, f, reg, val, 2, stw);
+ case 4:
+ CFGWRITE(b, s, f, reg, val, 4, stl);
+ }
+}
+
static device_method_t irongate_pcib_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, irongate_pcib_probe),
@@ -79,17 +190,23 @@ static device_method_t irongate_pcib_methods[] = {
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ /* alphapci interface */
+ DEVMETHOD(alphapci_cvt_dense, irongate_pcib_cvt_dense),
+ DEVMETHOD(alphapci_cvt_bwx, irongate_pcib_cvt_bwx),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, irongate_pcib_maxslots),
+ DEVMETHOD(pcib_read_config, irongate_pcib_read_config),
+ DEVMETHOD(pcib_write_config, irongate_pcib_write_config),
{ 0, 0 }
};
-
static driver_t irongate_pcib_driver = {
"pcib",
irongate_pcib_methods,
1,
};
-
DRIVER_MODULE(pcib, irongate, irongate_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/alpha/pci/lca.c b/sys/alpha/pci/lca.c
index c1b8082..323c94c 100644
--- a/sys/alpha/pci/lca.c
+++ b/sys/alpha/pci/lca.c
@@ -59,97 +59,14 @@ struct lca_softc {
#define LCA_SOFTC(dev) (struct lca_softc*) device_get_softc(dev)
-static alpha_chipset_inb_t lca_inb;
-static alpha_chipset_inw_t lca_inw;
-static alpha_chipset_inl_t lca_inl;
-static alpha_chipset_outb_t lca_outb;
-static alpha_chipset_outw_t lca_outw;
-static alpha_chipset_outl_t lca_outl;
-static alpha_chipset_readb_t lca_readb;
-static alpha_chipset_readw_t lca_readw;
-static alpha_chipset_readl_t lca_readl;
-static alpha_chipset_writeb_t lca_writeb;
-static alpha_chipset_writew_t lca_writew;
-static alpha_chipset_writel_t lca_writel;
-static alpha_chipset_maxdevs_t lca_maxdevs;
-static alpha_chipset_cfgreadb_t lca_cfgreadb;
-static alpha_chipset_cfgreadw_t lca_cfgreadw;
-static alpha_chipset_cfgreadl_t lca_cfgreadl;
-static alpha_chipset_cfgwriteb_t lca_cfgwriteb;
-static alpha_chipset_cfgwritew_t lca_cfgwritew;
-static alpha_chipset_cfgwritel_t lca_cfgwritel;
-static alpha_chipset_addrcvt_t lca_cvt_dense;
static alpha_chipset_read_hae_t lca_read_hae;
static alpha_chipset_write_hae_t lca_write_hae;
static alpha_chipset_t lca_chipset = {
- lca_inb,
- lca_inw,
- lca_inl,
- lca_outb,
- lca_outw,
- lca_outl,
- lca_readb,
- lca_readw,
- lca_readl,
- lca_writeb,
- lca_writew,
- lca_writel,
- lca_maxdevs,
- lca_cfgreadb,
- lca_cfgreadw,
- lca_cfgreadl,
- lca_cfgwriteb,
- lca_cfgwritew,
- lca_cfgwritel,
- lca_cvt_dense,
- NULL,
lca_read_hae,
lca_write_hae,
};
-static u_int8_t
-lca_inb(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_BYTE(KV(LCA_PCI_SIO), port);
-}
-
-static u_int16_t
-lca_inw(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_WORD(KV(LCA_PCI_SIO), port);
-}
-
-static u_int32_t
-lca_inl(u_int32_t port)
-{
- alpha_mb();
- return SPARSE_READ_LONG(KV(LCA_PCI_SIO), port);
-}
-
-static void
-lca_outb(u_int32_t port, u_int8_t data)
-{
- SPARSE_WRITE_BYTE(KV(LCA_PCI_SIO), port, data);
- alpha_wmb();
-}
-
-static void
-lca_outw(u_int32_t port, u_int16_t data)
-{
- SPARSE_WRITE_WORD(KV(LCA_PCI_SIO), port, data);
- alpha_wmb();
-}
-
-static void
-lca_outl(u_int32_t port, u_int32_t data)
-{
- SPARSE_WRITE_LONG(KV(LCA_PCI_SIO), port, data);
- alpha_wmb();
-}
-
/*
* The LCA HAE is write-only. According to NetBSD, this is where it starts.
*/
@@ -161,14 +78,14 @@ static u_int32_t lca_hae_mem = 0x80000000;
*/
#define REG1 (1UL << 24)
-static __inline void
-lca_set_hae_mem(u_int32_t *pa)
+static u_int32_t
+lca_set_hae_mem(void *arg, u_int32_t pa)
{
int s;
u_int32_t msb;
- if(*pa >= REG1){
- msb = *pa & 0xf8000000;
- *pa -= msb;
+ if(pa >= REG1){
+ msb = pa & 0xf8000000;
+ pa -= msb;
s = splhigh();
if (msb != lca_hae_mem) {
lca_hae_mem = msb;
@@ -178,152 +95,7 @@ lca_set_hae_mem(u_int32_t *pa)
}
splx(s);
}
-}
-
-static u_int8_t
-lca_readb(u_int32_t pa)
-{
- alpha_mb();
- lca_set_hae_mem(&pa);
- return SPARSE_READ_BYTE(KV(LCA_PCI_SPARSE), pa);
-}
-
-static u_int16_t
-lca_readw(u_int32_t pa)
-{
- alpha_mb();
- lca_set_hae_mem(&pa);
- return SPARSE_READ_WORD(KV(LCA_PCI_SPARSE), pa);
-}
-
-static u_int32_t
-lca_readl(u_int32_t pa)
-{
- alpha_mb();
- lca_set_hae_mem(&pa);
- return SPARSE_READ_LONG(KV(LCA_PCI_SPARSE), pa);
-}
-
-static void
-lca_writeb(u_int32_t pa, u_int8_t data)
-{
- lca_set_hae_mem(&pa);
- SPARSE_WRITE_BYTE(KV(LCA_PCI_SPARSE), pa, data);
- alpha_wmb();
-}
-
-static void
-lca_writew(u_int32_t pa, u_int16_t data)
-{
- lca_set_hae_mem(&pa);
- SPARSE_WRITE_WORD(KV(LCA_PCI_SPARSE), pa, data);
- alpha_wmb();
-}
-
-static void
-lca_writel(u_int32_t pa, u_int32_t data)
-{
- lca_set_hae_mem(&pa);
- SPARSE_WRITE_LONG(KV(LCA_PCI_SPARSE), pa, data);
- alpha_wmb();
-}
-
-static int
-lca_maxdevs(u_int b)
-{
- return 12; /* XXX */
-}
-
-#define LCA_CFGOFF(b, s, f, r) \
- ((b) ? (((b) << 16) | ((s) << 11) | ((f) << 8) | (r)) \
- : ((1 << ((s) + 11)) | ((f) << 8) | (r)))
-
-#define LCA_TYPE1_SETUP(b,s) if ((b)) { \
- do { \
- (s) = splhigh(); \
- alpha_mb(); \
- REGVAL(LCA_IOC_CONF) = 1; \
- alpha_mb(); \
- } while(0); \
-}
-
-#define LCA_TYPE1_TEARDOWN(b,s) if ((b)) { \
- do { \
- alpha_mb(); \
- REGVAL(LCA_IOC_CONF) = 0; \
- alpha_mb(); \
- splx((s)); \
- } while(0); \
-}
-
-#define CFGREAD(b, s, f, r, width, type) \
- type val = ~0; \
- int ipl = 0; \
- vm_offset_t off = LCA_CFGOFF(b, s, f, r); \
- vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(LCA_PCI_CONF), off); \
- alpha_mb(); \
- LCA_TYPE1_SETUP(b,ipl); \
- if (!badaddr((caddr_t)kv, sizeof(type))) { \
- val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
- } \
- LCA_TYPE1_TEARDOWN(b,ipl); \
- return val
-
-#define CFGWRITE(b, s, f, r, data, width, type) \
- int ipl = 0; \
- vm_offset_t off = LCA_CFGOFF(b, s, f, r); \
- vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(LCA_PCI_CONF), off); \
- alpha_mb(); \
- LCA_TYPE1_SETUP(b,ipl); \
- if (!badaddr((caddr_t)kv, sizeof(type))) { \
- SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \
- alpha_wmb(); \
- } \
- LCA_TYPE1_TEARDOWN(b,ipl); \
- return
-
-static u_int8_t
-lca_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(b, s, f, r, BYTE, u_int8_t);
-}
-
-static u_int16_t
-lca_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(b, s, f, r, WORD, u_int16_t);
-}
-
-static u_int32_t
-lca_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(b, s, f, r, LONG, u_int32_t);
-}
-
-static void
-lca_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
-{
- CFGWRITE(b, s, f, r, data, BYTE, u_int8_t);
-}
-
-static void
-lca_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
-{
- CFGWRITE(b, s, f, r, data, WORD, u_int16_t);
-}
-
-static void
-lca_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
-{
- CFGWRITE(b, s, f, r, data, LONG, u_int16_t);
-}
-
-static vm_offset_t
-lca_cvt_dense(vm_offset_t addr)
-{
- addr &= 0xffffffffUL;
- return (addr | LCA_PCI_DENSE);
-
+ return pa;
}
static u_int64_t
@@ -336,7 +108,7 @@ static void
lca_write_hae(u_int64_t hae)
{
u_int32_t pa = hae;
- lca_set_hae_mem(&pa);
+ lca_set_hae_mem(0, pa);
}
static int lca_probe(device_t dev);
@@ -382,7 +154,7 @@ lca_sgmap_invalidate(void)
}
static void
-lca_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa)
+lca_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
{
u_int64_t *sgtable = arg;
int index = alpha_btop(ba - LCA_SGMAP_BASE);
@@ -435,10 +207,18 @@ void
lca_init()
{
static int initted = 0;
+ static struct swiz_space io_space, mem_space;
if (initted) return;
initted = 1;
+ swiz_init_space(&io_space, KV(LCA_PCI_SIO));
+ swiz_init_space_hae(&mem_space, KV(LCA_PCI_SPARSE),
+ lca_set_hae_mem, 0);
+
+ busspace_isa_io = (struct alpha_busspace *) &io_space;
+ busspace_isa_mem = (struct alpha_busspace *) &mem_space;
+
/* Type 0 PCI conf access. */
REGVAL64(LCA_IOC_CONF) = 0;
diff --git a/sys/alpha/pci/lca_pci.c b/sys/alpha/pci/lca_pci.c
index 1765c3b..e17d1e4 100644
--- a/sys/alpha/pci/lca_pci.c
+++ b/sys/alpha/pci/lca_pci.c
@@ -34,6 +34,15 @@
#include <machine/bus.h>
#include <sys/rman.h>
#include <pci/pcivar.h>
+#include <machine/swiz.h>
+
+#include <alpha/pci/lcareg.h>
+#include <alpha/pci/lcavar.h>
+
+#include "alphapci_if.h"
+#include "pcib_if.h"
+
+#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
static devclass_t pcib_devclass;
@@ -50,13 +59,105 @@ lca_pcib_probe(device_t dev)
static int
lca_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
{
- if (which == PCIB_IVAR_HOSE) {
+ if (which == PCIB_IVAR_BUS) {
*result = 0;
return 0;
}
return ENOENT;
}
+static void *
+lca_pcib_cvt_dense(device_t dev, vm_offset_t addr)
+{
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | LCA_PCI_DENSE);
+}
+
+static int
+lca_pcib_maxslots(device_t dev)
+{
+ return 31;
+}
+
+#define LCA_CFGOFF(b, s, f, r) \
+ ((b) ? (((b) << 16) | ((s) << 11) | ((f) << 8) | (r)) \
+ : ((1 << ((s) + 11)) | ((f) << 8) | (r)))
+
+#define LCA_TYPE1_SETUP(b,s) if ((b)) { \
+ do { \
+ (s) = splhigh(); \
+ alpha_mb(); \
+ REGVAL(LCA_IOC_CONF) = 1; \
+ alpha_mb(); \
+ } while(0); \
+}
+
+#define LCA_TYPE1_TEARDOWN(b,s) if ((b)) { \
+ do { \
+ alpha_mb(); \
+ REGVAL(LCA_IOC_CONF) = 0; \
+ alpha_mb(); \
+ splx((s)); \
+ } while(0); \
+}
+
+#define CFGREAD(b, s, f, r, width, type) do { \
+ type val = ~0; \
+ int ipl = 0; \
+ vm_offset_t off = LCA_CFGOFF(b, s, f, r); \
+ vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(LCA_PCI_CONF), off); \
+ alpha_mb(); \
+ LCA_TYPE1_SETUP(b,ipl); \
+ if (!badaddr((caddr_t)kv, sizeof(type))) { \
+ val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
+ } \
+ LCA_TYPE1_TEARDOWN(b,ipl); \
+ return val; \
+} while (0)
+
+#define CFGWRITE(b, s, f, r, data, width, type) do { \
+ int ipl = 0; \
+ vm_offset_t off = LCA_CFGOFF(b, s, f, r); \
+ vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(LCA_PCI_CONF), off); \
+ alpha_mb(); \
+ LCA_TYPE1_SETUP(b,ipl); \
+ if (!badaddr((caddr_t)kv, sizeof(type))) { \
+ SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \
+ alpha_wmb(); \
+ } \
+ LCA_TYPE1_TEARDOWN(b,ipl); \
+ return; \
+} while (0)
+
+u_int32_t
+lca_pcib_read_config(device_t dev, int b, int s, int f,
+ int reg, int width)
+{
+ switch (width) {
+ case 1:
+ CFGREAD(b, s, f, reg, BYTE, u_int8_t);
+ case 2:
+ CFGREAD(b, s, f, reg, WORD, u_int16_t);
+ case 4:
+ CFGREAD(b, s, f, reg, LONG, u_int32_t);
+ }
+ return ~0;
+}
+
+static void
+lca_pcib_write_config(device_t dev, int b, int s, int f,
+ int reg, u_int32_t val, int width)
+{
+ switch (width) {
+ case 1:
+ CFGWRITE(b, s, f, reg, val, BYTE, u_int8_t);
+ case 2:
+ CFGWRITE(b, s, f, reg, val, WORD, u_int16_t);
+ case 4:
+ CFGWRITE(b, s, f, reg, val, LONG, u_int32_t);
+ }
+}
+
static device_method_t lca_pcib_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, lca_pcib_probe),
@@ -72,6 +173,14 @@ static device_method_t lca_pcib_methods[] = {
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ /* alphapci interface */
+ DEVMETHOD(alphapci_cvt_dense, lca_pcib_cvt_dense),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, lca_pcib_maxslots),
+ DEVMETHOD(pcib_read_config, lca_pcib_read_config),
+ DEVMETHOD(pcib_write_config, lca_pcib_write_config),
+
{ 0, 0 }
};
diff --git a/sys/alpha/pci/lcavar.h b/sys/alpha/pci/lcavar.h
index 1619539..2f22ade 100644
--- a/sys/alpha/pci/lcavar.h
+++ b/sys/alpha/pci/lcavar.h
@@ -26,4 +26,8 @@
* $FreeBSD$
*/
+struct device;
+
extern void lca_init(void);
+u_int32_t lca_pcib_read_config(struct device *dev, int b, int s, int f,
+ int reg, int width);
diff --git a/sys/alpha/pci/mcpcia_pci.c b/sys/alpha/pci/mcpcia_pci.c
deleted file mode 100644
index cbcf934..0000000
--- a/sys/alpha/pci/mcpcia_pci.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $FreeBSD$ */
-/*
- * Copyright (c) 2000 Matthew Jacob
- * 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.
- *
- */
-
-#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
-mcpcia_pcib_probe(device_t dev)
-{
- device_set_desc(dev, "MCPCIA PCI host bus adapter");
- device_add_child(dev, "pci", device_get_unit(dev) << 4);
- return (0);
-}
-
-static int
-mcpcia_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
-{
- if (which == PCIB_IVAR_HOSE) {
- *result = *(int*) device_get_ivars(dev);
- return 0;
- }
- return ENOENT;
-}
-
-static device_method_t mcpcia_pcib_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, mcpcia_pcib_probe),
- DEVMETHOD(device_attach, bus_generic_attach),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_read_ivar, mcpcia_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 mcpcia_pcib_driver = {
- "pcib", mcpcia_pcib_methods, 1
-};
-
-DRIVER_MODULE(pcib, mcpcia, mcpcia_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/alpha/pci/pcibus.c b/sys/alpha/pci/pcibus.c
index 5bed15e..8aaf9fb 100644
--- a/sys/alpha/pci/pcibus.c
+++ b/sys/alpha/pci/pcibus.c
@@ -45,11 +45,15 @@
#include <alpha/pci/pcibus.h>
#include <alpha/isa/isavar.h>
+#include "alphapci_if.h"
#include "isa.h"
#define ISA_IRQ_OFFSET 0xe0
#define ISA_IRQ_LEN 0x10
+struct alpha_busspace *busspace_isa_io;
+struct alpha_busspace *busspace_isa_mem;
+
char chipset_type[10];
int chipset_bwx = 0;
long chipset_ports = 0;
@@ -71,73 +75,6 @@ SYSCTL_LONG(_hw_chipset, OID_AUTO, dense, CTLFLAG_RD, &chipset_dense, 0,
SYSCTL_LONG(_hw_chipset, OID_AUTO, hae_mask, CTLFLAG_RD, &chipset_hae_mask, 0,
"PCI chipset mask for HAE register");
-#ifdef notyet
-
-/* return max number of devices on the bus */
-int
-pci_maxdevs(pcicfgregs *cfg)
-{
- return chipset.maxdevs(cfg->bus);
-}
-
-#endif
-
-/* read configuration space register */
-
-int
-pci_cfgread(pcicfgregs *cfg, int reg, int bytes)
-{
- switch (bytes) {
- case 1:
- return chipset.cfgreadb(cfg->hose, cfg->bus,
- cfg->slot, cfg->func, reg);
- case 2:
- return chipset.cfgreadw(cfg->hose, cfg->bus,
- cfg->slot, cfg->func, reg);
- case 4:
- return chipset.cfgreadl(cfg->hose, cfg->bus,
- cfg->slot, cfg->func, reg);
- }
- return ~0;
-}
-
-
-/* write configuration space register */
-
-void
-pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes)
-{
- switch (bytes) {
- case 1:
- return chipset.cfgwriteb(cfg->hose, cfg->bus,
- cfg->slot, cfg->func, reg, data);
- case 2:
- return chipset.cfgwritew(cfg->hose, cfg->bus,
- cfg->slot, cfg->func, reg, data);
- case 4:
- return chipset.cfgwritel(cfg->hose, cfg->bus,
- cfg->slot, cfg->func, reg, data);
- }
-}
-
-vm_offset_t
-pci_cvt_to_dense(vm_offset_t sparse)
-{
- if(chipset.cvt_to_dense)
- return ALPHA_PHYS_TO_K0SEG(chipset.cvt_to_dense(sparse));
- else
- return NULL;
-}
-
-vm_offset_t
-pci_cvt_to_bwx(vm_offset_t sparse)
-{
- if(chipset.cvt_to_bwx)
- return ALPHA_PHYS_TO_K0SEG(chipset.cvt_to_bwx(sparse));
- else
- return NULL;
-}
-
void
alpha_platform_assign_pciintr(pcicfgregs *cfg)
{
@@ -274,6 +211,7 @@ pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
{
struct rman *rm;
struct resource *rv;
+ void *va;
switch (type) {
case SYS_RES_IRQ:
@@ -290,11 +228,8 @@ pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
break;
case SYS_RES_IOPORT:
- rm = &port_rman;
- break;
-
case SYS_RES_MEMORY:
- rm = &mem_rman;
+ rm = ALPHAPCI_GET_RMAN(bus, type);
break;
default:
@@ -305,21 +240,19 @@ pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
if (rv == 0)
return 0;
+ rman_set_bustag(rv, ALPHAPCI_GET_BUSTAG(bus, type));
+ rman_set_bushandle(rv, rv->r_start);
switch (type) {
case SYS_RES_MEMORY:
- rman_set_bustag(rv, ALPHA_BUS_SPACE_MEM);
- rman_set_bushandle(rv, rv->r_start);
+ va = 0;
if (flags & PCI_RF_DENSE)
- rman_set_virtual(rv, (void *) pci_cvt_to_dense(rv->r_start));
+ va = ALPHAPCI_CVT_DENSE(bus, rv->r_start);
else if (flags & PCI_RF_BWX)
- rman_set_virtual(rv, (void *) pci_cvt_to_bwx(rv->r_start));
+ va = ALPHAPCI_CVT_BWX(bus, rv->r_start);
else
- rman_set_virtual(rv, (void *) rv->r_start); /* maybe NULL? */
- break;
+ va = (void *) rv->r_start; /* maybe NULL? */
+ rman_set_virtual(rv, va);
- case SYS_RES_IOPORT:
- rman_set_bustag(rv, ALPHA_BUS_SPACE_IO);
- rman_set_bushandle(rv, rv->r_start);
break;
}
@@ -347,54 +280,32 @@ pci_release_resource(device_t bus, device_t child, int type, int rid,
return (rman_release_resource(r));
}
-void
-memcpy_fromio(void *d, u_int32_t s, size_t size)
-{
- char *cp = d;
-
- while (size--)
- *cp++ = readb(s++);
-}
-
-void
-memcpy_toio(u_int32_t d, void *s, size_t size)
+struct alpha_busspace *
+pci_get_bustag(device_t dev, int type)
{
- char *cp = s;
-
- while (size--)
- writeb(d++, *cp++);
-}
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return busspace_isa_io;
-void
-memcpy_io(u_int32_t d, u_int32_t s, size_t size)
-{
- while (size--)
- writeb(d++, readb(s++));
-}
+ case SYS_RES_MEMORY:
+ return busspace_isa_mem;
+ }
-void
-memset_io(u_int32_t d, int val, size_t size)
-{
- while (size--)
- writeb(d++, val);
+ return 0;
}
-void
-memsetw(void *d, int val, size_t size)
+struct rman *
+pci_get_rman(device_t dev, int type)
{
- u_int16_t *sp = d;
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return &port_rman;
- while (size--)
- *sp++ = val;
-}
+ case SYS_RES_MEMORY:
+ return &mem_rman;
+ }
-void
-memsetw_io(u_int32_t d, int val, size_t size)
-{
- while (size--) {
- writew(d, val);
- d += sizeof(u_int16_t);
- }
+ return 0;
}
#include "opt_ddb.h"
diff --git a/sys/alpha/pci/pcibus.h b/sys/alpha/pci/pcibus.h
index 27c5ffa..aa3e105 100644
--- a/sys/alpha/pci/pcibus.h
+++ b/sys/alpha/pci/pcibus.h
@@ -37,3 +37,5 @@ int pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r);
int pci_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r);
+struct alpha_busspace *pci_get_bustag(device_t dev, int type);
+struct rman *pci_get_rman(device_t dev, int type);
diff --git a/sys/alpha/pci/swiz.c b/sys/alpha/pci/swiz.c
new file mode 100644
index 0000000..01b3059
--- /dev/null
+++ b/sys/alpha/pci/swiz.c
@@ -0,0 +1,154 @@
+/*-
+ * 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, 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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/kobj.h>
+
+#include <machine/bus.h>
+#include <machine/swiz.h>
+
+static u_int8_t
+swiz_read_1(struct alpha_busspace *space, size_t offset)
+{
+ struct swiz_space *swiz = (struct swiz_space *) space;
+ alpha_mb();
+ if (swiz->sethae)
+ offset = swiz->sethae(swiz->arg, offset);
+ return SPARSE_READ_BYTE(swiz->base, offset);
+}
+
+static u_int16_t
+swiz_read_2(struct alpha_busspace *space, size_t offset)
+{
+ struct swiz_space *swiz = (struct swiz_space *) space;
+ alpha_mb();
+ if (swiz->sethae)
+ offset = swiz->sethae(swiz->arg, offset);
+ return SPARSE_READ_WORD(swiz->base, offset);
+}
+
+static u_int32_t
+swiz_read_4(struct alpha_busspace *space, size_t offset)
+{
+ struct swiz_space *swiz = (struct swiz_space *) space;
+ alpha_mb();
+ if (swiz->sethae)
+ offset = swiz->sethae(swiz->arg, offset);
+ return SPARSE_READ_LONG(swiz->base, offset);
+}
+
+static void
+swiz_write_1(struct alpha_busspace *space, size_t offset, u_int8_t data)
+{
+ struct swiz_space *swiz = (struct swiz_space *) space;
+ if (swiz->sethae)
+ offset = swiz->sethae(swiz->arg, offset);
+ SPARSE_WRITE_BYTE(swiz->base, offset, data);
+ alpha_mb();
+}
+
+static void
+swiz_write_2(struct alpha_busspace *space, size_t offset, u_int16_t data)
+{
+ struct swiz_space *swiz = (struct swiz_space *) space;
+ if (swiz->sethae)
+ offset = swiz->sethae(swiz->arg, offset);
+ SPARSE_WRITE_WORD(swiz->base, offset, data);
+ alpha_mb();
+}
+
+static void
+swiz_write_4(struct alpha_busspace *space, size_t offset, u_int32_t data)
+{
+ struct swiz_space *swiz = (struct swiz_space *) space;
+ if (swiz->sethae)
+ offset = swiz->sethae(swiz->arg, offset);
+ SPARSE_WRITE_LONG(swiz->base, offset, data);
+ alpha_mb();
+}
+
+static struct alpha_busspace_ops swiz_space_ops = {
+ swiz_read_1,
+ swiz_read_2,
+ swiz_read_4,
+
+ busspace_generic_read_multi_1,
+ busspace_generic_read_multi_2,
+ busspace_generic_read_multi_4,
+
+ busspace_generic_read_region_1,
+ busspace_generic_read_region_2,
+ busspace_generic_read_region_4,
+
+ swiz_write_1,
+ swiz_write_2,
+ swiz_write_4,
+
+ busspace_generic_write_multi_1,
+ busspace_generic_write_multi_2,
+ busspace_generic_write_multi_4,
+
+ busspace_generic_write_region_1,
+ busspace_generic_write_region_2,
+ busspace_generic_write_region_4,
+
+ busspace_generic_set_multi_1,
+ busspace_generic_set_multi_2,
+ busspace_generic_set_multi_4,
+
+ busspace_generic_set_region_1,
+ busspace_generic_set_region_2,
+ busspace_generic_set_region_4,
+
+ busspace_generic_copy_region_1,
+ busspace_generic_copy_region_2,
+ busspace_generic_copy_region_4,
+
+ busspace_generic_barrier,
+};
+
+void
+swiz_init_space(struct swiz_space *swiz, u_int64_t base)
+{
+ swiz->ops = &swiz_space_ops;
+ swiz->base = base;
+ swiz->sethae = 0;
+ swiz->arg = 0;
+}
+
+void swiz_init_space_hae(struct swiz_space *swiz, u_int64_t base,
+ swiz_sethae_fn sethae, void *arg)
+{
+ swiz->ops = &swiz_space_ops;
+ swiz->base = base;
+ swiz->sethae = sethae;
+ swiz->arg = arg;
+}
+
diff --git a/sys/alpha/pci/t2.c b/sys/alpha/pci/t2.c
index 554fc48..db7deae 100644
--- a/sys/alpha/pci/t2.c
+++ b/sys/alpha/pci/t2.c
@@ -66,110 +66,27 @@ struct t2_softc {
#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)
+static u_int32_t
+t2_set_hae_mem(void *arg, u_int32_t pa)
{
int s;
u_int32_t msb;
- if(*pa >= REG1){
- msb = *pa & 0xf8000000;
- *pa -= 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) {
@@ -180,72 +97,7 @@ t2_set_hae_mem(u_int32_t *pa)
}
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);
-
+ return pa;
}
static u_int64_t
@@ -258,94 +110,7 @@ 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);
+ t2_set_hae_mem(0, pa);
}
static int t2_probe(device_t dev);
@@ -407,7 +172,7 @@ t2_sgmap_invalidate(void)
}
static void
-t2_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa)
+t2_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
{
u_int64_t *sgtable = arg;
int index = alpha_btop(ba - T2_SGMAP_BASE);
@@ -468,10 +233,18 @@ void
t2_init()
{
static int initted = 0;
+ static struct swiz_space io_space, mem_space;
if (initted) return;
initted = 1;
+ swiz_init_space(&io_space, KV(T2_PCI_SIO));
+ swiz_init_space_hae(&mem_space, KV(T2_PCI_SPARSE),
+ t2_set_hae_mem, 0);
+
+ busspace_isa_io = (kobj_t) &io_space;
+ busspace_isa_mem = (kobj_t) &mem_space;
+
chipset = t2_chipset;
}
diff --git a/sys/alpha/pci/t2_pci.c b/sys/alpha/pci/t2_pci.c
index 2213bb3..5d3eb21 100644
--- a/sys/alpha/pci/t2_pci.c
+++ b/sys/alpha/pci/t2_pci.c
@@ -34,6 +34,15 @@
#include <machine/bus.h>
#include <sys/rman.h>
#include <pci/pcivar.h>
+#include <machine/swiz.h>
+
+#include <alpha/pci/t2reg.h>
+#include <alpha/pci/t2var.h>
+
+#include "alphapci_if.h"
+#include "pcib_if.h"
+
+#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
static devclass_t pcib_devclass;
@@ -53,13 +62,108 @@ t2_pcib_probe(device_t dev)
static int
t2_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
{
- if (which == PCIB_IVAR_HOSE) {
+ if (which == PCIB_IVAR_BUS) {
*result = 0;
return 0;
}
return ENOENT;
}
+static void *
+t2_pcib_cvt_dense(device_t dev, vm_offset_t addr)
+{
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | T2_PCI_DENSE);
+}
+
+static int
+t2_pcib_maxslots(device_t dev)
+{
+ return 31;
+}
+
+#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) do { \
+ 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; \
+} while (0)
+
+#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) do { \
+ 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; \
+} while (0)
+
+static u_int32_t
+t2_pcib_read_config(device_t dev, int b, int s, int f,
+ int reg, int width)
+{
+ switch (width) {
+ case 1:
+ SWIZ_CFGREAD(b, s, f, reg, BYTE, u_int8_t);
+ case 2:
+ SWIZ_CFGREAD(b, s, f, reg, WORD, u_int16_t);
+ case 4:
+ SWIZ_CFGREAD(b, s, f, reg, LONG, u_int32_t);
+ }
+ return ~0;
+}
+
+static void
+t2_pcib_write_config(device_t dev, int b, int s, int f,
+ int reg, u_int32_t val, int width)
+{
+ switch (width) {
+ case 1:
+ SWIZ_CFGWRITE(b, s, f, reg, val, BYTE, u_int8_t);
+ case 2:
+ SWIZ_CFGWRITE(b, s, f, reg, val, WORD, u_int16_t);
+ case 4:
+ SWIZ_CFGWRITE(b, s, f, reg, val, LONG, u_int32_t);
+ }
+}
+
static device_method_t t2_pcib_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, t2_pcib_probe),
@@ -75,6 +179,14 @@ static device_method_t t2_pcib_methods[] = {
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ /* alphapci interface */
+ DEVMETHOD(alphapci_cvt_dense, t2_pcib_cvt_dense),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, t2_pcib_maxslots),
+ DEVMETHOD(pcib_read_config, t2_pcib_read_config),
+ DEVMETHOD(pcib_write_config, t2_pcib_write_config),
+
{ 0, 0 }
};
diff --git a/sys/alpha/pci/t2var.h b/sys/alpha/pci/t2var.h
index ef47d0b..cadfa48 100644
--- a/sys/alpha/pci/t2var.h
+++ b/sys/alpha/pci/t2var.h
@@ -26,4 +26,6 @@
* $FreeBSD$
*/
+extern vm_offset_t t2_csr_base;
+
extern void t2_init(void);
diff --git a/sys/alpha/pci/tsunami.c b/sys/alpha/pci/tsunami.c
index 41f67a5..4f43e5c 100644
--- a/sys/alpha/pci/tsunami.c
+++ b/sys/alpha/pci/tsunami.c
@@ -67,302 +67,17 @@ static volatile tsunami_pchip *pchip[2] = {pchip0, pchip1};
#define TSUNAMI_SOFTC(dev) (struct tsunami_softc*) device_get_softc(dev)
-static alpha_chipset_inb_t tsunami_inb;
-static alpha_chipset_inw_t tsunami_inw;
-static alpha_chipset_inl_t tsunami_inl;
-static alpha_chipset_outb_t tsunami_outb;
-static alpha_chipset_outw_t tsunami_outw;
-static alpha_chipset_outl_t tsunami_outl;
-static alpha_chipset_readb_t tsunami_readb;
-static alpha_chipset_readw_t tsunami_readw;
-static alpha_chipset_readl_t tsunami_readl;
-static alpha_chipset_writeb_t tsunami_writeb;
-static alpha_chipset_writew_t tsunami_writew;
-static alpha_chipset_writel_t tsunami_writel;
-static alpha_chipset_maxdevs_t tsunami_maxdevs;
-static alpha_chipset_cfgreadb_t tsunami_cfgreadb;
-static alpha_chipset_cfgreadw_t tsunami_cfgreadw;
-static alpha_chipset_cfgreadl_t tsunami_cfgreadl;
-static alpha_chipset_cfgwriteb_t tsunami_cfgwriteb;
-static alpha_chipset_cfgwritew_t tsunami_cfgwritew;
-static alpha_chipset_cfgwritel_t tsunami_cfgwritel;
-static alpha_chipset_addrcvt_t tsunami_cvt_dense, tsunami_cvt_bwx;
-
static alpha_chipset_read_hae_t tsunami_read_hae;
static alpha_chipset_write_hae_t tsunami_write_hae;
static alpha_chipset_t tsunami_chipset = {
- tsunami_inb,
- tsunami_inw,
- tsunami_inl,
- tsunami_outb,
- tsunami_outw,
- tsunami_outl,
- tsunami_readb,
- tsunami_readw,
- tsunami_readl,
- tsunami_writeb,
- tsunami_writew,
- tsunami_writel,
- tsunami_maxdevs,
- tsunami_cfgreadb,
- tsunami_cfgreadw,
- tsunami_cfgreadl,
- tsunami_cfgwriteb,
- tsunami_cfgwritew,
- tsunami_cfgwritel,
- tsunami_cvt_dense,
- tsunami_cvt_bwx,
tsunami_read_hae,
tsunami_write_hae,
};
-/*
- * This setup will only allow for one additional hose
- */
-
-#define ADDR_TO_HOSE(x) ((x) >> 31)
-#define STRIP_HOSE(x) ((x) & 0x7fffffff)
-
static void tsunami_intr_enable __P((int));
static void tsunami_intr_disable __P((int));
-static u_int8_t
-tsunami_inb(u_int32_t port)
-{
- int hose = ADDR_TO_HOSE(port);
- port = STRIP_HOSE(port);
- alpha_mb();
- return ldbu(KV(TSUNAMI_IO(hose) + port));
-}
-
-static u_int16_t
-tsunami_inw(u_int32_t port)
-{
- int hose = ADDR_TO_HOSE(port);
- port = STRIP_HOSE(port);
- alpha_mb();
- return ldwu(KV(TSUNAMI_IO(hose) + port));
-}
-
-static u_int32_t
-tsunami_inl(u_int32_t port)
-{
- int hose = ADDR_TO_HOSE(port);
- port = STRIP_HOSE(port);
- alpha_mb();
- return ldl(KV(TSUNAMI_IO(hose) + port));
-}
-
-static void
-tsunami_outb(u_int32_t port, u_int8_t data)
-{
- int hose = ADDR_TO_HOSE(port);
- port = STRIP_HOSE(port);
- stb(KV(TSUNAMI_IO(hose) + port), data);
- alpha_mb();
-}
-
-static void
-tsunami_outw(u_int32_t port, u_int16_t data)
-{
- int hose = ADDR_TO_HOSE(port);
- port = STRIP_HOSE(port);
- stw(KV(TSUNAMI_IO(hose) + port), data);
- alpha_mb();
-}
-
-static void
-tsunami_outl(u_int32_t port, u_int32_t data)
-{
- int hose = ADDR_TO_HOSE(port);
- port = STRIP_HOSE(port);
- stl(KV(TSUNAMI_IO(hose) + port), data);
- alpha_mb();
-}
-
-static u_int8_t
-tsunami_readb(u_int32_t pa)
-{
- int hose = ADDR_TO_HOSE(pa);
- pa = STRIP_HOSE(pa);
- alpha_mb();
- return ldbu(KV(TSUNAMI_MEM(hose) + pa));
-}
-
-static u_int16_t
-tsunami_readw(u_int32_t pa)
-{
- int hose = ADDR_TO_HOSE(pa);
- pa = STRIP_HOSE(pa);
- alpha_mb();
- return ldwu(KV(TSUNAMI_MEM(hose) + pa));
-}
-
-static u_int32_t
-tsunami_readl(u_int32_t pa)
-{
- int hose = ADDR_TO_HOSE(pa);
- pa = STRIP_HOSE(pa);
- alpha_mb();
- return ldl(KV(TSUNAMI_MEM(hose) + pa));
-}
-
-static void
-tsunami_writeb(u_int32_t pa, u_int8_t data)
-{
- int hose = ADDR_TO_HOSE(pa);
- pa = STRIP_HOSE(pa);
- stb(KV(TSUNAMI_MEM(hose) + pa), data);
- alpha_mb();
-}
-
-static void
-tsunami_writew(u_int32_t pa, u_int16_t data)
-{
- int hose = ADDR_TO_HOSE(pa);
- pa = STRIP_HOSE(pa);
- stw(KV(TSUNAMI_MEM(hose) + pa), data);
- alpha_mb();
-}
-
-static void
-tsunami_writel(u_int32_t pa, u_int32_t data)
-{
- int hose = ADDR_TO_HOSE(pa);
- pa = STRIP_HOSE(pa);
- stl(KV(TSUNAMI_MEM(hose) + pa), data);
- alpha_mb();
-}
-
-static int
-tsunami_maxdevs(u_int b)
-{
- return 12; /* XXX */
-}
-
-static void
-tsunami_clear_abort(void)
-{
- alpha_mb();
- alpha_pal_draina();
-}
-
-static int
-tsunami_check_abort(void)
-{
-/* u_int32_t errbits;*/
- int ba = 0;
-
- alpha_pal_draina();
- alpha_mb();
-#if 0
- errbits = REGVAL(TSUNAMI_CSR_TSUNAMI_ERR);
- if (errbits & (TSUNAMI_ERR_RCVD_MAS_ABT|TSUNAMI_ERR_RCVD_TAR_ABT))
- ba = 1;
-
- if (errbits) {
- REGVAL(TSUNAMI_CSR_TSUNAMI_ERR) = errbits;
- alpha_mb();
- alpha_pal_draina();
- }
-#endif
- return ba;
-}
-
-#define TSUNAMI_CFGADDR(b, s, f, r, h) \
- KV(TSUNAMI_CONF(h) | ((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
-
-#define CFGREAD(h, b, s, f, r, op, width, type) \
- int bus; \
- vm_offset_t va; \
- type data; \
- if (h == (u_int8_t)-1) \
- h = tsunami_hose_from_bus(b); \
- bus = tsunami_bus_within_hose(h, b); \
- va = TSUNAMI_CFGADDR(bus, s, f, r, h); \
- tsunami_clear_abort(); \
- if (badaddr((caddr_t)va, width)) { \
- tsunami_check_abort(); \
- return ~0; \
- } \
- data = ##op##(va); \
- if (tsunami_check_abort()) \
- return ~0; \
- return data;
-
-#define CFWRITE(h, b, s, f, r, data, op, width) \
- int bus; \
- vm_offset_t va; \
- if (h == (u_int8_t)-1) \
- h = tsunami_hose_from_bus(b); \
- bus = tsunami_bus_within_hose(h, b); \
- va = TSUNAMI_CFGADDR(bus, s, f, r, h); \
- tsunami_clear_abort(); \
- if (badaddr((caddr_t)va, width)) \
- return; \
- ##op##(va, data); \
- tsunami_check_abort();
-
-
-
-
-static u_int8_t
-tsunami_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(h, b, s, f, r, ldbu, 1, u_int8_t)
-}
-
-static u_int16_t
-tsunami_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(h, b, s, f, r, ldwu, 2, u_int16_t)
-}
-
-static u_int32_t
-tsunami_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- CFGREAD(h, b, s, f, r, ldl, 4, u_int32_t)
-}
-
-static void
-tsunami_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
-{
- CFWRITE(h, b, s, f, r, data, stb, 1)
-}
-
-static void
-tsunami_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
-{
- CFWRITE(h, b, s, f, r, data, stw, 2)
-}
-
-static void
-tsunami_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
-{
- CFWRITE(h, b, s, f, r, data, stl, 4)
-}
-
-
-vm_offset_t
-tsunami_cvt_bwx(vm_offset_t addr)
-{
- int hose;
- vm_offset_t laddr;
- laddr = addr & 0xffffffffUL;
- hose = ADDR_TO_HOSE(laddr);
- laddr = STRIP_HOSE(addr);
- laddr |= TSUNAMI_MEM(hose);
- return (KV(laddr));
-}
-
-vm_offset_t
-tsunami_cvt_dense(vm_offset_t addr)
-{
- return tsunami_cvt_bwx(addr);
-}
-
-
/*
* There doesn't appear to be an hae on this platform
*/
@@ -394,10 +109,6 @@ static device_method_t tsunami_methods[] = {
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
- 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, tsunami_setup_intr),
DEVMETHOD(bus_teardown_intr, tsunami_teardown_intr),
@@ -478,7 +189,7 @@ tsunami_sgmap_invalidate(void)
}
static void
-tsunami_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa)
+tsunami_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
{
u_int64_t *sgtable = arg;
int index = alpha_btop(ba - TSUNAMI_SGMAP_BASE);
@@ -522,10 +233,21 @@ void
tsunami_init()
{
static int initted = 0;
+ static struct bwx_space io_space;
+ static struct bwx_space mem_space;
if (initted) return;
initted = 1;
+ /*
+ * Define two temporary spaces for bootstrap i/o on hose 0.
+ */
+ bwx_init_space(&io_space, KV(TSUNAMI_IO(0)));
+ bwx_init_space(&mem_space, KV(TSUNAMI_MEM(0)));
+
+ busspace_isa_io = (kobj_t) &io_space;
+ busspace_isa_mem = (kobj_t) &mem_space;
+
chipset = tsunami_chipset;
platform.pci_intr_enable = tsunami_intr_enable;
platform.pci_intr_disable = tsunami_intr_disable;
@@ -539,7 +261,6 @@ static int
tsunami_probe(device_t dev)
{
device_t child;
- int *hose;
int i;
if (tsunami0)
return ENXIO;
@@ -554,18 +275,13 @@ tsunami_probe(device_t dev)
isa_init_intr();
for(i = 0; i < tsunami_num_pchips; i++) {
- hose = malloc(sizeof(int), M_DEVBUF, M_NOWAIT);
- *hose = i;
child = device_add_child(dev, "pcib", i);
- device_set_ivars(child, hose);
pchip_init(pchip[i], i);
}
return 0;
}
-
-
static int
tsunami_attach(device_t dev)
{
diff --git a/sys/alpha/pci/tsunami_pci.c b/sys/alpha/pci/tsunami_pci.c
index 17d7be2..ebf8855 100644
--- a/sys/alpha/pci/tsunami_pci.c
+++ b/sys/alpha/pci/tsunami_pci.c
@@ -38,111 +38,213 @@
#include <pci/pcivar.h>
#include <alpha/pci/tsunamireg.h>
#include <alpha/pci/tsunamivar.h>
+#include <alpha/pci/pcibus.h>
+#include <machine/resource.h>
+#include <machine/bwx.h>
+#include "alphapci_if.h"
+#include "pcib_if.h"
+
+struct tsunami_hose_softc {
+ struct bwx_space io; /* accessor for ports */
+ struct bwx_space mem; /* accessor for memory */
+ struct rman io_rman; /* resource manager for ports */
+ struct rman mem_rman; /* resource manager for memory */
+};
static devclass_t pcib_devclass;
-int tsunami_hoses[TSUNAMI_MAXHOSES+1] = {1,-1,-1,-1,-1};
-int tsunami_maxhoseno = 0;
+static int
+tsunami_pcib_probe(device_t dev)
+{
+ struct tsunami_hose_softc *sc = device_get_softc(dev);
+ device_t child;
-extern int tsunami_num_pchips;
+ device_set_desc(dev, "21271 PCI host bus adapter");
-/*
- * This comment attempts to explain why and how we are mapping from
- * the DEQ assigned bus numbers to the FreeBSD assigned numbers.
- *
- * FreeBSD must number buses with monotonically increasing numbers for a
- * variety of reasons (pciconf, newbus, etc).
- *
- * DEQ numbers them (from what I can tell) on a per-hose bases. And
- * for some reason they seem to always leave bus 1 unused.
- *
- * When generating config space addrs, we need to know if we are
- * directly on the primary bus on that hose, or if we are behind a ppb.
- * We keep track of this by assigning hoses monotonically increasing
- * numbers. This fits nicely with DEQ not using bus number 1; I
- * assume that is what it as intended for. I guess we'll see if they
- * come out with a system using more than one pchip..
- *
- * Next, we must attempt to map the FreeBSD assigned numbers to the
- * numbers assigned by DEQ in order to generate proper config space
- * addrs. We store the next number past the 0th bus of our hose and
- * do subtraction to determine what the DEQ number should have been,
- * given a FreeBSD bus number. This is disgusting & quite possibly
- * wrong.
- */
+ child = device_add_child(dev, "pci", -1);
+
+ bwx_init_space(&sc->io, KV(TSUNAMI_IO(device_get_unit(dev))));
+ bwx_init_space(&sc->mem, KV(TSUNAMI_MEM(device_get_unit(dev))));
+
+ sc->io_rman.rm_start = 0;
+ sc->io_rman.rm_end = ~0u;
+ sc->io_rman.rm_type = RMAN_ARRAY;
+ sc->io_rman.rm_descr = "I/O ports";
+ if (rman_init(&sc->io_rman)
+ || rman_manage_region(&sc->io_rman, 0x0, (1L << 32)))
+ panic("tsunami_pcib_probe: io_rman");
+
+ sc->mem_rman.rm_start = 0;
+ sc->mem_rman.rm_end = ~0u;
+ sc->mem_rman.rm_type = RMAN_ARRAY;
+ sc->mem_rman.rm_descr = "I/O memory";
+ if (rman_init(&sc->mem_rman)
+ || rman_manage_region(&sc->mem_rman, 0x0, (1L << 32)))
+ panic("tsunami_pcib_probe: mem_rman");
-int
-tsunami_bus_within_hose(int hose, int bus)
+ /*
+ * Replace the temporary bootstrap spaces with real onys. This
+ * isn't stictly necessary but it keeps things tidy.
+ */
+ if (device_get_unit(dev) == 0) {
+ busspace_isa_io = (kobj_t) &sc->io;
+ busspace_isa_mem = (kobj_t) &sc->mem;
+ }
+
+ return 0;
+}
+
+static int
+tsunami_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
{
- if (hose == bus)
- return 0;
- else
- return ( (bus - tsunami_hoses[hose]) + 1);
+ if (which == PCIB_IVAR_BUS) {
+ *result = 0;
+ }
+ return ENOENT;
}
-/*
- * this function supports pciconf ioctls
- */
+static void *
+tsunami_pcib_cvt_dense(device_t dev, vm_offset_t addr)
+{
+ int h = device_get_unit(dev);
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | TSUNAMI_MEM(h));
+}
+
+static void *
+tsunami_pcib_cvt_bwx(device_t dev, vm_offset_t addr)
+{
+ int h = device_get_unit(dev);
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | TSUNAMI_MEM(h));
+}
-int
-tsunami_hose_from_bus(int bus)
+static kobj_t
+tsunami_pcib_get_bustag(device_t dev, int type)
{
- int i;
+ struct tsunami_hose_softc *sc = device_get_softc(dev);
- if (bus < tsunami_maxhoseno)
- return bus;
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return (kobj_t) &sc->io;
- for (i = 1; i <= TSUNAMI_MAXHOSES && tsunami_hoses[i] != -1; i++){
- if(tsunami_hoses[i] >= bus)
- return i-1;
+ case SYS_RES_MEMORY:
+ return (kobj_t) &sc->mem;
}
- return i-1;
+ return 0;
}
+static struct rman *
+tsunami_pcib_get_rman(device_t dev, int type)
+{
+ struct tsunami_hose_softc *sc = device_get_softc(dev);
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return &sc->io_rman;
+
+ case SYS_RES_MEMORY:
+ return &sc->mem_rman;
+ }
+
+ return 0;
+}
static int
-tsunami_pcib_probe(device_t dev)
+tsunami_pcib_maxslots(device_t dev)
{
- static int error;
- device_t child;
- int lastbus;
+ return 31;
+}
- device_set_desc(dev, "21271 PCI host bus adapter");
+static void
+tsunami_clear_abort(void)
+{
+ alpha_mb();
+ alpha_pal_draina();
+}
- child = device_add_child(dev, "pci", -1);
+static int
+tsunami_check_abort(void)
+{
+/* u_int32_t errbits;*/
+ int ba = 0;
- if (tsunami_maxhoseno) {
- lastbus = (device_get_unit(child) - 1);
- if (lastbus == 0) /* didn't have a ppb on hose 0 */
- lastbus++;
- tsunami_hoses[tsunami_maxhoseno] = lastbus;
+ alpha_pal_draina();
+ alpha_mb();
+#if 0
+ errbits = REGVAL(TSUNAMI_CSR_TSUNAMI_ERR);
+ if (errbits & (TSUNAMI_ERR_RCVD_MAS_ABT|TSUNAMI_ERR_RCVD_TAR_ABT))
+ ba = 1;
+
+ if (errbits) {
+ REGVAL(TSUNAMI_CSR_TSUNAMI_ERR) = errbits;
+ alpha_mb();
+ alpha_pal_draina();
}
- if ((error = device_delete_child(dev, child)))
- panic("tsunami_pcib_probe: device_delete_child failed\n");
-
- child = device_add_child(dev, "pci", tsunami_maxhoseno);
-
- if (tsunami_maxhoseno != device_get_unit(child)) {
- printf("tsunami_pcib_probe: wanted unit %d ",
- tsunami_maxhoseno);
- printf(" got unit %d\n", device_get_unit(child));
- panic("tsunami_pcib_probe: incorrect bus numbering");
+#endif
+ return ba;
+}
+
+#define TSUNAMI_CFGADDR(b, s, f, r, h) \
+ KV(TSUNAMI_CONF(h) | ((b) << 16) | ((s) << 11) | ((f) << 8) | (r))
+
+#define CFGREAD(h, b, s, f, r, op, width, type) do { \
+ vm_offset_t va; \
+ type data; \
+ va = TSUNAMI_CFGADDR(b, s, f, r, h); \
+ tsunami_clear_abort(); \
+ if (badaddr((caddr_t)va, width)) { \
+ tsunami_check_abort(); \
+ return ~0; \
+ } \
+ data = ##op##(va); \
+ if (tsunami_check_abort()) \
+ return ~0; \
+ return data; \
+} while (0)
+
+#define CFGWRITE(h, b, s, f, r, data, op, width) do { \
+ vm_offset_t va; \
+ va = TSUNAMI_CFGADDR(b, s, f, r, h); \
+ tsunami_clear_abort(); \
+ if (badaddr((caddr_t)va, width)) \
+ return; \
+ ##op##(va, data); \
+ tsunami_check_abort(); \
+} while (0)
+
+static u_int32_t
+tsunami_pcib_read_config(device_t dev, int b, int s, int f,
+ int reg, int width)
+{
+ int h = device_get_unit(dev);
+ switch (width) {
+ case 1:
+ CFGREAD(h, b, s, f, reg, ldbu, 1, u_int8_t);
+ case 2:
+ CFGREAD(h, b, s, f, reg, ldwu, 2, u_int16_t);
+ case 4:
+ CFGREAD(h, b, s, f, reg, ldl, 4, u_int32_t);
}
- tsunami_maxhoseno++;
- return 0;
+ return ~0;
}
-static int
-tsunami_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
+static void
+tsunami_pcib_write_config(device_t dev, int b, int s, int f,
+ int reg, u_int32_t val, int width)
{
- if (which == PCIB_IVAR_HOSE) {
- *result = *(int*) device_get_ivars(dev);
- return 0;
+ int h = device_get_unit(dev);
+ switch (width) {
+ case 1:
+ CFGWRITE(h, b, s, f, reg, val, stb, 1);
+ case 2:
+ CFGWRITE(h, b, s, f, reg, val, stw, 2);
+ case 4:
+ CFGWRITE(h, b, s, f, reg, val, stl, 4);
}
- return ENOENT;
}
static device_method_t tsunami_pcib_methods[] = {
@@ -153,13 +255,24 @@ static device_method_t tsunami_pcib_methods[] = {
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_read_ivar, tsunami_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_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, alpha_platform_pci_setup_intr),
DEVMETHOD(bus_teardown_intr, alpha_platform_pci_teardown_intr),
+ /* alphapci interface */
+ DEVMETHOD(alphapci_cvt_dense, tsunami_pcib_cvt_dense),
+ DEVMETHOD(alphapci_cvt_bwx, tsunami_pcib_cvt_bwx),
+ DEVMETHOD(alphapci_get_bustag, tsunami_pcib_get_bustag),
+ DEVMETHOD(alphapci_get_rman, tsunami_pcib_get_rman),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, tsunami_pcib_maxslots),
+ DEVMETHOD(pcib_read_config, tsunami_pcib_read_config),
+ DEVMETHOD(pcib_write_config, tsunami_pcib_write_config),
+
{ 0, 0 }
};
@@ -167,7 +280,7 @@ static device_method_t tsunami_pcib_methods[] = {
static driver_t tsunami_pcib_driver = {
"pcib",
tsunami_pcib_methods,
- 1,
+ sizeof(struct tsunami_hose_softc),
};
OpenPOWER on IntegriCloud