summaryrefslogtreecommitdiffstats
path: root/sys/alpha
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
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')
-rw-r--r--sys/alpha/alpha/busdma_machdep.c2
-rw-r--r--sys/alpha/alpha/busspace.c289
-rw-r--r--sys/alpha/alpha/clock.c1
-rw-r--r--sys/alpha/alpha/dec_1000a.c1
-rw-r--r--sys/alpha/alpha/dec_2100_a50.c5
-rw-r--r--sys/alpha/alpha/dec_2100_a500.c3
-rw-r--r--sys/alpha/alpha/dec_axppci_33.c4
-rw-r--r--sys/alpha/alpha/dec_st6600.c1
-rw-r--r--sys/alpha/include/bus.h1199
-rw-r--r--sys/alpha/include/bwx.h16
-rw-r--r--sys/alpha/include/chipset.h62
-rw-r--r--sys/alpha/include/cpufunc.h70
-rw-r--r--sys/alpha/include/swiz.h22
-rw-r--r--sys/alpha/mcbus/mcbus.c6
-rw-r--r--sys/alpha/mcbus/mcpcia.c595
-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
-rw-r--r--sys/alpha/tlsb/dwlpx.c728
-rw-r--r--sys/alpha/tlsb/kftxx.c2
39 files changed, 2604 insertions, 4080 deletions
diff --git a/sys/alpha/alpha/busdma_machdep.c b/sys/alpha/alpha/busdma_machdep.c
index aa92602..a10f367 100644
--- a/sys/alpha/alpha/busdma_machdep.c
+++ b/sys/alpha/alpha/busdma_machdep.c
@@ -513,7 +513,7 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
} while (buflen > 0);
if (buflen != 0) {
- printf("bus_dmamap_load: Too many segs! buf_len = 0x%lx\n",
+ printf("bus_dmamap_load: Too many segs! buf_len = 0x%x\n",
buflen);
error = EFBIG;
}
diff --git a/sys/alpha/alpha/busspace.c b/sys/alpha/alpha/busspace.c
new file mode 100644
index 0000000..d26ce61
--- /dev/null
+++ b/sys/alpha/alpha/busspace.c
@@ -0,0 +1,289 @@
+/*-
+ * 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/cdefs.h> /* RCS ID & Copyright macro defns */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/kobj.h>
+
+#include <machine/bus.h>
+#include "busspace_if.h"
+
+void
+busspace_generic_read_multi_1(struct alpha_busspace *space, size_t offset,
+ u_int8_t *addr, size_t count)
+{
+ while (count--) {
+ *addr++ = space->ab_ops->abo_read_1(space, offset);
+ }
+}
+
+void
+busspace_generic_read_multi_2(struct alpha_busspace *space, size_t offset,
+ u_int16_t *addr, size_t count)
+{
+ while (count--) {
+ *addr++ = space->ab_ops->abo_read_2(space, offset);
+ }
+}
+
+void
+busspace_generic_read_multi_4(struct alpha_busspace *space, size_t offset,
+ u_int32_t *addr, size_t count)
+{
+ while (count--) {
+ *addr++ = space->ab_ops->abo_read_4(space, offset);
+ }
+}
+
+void
+busspace_generic_read_region_1(struct alpha_busspace *space, size_t offset,
+ u_int8_t *addr, size_t count)
+{
+ while (count--) {
+ *addr++ = space->ab_ops->abo_read_1(space, offset);
+ offset += 1;
+ }
+}
+
+void
+busspace_generic_read_region_2(struct alpha_busspace *space, size_t offset,
+ u_int16_t *addr, size_t count)
+{
+ while (count--) {
+ *addr++ = space->ab_ops->abo_read_2(space, offset);
+ offset += 2;
+ }
+}
+
+void
+busspace_generic_read_region_4(struct alpha_busspace *space, size_t offset,
+ u_int32_t *addr, size_t count)
+{
+ while (count--) {
+ *addr++ = space->ab_ops->abo_read_4(space, offset);
+ offset += 4;
+ }
+}
+
+void
+busspace_generic_write_multi_1(struct alpha_busspace *space, size_t offset,
+ const u_int8_t *addr, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_1(space, offset, *addr++);
+ }
+}
+
+void
+busspace_generic_write_multi_2(struct alpha_busspace *space, size_t offset,
+ const u_int16_t *addr, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_2(space, offset, *addr++);
+ }
+}
+
+void
+busspace_generic_write_multi_4(struct alpha_busspace *space, size_t offset,
+ const u_int32_t *addr, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_4(space, offset, *addr++);
+ }
+}
+
+void
+busspace_generic_write_region_1(struct alpha_busspace *space, size_t offset,
+ const u_int8_t *addr, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_1(space, offset, *addr++);
+ offset += 1;
+ }
+}
+
+void
+busspace_generic_write_region_2(struct alpha_busspace *space, size_t offset,
+ const u_int16_t *addr, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_2(space, offset, *addr++);
+ offset += 2;
+ }
+}
+
+void
+busspace_generic_write_region_4(struct alpha_busspace *space, size_t offset,
+ const u_int32_t *addr, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_4(space, offset, *addr++);
+ offset += 4;
+ }
+}
+
+void
+busspace_generic_set_multi_1(struct alpha_busspace *space, size_t offset,
+ u_int8_t value, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_1(space, offset, value);
+ }
+}
+
+void
+busspace_generic_set_multi_2(struct alpha_busspace *space, size_t offset,
+ u_int16_t value, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_2(space, offset, value);
+ }
+}
+
+void
+busspace_generic_set_multi_4(struct alpha_busspace *space, size_t offset,
+ u_int32_t value, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_4(space, offset, value);
+ }
+}
+
+void
+busspace_generic_set_region_1(struct alpha_busspace *space, size_t offset,
+ u_int8_t value, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_1(space, offset, value);
+ offset += 1;
+ }
+}
+
+void
+busspace_generic_set_region_2(struct alpha_busspace *space, size_t offset,
+ u_int16_t value, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_2(space, offset, value);
+ offset += 2;
+ }
+}
+
+void
+busspace_generic_set_region_4(struct alpha_busspace *space, size_t offset,
+ u_int32_t value, size_t count)
+{
+ while (count--) {
+ space->ab_ops->abo_write_4(space, offset, value);
+ offset += 4;
+ }
+}
+
+void
+busspace_generic_copy_region_1(struct alpha_busspace *space,
+ size_t offset1, size_t offset2, size_t count)
+{
+ u_int8_t value;
+ if (offset1 > offset2) {
+ while (count--) {
+ value = space->ab_ops->abo_read_1(space, offset1);
+ space->ab_ops->abo_write_1(space, offset2, value);
+ offset1 += 1;
+ offset2 += 1;
+ }
+ } else {
+ offset1 += count - 1;
+ offset2 += count - 1;
+ while (count--) {
+ value = space->ab_ops->abo_read_1(space, offset1);
+ space->ab_ops->abo_write_1(space, offset2, value);
+ offset1 -= 1;
+ offset2 -= 1;
+ }
+ }
+}
+
+void
+busspace_generic_copy_region_2(struct alpha_busspace *space,
+ size_t offset1, size_t offset2, size_t count)
+{
+ u_int16_t value;
+ if (offset1 > offset2) {
+ while (count--) {
+ value = space->ab_ops->abo_read_1(space, offset1);
+ space->ab_ops->abo_write_1(space, offset2, value);
+ offset1 += 2;
+ offset2 += 2;
+ }
+ } else {
+ offset1 += 2*(count - 1);
+ offset2 += 2*(count - 1);
+ while (count--) {
+ value = space->ab_ops->abo_read_2(space, offset1);
+ space->ab_ops->abo_write_2(space, offset2, value);
+ offset1 -= 2;
+ offset2 -= 2;
+ }
+ }
+}
+
+void
+busspace_generic_copy_region_4(struct alpha_busspace *space,
+ size_t offset1, size_t offset2, size_t count)
+{
+ u_int32_t value;
+ if (offset1 > offset2) {
+ while (count--) {
+ value = space->ab_ops->abo_read_4(space, offset1);
+ space->ab_ops->abo_write_4(space, offset2, value);
+ offset1 += 4;
+ offset2 += 4;
+ }
+ } else {
+ offset1 += 4*(count - 1);
+ offset2 += 4*(count - 1);
+ while (count--) {
+ value = space->ab_ops->abo_read_4(space, offset1);
+ space->ab_ops->abo_write_4(space, offset2, value);
+ offset1 -= 4;
+ offset2 -= 4;
+ }
+ }
+}
+
+void
+busspace_generic_barrier(struct alpha_busspace *space, size_t offset, size_t len, int flags)
+{
+ if (flags & BUS_SPACE_BARRIER_READ)
+ alpha_mb();
+ else
+ alpha_wmb();
+}
diff --git a/sys/alpha/alpha/clock.c b/sys/alpha/alpha/clock.c
index ececbeb..88adaa4 100644
--- a/sys/alpha/alpha/clock.c
+++ b/sys/alpha/alpha/clock.c
@@ -54,6 +54,7 @@
#include <sys/timetc.h>
#include <machine/cpuconf.h>
+#include <machine/bus.h>
#include <machine/clock.h>
#include <machine/clockvar.h>
#include <isa/isareg.h>
diff --git a/sys/alpha/alpha/dec_1000a.c b/sys/alpha/alpha/dec_1000a.c
index ba8b27f..321c8cb 100644
--- a/sys/alpha/alpha/dec_1000a.c
+++ b/sys/alpha/alpha/dec_1000a.c
@@ -83,6 +83,7 @@
#include <machine/rpb.h>
#include <machine/cpuconf.h>
#include <machine/clock.h>
+#include <machine/bus.h>
#include <alpha/pci/apecsvar.h>
#include <alpha/pci/ciavar.h>
diff --git a/sys/alpha/alpha/dec_2100_a50.c b/sys/alpha/alpha/dec_2100_a50.c
index bafb34b..d9e8895 100644
--- a/sys/alpha/alpha/dec_2100_a50.c
+++ b/sys/alpha/alpha/dec_2100_a50.c
@@ -247,8 +247,9 @@ default:
* Read the SIO IRQ routing register to determine where the
* interrupt will actually be routed. Thank you, NetBSD.
*/
-
- pirqreg = chipset.cfgreadl(0, 0, 7, 0, SIO_PCIREG_PIRQ_RTCTRL);
+
+ pirqreg = apecs_pcib_read_config(0, 0, 7, 0,
+ SIO_PCIREG_PIRQ_RTCTRL, 4);
pirqline = (pirqreg >> (pirq * 8)) & 0xff;
if ((pirqline & 0x80) != 0)
panic("bad pirqline %d",pirqline);
diff --git a/sys/alpha/alpha/dec_2100_a500.c b/sys/alpha/alpha/dec_2100_a500.c
index e8c92a3..50909b4 100644
--- a/sys/alpha/alpha/dec_2100_a500.c
+++ b/sys/alpha/alpha/dec_2100_a500.c
@@ -36,6 +36,7 @@
#include <machine/rpb.h>
#include <machine/cpuconf.h>
#include <machine/clock.h>
+#include <machine/bus.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <alpha/pci/t2var.h>
@@ -57,8 +58,6 @@ extern int siocnattach __P((int, int));
extern int siogdbattach __P((int, int));
extern int sccnattach __P((void));
-extern vm_offset_t t2_csr_base;
-
void
dec_2100_a500_init(cputype)
{
diff --git a/sys/alpha/alpha/dec_axppci_33.c b/sys/alpha/alpha/dec_axppci_33.c
index 54984a8..40b3c87 100644
--- a/sys/alpha/alpha/dec_axppci_33.c
+++ b/sys/alpha/alpha/dec_axppci_33.c
@@ -41,6 +41,7 @@
#include <machine/rpb.h>
#include <machine/cpuconf.h>
#include <machine/clock.h>
+#include <machine/bus.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <alpha/pci/lcavar.h>
@@ -265,7 +266,8 @@ dec_axppci_33_intr_map(void *arg)
return;
}
- pirqreg = chipset.cfgreadl(0, 0, 7, 0, SIO_PCIREG_PIRQ_RTCTRL);
+ pirqreg = lca_pcib_read_config(0, 0, 7, 0,
+ SIO_PCIREG_PIRQ_RTCTRL, 4);
#if 0
printf("dec_axppci_33_intr_map: device %d pin %c: pirq %d, reg = %x\n",
device, '@' + cfg->intpin, pirq, pirqreg);
diff --git a/sys/alpha/alpha/dec_st6600.c b/sys/alpha/alpha/dec_st6600.c
index 22e9455..ae74ce5 100644
--- a/sys/alpha/alpha/dec_st6600.c
+++ b/sys/alpha/alpha/dec_st6600.c
@@ -42,7 +42,6 @@
#include <machine/clock.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
-#include <alpha/pci/tsunamireg.h>
#include <alpha/pci/tsunamivar.h>
#include "sio.h"
diff --git a/sys/alpha/include/bus.h b/sys/alpha/include/bus.h
index 5fb1ccf..7fe2726 100644
--- a/sys/alpha/include/bus.h
+++ b/sys/alpha/include/bus.h
@@ -72,28 +72,13 @@
#ifndef _ALPHA_BUS_H_
#define _ALPHA_BUS_H_
-#include <machine/cpufunc.h>
-
-/*
- * To remain compatible with NetBSD's interface, default to both memio and
- * pio when neither of them is defined.
- */
-#if !defined(_ALPHA_BUS_PIO_H_) && !defined(_ALPHA_BUS_MEMIO_H_)
-#define _ALPHA_BUS_PIO_H_
-#define _ALPHA_BUS_MEMIO_H_
-#endif
-
-/*
- * Values for the alpha bus space tag, not to be used directly by MI code.
- */
-#define ALPHA_BUS_SPACE_IO 0 /* space is i/o space */
-#define ALPHA_BUS_SPACE_MEM 1 /* space is mem space */
-
/*
* Bus address and size types
*/
-typedef u_long bus_addr_t;
-typedef u_long bus_size_t;
+typedef u_int32_t bus_addr_t;
+typedef u_int32_t bus_size_t;
+typedef struct alpha_busspace *bus_space_tag_t;
+typedef u_int32_t bus_space_handle_t;
#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
@@ -104,928 +89,280 @@ typedef u_long bus_size_t;
#define BUS_SPACE_UNRESTRICTED (~0)
-/*
- * Access methods for bus resources and address space.
- */
-typedef int bus_space_tag_t;
-typedef u_long bus_space_handle_t;
-
-/*
- * Map a region of device bus space into CPU virtual address space.
- */
-
-#define BUS_SPACE_MAP_CACHEABLE 0x01
-#define BUS_SPACE_MAP_LINEAR 0x02
-
-int bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
- int flags, bus_space_handle_t *bshp);
-
-/*
- * Unmap a region of device bus space.
- */
-
-void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
- bus_size_t size);
-
-/*
- * Get a new handle for a subregion of an already-mapped area of bus space.
- */
-
-int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
- bus_size_t offset, bus_size_t size,
- bus_space_handle_t *nbshp);
-
-/*
- * Allocate a region of memory that is accessible to devices in bus space.
- */
-
-int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
- bus_addr_t rend, bus_size_t size, bus_size_t align,
- bus_size_t boundary, int flags, bus_addr_t *addrp,
- bus_space_handle_t *bshp);
-
-/*
- * Free a region of bus space accessible memory.
- */
-
-void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
- bus_size_t size);
-
-#if defined(_ALPHA_BUS_PIO_H_) || defined(_ALPHA_BUS_MEMIO_H_)
-
-/*
- * Read a 1, 2, 4, or 8 byte quantity from bus space
- * described by tag/handle/offset.
- */
-static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
- bus_space_handle_t handle,
- bus_size_t offset);
-
-static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
- bus_space_handle_t handle,
- bus_size_t offset);
-
-static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
- bus_space_handle_t handle,
- bus_size_t offset);
-
-static __inline u_int8_t
-bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
- bus_size_t offset)
-{
-#if defined (_ALPHA_BUS_PIO_H_)
-#if defined (_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- return (inb(handle + offset));
-#endif
-#if defined (_ALPHA_BUS_MEMIO_H_)
- return (readb(handle + offset));
-#endif
-}
-
-static __inline u_int16_t
-bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
- bus_size_t offset)
-{
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- return (inw(handle + offset));
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
- return (readw(handle + offset));
-#endif
-}
-
-static __inline u_int32_t
-bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
- bus_size_t offset)
-{
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- return (inl(handle + offset));
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
- return (readl(handle + offset));
-#endif
-}
-
-#if 0 /* Cause a link error for bus_space_read_8 */
-#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
-#endif
-
-/*
- * Read `count' 1, 2, 4, or 8 byte quantities from bus space
- * described by tag/handle/offset and copy into buffer provided.
- */
-static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t *addr,
- size_t count);
-
-static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t *addr,
- size_t count);
-
-static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t *addr,
- size_t count);
+struct alpha_busspace;
+
+struct alpha_busspace_ops {
+ u_int8_t (*abo_read_1)(struct alpha_busspace *space, size_t offset);
+ u_int16_t (*abo_read_2)(struct alpha_busspace *space, size_t offset);
+ u_int32_t (*abo_read_4)(struct alpha_busspace *space, size_t offset);
+
+ void (*abo_read_multi_1)(struct alpha_busspace *space,
+ size_t offset,
+ u_int8_t *addr, size_t count);
+ void (*abo_read_multi_2)(struct alpha_busspace *space,
+ size_t offset,
+ u_int16_t *addr, size_t count);
+ void (*abo_read_multi_4)(struct alpha_busspace *space,
+ size_t offset,
+ u_int32_t *addr, size_t count);
+
+ void (*abo_read_region_1)(struct alpha_busspace *space,
+ size_t offset,
+ u_int8_t *addr, size_t count);
+ void (*abo_read_region_2)(struct alpha_busspace *space,
+ size_t offset,
+ u_int16_t *addr, size_t count);
+ void (*abo_read_region_4)(struct alpha_busspace *space,
+ size_t offset,
+ u_int32_t *addr, size_t count);
+
+ void (*abo_write_1)(struct alpha_busspace *space, size_t offset,
+ u_int8_t value);
+ void (*abo_write_2)(struct alpha_busspace *space, size_t offset,
+ u_int16_t value);
+ void (*abo_write_4)(struct alpha_busspace *space, size_t offset,
+ u_int32_t value);
+
+ void (*abo_write_multi_1)(struct alpha_busspace *space,
+ size_t offset,
+ const u_int8_t *addr, size_t count);
+ void (*abo_write_multi_2)(struct alpha_busspace *space,
+ size_t offset,
+ const u_int16_t *addr, size_t count);
+ void (*abo_write_multi_4)(struct alpha_busspace *space,
+ size_t offset,
+ const u_int32_t *addr, size_t count);
+
+ void (*abo_write_region_1)(struct alpha_busspace *space,
+ size_t offset,
+ const u_int8_t *addr, size_t count);
+ void (*abo_write_region_2)(struct alpha_busspace *space,
+ size_t offset,
+ const u_int16_t *addr, size_t count);
+ void (*abo_write_region_4)(struct alpha_busspace *space,
+ size_t offset,
+ const u_int32_t *addr, size_t count);
+
+ void (*abo_set_multi_1)(struct alpha_busspace *space, size_t offset,
+ u_int8_t value, size_t count);
+ void (*abo_set_multi_2)(struct alpha_busspace *space, size_t offset,
+ u_int16_t value, size_t count);
+ void (*abo_set_multi_4)(struct alpha_busspace *space, size_t offset,
+ u_int32_t value, size_t count);
+
+ void (*abo_set_region_1)(struct alpha_busspace *space,
+ size_t offset,
+ u_int8_t value, size_t count);
+ void (*abo_set_region_2)(struct alpha_busspace *space,
+ size_t offset,
+ u_int16_t value, size_t count);
+ void (*abo_set_region_4)(struct alpha_busspace *space,
+ size_t offset,
+ u_int32_t value, size_t count);
+
+ void (*abo_copy_region_1)(struct alpha_busspace *space,
+ size_t offset1, size_t offset2,
+ size_t count);
+ void (*abo_copy_region_2)(struct alpha_busspace *space,
+ size_t offset1, size_t offset2,
+ size_t count);
+ void (*abo_copy_region_4)(struct alpha_busspace *space,
+ size_t offset1, size_t offset2,
+ size_t count);
+
+ void (*abo_barrier)(struct alpha_busspace *space, size_t offset,
+ size_t len, int flags);
+};
+
+struct alpha_busspace {
+ struct alpha_busspace_ops *ab_ops;
+};
+
+/* Back-compat functions for old ISA drivers */
+
+extern struct alpha_busspace *busspace_isa_io;
+extern struct alpha_busspace *busspace_isa_mem;
+
+#define inb(o) bus_space_read_1(busspace_isa_io, o, 0)
+#define inw(o) bus_space_read_2(busspace_isa_io, o, 0)
+#define inl(o) bus_space_read_4(busspace_isa_io, o, 0)
+#define outb(o, v) bus_space_write_1(busspace_isa_io, o, 0, v)
+#define outw(o, v) bus_space_write_2(busspace_isa_io, o, 0, v)
+#define outl(o, v) bus_space_write_4(busspace_isa_io, o, 0, v)
+
+#define readb(o) bus_space_read_1(busspace_isa_mem, o, 0)
+#define readw(o) bus_space_read_2(busspace_isa_mem, o, 0)
+#define readl(o) bus_space_read_4(busspace_isa_mem, o, 0)
+#define writeb(o, v) bus_space_write_1(busspace_isa_mem, o, 0, v)
+#define writew(o, v) bus_space_write_2(busspace_isa_mem, o, 0, v)
+#define writel(o, v) bus_space_write_4(busspace_isa_mem, o, 0, v)
+
+#define insb(o, a, c) bus_space_read_multi_1(busspace_isa_io, o, 0, \
+ (void*)a, c)
+#define insw(o, a, c) bus_space_read_multi_2(busspace_isa_io, o, 0, \
+ (void*)a, c)
+#define insl(o, a, c) bus_space_read_multi_4(busspace_isa_io, o, 0, \
+ (void*)a, c)
+
+#define outsb(o, a, c) bus_space_write_multi_1(busspace_isa_io, o, 0, \
+ (void*)a, c)
+#define outsw(o, a, c) bus_space_write_multi_2(busspace_isa_io, o, 0, \
+ (void*)a, c)
+#define outsl(o, a, c) bus_space_write_multi_4(busspace_isa_io, o, 0, \
+ (void*)a, c)
+
+#define memcpy_fromio(d, s, c) \
+ bus_space_read_region_1(busspace_isa_mem, s, 0, d, c)
+#define memcpy_toio(d, s, c) \
+ bus_space_write_region_1(busspace_isa_mem, d, 0, s, c)
+#define memcpy_io(d, s, c) \
+ bus_space_copy_region_1(busspace_isa_mem, s, 0, d, 0, c)
+#define memset_io(d, v, c) \
+ bus_space_set_region_1(busspace_isa_mem, d, 0, v, c)
+#define memsetw_io(d, v, c) \
+ bus_space_set_region_2(busspace_isa_mem, d, 0, v, c)
static __inline void
-bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t *addr, size_t count)
+memsetw(void *d, int val, size_t size)
{
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- *addr++ = inb(bsh + offset);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- *addr++ = readb(bsh + offset);
-#endif
-}
+ u_int16_t *sp = d;
-static __inline void
-bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- *addr++ = inw(baddr);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- *addr++ = readw(baddr);
-#endif
-}
-
-static __inline void
-bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- *addr++ = inl(baddr);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- *addr++ = readl(baddr);
-#endif
-}
-
-#if 0 /* Cause a link error for bus_space_read_multi_8 */
-#define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
-#endif
-
-/*
- * Read `count' 1, 2, 4, or 8 byte quantities from bus space
- * described by tag/handle and starting at `offset' and copy into
- * buffer provided.
- */
-static __inline void bus_space_read_region_1(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t *addr,
- size_t count);
-
-static __inline void bus_space_read_region_2(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t *addr,
- size_t count);
-
-static __inline void bus_space_read_region_4(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t *addr,
- size_t count);
-
-
-static __inline void
-bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--) {
- *addr++ = inb(baddr);
- baddr += 1;
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--) {
- *addr++ = readb(baddr);
- baddr += 1;
- }
-#endif
-}
-
-static __inline void
-bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--) {
- *addr++ = inw(baddr);
- baddr += 2;
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--) {
- *addr++ = readw(baddr);
- baddr += 2;
- }
-#endif
-}
-
-static __inline void
-bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--) {
- *addr++ = inl(baddr);
- baddr += 4;
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--) {
- *addr++ = readb(baddr);
- baddr += 4;
- }
-#endif
+ while (size--)
+ *sp++ = val;
}
-#if 0 /* Cause a link error for bus_space_read_region_8 */
-#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
-#endif
+void busspace_generic_read_multi_1(struct alpha_busspace *space,
+ size_t offset,
+ u_int8_t *addr, size_t count);
+void busspace_generic_read_multi_2(struct alpha_busspace *space,
+ size_t offset,
+ u_int16_t *addr, size_t count);
+void busspace_generic_read_multi_4(struct alpha_busspace *space,
+ size_t offset,
+ u_int32_t *addr, size_t count);
+void busspace_generic_read_region_1(struct alpha_busspace *space,
+ size_t offset,
+ u_int8_t *addr, size_t count);
+void busspace_generic_read_region_2(struct alpha_busspace *space,
+ size_t offset,
+ u_int16_t *addr, size_t count);
+void busspace_generic_read_region_4(struct alpha_busspace *space,
+ size_t offset,
+ u_int32_t *addr, size_t count);
+void busspace_generic_write_multi_1(struct alpha_busspace *space,
+ size_t offset,
+ const u_int8_t *addr, size_t count);
+void busspace_generic_write_multi_2(struct alpha_busspace *space,
+ size_t offset,
+ const u_int16_t *addr, size_t count);
+void busspace_generic_write_multi_4(struct alpha_busspace *space,
+ size_t offset,
+ const u_int32_t *addr, size_t count);
+void busspace_generic_write_region_1(struct alpha_busspace *space,
+ size_t offset,
+ const u_int8_t *addr, size_t count);
+void busspace_generic_write_region_2(struct alpha_busspace *space,
+ size_t offset,
+ const u_int16_t *addr, size_t count);
+void busspace_generic_write_region_4(struct alpha_busspace *space,
+ size_t offset,
+ const u_int32_t *addr, size_t count);
+void busspace_generic_set_multi_1(struct alpha_busspace *space,
+ size_t offset,
+ u_int8_t value, size_t count);
+void busspace_generic_set_multi_2(struct alpha_busspace *space,
+ size_t offset,
+ u_int16_t value, size_t count);
+void busspace_generic_set_multi_4(struct alpha_busspace *space,
+ size_t offset,
+ u_int32_t value, size_t count);
+void busspace_generic_set_region_1(struct alpha_busspace *space,
+ size_t offset,
+ u_int8_t value, size_t count);
+void busspace_generic_set_region_2(struct alpha_busspace *space,
+ size_t offset,
+ u_int16_t value, size_t count);
+void busspace_generic_set_region_4(struct alpha_busspace *space,
+ size_t offset,
+ u_int32_t value, size_t count);
+void busspace_generic_copy_region_1(struct alpha_busspace *space,
+ size_t offset1,
+ size_t offset2,
+ size_t count);
+void busspace_generic_copy_region_2(struct alpha_busspace *space,
+ size_t offset1,
+ size_t offset2,
+ size_t count);
+void busspace_generic_copy_region_4(struct alpha_busspace *space,
+ size_t offset1,
+ size_t offset2,
+ size_t count);
+void busspace_generic_barrier(struct alpha_busspace *space,
+ size_t offset, size_t len,
+ int flags);
-/*
- * Write the 1, 2, 4, or 8 byte value `value' to bus space
- * described by tag/handle/offset.
- */
-
-static __inline void bus_space_write_1(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t value);
-
-static __inline void bus_space_write_2(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t value);
-
-static __inline void bus_space_write_4(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t value);
-
-static __inline void
-bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t value)
-{
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- outb(bsh + offset, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- writeb(bsh + offset, value);
-#endif
-}
-
-static __inline void
-bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t value)
-{
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- outw(bsh + offset, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- writew(bsh + offset, value);
-#endif
-}
-
-static __inline void
-bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t value)
-{
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- outl(bsh + offset, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- writel(bsh + offset, value);
-#endif
-}
-
-#if 0 /* Cause a link error for bus_space_write_8 */
-#define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
-#endif
-
-/*
- * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
- * provided to bus space described by tag/handle/offset.
- */
-
-static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- const u_int8_t *addr,
- size_t count);
-static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- const u_int16_t *addr,
- size_t count);
-
-static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- const u_int32_t *addr,
- size_t count);
-
-static __inline void
-bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, const u_int8_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- outb(baddr, *addr++);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- writeb(baddr, *addr++);
-#endif
-}
-
-static __inline void
-bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, const u_int16_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- outw(baddr, *addr++);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- writew(baddr, *addr++);
-#endif
-}
-
-static __inline void
-bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, const u_int32_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- outl(baddr, *addr++);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- writel(baddr, *addr++);
-#endif
-}
-
-#if 0 /* Cause a link error for bus_space_write_multi_8 */
-#define bus_space_write_multi_8(t, h, o, a, c) \
- !!! bus_space_write_multi_8 unimplemented !!!
-#endif
-
-/*
- * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
- * to bus space described by tag/handle starting at `offset'.
- */
-
-static __inline void bus_space_write_region_1(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- const u_int8_t *addr,
- size_t count);
-static __inline void bus_space_write_region_2(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- const u_int16_t *addr,
- size_t count);
-static __inline void bus_space_write_region_4(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- const u_int32_t *addr,
- size_t count);
-
-static __inline void
-bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, const u_int8_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--) {
- outb(baddr, *addr++);
- baddr += 1;
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--) {
- writeb(baddr, *addr++);
- baddr += 1;
- }
-#endif
-}
-
-static __inline void
-bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, const u_int16_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--) {
- outw(baddr, *addr++);
- baddr += 2;
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--) {
- writew(baddr, *addr++);
- baddr += 2;
- }
-#endif
-}
-
-static __inline void
-bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, const u_int32_t *addr, size_t count)
-{
- bus_addr_t baddr = bsh + offset;
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--) {
- outl(baddr, *addr++);
- baddr += 4;
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--) {
- writel(baddr, *addr++);
- baddr += 4;
- }
-#endif
-}
-
-#if 0 /* Cause a link error for bus_space_write_region_8 */
-#define bus_space_write_region_8 \
- !!! bus_space_write_region_8 unimplemented !!!
-#endif
-
-/*
- * Write the 1, 2, 4, or 8 byte value `val' to bus space described
- * by tag/handle/offset `count' times.
- */
-
-static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- u_int8_t value, size_t count);
-static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- u_int16_t value, size_t count);
-static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset,
- u_int32_t value, size_t count);
-
-static __inline void
-bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t value, size_t count)
-{
- bus_addr_t addr = bsh + offset;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- outb(addr, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- writeb(addr, value);
-#endif
-}
-
-static __inline void
-bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t value, size_t count)
-{
- bus_addr_t addr = bsh + offset;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- outw(addr, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- writew(addr, value);
-#endif
-}
-
-static __inline void
-bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t value, size_t count)
-{
- bus_addr_t addr = bsh + offset;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- while (count--)
- outl(addr, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- while (count--)
- writel(addr, value);
-#endif
-}
-
-#if 0 /* Cause a link error for bus_space_set_multi_8 */
-#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
-#endif
-
-/*
- * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
- * by tag/handle starting at `offset'.
- */
-
-static __inline void bus_space_set_region_1(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t value,
- size_t count);
-static __inline void bus_space_set_region_2(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t value,
- size_t count);
-static __inline void bus_space_set_region_4(bus_space_tag_t tag,
- bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t value,
- size_t count);
-
-static __inline void
-bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int8_t value, size_t count)
-{
- bus_addr_t addr = bsh + offset;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- for (; count != 0; count--, addr++)
- outb(addr, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- for (; count != 0; count--, addr++)
- writeb(addr, value);
-#endif
-}
-
-static __inline void
-bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int16_t value, size_t count)
-{
- bus_addr_t addr = bsh + offset;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- for (; count != 0; count--, addr += 2)
- outw(addr, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- for (; count != 0; count--, addr += 2)
- writew(addr, value);
-#endif
-}
-
-static __inline void
-bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, u_int32_t value, size_t count)
-{
- bus_addr_t addr = bsh + offset;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- for (; count != 0; count--, addr += 4)
- outl(addr, value);
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- for (; count != 0; count--, addr += 4)
- writel(addr, value);
-#endif
-}
-
-#if 0 /* Cause a link error for bus_space_set_region_8 */
-#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
-#endif
-
-/*
- * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
- * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
- */
-
-static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
- bus_space_handle_t bsh1,
- bus_size_t off1,
- bus_space_handle_t bsh2,
- bus_size_t off2, size_t count);
-
-static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
- bus_space_handle_t bsh1,
- bus_size_t off1,
- bus_space_handle_t bsh2,
- bus_size_t off2, size_t count);
-
-static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
- bus_space_handle_t bsh1,
- bus_size_t off1,
- bus_space_handle_t bsh2,
- bus_size_t off2, size_t count);
-
-static __inline void
-bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
- bus_size_t off1, bus_space_handle_t bsh2,
- bus_size_t off2, size_t count)
-{
- bus_addr_t addr1 = bsh1 + off1;
- bus_addr_t addr2 = bsh2 + off2;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- {
- if (addr1 >= addr2) {
- /* src after dest: copy forward */
- for (; count != 0; count--, addr1++, addr2++)
- outb(addr2, inb(addr1));
- } else {
- /* dest after src: copy backwards */
- for (addr1 += (count - 1), addr2 += (count - 1);
- count != 0; count--, addr1--, addr2--)
- outb(addr2, inb(addr1));
- }
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- {
- if (addr1 >= addr2) {
- /* src after dest: copy forward */
- for (; count != 0; count--, addr1++, addr2++)
- writeb(addr2, readb(addr1));
- } else {
- /* dest after src: copy backwards */
- for (addr1 += (count - 1), addr2 += (count - 1);
- count != 0; count--, addr1--, addr2--)
- writeb(addr2, readb(addr1));
- }
- }
-#endif
-}
-
-static __inline void
-bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
- bus_size_t off1, bus_space_handle_t bsh2,
- bus_size_t off2, size_t count)
-{
- bus_addr_t addr1 = bsh1 + off1;
- bus_addr_t addr2 = bsh2 + off2;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- {
- if (addr1 >= addr2) {
- /* src after dest: copy forward */
- for (; count != 0; count--, addr1 += 2, addr2 += 2)
- outw(addr2, inw(addr1));
- } else {
- /* dest after src: copy backwards */
- for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
- count != 0; count--, addr1 -= 2, addr2 -= 2)
- outw(addr2, inw(addr1));
- }
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- {
- if (addr1 >= addr2) {
- /* src after dest: copy forward */
- for (; count != 0; count--, addr1 += 2, addr2 += 2)
- writew(addr2, readw(addr1));
- } else {
- /* dest after src: copy backwards */
- for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
- count != 0; count--, addr1 -= 2, addr2 -= 2)
- writew(addr2, readw(addr1));
- }
- }
-#endif
-}
-
-static __inline void
-bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
- bus_size_t off1, bus_space_handle_t bsh2,
- bus_size_t off2, size_t count)
-{
- bus_addr_t addr1 = bsh1 + off1;
- bus_addr_t addr2 = bsh2 + off2;
-
-#if defined(_ALPHA_BUS_PIO_H_)
-#if defined(_ALPHA_BUS_MEMIO_H_)
- if (tag == ALPHA_BUS_SPACE_IO)
-#endif
- {
- if (addr1 >= addr2) {
- /* src after dest: copy forward */
- for (; count != 0; count--, addr1 += 4, addr2 += 4)
- outl(addr2, inl(addr1));
- } else {
- /* dest after src: copy backwards */
- for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
- count != 0; count--, addr1 -= 4, addr2 -= 4)
- outl(addr2, inl(addr1));
- }
- }
-#endif
-#if defined(_ALPHA_BUS_MEMIO_H_)
-#if defined(_ALPHA_BUS_PIO_H_)
- else
-#endif
- {
- if (addr1 >= addr2) {
- /* src after dest: copy forward */
- for (; count != 0; count--, addr1 += 4, addr2 += 4)
- writel(addr2, readl(addr1));
- } else {
- /* dest after src: copy backwards */
- for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
- count != 0; count--, addr1 -= 4, addr2 -= 4)
- writel(addr2, readl(addr1));
- }
- }
-#endif
-}
-
-#endif /* defined(_ALPHA_BUS_PIO_H_) || defined(_ALPHA_MEM_IO_H_) */
-
-#if 0 /* Cause a link error for bus_space_copy_8 */
-#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
-#endif
-
-/*
- * Bus read/write barrier methods.
- *
- * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
- * bus_size_t offset, bus_size_t len, int flags);
- *
- */
#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
-static __inline void
-bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
- bus_size_t offset, bus_size_t len, int flags)
-{
- if (flags & BUS_SPACE_BARRIER_READ)
- alpha_mb();
- else
- alpha_wmb();
-}
-
+#define bus_space_read_1(t, h, o) \
+ (t)->ab_ops->abo_read_1(t, (h)+(o))
+#define bus_space_read_2(t, h, o) \
+ (t)->ab_ops->abo_read_2(t, (h)+(o))
+#define bus_space_read_4(t, h, o) \
+ (t)->ab_ops->abo_read_4(t, (h)+(o))
+#define bus_space_read_multi_1(t, h, o, a, c) \
+ (t)->ab_ops->abo_read_multi_1(t, (h)+(o), a, c)
+#define bus_space_read_multi_2(t, h, o, a, c) \
+ (t)->ab_ops->abo_read_multi_2(t, (h)+(o), a, c)
+#define bus_space_read_multi_4(t, h, o, a, c) \
+ (t)->ab_ops->abo_read_multi_4(t, (h)+(o), a, c)
+#define bus_space_read_region_1(t, h, o, a, c) \
+ (t)->ab_ops->abo_read_region_1(t, (h)+(o), a, c)
+#define bus_space_read_region_2(t, h, o, a, c) \
+ (t)->ab_ops->abo_read_region_2(t, (h)+(o), a, c)
+#define bus_space_read_region_4(t, h, o, a, c) \
+ (t)->ab_ops->abo_read_region_4(t, (h)+(o), a, c)
+
+#define bus_space_write_1(t, h, o, v) \
+ (t)->ab_ops->abo_write_1(t, (h)+(o), v)
+#define bus_space_write_2(t, h, o, v) \
+ (t)->ab_ops->abo_write_2(t, (h)+(o), v)
+#define bus_space_write_4(t, h, o, v) \
+ (t)->ab_ops->abo_write_4(t, (h)+(o), v)
+#define bus_space_write_multi_1(t, h, o, a, c) \
+ (t)->ab_ops->abo_write_multi_1(t, (h)+(o), a, c)
+#define bus_space_write_multi_2(t, h, o, a, c) \
+ (t)->ab_ops->abo_write_multi_2(t, (h)+(o), a, c)
+#define bus_space_write_multi_4(t, h, o, a, c) \
+ (t)->ab_ops->abo_write_multi_4(t, (h)+(o), a, c)
+#define bus_space_write_region_1(t, h, o, a, c) \
+ (t)->ab_ops->abo_write_region_1(t, (h)+(o), a, c)
+#define bus_space_write_region_2(t, h, o, a, c) \
+ (t)->ab_ops->abo_write_region_2(t, (h)+(o), a, c)
+#define bus_space_write_region_4(t, h, o, a, c) \
+ (t)->ab_ops->abo_write_region_4(t, (h)+(o), a, c)
+#define bus_space_set_multi_1(t, h, o, v, c) \
+ (t)->ab_ops->abo_set_multi_1(t, (h)+(o), v, c)
+#define bus_space_set_multi_2(t, h, o, v, c) \
+ (t)->ab_ops->abo_set_multi_2(t, (h)+(o), v, c)
+#define bus_space_set_multi_4(t, h, o, v, c) \
+ (t)->ab_ops->abo_set_multi_4(t, (h)+(o), v, c)
+#define bus_space_set_region_1(t, h, o, v, c) \
+ (t)->ab_ops->abo_set_region_1(t, (h)+(o), v, c)
+#define bus_space_set_region_2(t, h, o, v, c) \
+ (t)->ab_ops->abo_set_region_2(t, (h)+(o), v, c)
+#define bus_space_set_region_4(t, h, o, v, c) \
+ (t)->ab_ops->abo_set_region_4(t, (h)+(o), v, c)
+
+#define bus_space_copy_region_1(t, h1, o1, h2, o2, c) \
+ (t)->ab_ops->abo_copy_region_1(t, (h1)+(o1), (h2)+(o2), c)
+#define bus_space_copy_region_2(t, h1, o1, h2, o2, c) \
+ (t)->ab_ops->abo_copy_region_2(t, (h1)+(o1), (h2)+(o2), c)
+#define bus_space_copy_region_4(t, h1, o1, h2, o2, c) \
+ (t)->ab_ops->abo_copy_region_4(t, (h1)+(o1), (h2)+(o2), c)
+
+#define bus_space_barrier(t, h, o, l, f) \
+ (t)->ab_ops->abo_barrier(t, (h)+(o), l, f)
/*
* Flags used in various bus DMA methods.
diff --git a/sys/alpha/include/bwx.h b/sys/alpha/include/bwx.h
index 3d63995..bb2866b 100644
--- a/sys/alpha/include/bwx.h
+++ b/sys/alpha/include/bwx.h
@@ -93,11 +93,25 @@ stw_nb(vm_offset_t va, u_int64_t r)
__asm__ __volatile__ ("stw %1,%0" : "=m"(*(u_int16_t*)va) : "r"(r));
}
-
static __inline void
stl_nb(vm_offset_t va, u_int64_t r)
{
__asm__ __volatile__ ("stl %1,%0" : "=m"(*(u_int32_t*)va) : "r"(r));
}
+#ifdef _KERNEL
+
+/*
+ * A kernel object for accessing memory-like spaces (port and
+ * memory spaces) using BWX instructions.
+ */
+struct bwx_space {
+ struct alpha_busspace_ops *ops;
+ u_int64_t base; /* base address of space */
+};
+
+void bwx_init_space(struct bwx_space *bwx, u_int64_t base);
+
+#endif /* _KERNEL */
+
#endif /* !_MACHINE_BWX_H_ */
diff --git a/sys/alpha/include/chipset.h b/sys/alpha/include/chipset.h
index 18792f1..048fbed 100644
--- a/sys/alpha/include/chipset.h
+++ b/sys/alpha/include/chipset.h
@@ -29,31 +29,6 @@
#ifndef _MACHINE_CHIPSET_H_
#define _MACHINE_CHIPSET_H_
-typedef u_int8_t alpha_chipset_inb_t(u_int32_t port);
-typedef u_int16_t alpha_chipset_inw_t(u_int32_t port);
-typedef u_int32_t alpha_chipset_inl_t(u_int32_t port);
-typedef void alpha_chipset_outb_t(u_int32_t port, u_int8_t data);
-typedef void alpha_chipset_outw_t(u_int32_t port, u_int16_t data);
-typedef void alpha_chipset_outl_t(u_int32_t port, u_int32_t data);
-
-typedef u_int8_t alpha_chipset_readb_t(u_int32_t pa);
-typedef u_int16_t alpha_chipset_readw_t(u_int32_t pa);
-typedef u_int32_t alpha_chipset_readl_t(u_int32_t pa);
-typedef void alpha_chipset_writeb_t(u_int32_t pa, u_int8_t data);
-typedef void alpha_chipset_writew_t(u_int32_t pa, u_int16_t data);
-typedef void alpha_chipset_writel_t(u_int32_t pa, u_int32_t data);
-
-typedef int alpha_chipset_maxdevs_t(u_int bus);
-typedef u_int8_t alpha_chipset_cfgreadb_t(u_int, u_int, u_int, u_int, u_int);
-typedef u_int16_t alpha_chipset_cfgreadw_t(u_int, u_int, u_int, u_int, u_int);
-typedef u_int32_t alpha_chipset_cfgreadl_t(u_int, u_int, u_int, u_int, u_int);
-typedef void alpha_chipset_cfgwriteb_t(u_int, u_int, u_int, u_int, u_int,
- u_int8_t);
-typedef void alpha_chipset_cfgwritew_t(u_int, u_int, u_int, u_int, u_int,
- u_int16_t);
-typedef void alpha_chipset_cfgwritel_t(u_int, u_int, u_int, u_int, u_int,
- u_int32_t);
-typedef vm_offset_t alpha_chipset_addrcvt_t(vm_offset_t);
typedef u_int64_t alpha_chipset_read_hae_t(void);
typedef void alpha_chipset_write_hae_t(u_int64_t);
@@ -61,43 +36,6 @@ struct sgmap;
typedef struct alpha_chipset {
/*
- * I/O port access
- */
- alpha_chipset_inb_t* inb;
- alpha_chipset_inw_t* inw;
- alpha_chipset_inl_t* inl;
- alpha_chipset_outb_t* outb;
- alpha_chipset_outw_t* outw;
- alpha_chipset_outl_t* outl;
-
- /*
- * Memory access
- */
- alpha_chipset_readb_t* readb;
- alpha_chipset_readw_t* readw;
- alpha_chipset_readl_t* readl;
- alpha_chipset_writeb_t* writeb;
- alpha_chipset_writew_t* writew;
- alpha_chipset_writel_t* writel;
-
- /*
- * PCI configuration access
- */
- alpha_chipset_maxdevs_t* maxdevs;
- alpha_chipset_cfgreadb_t* cfgreadb;
- alpha_chipset_cfgreadw_t* cfgreadw;
- alpha_chipset_cfgreadl_t* cfgreadl;
- alpha_chipset_cfgwriteb_t* cfgwriteb;
- alpha_chipset_cfgwritew_t* cfgwritew;
- alpha_chipset_cfgwritel_t* cfgwritel;
-
- /*
- * PCI address space translation functions
- */
- alpha_chipset_addrcvt_t* cvt_to_dense;
- alpha_chipset_addrcvt_t* cvt_to_bwx;
-
- /*
* Access the HAE register
*/
alpha_chipset_read_hae_t* read_hae;
diff --git a/sys/alpha/include/cpufunc.h b/sys/alpha/include/cpufunc.h
index 96a91b6..e7d37f0 100644
--- a/sys/alpha/include/cpufunc.h
+++ b/sys/alpha/include/cpufunc.h
@@ -44,76 +44,6 @@ breakpoint(void)
#endif
-#define inb(port) chipset.inb(port)
-#define inw(port) chipset.inw(port)
-#define inl(port) chipset.inl(port)
-#define outb(port, data) chipset.outb(port, data)
-#define outw(port, data) chipset.outw(port, data)
-#define outl(port, data) chipset.outl(port, data)
-
-#define readb(pa) chipset.readb(pa)
-#define readw(pa) chipset.readw(pa)
-#define readl(pa) chipset.readl(pa)
-#define writeb(pa,v) chipset.writeb(pa,v)
-#define writew(pa,v) chipset.writew(pa,v)
-#define writel(pa,v) chipset.writel(pa,v)
-
-/*
- * Bulk i/o (for IDE driver).
- */
-static __inline void insb(u_int32_t port, void *buffer, size_t count)
-{
- u_int8_t *p = (u_int8_t *) buffer;
- while (count--)
- *p++ = inb(port);
-}
-
-static __inline void insw(u_int32_t port, void *buffer, size_t count)
-{
- u_int16_t *p = (u_int16_t *) buffer;
- while (count--)
- *p++ = inw(port);
-}
-
-static __inline void insl(u_int32_t port, void *buffer, size_t count)
-{
- u_int32_t *p = (u_int32_t *) buffer;
- while (count--)
- *p++ = inl(port);
-}
-
-static __inline void outsb(u_int32_t port, const void *buffer, size_t count)
-{
- const u_int8_t *p = (const u_int8_t *) buffer;
- while (count--)
- outb(port, *p++);
-}
-
-static __inline void outsw(u_int32_t port, const void *buffer, size_t count)
-{
- const u_int16_t *p = (const u_int16_t *) buffer;
- while (count--)
- outw(port, *p++);
-}
-
-static __inline void outsl(u_int32_t port, const void *buffer, size_t count)
-{
- const u_int32_t *p = (const u_int32_t *) buffer;
- while (count--)
- outl(port, *p++);
-}
-
-/*
- * String version of IO memory access ops:
- */
-extern void memcpy_fromio(void *, u_int32_t, size_t);
-extern void memcpy_toio(u_int32_t, void *, size_t);
-extern void memcpy_io(u_int32_t, u_int32_t, size_t);
-extern void memset_io(u_int32_t, int, size_t);
-extern void memsetw(void *, int, size_t);
-extern void memsetw_io(u_int32_t, int, size_t);
-
-
#endif /* _KERNEL */
#endif /* !_MACHINE_CPUFUNC_H_ */
diff --git a/sys/alpha/include/swiz.h b/sys/alpha/include/swiz.h
index 4b6397a..465a81a 100644
--- a/sys/alpha/include/swiz.h
+++ b/sys/alpha/include/swiz.h
@@ -70,4 +70,26 @@
#define SPARSE_WRITE_LONG(base, o, d) \
SPARSE_WRITE(base + SPARSE_LONG_OFFSET(o), d)
+#ifdef _KERNEL
+
+/*
+ * A kernel object for accessing memory-like spaces (port and
+ * memory spaces) using SWIZ instructions.
+ */
+
+typedef u_int32_t (*swiz_sethae_fn)(void *arg, u_int32_t hae);
+
+struct swiz_space {
+ struct alpha_busspace_ops *ops;
+ u_int64_t base; /* base address of space */
+ swiz_sethae_fn sethae; /* function to set HAE */
+ void *arg; /* arg to sethae() */
+};
+
+void swiz_init_space(struct swiz_space *swiz, u_int64_t base);
+void swiz_init_space_hae(struct swiz_space *swiz, u_int64_t base,
+ swiz_sethae_fn sethae, void *arg);
+
+#endif /* _KERNEL */
+
#endif /* !_MACHINE_SWIZ_H_ */
diff --git a/sys/alpha/mcbus/mcbus.c b/sys/alpha/mcbus/mcbus.c
index 4f8e463..a0bf2d6 100644
--- a/sys/alpha/mcbus/mcbus.c
+++ b/sys/alpha/mcbus/mcbus.c
@@ -220,7 +220,7 @@ static int
mcbus_setup_intr(device_t dev, device_t child, struct resource *r, int f,
driver_intr_t *intr, void *a, void **ac)
{
- if (strncmp(device_get_name(child), "mcpcia", 6) == 0) {
+ if (strncmp(device_get_name(child), "pcib", 6) == 0) {
if (mcbus0_softc->sub_intr == NULL)
mcbus0_softc->sub_intr = intr;
return (0);
@@ -232,7 +232,7 @@ mcbus_setup_intr(device_t dev, device_t child, struct resource *r, int f,
static int
mcbus_teardown_intr(device_t dev, device_t child, struct resource *i, void *c)
{
- if (strncmp(device_get_name(child), "mcpcia", 6) == 0) {
+ if (strncmp(device_get_name(child), "pcib", 6) == 0) {
mcbus0_softc->sub_intr = NULL;
return (0);
} else {
@@ -257,7 +257,7 @@ mcbus_add_child(struct mcbus_softc *mcbus, struct mcbus_device *mdev)
switch (mdev->ma_type) {
case MCBUS_TYPE_PCI:
- dn = "mcpcia";
+ dn = "pcib";
ds = "MCPCIA PCI Bus Bridge";
un = mcpciaproto++;
break;
diff --git a/sys/alpha/mcbus/mcpcia.c b/sys/alpha/mcbus/mcpcia.c
index 2bf987d..f325d44 100644
--- a/sys/alpha/mcbus/mcpcia.c
+++ b/sys/alpha/mcbus/mcpcia.c
@@ -52,6 +52,9 @@
#include <alpha/pci/pcibus.h>
#include <pci/pcivar.h>
+#include "alphapci_if.h"
+#include "pcib_if.h"
+
static devclass_t mcpcia_devclass;
/* We're only allowing for one MCBUS right now */
@@ -67,42 +70,18 @@ struct mcpcia_softc {
vm_offset_t smem_base; /* sparse memory */
vm_offset_t io_base; /* sparse i/o */
int mcpcia_inst; /* our mcpcia instance # */
+ struct swiz_space io_space; /* accessor for ports */
+ struct swiz_space mem_space; /* accessor for memory */
+ struct rman io_rman; /* resource manager for ports */
+ struct rman mem_rman; /* resource manager for memory */
};
static struct mcpcia_softc *mcpcia_eisa = NULL;
extern void dec_kn300_cons_init(void);
-
-static int mcpcia_probe(device_t dev);
-static int mcpcia_attach(device_t dev);
-
-static int mcpcia_setup_intr(device_t, device_t, struct resource *, int,
- driver_intr_t *, void *, void **);
-static int
-mcpcia_teardown_intr(device_t, device_t, struct resource *, void *);
static driver_intr_t mcpcia_intr;
static void mcpcia_enable_intr(struct mcpcia_softc *, int);
static void mcpcia_disable_intr(struct mcpcia_softc *, int);
-
-static device_method_t mcpcia_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, mcpcia_probe),
- DEVMETHOD(device_attach, mcpcia_attach),
-
- /* Bus interface */
- DEVMETHOD(bus_setup_intr, mcpcia_setup_intr),
- DEVMETHOD(bus_teardown_intr, mcpcia_teardown_intr),
- 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),
-
- { 0, 0 }
-};
-static driver_t mcpcia_driver = {
- "mcpcia", mcpcia_methods, sizeof (struct mcpcia_softc)
-};
-
/*
* SGMAP window for ISA: 8M at 8M
*/
@@ -129,354 +108,12 @@ do { \
} while (0)
static void mcpcia_dma_init(struct mcpcia_softc *);
-static void mcpcia_sgmap_map(void *, vm_offset_t, vm_offset_t);
+static void mcpcia_sgmap_map(void *, bus_addr_t, vm_offset_t);
#define MCPCIA_SOFTC(dev) (struct mcpcia_softc *) device_get_softc(dev)
static struct mcpcia_softc *mcpcia_root;
-static alpha_chipset_inb_t mcpcia_inb;
-static alpha_chipset_inw_t mcpcia_inw;
-static alpha_chipset_inl_t mcpcia_inl;
-static alpha_chipset_outb_t mcpcia_outb;
-static alpha_chipset_outw_t mcpcia_outw;
-static alpha_chipset_outl_t mcpcia_outl;
-static alpha_chipset_readb_t mcpcia_readb;
-static alpha_chipset_readw_t mcpcia_readw;
-static alpha_chipset_readl_t mcpcia_readl;
-static alpha_chipset_writeb_t mcpcia_writeb;
-static alpha_chipset_writew_t mcpcia_writew;
-static alpha_chipset_writel_t mcpcia_writel;
-static alpha_chipset_maxdevs_t mcpcia_maxdevs;
-static alpha_chipset_cfgreadb_t mcpcia_cfgreadb;
-static alpha_chipset_cfgreadw_t mcpcia_cfgreadw;
-static alpha_chipset_cfgreadl_t mcpcia_cfgreadl;
-static alpha_chipset_cfgwriteb_t mcpcia_cfgwriteb;
-static alpha_chipset_cfgwritew_t mcpcia_cfgwritew;
-static alpha_chipset_cfgwritel_t mcpcia_cfgwritel;
-
-static alpha_chipset_t mcpcia_chipset = {
- mcpcia_inb,
- mcpcia_inw,
- mcpcia_inl,
- mcpcia_outb,
- mcpcia_outw,
- mcpcia_outl,
- mcpcia_readb,
- mcpcia_readw,
- mcpcia_readl,
- mcpcia_writeb,
- mcpcia_writew,
- mcpcia_writel,
- mcpcia_maxdevs,
- mcpcia_cfgreadb,
- mcpcia_cfgreadw,
- mcpcia_cfgreadl,
- mcpcia_cfgwriteb,
- mcpcia_cfgwritew,
- mcpcia_cfgwritel,
-};
-
-#define MCPCIA_NMBR(port) ((port >> 30) & 0x3)
-#define MCPCIA_INST(port) mcpcias[MCPCIA_NMBR(port)]
-#define MCPCIA_ADDR(port) (port & 0x3fffffff)
-
-static u_int8_t
-mcpcia_inb(u_int32_t port)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port));
- if (port < (1 << 16)) {
- if (mcpcia_eisa == NULL) {
- return (0xff);
- }
- return SPARSE_READ_BYTE(mcpcia_eisa->io_base, port);
- }
- return SPARSE_READ_BYTE(sc->io_base, MCPCIA_ADDR(port));
-}
-
-static u_int16_t
-mcpcia_inw(u_int32_t port)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port));
- if (port < (1 << 16)) {
- if (mcpcia_eisa == NULL) {
- return (0xffff);
- }
- return SPARSE_READ_WORD(mcpcia_eisa->io_base, port);
- }
- return SPARSE_READ_WORD(sc->io_base, MCPCIA_ADDR(port));
-}
-
-static u_int32_t
-mcpcia_inl(u_int32_t port)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port));
- return SPARSE_READ_LONG(sc->io_base, MCPCIA_ADDR(port));
-}
-
-static void
-mcpcia_outb(u_int32_t port, u_int8_t data)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port));
- if (port < (1 << 16)) {
- if (mcpcia_eisa)
- SPARSE_WRITE_BYTE(mcpcia_eisa->io_base, port, data);
- } else {
- SPARSE_WRITE_BYTE(sc->io_base, MCPCIA_ADDR(port), data);
- }
- alpha_mb();
-}
-
-static void
-mcpcia_outw(u_int32_t port, u_int16_t data)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port));
- if (port < (1 << 16)) {
- if (mcpcia_eisa)
- SPARSE_WRITE_WORD(mcpcia_eisa->io_base, port, data);
- } else {
- SPARSE_WRITE_WORD(sc->io_base, MCPCIA_ADDR(port), data);
- }
- alpha_mb();
-}
-
-static void
-mcpcia_outl(u_int32_t port, u_int32_t data)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(port));
- SPARSE_WRITE_LONG(sc->io_base, MCPCIA_ADDR(port), data);
- alpha_mb();
-}
-
-static u_int8_t
-mcpcia_readb(u_int32_t pa)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa));
- if (pa < (8 << 20)) {
- if (mcpcia_eisa == NULL) {
- return (0xff);
- }
- return SPARSE_READ_BYTE(mcpcia_eisa->smem_base, pa);
- }
- return SPARSE_READ_BYTE(sc->smem_base, MCPCIA_ADDR(pa));
-}
-
-static u_int16_t
-mcpcia_readw(u_int32_t pa)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa));
- if (pa < (8 << 20)) {
- if (mcpcia_eisa == NULL) {
- return (0xffff);
- }
- return SPARSE_READ_WORD(mcpcia_eisa->smem_base, pa);
- }
- return SPARSE_READ_WORD(sc->smem_base, MCPCIA_ADDR(pa));
-}
-
-static u_int32_t
-mcpcia_readl(u_int32_t pa)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa));
- return SPARSE_READ_LONG(sc->smem_base, MCPCIA_ADDR(pa));
-}
-
-static void
-mcpcia_writeb(u_int32_t pa, u_int8_t data)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa));
- if (pa < (8 << 20)) {
- if (mcpcia_eisa)
- SPARSE_WRITE_BYTE(mcpcia_eisa->smem_base, pa, data);
- } else {
- SPARSE_WRITE_BYTE(sc->smem_base, MCPCIA_ADDR(pa), data);
- }
- alpha_mb();
-}
-
-static void
-mcpcia_writew(u_int32_t pa, u_int16_t data)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa));
- if (pa < (8 << 20)) {
- if (mcpcia_eisa)
- SPARSE_WRITE_WORD(mcpcia_eisa->smem_base, pa, data);
- } else {
- SPARSE_WRITE_WORD(sc->smem_base, MCPCIA_ADDR(pa), data);
- }
- alpha_mb();
-}
-
-static void
-mcpcia_writel(u_int32_t pa, u_int32_t data)
-{
- struct mcpcia_softc *sc = MCPCIA_SOFTC(MCPCIA_INST(pa));
- SPARSE_WRITE_LONG(sc->smem_base, MCPCIA_ADDR(pa), data);
- alpha_mb();
-}
-
-static int
-mcpcia_maxdevs(u_int b)
-{
- return (MCPCIA_MAXDEV);
-}
-
-static u_int32_t mcpcia_cfgread(u_int, u_int, u_int, u_int, u_int, int);
-static void mcpcia_cfgwrite(u_int, u_int, u_int, u_int, u_int, int, u_int32_t);
-
-#if 0
-#define RCFGP printf
-#else
-#define RCFGP if (0) printf
-#endif
-
-static u_int32_t
-mcpcia_cfgread(u_int bh, u_int bus, u_int slot, u_int func, u_int off, int sz)
-{
- device_t dev;
- struct mcpcia_softc *sc;
- u_int32_t *dp, data, rvp;
- u_int64_t paddr;
-
- RCFGP("CFGREAD %u.%u.%u.%u.%u.%d", bh, bus, slot, func, off, sz);
- rvp = data = ~0;
- if (bh == (u_int8_t)-1)
- bh = bus >> 4;
- dev = mcpcias[bh];
- if (dev == (device_t) 0) {
- RCFGP(" (no dev)\n");
- return (data);
- }
- sc = MCPCIA_SOFTC(dev);
- bus &= 0xf;
-
- /*
- * There's nothing in slot 0 on a primary bus.
- */
- if (bus == 0 && (slot < 1 || slot >= MCPCIA_MAXDEV)) {
- RCFGP(" (no slot)\n");
- return (data);
- }
-
- paddr = bus << 21;
- paddr |= slot << 16;
- paddr |= func << 13;
- paddr |= ((sz - 1) << 3);
- paddr |= ((unsigned long) ((off >> 2) << 7));
- paddr |= MCPCIA_PCI_CONF;
- paddr |= sc->sysbase;
- dp = (u_int32_t *)KV(paddr);
- RCFGP(" hose %d MID%d paddr 0x%lx", bh, mcbus_get_mid(dev), paddr);
- if (badaddr(dp, sizeof (*dp)) == 0) {
- data = *dp;
- }
- if (data != ~0) {
- if (sz == 1) {
- rvp = SPARSE_BYTE_EXTRACT(off, data);
- } else if (sz == 2) {
- rvp = SPARSE_WORD_EXTRACT(off, data);
- } else {
- rvp = data;
- }
- } else {
- rvp = data;
- }
- RCFGP(" data %x->0x%x\n", data, rvp);
- return (rvp);
-}
-
-#if 0
-#define WCFGP printf
-#else
-#define WCFGP if (0) printf
-#endif
-
-static void
-mcpcia_cfgwrite(u_int bh, u_int bus, u_int slot, u_int func, u_int off,
- int sz, u_int32_t data)
-{
- device_t dev;
- struct mcpcia_softc *sc;
- u_int32_t *dp;
- u_int64_t paddr;
-
- WCFGP("CFGWRITE %u.%u.%u.%u.%u.%d", bh, bus, slot, func, off, sz);
- if (bh == (u_int8_t)-1)
- bh = bus >> 4;
- dev = mcpcias[bh];
- if (dev == (device_t) 0) {
- WCFGP(" (no dev)\n");
- return;
- }
- sc = MCPCIA_SOFTC(dev);
- bus &= 0xf;
-
- /*
- * There's nothing in slot 0 on a primary bus.
- */
- if (bus == 0 && (slot < 1 || slot >= MCPCIA_MAXDEV)) {
- WCFGP(" (no slot)\n");
- return;
- }
-
- paddr = bus << 21;
- paddr |= slot << 16;
- paddr |= func << 13;
- paddr |= ((sz - 1) << 3);
- paddr |= ((unsigned long) ((off >> 2) << 7));
- paddr |= MCPCIA_PCI_CONF;
- paddr |= sc->sysbase;
- dp = (u_int32_t *)KV(paddr);
- WCFGP(" hose %d MID%d paddr 0x%lx\n", bh, mcbus_get_mid(dev), paddr);
- if (badaddr(dp, sizeof (*dp)) == 0) {
- u_int32_t new_data;
- if (sz == 1) {
- new_data = SPARSE_BYTE_INSERT(off, data);
- } else if (sz == 2) {
- new_data = SPARSE_WORD_INSERT(off, data);
- } else {
- new_data = data;
- }
- *dp = new_data;
- }
-}
-
-static u_int8_t
-mcpcia_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- return (u_int8_t) mcpcia_cfgread(h, b, s, f, r, 1);
-}
-
-static u_int16_t
-mcpcia_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- return (u_int16_t) mcpcia_cfgread(h, b, s, f, r, 2);
-}
-
-static u_int32_t
-mcpcia_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- return mcpcia_cfgread(h, b, s, f, r, 4);
-}
-
-static void
-mcpcia_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
-{
- mcpcia_cfgwrite(h, b, s, f, r, 1, (u_int32_t) data);
-}
-
-static void
-mcpcia_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
-{
- mcpcia_cfgwrite(h, b, s, f, r, 2, (u_int32_t) data);
-}
-
-static void
-mcpcia_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
-{
- mcpcia_cfgwrite(h, b, s, f, r, 4, (u_int32_t) data);
-}
-
static int
mcpcia_probe(device_t dev)
{
@@ -503,7 +140,7 @@ mcpcia_probe(device_t dev)
if (unit == 0) {
pci_init_resources();
}
- child = device_add_child(dev, "pcib", unit);
+ child = device_add_child(dev, "pci", -1);
device_set_ivars(child, &sc->mcpcia_inst);
return (0);
}
@@ -518,7 +155,6 @@ mcpcia_attach(device_t dev)
int mid, gid, rval;
void *intr;
- chipset = mcpcia_chipset;
mid = mcbus_get_mid(dev);
gid = mcbus_get_gid(dev);
@@ -530,6 +166,25 @@ mcpcia_attach(device_t dev)
sc->smem_base = regs + MCPCIA_PCI_SPARSE;
sc->io_base = regs + MCPCIA_PCI_IOSPACE;
+ swiz_init_space(&sc->io_space, sc->io_base);
+ swiz_init_space(&sc->mem_space, sc->smem_base);
+
+ 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("mcpcia_attach: 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("mcpcia_attach: mem_rman");
+
/*
* Disable interrupts and clear errors prior to probing
*/
@@ -538,7 +193,6 @@ mcpcia_attach(device_t dev)
REGVAL(MCPCIA_CAP_ERR(sc)) = 0xFFFFFFFF;
alpha_mb();
-
/*
* Say who we are
*/
@@ -569,7 +223,12 @@ mcpcia_attach(device_t dev)
BUS_SETUP_INTR(p, dev, NULL, INTR_TYPE_MISC, mcpcia_intr, 0, &intr);
if (rval == 0) {
if (sc == mcpcia_eisa) {
+ busspace_isa_io = (struct alpha_busspace *)
+ &sc->io_space;
+ busspace_isa_mem = (struct alpha_busspace *)
+ &sc->mem_space;
printf("Attaching Real Console\n");
+ mcpcia_enable_intr(sc, 16);
dec_kn300_cons_init();
/*
* Enable EISA interrupts.
@@ -681,8 +340,159 @@ mcpcia_teardown_intr(device_t dev, device_t child, struct resource *i, void *c)
return (rman_deactivate_resource(i));
}
+static int
+mcpcia_read_ivar(device_t dev, device_t child, int which, u_long *result)
+{
+ switch (which) {
+ case PCIB_IVAR_BUS:
+ *result = 0;
+ return 0;
+ }
+ return ENOENT;
+}
+
+static void *
+mcpcia_cvt_dense(device_t dev, vm_offset_t addr)
+{
+ struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
+
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | sc->dmem_base);
+
+}
+
+static struct alpha_busspace *
+mcpcia_get_bustag(device_t dev, int type)
+{
+ struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return (struct alpha_busspace *) &sc->io_space;
+
+ case SYS_RES_MEMORY:
+ return (struct alpha_busspace *) &sc->mem_space;
+ }
+
+ return 0;
+}
+
+static struct rman *
+mcpcia_get_rman(device_t dev, int type)
+{
+ struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return &sc->io_rman;
+
+ case SYS_RES_MEMORY:
+ return &sc->mem_rman;
+ }
+
+ return 0;
+}
+
+static int
+mcpcia_maxslots(device_t dev)
+{
+ return (MCPCIA_MAXDEV);
+}
+
+static u_int32_t
+mcpcia_read_config(device_t dev, int bus, int slot, int func,
+ int off, int sz)
+{
+ struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
+ u_int32_t *dp, data, rvp;
+ u_int64_t paddr;
+
+ rvp = data = ~0;
+
+ /*
+ * There's nothing in slot 0 on a primary bus.
+ */
+ if (bus == 0 && (slot < 1 || slot >= MCPCIA_MAXDEV))
+ return (data);
+
+ paddr = bus << 21;
+ paddr |= slot << 16;
+ paddr |= func << 13;
+ paddr |= ((sz - 1) << 3);
+ paddr |= ((unsigned long) ((off >> 2) << 7));
+ paddr |= MCPCIA_PCI_CONF;
+ paddr |= sc->sysbase;
+ dp = (u_int32_t *)KV(paddr);
+
+#if 0
+printf("CFGREAD MID %d %d.%d.%d sz %d off %d -> paddr 0x%x",
+mcbus_get_mid(dev), bus , slot, func, sz, off, paddr);
+#endif
+ if (badaddr(dp, sizeof (*dp)) == 0) {
+ data = *dp;
+ }
+ if (data != ~0) {
+ if (sz == 1) {
+ rvp = SPARSE_BYTE_EXTRACT(off, data);
+ } else if (sz == 2) {
+ rvp = SPARSE_WORD_EXTRACT(off, data);
+ } else {
+ rvp = data;
+ }
+ } else {
+ rvp = data;
+ }
+
+#if 0
+printf(" data 0x%x -> 0x%x\n", data, rvp);
+#endif
+ return (rvp);
+}
+
+static void
+mcpcia_write_config(device_t dev, int bus, int slot, int func,
+ int off, u_int32_t data, int sz)
+{
+ struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
+ u_int32_t *dp;
+ u_int64_t paddr;
+
+ /*
+ * There's nothing in slot 0 on a primary bus.
+ */
+ if (bus != 0 && (slot < 1 || slot >= MCPCIA_MAXDEV))
+ return;
+
+ paddr = bus << 21;
+ paddr |= slot << 16;
+ paddr |= func << 13;
+ paddr |= ((sz - 1) << 3);
+ paddr |= ((unsigned long) ((off >> 2) << 7));
+ paddr |= MCPCIA_PCI_CONF;
+ paddr |= sc->sysbase;
+ dp = (u_int32_t *)KV(paddr);
+
+ if (badaddr(dp, sizeof (*dp)) == 0) {
+ u_int32_t new_data;
+ if (sz == 1) {
+ new_data = SPARSE_BYTE_INSERT(off, data);
+ } else if (sz == 2) {
+ new_data = SPARSE_WORD_INSERT(off, data);
+ } else {
+ new_data = data;
+ }
+
+#if 0
+printf("CFGWRITE MID%d %d.%d.%d sz %d off %d paddr %lx, data %x new_data %x\n",
+mcbus_get_mid(dev), bus , slot, func, sz, off, paddr, data, new_data);
+#endif
+
+ *dp = new_data;
+ }
+}
+
static void
-mcpcia_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa)
+mcpcia_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
{
u_int64_t *sgtable = arg;
int index = alpha_btop(ba - MCPCIA_ISA_SG_MAPPED_BASE);
@@ -807,4 +617,37 @@ mcpcia_intr(void *arg)
alpha_dispatch_intr(NULL, vec);
}
-DRIVER_MODULE(mcpcia, mcbus, mcpcia_driver, mcpcia_devclass, 0, 0);
+
+static device_method_t mcpcia_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, mcpcia_probe),
+ DEVMETHOD(device_attach, mcpcia_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_read_ivar, mcpcia_read_ivar),
+ DEVMETHOD(bus_setup_intr, mcpcia_setup_intr),
+ DEVMETHOD(bus_teardown_intr, mcpcia_teardown_intr),
+ 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),
+
+ /* alphapci interface */
+ DEVMETHOD(alphapci_cvt_dense, mcpcia_cvt_dense),
+ DEVMETHOD(alphapci_get_bustag, mcpcia_get_bustag),
+ DEVMETHOD(alphapci_get_rman, mcpcia_get_rman),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, mcpcia_maxslots),
+ DEVMETHOD(pcib_read_config, mcpcia_read_config),
+ DEVMETHOD(pcib_write_config, mcpcia_write_config),
+
+ { 0, 0 }
+};
+
+static driver_t mcpcia_driver = {
+ "pcib", mcpcia_methods, sizeof (struct mcpcia_softc)
+};
+
+DRIVER_MODULE(pcib, mcbus, mcpcia_driver, mcpcia_devclass, 0, 0);
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),
};
diff --git a/sys/alpha/tlsb/dwlpx.c b/sys/alpha/tlsb/dwlpx.c
index 032f0b3..91d6600 100644
--- a/sys/alpha/tlsb/dwlpx.c
+++ b/sys/alpha/tlsb/dwlpx.c
@@ -88,6 +88,9 @@
#include <alpha/pci/pcibus.h>
#include <pci/pcivar.h>
+#include "alphapci_if.h"
+#include "pcib_if.h"
+
static devclass_t dwlpx_devclass;
static device_t dwlpxs[DWLPX_NIONODE][DWLPX_NHOSE];
@@ -101,6 +104,10 @@ struct dwlpx_softc {
vm_offset_t dmem_base; /* dense memory */
vm_offset_t smem_base; /* sparse memory */
vm_offset_t io_base; /* sparse i/o */
+ struct swiz_space io_space; /* accessor for ports */
+ struct swiz_space mem_space; /* accessor for memory */
+ struct rman io_rman; /* resource manager for ports */
+ struct rman mem_rman; /* resource manager for memory */
int bushose; /* our bus && hose */
u_int : 26,
nhpc : 2, /* how many HPCs */
@@ -108,34 +115,8 @@ struct dwlpx_softc {
sgmapsz : 3; /* Scatter Gather map size */
};
-static int dwlpx_probe(device_t dev);
-static int dwlpx_attach(device_t dev);
-
-static int dwlpx_setup_intr(device_t, device_t, struct resource *, int,
- driver_intr_t *, void *, void **);
-static int
-dwlpx_teardown_intr(device_t, device_t, struct resource *, void *);
static driver_intr_t dwlpx_intr;
-static device_method_t dwlpx_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, dwlpx_probe),
- DEVMETHOD(device_attach, dwlpx_attach),
-
- /* Bus interface */
- DEVMETHOD(bus_setup_intr, dwlpx_setup_intr),
- DEVMETHOD(bus_teardown_intr, dwlpx_teardown_intr),
- 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),
-
- { 0, 0 }
-};
-static driver_t dwlpx_driver = {
- "dwlpx", dwlpx_methods, sizeof (struct dwlpx_softc)
-};
-
static u_int32_t imaskcache[DWLPX_NIONODE][DWLPX_NHOSE][NHPC];
static void dwlpx_eintr(unsigned long);
@@ -152,391 +133,9 @@ static void dwlpx_eintr(unsigned long);
#define DWLPx_SG_MAPPED_SIZE(x) ((x) * PAGE_SIZE)
static void dwlpx_dma_init(struct dwlpx_softc *);
-
-
#define DWLPX_SOFTC(dev) (struct dwlpx_softc *) device_get_softc(dev)
static struct dwlpx_softc *dwlpx_root;
-static alpha_chipset_inb_t dwlpx_inb;
-static alpha_chipset_inw_t dwlpx_inw;
-static alpha_chipset_inl_t dwlpx_inl;
-static alpha_chipset_outb_t dwlpx_outb;
-static alpha_chipset_outw_t dwlpx_outw;
-static alpha_chipset_outl_t dwlpx_outl;
-static alpha_chipset_readb_t dwlpx_readb;
-static alpha_chipset_readw_t dwlpx_readw;
-static alpha_chipset_readl_t dwlpx_readl;
-static alpha_chipset_writeb_t dwlpx_writeb;
-static alpha_chipset_writew_t dwlpx_writew;
-static alpha_chipset_writel_t dwlpx_writel;
-static alpha_chipset_maxdevs_t dwlpx_maxdevs;
-static alpha_chipset_cfgreadb_t dwlpx_cfgreadb;
-static alpha_chipset_cfgreadw_t dwlpx_cfgreadw;
-static alpha_chipset_cfgreadl_t dwlpx_cfgreadl;
-static alpha_chipset_cfgwriteb_t dwlpx_cfgwriteb;
-static alpha_chipset_cfgwritew_t dwlpx_cfgwritew;
-static alpha_chipset_cfgwritel_t dwlpx_cfgwritel;
-
-static alpha_chipset_t dwlpx_chipset = {
- dwlpx_inb,
- dwlpx_inw,
- dwlpx_inl,
- dwlpx_outb,
- dwlpx_outw,
- dwlpx_outl,
- dwlpx_readb,
- dwlpx_readw,
- dwlpx_readl,
- dwlpx_writeb,
- dwlpx_writew,
- dwlpx_writel,
- dwlpx_maxdevs,
- dwlpx_cfgreadb,
- dwlpx_cfgreadw,
- dwlpx_cfgreadl,
- dwlpx_cfgwriteb,
- dwlpx_cfgwritew,
- dwlpx_cfgwritel,
-};
-
-#define DWLPX_IONODE(port) ((port >> 29) & 0x7)
-#define DWLPX_HOSE(port) ((port >> 27) & 0x3)
-#define DWLPX_INST(port) dwlpxs[DWLPX_IONODE(port)][DWLPX_HOSE(port)]
-#define DWLPX_ADDR(port) (port & 0x07ffffff)
-
-static u_int8_t
-dwlpx_inb(u_int32_t port)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(port));
- return SPARSE_READ_BYTE(sc->io_base, DWLPX_ADDR(port));
-}
-
-static u_int16_t
-dwlpx_inw(u_int32_t port)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(port));
- return SPARSE_READ_WORD(sc->io_base, DWLPX_ADDR(port));
-}
-
-static u_int32_t
-dwlpx_inl(u_int32_t port)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(port));
- return SPARSE_READ_LONG(sc->io_base, DWLPX_ADDR(port));
-}
-
-static void
-dwlpx_outb(u_int32_t port, u_int8_t data)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(port));
- SPARSE_WRITE_BYTE(sc->io_base, DWLPX_ADDR(port), data);
- alpha_mb();
-}
-
-static void
-dwlpx_outw(u_int32_t port, u_int16_t data)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(port));
- SPARSE_WRITE_WORD(sc->io_base, DWLPX_ADDR(port), data);
- alpha_mb();
-}
-
-static void
-dwlpx_outl(u_int32_t port, u_int32_t data)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(port));
- SPARSE_WRITE_LONG(sc->io_base, DWLPX_ADDR(port), data);
- alpha_mb();
-}
-
-static u_int8_t
-dwlpx_readb(u_int32_t pa)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(pa));
- return SPARSE_READ_BYTE(sc->smem_base, DWLPX_ADDR(pa));
-}
-
-static u_int16_t
-dwlpx_readw(u_int32_t pa)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(pa));
- return SPARSE_READ_WORD(sc->smem_base, DWLPX_ADDR(pa));
-}
-
-static u_int32_t
-dwlpx_readl(u_int32_t pa)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(pa));
- return SPARSE_READ_LONG(sc->smem_base, DWLPX_ADDR(pa));
-}
-
-static void
-dwlpx_writeb(u_int32_t pa, u_int8_t data)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(pa));
- SPARSE_WRITE_BYTE(sc->smem_base, DWLPX_ADDR(pa), data);
- alpha_mb();
-}
-
-static void
-dwlpx_writew(u_int32_t pa, u_int16_t data)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(pa));
- SPARSE_WRITE_WORD(sc->smem_base, DWLPX_ADDR(pa), data);
- alpha_mb();
-}
-
-static void
-dwlpx_writel(u_int32_t pa, u_int32_t data)
-{
- struct dwlpx_softc *sc = DWLPX_SOFTC(DWLPX_INST(pa));
- SPARSE_WRITE_LONG(sc->smem_base, DWLPX_ADDR(pa), data);
- alpha_mb();
-}
-
-static int
-dwlpx_maxdevs(u_int b)
-{
- return (DWLPX_MAXDEV);
-}
-
-static u_int32_t dwlpx_cfgread(u_int, u_int, u_int, u_int, u_int, int);
-static void dwlpx_cfgwrite(u_int, u_int, u_int, u_int, u_int, int, u_int32_t);
-
-#if 0
-#define RCFGP printf
-#else
-#define RCFGP if (0) printf
-#endif
-
-
-static u_int32_t
-dwlpx_cfgread(u_int bh, u_int bus, u_int slot, u_int func, u_int off, int sz)
-{
- struct dwlpx_softc *sc;
- device_t dev;
- u_int32_t *dp, data, rvp, pci_idsel, hpcdev;
- unsigned long paddr;
- int hose, ionode;
- int s = 0, i;
-
- RCFGP("CFGREAD %u.%u.%u.%u.%u.%d", bh, bus, slot, func, off, sz);
-
- rvp = data = ~0;
- if (bh == (u_int8_t)-1)
- bh = bus >> 4;
- ionode = ((bh >> 2) & 0x7);
- hose = (bh & 0x3);
- dev = dwlpxs[ionode][hose];
- if (dev == (device_t) 0) {
- RCFGP(" (no dev)\n");
- return (data);
- }
- sc = DWLPX_SOFTC(dev);
- bus &= 0xf;
-
- if (sc->nhpc < 1) {
- RCFGP(" (no hpcs)\n");
- return (data);
- } else if (sc->nhpc < 2 && slot >= 4) {
- RCFGP(" (bad hpcs (%d) <> bad slot (%d))\n", sc->nhpc, slot);
- return (data);
- } else if (sc->nhpc < 3 && slot >= 8) {
- RCFGP(" (bad hpcs (%d) <> bad slot (%d))\n", sc->nhpc, slot);
- return (data);
- } else if (slot >= DWLPX_MAXDEV) {
- RCFGP(" (bad slot (%d))\n", slot);
- return (data);
- }
- hpcdev = slot >> 2;
- pci_idsel = (1 << ((slot & 0x3) + 2));
- paddr = (hpcdev << 22) | (pci_idsel << 16) | (func << 13);
-
- if (bus) {
- paddr &= 0x1fffff;
- paddr |= (bus << 21);
- alpha_pal_draina();
- s = splhigh();
- /*
- * Set up HPCs for type 1 cycles.
- */
- for (i = 0; i < sc->nhpc; i++) {
- rvp = REGVAL(PCIA_CTL(i)+sc->sysbase) | PCIA_CTL_T1CYC;
- alpha_mb();
- REGVAL(PCIA_CTL(i) + sc->sysbase) = rvp;
- alpha_mb();
- }
- }
-
- paddr |= ((unsigned long) ((off >> 2) << 7));
- paddr |= ((sz - 1) << 3);
- paddr |= DWLPX_PCI_CONF;
- paddr |= ((unsigned long) hose) << 34;
- paddr |= ((unsigned long) ionode) << 36;
- paddr |= 1L << 39;
-
- dp = (u_int32_t *)KV(paddr);
- RCFGP(" hose %d node%d paddr 0x%lx", bh, ionode+4, paddr);
- if (badaddr(dp, sizeof (*dp)) == 0) {
- data = *dp;
- }
- if (bus) {
- alpha_pal_draina();
- for (i = 0; i < sc->nhpc; i++) {
- rvp = REGVAL(PCIA_CTL(i)+sc->sysbase) & ~PCIA_CTL_T1CYC;
- alpha_mb();
- REGVAL(PCIA_CTL(i) + sc->sysbase) = rvp;
- alpha_mb();
- }
- (void) splx(s);
- }
-
- if (data != ~0) {
- if (sz == 1) {
- rvp = SPARSE_BYTE_EXTRACT(off, data);
- } else if (sz == 2) {
- rvp = SPARSE_WORD_EXTRACT(off, data);
- } else {
- rvp = data;
- }
- } else {
- rvp = data;
- }
- RCFGP(" data %x->0x%x\n", data, rvp);
- return (rvp);
-}
-
-#if 0
-#define WCFGP printf
-#else
-#define WCFGP if (0) printf
-#endif
-
-static void
-dwlpx_cfgwrite(u_int bh, u_int bus, u_int slot, u_int func, u_int off,
- int sz, u_int32_t data)
-{
- int hose, ionode;
- int s = 0, i;
- u_int32_t *dp, rvp, pci_idsel, hpcdev;
- unsigned long paddr;
- struct dwlpx_softc *sc;
- device_t dev;
-
- WCFGP("CFGWRITE %u.%u.%u.%u.%u.%d", bh, bus, slot, func, off, sz);
- if (bh == (u_int8_t)-1)
- bh = bus >> 4;
- ionode = ((bh >> 2) & 0x7);
- hose = (bh & 0x3);
- dev = dwlpxs[ionode][hose];
- if (dev == (device_t) 0) {
- WCFGP(" (no dev)\n");
- return;
- }
- sc = DWLPX_SOFTC(dev);
- bus &= 0xf;
-
- if (sc->nhpc < 1) {
- WCFGP(" (no hpcs)\n");
- return;
- } else if (sc->nhpc < 2 && slot >= 4) {
- WCFGP(" (bad hpcs (%d) <> bad slot (%d))\n", sc->nhpc, slot);
- return;
- } else if (sc->nhpc < 3 && slot >= 8) {
- WCFGP(" (bad hpcs (%d) <> bad slot (%d))\n", sc->nhpc, slot);
- return;
- } else if (slot >= DWLPX_MAXDEV) {
- WCFGP(" (bad slot (%d))\n", slot);
- return;
- }
- hpcdev = slot >> 2;
- pci_idsel = (1 << ((slot & 0x3) + 2));
- paddr = (hpcdev << 22) | (pci_idsel << 16) | (func << 13);
- bus = 0;
-
- if (bus) {
- paddr &= 0x1fffff;
- paddr |= (bus << 21);
- alpha_pal_draina();
- s = splhigh();
- /*
- * Set up HPCs for type 1 cycles.
- */
- for (i = 0; i < sc->nhpc; i++) {
- rvp = REGVAL(PCIA_CTL(i)+sc->sysbase) | PCIA_CTL_T1CYC;
- alpha_mb();
- REGVAL(PCIA_CTL(i) + sc->sysbase) = rvp;
- alpha_mb();
- }
- }
-
- paddr |= ((unsigned long) ((off >> 2) << 7));
- paddr |= ((sz - 1) << 3);
- paddr |= DWLPX_PCI_CONF;
- paddr |= ((unsigned long) hose) << 34;
- paddr |= ((unsigned long) ionode) << 36;
- paddr |= 1L << 39;
- dp = (u_int32_t *)KV(paddr);
- WCFGP(" hose %d node%d paddr 0x%lx\n", bh, ionode+4, paddr);
- if (badaddr(dp, sizeof (*dp)) == 0) {
- u_int32_t new_data;
- if (sz == 1) {
- new_data = SPARSE_BYTE_INSERT(off, data);
- } else if (sz == 2) {
- new_data = SPARSE_WORD_INSERT(off, data);
- } else {
- new_data = data;
- }
- *dp = new_data;
- }
- if (bus) {
- alpha_pal_draina();
- for (i = 0; i < sc->nhpc; i++) {
- rvp = REGVAL(PCIA_CTL(i)+sc->sysbase) & ~PCIA_CTL_T1CYC;
- alpha_mb();
- REGVAL(PCIA_CTL(i) + sc->sysbase) = rvp;
- alpha_mb();
- }
- (void) splx(s);
- }
-}
-
-static u_int8_t
-dwlpx_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- return (u_int8_t) dwlpx_cfgread(h, b, s, f, r, 1);
-}
-
-static u_int16_t
-dwlpx_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- return (u_int16_t) dwlpx_cfgread(h, b, s, f, r, 2);
-}
-
-static u_int32_t
-dwlpx_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
-{
- return dwlpx_cfgread(h, b, s, f, r, 4);
-}
-
-static void
-dwlpx_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
-{
- dwlpx_cfgwrite(h, b, s, f, r, 1, (u_int32_t) data);
-}
-
-static void
-dwlpx_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
-{
- dwlpx_cfgwrite(h, b, s, f, r, 2, (u_int32_t) data);
-}
-
-static void
-dwlpx_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
-{
- dwlpx_cfgwrite(h, b, s, f, r, 4, (u_int32_t) data);
-}
-
static int
dwlpx_probe(device_t dev)
{
@@ -586,7 +185,7 @@ dwlpx_probe(device_t dev)
pci_init_resources();
}
- child = device_add_child(dev, "pcib", device_get_unit(dev));
+ child = device_add_child(dev, "pci", -1);
device_set_ivars(child, &sc->bushose);
return (0);
}
@@ -604,9 +203,6 @@ dwlpx_attach(device_t dev)
io = kft_get_node(dev) - 4;
hose = kft_get_hosenum(dev);
- chipset = dwlpx_chipset;
- /* chipset.intrdev = dev; */
-
sc->sysbase = DWLPX_BASE(io + 4, hose);
regs = (vm_offset_t) KV(sc->sysbase);
sc->dmem_base = regs + DWLPX_PCI_DENSE;
@@ -614,6 +210,29 @@ dwlpx_attach(device_t dev)
sc->io_base = regs + DWLPX_PCI_IOSPACE;
/*
+ * Maybe initialise busspace_isa_io and busspace_isa_mem
+ * here. Does the 8200 actually have any ISA slots?
+ */
+ swiz_init_space(&sc->io_space, sc->io_base);
+ swiz_init_space(&sc->mem_space, sc->smem_base);
+
+ 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("dwlpx_attach: 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("dwlpx_attach: mem_rman");
+
+ /*
* Set up interrupt stuff for this DWLPX.
*
* Note that all PCI interrupt pins are disabled at this time.
@@ -757,6 +376,7 @@ static int
dwlpx_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
driver_intr_t *intr, void *arg, void **cookiep)
{
+ struct dwlpx_softc *sc = DWLPX_SOFTC(dev);
int slot, ionode, hose, error, vector, intpin;
error = rman_activate_resource(irq);
@@ -765,9 +385,8 @@ dwlpx_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
intpin = pci_get_intpin(child);
slot = pci_get_slot(child);
- hose = pci_get_hose(child);
- ionode = hose >> 2;
- hose &= 0x3;
+ ionode = sc->bushose >> 2;
+ hose = sc->bushose & 0x3;
vector = DWLPX_MVEC(ionode, hose, slot);
error = alpha_setup_intr(vector, intr, arg, cookiep,
@@ -783,19 +402,258 @@ dwlpx_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
static int
dwlpx_teardown_intr(device_t dev, device_t child, struct resource *irq, void *c)
{
+ struct dwlpx_softc *sc = DWLPX_SOFTC(dev);
int slot, ionode, hose, vector, intpin;
intpin = pci_get_intpin(child);
slot = pci_get_slot(child);
- hose = pci_get_hose(child);
- ionode = hose >> 2;
- hose &= 0x3;
+ ionode = sc->bushose >> 2;
+ hose = sc->bushose & 0x3;
vector = DWLPX_MVEC(ionode, hose, slot);
dwlpx_enadis_intr(vector, intpin, 0);
alpha_teardown_intr(c);
return rman_deactivate_resource(irq);
}
+static int
+dwlpx_read_ivar(device_t dev, device_t child, int which, u_long *result)
+{
+ switch (which) {
+ case PCIB_IVAR_BUS:
+ *result = 0;
+ return 0;
+ }
+ return ENOENT;
+}
+
+static void *
+dwlpx_cvt_dense(device_t dev, vm_offset_t addr)
+{
+ struct dwlpx_softc *sc = DWLPX_SOFTC(dev);
+
+ addr &= 0xffffffffUL;
+ return (void *) KV(addr | sc->dmem_base);
+
+}
+
+static kobj_t
+dwlpx_get_bustag(device_t dev, int type)
+{
+ struct dwlpx_softc *sc = DWLPX_SOFTC(dev);
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return (kobj_t) &sc->io_space;
+
+ case SYS_RES_MEMORY:
+ return (kobj_t) &sc->mem_space;
+ }
+
+ return 0;
+}
+
+static struct rman *
+dwlpx_get_rman(device_t dev, int type)
+{
+ struct dwlpx_softc *sc = DWLPX_SOFTC(dev);
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return &sc->io_rman;
+
+ case SYS_RES_MEMORY:
+ return &sc->mem_rman;
+ }
+
+ return 0;
+}
+
+static int
+dwlpx_maxslots(device_t dev)
+{
+ return (DWLPX_MAXDEV);
+}
+
+static u_int32_t
+dwlpx_read_config(device_t dev, int bus, int slot, int func,
+ int off, int sz)
+{
+ struct dwlpx_softc *sc = DWLPX_SOFTC(dev);
+ u_int32_t *dp, data, rvp, pci_idsel, hpcdev;
+ unsigned long paddr;
+ int hose, ionode;
+ int secondary = 0, s = 0, i;
+
+ rvp = data = ~0;
+
+ ionode = ((sc->bushose >> 2) & 0x7);
+ hose = (sc->bushose & 0x3);
+
+ if (sc->nhpc < 1)
+ return (data);
+ else if (sc->nhpc < 2 && slot >= 4)
+ return (data);
+ else if (sc->nhpc < 3 && slot >= 8)
+ return (data);
+ else if (slot >= DWLPX_MAXDEV)
+ return (data);
+ hpcdev = slot >> 2;
+ pci_idsel = (1 << ((slot & 0x3) + 2));
+ paddr = (hpcdev << 22) | (pci_idsel << 16) | (func << 13);
+
+ if (secondary) {
+ paddr &= 0x1fffff;
+ paddr |= (secondary << 21);
+
+#if 0
+ printf("read secondary %d reg %x (paddr %lx)",
+ secondary, offset, tag);
+#endif
+
+ alpha_pal_draina();
+ s = splhigh();
+ /*
+ * Set up HPCs for type 1 cycles.
+ */
+ for (i = 0; i < sc->nhpc; i++) {
+ rvp = REGVAL(PCIA_CTL(i)+sc->sysbase) | PCIA_CTL_T1CYC;
+ alpha_mb();
+ REGVAL(PCIA_CTL(i) + sc->sysbase) = rvp;
+ alpha_mb();
+ }
+ }
+
+ paddr |= ((unsigned long) ((off >> 2) << 7));
+ paddr |= ((sz - 1) << 3);
+ paddr |= DWLPX_PCI_CONF;
+ paddr |= ((unsigned long) hose) << 34;
+ paddr |= ((unsigned long) ionode) << 36;
+ paddr |= 1L << 39;
+
+ dp = (u_int32_t *)KV(paddr);
+
+#if 0
+printf("CFGREAD %d.%d.%d.%d.%d.%d.%d -> paddr 0x%lx",
+ionode+4, hose, bus, slot, func, off, sz, paddr);
+#endif
+
+ if (badaddr(dp, sizeof (*dp)) == 0) {
+ data = *dp;
+ }
+
+ if (secondary) {
+ alpha_pal_draina();
+ for (i = 0; i < sc->nhpc; i++) {
+ rvp = REGVAL(PCIA_CTL(i)+sc->sysbase) & ~PCIA_CTL_T1CYC;
+ alpha_mb();
+ REGVAL(PCIA_CTL(i) + sc->sysbase) = rvp;
+ alpha_mb();
+ }
+ (void) splx(s);
+ }
+
+ if (data != ~0) {
+ if (sz == 1) {
+ rvp = SPARSE_BYTE_EXTRACT(off, data);
+ } else if (sz == 2) {
+ rvp = SPARSE_WORD_EXTRACT(off, data);
+ } else {
+ rvp = data;
+ }
+ } else {
+ rvp = data;
+ }
+
+#if 0
+printf(" data 0x%x -> 0x%x\n", data, rvp);
+#endif
+ return (rvp);
+}
+
+static void
+dwlpx_write_config(device_t dev, int bus, int slot, int func,
+ int off, u_int32_t data, int sz)
+{
+ struct dwlpx_softc *sc = DWLPX_SOFTC(dev);
+ int hose, ionode;
+ int secondary = 0, s = 0, i;
+ u_int32_t *dp, rvp, pci_idsel, hpcdev;
+ unsigned long paddr;
+
+ ionode = ((sc->bushose >> 2) & 0x7);
+ hose = (sc->bushose & 0x3);
+
+ if (sc->nhpc < 1)
+ return;
+ else if (sc->nhpc < 2 && slot >= 4)
+ return;
+ else if (sc->nhpc < 3 && slot >= 8)
+ return;
+ else if (slot >= DWLPX_MAXDEV)
+ return;
+ hpcdev = slot >> 2;
+ pci_idsel = (1 << ((slot & 0x3) + 2));
+ paddr = (hpcdev << 22) | (pci_idsel << 16) | (func << 13);
+
+ if (secondary) {
+ paddr &= 0x1fffff;
+ paddr |= (secondary << 21);
+
+#if 0
+ printf("write secondary %d reg %x (paddr %lx)",
+ secondary, offset, tag);
+#endif
+
+ alpha_pal_draina();
+ s = splhigh();
+ /*
+ * Set up HPCs for type 1 cycles.
+ */
+ for (i = 0; i < sc->nhpc; i++) {
+ rvp = REGVAL(PCIA_CTL(i)+sc->sysbase) | PCIA_CTL_T1CYC;
+ alpha_mb();
+ REGVAL(PCIA_CTL(i) + sc->sysbase) = rvp;
+ alpha_mb();
+ }
+ }
+
+ paddr |= ((unsigned long) ((off >> 2) << 7));
+ paddr |= ((sz - 1) << 3);
+ paddr |= DWLPX_PCI_CONF;
+ paddr |= ((unsigned long) hose) << 34;
+ paddr |= ((unsigned long) ionode) << 36;
+ paddr |= 1L << 39;
+
+ dp = (u_int32_t *)KV(paddr);
+ if (badaddr(dp, sizeof (*dp)) == 0) {
+ u_int32_t new_data;
+ if (sz == 1) {
+ new_data = SPARSE_BYTE_INSERT(off, data);
+ } else if (sz == 2) {
+ new_data = SPARSE_WORD_INSERT(off, data);
+ } else {
+ new_data = data;
+ }
+
+#if 0
+printf("CFGWRITE %d.%d.%d.%d.%d.%d.%d paddr 0x%lx data 0x%x -> 0x%x\n",
+ionode+4, hose, bus, slot, func, off, sz, paddr, data, new_data);
+#endif
+
+ *dp = new_data;
+ }
+ if (secondary) {
+ alpha_pal_draina();
+ for (i = 0; i < sc->nhpc; i++) {
+ rvp = REGVAL(PCIA_CTL(i)+sc->sysbase) & ~PCIA_CTL_T1CYC;
+ alpha_mb();
+ REGVAL(PCIA_CTL(i) + sc->sysbase) = rvp;
+ alpha_mb();
+ }
+ (void) splx(s);
+ }
+}
+
static void
dwlpx_dma_init(struct dwlpx_softc *sc)
{
@@ -971,4 +829,36 @@ dwlpx_eintr(unsigned long vec)
}
}
-DRIVER_MODULE(dwlpx, kft, dwlpx_driver, dwlpx_devclass, 0, 0);
+static device_method_t dwlpx_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, dwlpx_probe),
+ DEVMETHOD(device_attach, dwlpx_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_read_ivar, dwlpx_read_ivar),
+ DEVMETHOD(bus_setup_intr, dwlpx_setup_intr),
+ DEVMETHOD(bus_teardown_intr, dwlpx_teardown_intr),
+ 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),
+
+ /* alphapci interface */
+ DEVMETHOD(alphapci_cvt_dense, dwlpx_cvt_dense),
+ DEVMETHOD(alphapci_get_bustag, dwlpx_get_bustag),
+ DEVMETHOD(alphapci_get_rman, dwlpx_get_rman),
+
+ /* pcib interface */
+ DEVMETHOD(pcib_maxslots, dwlpx_maxslots),
+ DEVMETHOD(pcib_read_config, dwlpx_read_config),
+ DEVMETHOD(pcib_write_config, dwlpx_write_config),
+
+ { 0, 0 }
+};
+
+static driver_t dwlpx_driver = {
+ "pcib", dwlpx_methods, sizeof (struct dwlpx_softc)
+};
+
+DRIVER_MODULE(pcib, kft, dwlpx_driver, dwlpx_devclass, 0, 0);
diff --git a/sys/alpha/tlsb/kftxx.c b/sys/alpha/tlsb/kftxx.c
index 51745fc..c5c8672 100644
--- a/sys/alpha/tlsb/kftxx.c
+++ b/sys/alpha/tlsb/kftxx.c
@@ -143,7 +143,7 @@ kft_probe(device_t dev)
if (kd == NULL)
continue;
- kd->kd_name = "dwlpx";
+ kd->kd_name = "pcib";
kd->kd_node = sc->sc_node;
kd->kd_dtype = sc->sc_dtype;
kd->kd_hosenum = hose;
OpenPOWER on IntegriCloud