diff options
author | dfr <dfr@FreeBSD.org> | 2000-08-28 21:48:13 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2000-08-28 21:48:13 +0000 |
commit | dd8b44b3958fa67d802cbbec7c7d82f7fb476229 (patch) | |
tree | 61496c144b3ecd15192a2e07e755754e18346bc9 | |
parent | 9ed8ded4d312c58a27de9402fd9802e78a591cb9 (diff) | |
download | FreeBSD-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.
72 files changed, 3696 insertions, 4802 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; diff --git a/sys/amd64/pci/pci_bus.c b/sys/amd64/pci/pci_bus.c index 990b418..ceff6a5 100644 --- a/sys/amd64/pci/pci_bus.c +++ b/sys/amd64/pci/pci_bus.c @@ -41,35 +41,49 @@ #include <machine/segments.h> #include <machine/pc/bios.h> +#include "pcib_if.h" + static int cfgmech; static int devmax; static int usebios; -static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcibios_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcibios_cfgopen(void); -static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcireg_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcireg_cfgopen(void); /* read configuration space register */ -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +nexus_pcib_maxslots(device_t dev) +{ + return 31; +} + +static u_int32_t +nexus_pcib_read_config(device_t dev, int bus, int slot, int func, + int reg, int bytes) { return(usebios ? - pcibios_cfgread(cfg, reg, bytes) : - pcireg_cfgread(cfg, reg, bytes)); + pcibios_cfgread(bus, slot, func, reg, bytes) : + pcireg_cfgread(bus, slot, func, reg, bytes)); } /* write configuration space register */ -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +nexus_pcib_write_config(device_t dev, int bus, int slot, int func, + int reg, u_int32_t data, int bytes) { return(usebios ? - pcibios_cfgwrite(cfg, reg, data, bytes) : - pcireg_cfgwrite(cfg, reg, data, bytes)); + pcibios_cfgwrite(bus, slot, func, reg, data, bytes) : + pcireg_cfgwrite(bus, slot, func, reg, data, bytes)); } /* initialise access to PCI configuration space */ @@ -89,7 +103,7 @@ pci_cfgopen(void) /* config space access using BIOS functions */ static int -pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcibios_cfgread(int bus, int slot, int func, int reg, int bytes) { struct bios_regs args; u_int mask; @@ -110,7 +124,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) default: return(-1); } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); /* check call results? */ @@ -118,7 +132,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcibios_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { struct bios_regs args; @@ -135,7 +149,7 @@ pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) default: return; } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.ecx = data; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); @@ -200,12 +214,12 @@ pci_cfgdisable(void) } static int -pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcireg_cfgread(int bus, int slot, int func, int reg, int bytes) { int data = -1; int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { @@ -225,11 +239,11 @@ pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { case 1: @@ -373,7 +387,7 @@ pcireg_cfgopen(void) static devclass_t pcib_devclass; static const char * -nexus_pcib_is_host_bridge(pcicfgregs *cfg, +nexus_pcib_is_host_bridge(int bus, int slot, int func, u_int32_t id, u_int8_t class, u_int8_t subclass, u_int8_t *busnum) { @@ -386,8 +400,8 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, case 0x12258086: s = "Intel 824?? host to PCI bridge"; /* XXX This is a guess */ - /* *busnum = pci_cfgread(cfg, 0x41, 1); */ - *busnum = cfg->bus; + /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */ + *busnum = bus; break; case 0x71208086: s = "Intel 82810 (i810 GMCH) Host To Hub bridge"; @@ -421,7 +435,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, break; case 0x84c48086: s = "Intel 82454KX/GX (Orion) host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x4a, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1); break; case 0x84ca8086: /* @@ -435,13 +449,17 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, * Since the MIOC doesn't have a pci bus attached, we * pretend it wasn't there. */ - pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ - pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ - pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ - pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + pxb[0] = nexus_pcib_read_config(0, bus, slot, func, + 0xd0, 1); /* BUSNO[0] */ + pxb[1] = nexus_pcib_read_config(0, bus, slot, func, + 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = nexus_pcib_read_config(0, bus, slot, func, + 0xd3, 1); /* BUSNO[1] */ + pxb[3] = nexus_pcib_read_config(0, bus, slot, func, + 0xd4, 1) + 1; /* SUBA[1]+1 */ return NULL; case 0x84cb8086: - switch (cfg->slot) { + switch (slot) { case 0x12: s = "Intel 82454NX PXB#0, Bus#A"; *busnum = pxb[0]; @@ -513,19 +531,19 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, /* RCC -- vendor 0x1166 */ case 0x00051166: s = "RCC HE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00061166: /* FALLTHROUGH */ case 0x00081166: s = "RCC host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00091166: s = "RCC LE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; /* Integrated Micro Solutions -- vendor 0x10e0 */ @@ -549,7 +567,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, static void nexus_pcib_identify(driver_t *driver, device_t parent) { - pcicfgregs probe; + int bus, slot, func; u_int8_t hdrtype; int found = 0; int pcifunchigh; @@ -557,19 +575,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) if (pci_cfgopen() == 0) return; - probe.hose = 0; - probe.bus = 0; + bus = 0; retry: - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { - probe.func = 0; - hdrtype = pci_cfgread(&probe, PCIR_HEADERTYPE, 1); + for (slot = 0; slot <= PCI_SLOTMAX; slot++) { + func = 0; + hdrtype = nexus_pcib_read_config(0, bus, slot, func, + PCIR_HEADERTYPE, 1); if (hdrtype & PCIM_MFDEV) pcifunchigh = 7; else pcifunchigh = 0; - for (probe.func = 0; - probe.func <= pcifunchigh; - probe.func++) { + for (func = 0; func <= pcifunchigh; func++) { /* * Read the IDs and class from the device. */ @@ -578,14 +594,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) device_t child; const char *s; - id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + id = nexus_pcib_read_config(0, bus, slot, func, + PCIR_DEVVENDOR, 4); if (id == -1) continue; - class = pci_cfgread(&probe, PCIR_CLASS, 1); - subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + class = nexus_pcib_read_config(0, bus, slot, func, + PCIR_CLASS, 1); + subclass = nexus_pcib_read_config(0, bus, slot, func, + PCIR_SUBCLASS, 1); - s = nexus_pcib_is_host_bridge(&probe, id, - class, subclass, + s = nexus_pcib_is_host_bridge(bus, slot, func, + id, class, subclass, &busnum); if (s) { /* @@ -601,8 +620,8 @@ nexus_pcib_identify(driver_t *driver, device_t parent) } } } - if (found824xx && probe.bus == 0) { - probe.bus++; + if (found824xx && bus == 0) { + bus++; goto retry; } @@ -629,6 +648,17 @@ nexus_pcib_probe(device_t dev) return ENXIO; } +static int +nexus_pcib_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 device_method_t nexus_pcib_methods[] = { /* Device interface */ DEVMETHOD(device_identify, nexus_pcib_identify), @@ -640,6 +670,7 @@ static device_method_t nexus_pcib_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, nexus_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), @@ -647,6 +678,11 @@ static device_method_t nexus_pcib_methods[] = { DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* pcib interface */ + DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots), + DEVMETHOD(pcib_read_config, nexus_pcib_read_config), + DEVMETHOD(pcib_write_config, nexus_pcib_write_config), + { 0, 0 } }; diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c index 990b418..ceff6a5 100644 --- a/sys/amd64/pci/pci_cfgreg.c +++ b/sys/amd64/pci/pci_cfgreg.c @@ -41,35 +41,49 @@ #include <machine/segments.h> #include <machine/pc/bios.h> +#include "pcib_if.h" + static int cfgmech; static int devmax; static int usebios; -static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcibios_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcibios_cfgopen(void); -static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcireg_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcireg_cfgopen(void); /* read configuration space register */ -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +nexus_pcib_maxslots(device_t dev) +{ + return 31; +} + +static u_int32_t +nexus_pcib_read_config(device_t dev, int bus, int slot, int func, + int reg, int bytes) { return(usebios ? - pcibios_cfgread(cfg, reg, bytes) : - pcireg_cfgread(cfg, reg, bytes)); + pcibios_cfgread(bus, slot, func, reg, bytes) : + pcireg_cfgread(bus, slot, func, reg, bytes)); } /* write configuration space register */ -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +nexus_pcib_write_config(device_t dev, int bus, int slot, int func, + int reg, u_int32_t data, int bytes) { return(usebios ? - pcibios_cfgwrite(cfg, reg, data, bytes) : - pcireg_cfgwrite(cfg, reg, data, bytes)); + pcibios_cfgwrite(bus, slot, func, reg, data, bytes) : + pcireg_cfgwrite(bus, slot, func, reg, data, bytes)); } /* initialise access to PCI configuration space */ @@ -89,7 +103,7 @@ pci_cfgopen(void) /* config space access using BIOS functions */ static int -pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcibios_cfgread(int bus, int slot, int func, int reg, int bytes) { struct bios_regs args; u_int mask; @@ -110,7 +124,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) default: return(-1); } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); /* check call results? */ @@ -118,7 +132,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcibios_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { struct bios_regs args; @@ -135,7 +149,7 @@ pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) default: return; } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.ecx = data; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); @@ -200,12 +214,12 @@ pci_cfgdisable(void) } static int -pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcireg_cfgread(int bus, int slot, int func, int reg, int bytes) { int data = -1; int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { @@ -225,11 +239,11 @@ pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { case 1: @@ -373,7 +387,7 @@ pcireg_cfgopen(void) static devclass_t pcib_devclass; static const char * -nexus_pcib_is_host_bridge(pcicfgregs *cfg, +nexus_pcib_is_host_bridge(int bus, int slot, int func, u_int32_t id, u_int8_t class, u_int8_t subclass, u_int8_t *busnum) { @@ -386,8 +400,8 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, case 0x12258086: s = "Intel 824?? host to PCI bridge"; /* XXX This is a guess */ - /* *busnum = pci_cfgread(cfg, 0x41, 1); */ - *busnum = cfg->bus; + /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */ + *busnum = bus; break; case 0x71208086: s = "Intel 82810 (i810 GMCH) Host To Hub bridge"; @@ -421,7 +435,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, break; case 0x84c48086: s = "Intel 82454KX/GX (Orion) host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x4a, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1); break; case 0x84ca8086: /* @@ -435,13 +449,17 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, * Since the MIOC doesn't have a pci bus attached, we * pretend it wasn't there. */ - pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ - pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ - pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ - pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + pxb[0] = nexus_pcib_read_config(0, bus, slot, func, + 0xd0, 1); /* BUSNO[0] */ + pxb[1] = nexus_pcib_read_config(0, bus, slot, func, + 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = nexus_pcib_read_config(0, bus, slot, func, + 0xd3, 1); /* BUSNO[1] */ + pxb[3] = nexus_pcib_read_config(0, bus, slot, func, + 0xd4, 1) + 1; /* SUBA[1]+1 */ return NULL; case 0x84cb8086: - switch (cfg->slot) { + switch (slot) { case 0x12: s = "Intel 82454NX PXB#0, Bus#A"; *busnum = pxb[0]; @@ -513,19 +531,19 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, /* RCC -- vendor 0x1166 */ case 0x00051166: s = "RCC HE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00061166: /* FALLTHROUGH */ case 0x00081166: s = "RCC host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00091166: s = "RCC LE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; /* Integrated Micro Solutions -- vendor 0x10e0 */ @@ -549,7 +567,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, static void nexus_pcib_identify(driver_t *driver, device_t parent) { - pcicfgregs probe; + int bus, slot, func; u_int8_t hdrtype; int found = 0; int pcifunchigh; @@ -557,19 +575,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) if (pci_cfgopen() == 0) return; - probe.hose = 0; - probe.bus = 0; + bus = 0; retry: - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { - probe.func = 0; - hdrtype = pci_cfgread(&probe, PCIR_HEADERTYPE, 1); + for (slot = 0; slot <= PCI_SLOTMAX; slot++) { + func = 0; + hdrtype = nexus_pcib_read_config(0, bus, slot, func, + PCIR_HEADERTYPE, 1); if (hdrtype & PCIM_MFDEV) pcifunchigh = 7; else pcifunchigh = 0; - for (probe.func = 0; - probe.func <= pcifunchigh; - probe.func++) { + for (func = 0; func <= pcifunchigh; func++) { /* * Read the IDs and class from the device. */ @@ -578,14 +594,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) device_t child; const char *s; - id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + id = nexus_pcib_read_config(0, bus, slot, func, + PCIR_DEVVENDOR, 4); if (id == -1) continue; - class = pci_cfgread(&probe, PCIR_CLASS, 1); - subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + class = nexus_pcib_read_config(0, bus, slot, func, + PCIR_CLASS, 1); + subclass = nexus_pcib_read_config(0, bus, slot, func, + PCIR_SUBCLASS, 1); - s = nexus_pcib_is_host_bridge(&probe, id, - class, subclass, + s = nexus_pcib_is_host_bridge(bus, slot, func, + id, class, subclass, &busnum); if (s) { /* @@ -601,8 +620,8 @@ nexus_pcib_identify(driver_t *driver, device_t parent) } } } - if (found824xx && probe.bus == 0) { - probe.bus++; + if (found824xx && bus == 0) { + bus++; goto retry; } @@ -629,6 +648,17 @@ nexus_pcib_probe(device_t dev) return ENXIO; } +static int +nexus_pcib_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 device_method_t nexus_pcib_methods[] = { /* Device interface */ DEVMETHOD(device_identify, nexus_pcib_identify), @@ -640,6 +670,7 @@ static device_method_t nexus_pcib_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, nexus_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), @@ -647,6 +678,11 @@ static device_method_t nexus_pcib_methods[] = { DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* pcib interface */ + DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots), + DEVMETHOD(pcib_read_config, nexus_pcib_read_config), + DEVMETHOD(pcib_write_config, nexus_pcib_write_config), + { 0, 0 } }; diff --git a/sys/conf/files b/sys/conf/files index 298a154..b2b3b03 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -907,6 +907,7 @@ pci/pci_compat.c optional pci compat_oldpci \ pci/pcic_p.c optional pcic pci pci/pcisupport.c optional pci pci/pci_if.m optional pci +pci/pcib_if.m optional pci pci/simos.c optional simos pci/uhci_pci.c optional uhci pci/xrpu.c optional xrpu diff --git a/sys/conf/files.alpha b/sys/conf/files.alpha index 8ef0fd9..bb746e1 100644 --- a/sys/conf/files.alpha +++ b/sys/conf/files.alpha @@ -27,6 +27,7 @@ alpha/alpha/api_up1000.c optional api_up1000 alpha/alpha/atomic.s standard alpha/alpha/autoconf.c standard alpha/alpha/busdma_machdep.c standard +alpha/alpha/busspace.c standard alpha/alpha/clock.c standard alpha/alpha/clock_if.m standard alpha/alpha/cpuconf.c standard @@ -83,12 +84,14 @@ alpha/isa/mcclock_isa.c optional isa alpha/mcbus/mcbus.c optional dec_kn300 alpha/mcbus/mcmem.c optional dec_kn300 alpha/mcbus/mcpcia.c optional dec_kn300 +alpha/pci/alphapci_if.m optional pci alpha/pci/apecs.c optional dec_2100_a50 alpha/pci/apecs.c optional dec_eb64plus alpha/pci/apecs.c optional dec_1000a alpha/pci/apecs_pci.c optional dec_2100_a50 alpha/pci/apecs_pci.c optional dec_eb64plus alpha/pci/apecs_pci.c optional dec_1000a +alpha/pci/bwx.c optional pci alpha/pci/cia.c optional dec_eb164 alpha/pci/cia.c optional dec_kn20aa alpha/pci/cia.c optional dec_st550 @@ -97,18 +100,17 @@ alpha/pci/cia_pci.c optional dec_eb164 alpha/pci/cia_pci.c optional dec_kn20aa alpha/pci/cia_pci.c optional dec_st550 alpha/pci/cia_pci.c optional dec_1000a -alpha/pci/dwlpx_pci.c optional dec_kn8ae alpha/pci/irongate.c optional api_up1000 alpha/pci/irongate_pci.c optional api_up1000 alpha/pci/lca.c optional dec_axppci_33 alpha/pci/lca_pci.c optional dec_axppci_33 -alpha/pci/mcpcia_pci.c optional dec_kn300 alpha/pci/pci_eb164_intr.s optional dec_eb164 alpha/pci/pci_eb164_intr.s optional dec_kn20aa alpha/pci/pci_eb164_intr.s optional dec_st550 alpha/pci/pci_eb64plus_intr.s optional dec_2100_a50 alpha/pci/pci_eb64plus_intr.s optional dec_eb64plus alpha/pci/pcibus.c optional pci +alpha/pci/swiz.c optional pci alpha/pci/t2.c optional dec_2100_a500 alpha/pci/t2_pci.c optional dec_2100_a500 alpha/pci/tsunami.c optional dec_st6600 diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c index 3b9aabf..e861c3d 100644 --- a/sys/dev/aic7xxx/aic7xxx.c +++ b/sys/dev/aic7xxx/aic7xxx.c @@ -5715,7 +5715,7 @@ ahc_setup_data(struct ahc_softc *ahc, struct ccb_scsiio *csio, panic("ahc_setup_data - Transfer size " "larger than can device max"); - seg.ds_addr = (bus_addr_t)csio->data_ptr; + seg.ds_addr = (intptr_t)csio->data_ptr; seg.ds_len = csio->dxfer_len; ahc_execute_scb(scb, &seg, 1, 0); } diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index cbb5a34..fc89297 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -519,7 +519,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, { struct ata_pci_softc *sc = device_get_softc(dev); int masterdev = pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV; - int unit = (int)device_get_ivars(child); + int unit = (intptr_t)device_get_ivars(child); int myrid; if (type == SYS_RES_IOPORT) { diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index e0f89c6..86d945c 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -48,6 +48,7 @@ #include <vm/vm_object.h> #include <machine/clock.h> #include <machine/md_var.h> +#include <machine/bus.h> #include <dev/ata/ata-all.h> #include <dev/ata/ata-disk.h> diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index ad542024..838495d 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -43,6 +43,7 @@ #endif #include <dev/ata/ata-all.h> #include <dev/ata/ata-disk.h> +#include <machine/bus.h> #if NPCI > 0 diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index 1862ccf..b8ee8ae 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -39,6 +39,7 @@ #include <sys/bus.h> #include <sys/malloc.h> #include <machine/clock.h> +#include <machine/bus.h> #include <dev/ata/ata-all.h> #include <dev/ata/atapi-all.h> diff --git a/sys/dev/atkbdc/atkbdc.c b/sys/dev/atkbdc/atkbdc.c index 176ca66..ee643d0 100644 --- a/sys/dev/atkbdc/atkbdc.c +++ b/sys/dev/atkbdc/atkbdc.c @@ -160,7 +160,7 @@ atkbdc_configure(void) #if defined(__i386__) tag = I386_BUS_SPACE_IO; #elif defined(__alpha__) - tag = ALPHA_BUS_SPACE_IO; + tag = busspace_isa_io; #endif #if notyet diff --git a/sys/dev/fb/vga.c b/sys/dev/fb/vga.c index eafffea..bbbf258 100644 --- a/sys/dev/fb/vga.c +++ b/sys/dev/fb/vga.c @@ -48,6 +48,7 @@ #include <machine/md_var.h> #include <machine/pc/bios.h> +#include <machine/bus.h> #include <dev/fb/fbreg.h> #include <dev/fb/vgareg.h> diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 6189077..86ee964 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -216,15 +216,6 @@ static struct ispmdvec mdvec_2200 = { static int isp_pci_probe (device_t); static int isp_pci_attach (device_t); -/* This distinguishing define is not right, but it does work */ -#ifdef __alpha__ -#define IO_SPACE_MAPPING ALPHA_BUS_SPACE_IO -#define MEM_SPACE_MAPPING ALPHA_BUS_SPACE_MEM -#else -#define IO_SPACE_MAPPING I386_BUS_SPACE_IO -#define MEM_SPACE_MAPPING I386_BUS_SPACE_MEM -#endif - struct isp_pcisoftc { struct ispsoftc pci_isp; device_t pci_dev; diff --git a/sys/dev/kbd/atkbdc.c b/sys/dev/kbd/atkbdc.c index 176ca66..ee643d0 100644 --- a/sys/dev/kbd/atkbdc.c +++ b/sys/dev/kbd/atkbdc.c @@ -160,7 +160,7 @@ atkbdc_configure(void) #if defined(__i386__) tag = I386_BUS_SPACE_IO; #elif defined(__alpha__) - tag = ALPHA_BUS_SPACE_IO; + tag = busspace_isa_io; #endif #if notyet diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index 59cd8d7..423b713 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -222,12 +222,12 @@ mdstrategy_malloc(struct bio *bp) if (secno < sc->nsecp) { secpp = &sc->secp[secno]; - if ((u_int)*secpp > 255) { + if ((uintptr_t)*secpp > 255) { secp = *secpp; secval = 0; } else { secp = 0; - secval = (u_int) *secpp; + secval = (uintptr_t) *secpp; } } else { secpp = 0; @@ -262,7 +262,7 @@ mdstrategy_malloc(struct bio *bp) if (secp) FREE(secp, M_MDSECT); if (secpp) - *secpp = (u_char *)uc; + *secpp = (u_char *)(uintptr_t)uc; } else { if (!secpp) { MALLOC(secpp, u_char **, (secno + nsec + 1) * sizeof(u_char *), M_MD, M_WAITOK); @@ -276,7 +276,7 @@ mdstrategy_malloc(struct bio *bp) if (i == DEV_BSIZE) { if (secp) FREE(secp, M_MDSECT); - *secpp = (u_char *)uc; + *secpp = (u_char *)(uintptr_t)uc; } else { if (!secp) MALLOC(secp, u_char *, DEV_BSIZE, M_MDSECT, M_WAITOK); diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index cfda6c7..b31667c 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -56,6 +56,8 @@ #include <pci/pcireg.h> #include <pci/pcivar.h> +#include "pcib_if.h" + #ifdef __alpha__ #include <machine/rpb.h> #endif @@ -64,6 +66,8 @@ #include <machine/smp.h> #endif /* APIC_IO */ +static devclass_t pci_devclass; + struct pci_quirk { u_int32_t devid; /* Vendor/device of the card */ int type; @@ -177,7 +181,7 @@ pci_fixancient(pcicfgregs *cfg) /* read config data specific to header type 1 device (PCI to PCI bridge) */ static void * -pci_readppb(pcicfgregs *cfg) +pci_readppb(device_t pcib, int b, int s, int f) { pcih1cfgregs *p; @@ -187,35 +191,43 @@ pci_readppb(pcicfgregs *cfg) bzero(p, sizeof *p); - p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2); - p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2); + p->secstat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECSTAT_1, 2); + p->bridgectl = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_BRIDGECTL_1, 2); - p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1); + p->seclat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECLAT_1, 1); - p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2), - pci_cfgread(cfg, PCIR_IOBASEL_1, 1)); - p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2), - pci_cfgread(cfg, PCIR_IOLIMITL_1, 1)); + p->iobase = PCI_PPBIOBASE (PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_IOBASEH_1, 2), + PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_IOBASEL_1, 1)); + p->iolimit = PCI_PPBIOLIMIT (PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_IOLIMITH_1, 2), + PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_IOLIMITL_1, 1)); p->membase = PCI_PPBMEMBASE (0, - pci_cfgread(cfg, PCIR_MEMBASE_1, 2)); + PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_MEMBASE_1, 2)); p->memlimit = PCI_PPBMEMLIMIT (0, - pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2)); + PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_MEMLIMIT_1, 2)); p->pmembase = PCI_PPBMEMBASE ( - (pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4), - pci_cfgread(cfg, PCIR_PMBASEL_1, 2)); + (pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEH_1, 4), + PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEL_1, 2)); p->pmemlimit = PCI_PPBMEMLIMIT ( - (pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4), - pci_cfgread(cfg, PCIR_PMLIMITL_1, 2)); + (pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_PMLIMITH_1, 4), + PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMLIMITL_1, 2)); + return (p); } /* read config data specific to header type 2 device (PCI to CardBus bridge) */ static void * -pci_readpcb(pcicfgregs *cfg) +pci_readpcb(device_t pcib, int b, int s, int f) { pcih2cfgregs *p; @@ -225,60 +237,63 @@ pci_readpcb(pcicfgregs *cfg) bzero(p, sizeof *p); - p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2); - p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2); + p->secstat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECSTAT_2, 2); + p->bridgectl = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_BRIDGECTL_2, 2); - p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1); + p->seclat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECLAT_2, 1); - p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4); - p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4); - p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4); - p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4); + p->membase0 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMBASE0_2, 4); + p->memlimit0 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMLIMIT0_2, 4); + p->membase1 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMBASE1_2, 4); + p->memlimit1 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMLIMIT1_2, 4); - p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4); - p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4); - p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4); - p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4); + p->iobase0 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOBASE0_2, 4); + p->iolimit0 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOLIMIT0_2, 4); + p->iobase1 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOBASE1_2, 4); + p->iolimit1 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOLIMIT1_2, 4); - p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4); + p->pccardif = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PCCARDIF_2, 4); return p; } /* extract header type specific config data */ static void -pci_hdrtypedata(pcicfgregs *cfg) +pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg) { +#define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) switch (cfg->hdrtype) { case 0: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_0, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_0, 2); + cfg->subvendor = REG(PCIR_SUBVEND_0, 2); + cfg->subdevice = REG(PCIR_SUBDEV_0, 2); cfg->nummaps = PCI_MAXMAPS_0; break; case 1: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_1, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_1, 2); - cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_1, 1); - cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1); + cfg->subvendor = REG(PCIR_SUBVEND_1, 2); + cfg->subdevice = REG(PCIR_SUBDEV_1, 2); + cfg->secondarybus = REG(PCIR_SECBUS_1, 1); + cfg->subordinatebus = REG(PCIR_SUBBUS_1, 1); cfg->nummaps = PCI_MAXMAPS_1; - cfg->hdrspec = pci_readppb(cfg); + cfg->hdrspec = pci_readppb(pcib, b, s, f); break; case 2: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_2, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_2, 2); - cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_2, 1); - cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1); + cfg->subvendor = REG(PCIR_SUBVEND_2, 2); + cfg->subdevice = REG(PCIR_SUBDEV_2, 2); + cfg->secondarybus = REG(PCIR_SECBUS_2, 1); + cfg->subordinatebus = REG(PCIR_SUBBUS_2, 1); cfg->nummaps = PCI_MAXMAPS_2; - cfg->hdrspec = pci_readpcb(cfg); + cfg->hdrspec = pci_readpcb(pcib, b, s, f); break; } +#undef REG } /* read configuration header into pcicfgrect structure */ static struct pci_devinfo * -pci_readcfg(pcicfgregs *probe) +pci_read_device(device_t pcib, int b, int s, int f) { +#define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) pcicfgregs *cfg = NULL; struct pci_devinfo *devlist_entry; struct devlist *devlist_head; @@ -287,8 +302,7 @@ pci_readcfg(pcicfgregs *probe) devlist_entry = NULL; - if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) { - + if (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVVENDOR, 4) != -1) { devlist_entry = malloc(sizeof(struct pci_devinfo), M_DEVBUF, M_WAITOK); if (devlist_entry == NULL) @@ -297,23 +311,22 @@ pci_readcfg(pcicfgregs *probe) cfg = &devlist_entry->cfg; - cfg->hose = probe->hose; - cfg->bus = probe->bus; - cfg->slot = probe->slot; - cfg->func = probe->func; - cfg->vendor = pci_cfgread(cfg, PCIR_VENDOR, 2); - cfg->device = pci_cfgread(cfg, PCIR_DEVICE, 2); - cfg->cmdreg = pci_cfgread(cfg, PCIR_COMMAND, 2); - cfg->statreg = pci_cfgread(cfg, PCIR_STATUS, 2); - cfg->baseclass = pci_cfgread(cfg, PCIR_CLASS, 1); - cfg->subclass = pci_cfgread(cfg, PCIR_SUBCLASS, 1); - cfg->progif = pci_cfgread(cfg, PCIR_PROGIF, 1); - cfg->revid = pci_cfgread(cfg, PCIR_REVID, 1); - cfg->hdrtype = pci_cfgread(cfg, PCIR_HEADERTYPE, 1); - cfg->cachelnsz = pci_cfgread(cfg, PCIR_CACHELNSZ, 1); - cfg->lattimer = pci_cfgread(cfg, PCIR_LATTIMER, 1); - cfg->intpin = pci_cfgread(cfg, PCIR_INTPIN, 1); - cfg->intline = pci_cfgread(cfg, PCIR_INTLINE, 1); + cfg->bus = b; + cfg->slot = s; + cfg->func = f; + cfg->vendor = REG(PCIR_VENDOR, 2); + cfg->device = REG(PCIR_DEVICE, 2); + cfg->cmdreg = REG(PCIR_COMMAND, 2); + cfg->statreg = REG(PCIR_STATUS, 2); + cfg->baseclass = REG(PCIR_CLASS, 1); + cfg->subclass = REG(PCIR_SUBCLASS, 1); + cfg->progif = REG(PCIR_PROGIF, 1); + cfg->revid = REG(PCIR_REVID, 1); + cfg->hdrtype = REG(PCIR_HEADERTYPE, 1); + cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1); + cfg->lattimer = REG(PCIR_LATTIMER, 1); + cfg->intpin = REG(PCIR_INTPIN, 1); + cfg->intline = REG(PCIR_INTLINE, 1); #ifdef __alpha__ alpha_platform_assign_pciintr(cfg); #endif @@ -346,14 +359,14 @@ pci_readcfg(pcicfgregs *probe) } #endif /* APIC_IO */ - cfg->mingnt = pci_cfgread(cfg, PCIR_MINGNT, 1); - cfg->maxlat = pci_cfgread(cfg, PCIR_MAXLAT, 1); + cfg->mingnt = REG(PCIR_MINGNT, 1); + cfg->maxlat = REG(PCIR_MAXLAT, 1); cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; cfg->hdrtype &= ~PCIM_MFDEV; pci_fixancient(cfg); - pci_hdrtypedata(cfg); + pci_hdrtypedata(pcib, b, s, f, cfg); STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links); @@ -376,6 +389,7 @@ pci_readcfg(pcicfgregs *probe) pci_generation++; } return (devlist_entry); +#undef REG } #if 0 @@ -541,6 +555,7 @@ pci_devlist_get_parent(pcicfgregs *cfg) static int pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { + device_t pci, pcib; struct pci_io *io; const char *name; int error; @@ -782,17 +797,30 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case PCIOCREAD: io = (struct pci_io *)data; switch(io->pi_width) { - pcicfgregs probe; case 4: case 2: case 1: - probe.hose = -1; - probe.bus = io->pi_sel.pc_bus; - probe.slot = io->pi_sel.pc_dev; - probe.func = io->pi_sel.pc_func; - io->pi_data = pci_cfgread(&probe, - io->pi_reg, io->pi_width); - error = 0; + /* + * Assume that the user-level bus number is + * actually the pciN instance number. We map + * from that to the real pcib+bus combination. + */ + pci = devclass_get_device(pci_devclass, + io->pi_sel.pc_bus); + if (pci) { + int b = pcib_get_bus(pci); + pcib = device_get_parent(pci); + io->pi_data = + PCIB_READ_CONFIG(pcib, + b, + io->pi_sel.pc_dev, + io->pi_sel.pc_func, + io->pi_reg, + io->pi_width); + error = 0; + } else { + error = ENODEV; + } break; default: error = ENODEV; @@ -803,17 +831,30 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case PCIOCWRITE: io = (struct pci_io *)data; switch(io->pi_width) { - pcicfgregs probe; case 4: case 2: case 1: - probe.hose = -1; - probe.bus = io->pi_sel.pc_bus; - probe.slot = io->pi_sel.pc_dev; - probe.func = io->pi_sel.pc_func; - pci_cfgwrite(&probe, - io->pi_reg, io->pi_data, io->pi_width); - error = 0; + /* + * Assume that the user-level bus number is + * actually the pciN instance number. We map + * from that to the real pcib+bus combination. + */ + pci = devclass_get_device(pci_devclass, + io->pi_sel.pc_bus); + if (pci) { + int b = pcib_get_bus(pci); + pcib = device_get_parent(pci); + PCIB_WRITE_CONFIG(pcib, + b, + io->pi_sel.pc_dev, + io->pi_sel.pc_func, + io->pi_reg, + io->pi_data, + io->pi_width); + error = 0; + } else { + error = ENODEV; + } break; default: error = ENODEV; @@ -850,7 +891,6 @@ static struct cdevsw pcicdev = { #include "pci_if.h" - /* * New style pci driver. Parent device is either a pci-host-bridge or a * pci-pci-bridge. Both kinds are represented by instances of pcib. @@ -882,15 +922,17 @@ pci_print_verbose(struct pci_devinfo *dinfo) } static int -pci_porten(pcicfgregs *cfg) +pci_porten(device_t pcib, int b, int s, int f) { - return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0); + return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2) + & PCIM_CMD_PORTEN) != 0; } static int -pci_memen(pcicfgregs *cfg) +pci_memen(device_t pcib, int b, int s, int f) { - return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0); + return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2) + & PCIM_CMD_MEMEN) != 0; } /* @@ -898,10 +940,9 @@ pci_memen(pcicfgregs *cfg) * register is a 32bit map register or 2 if it is a 64bit register. */ static int -pci_add_map(device_t dev, pcicfgregs* cfg, int reg) +pci_add_map(device_t pcib, int b, int s, int f, int reg, + struct resource_list *rl) { - struct pci_devinfo *dinfo = device_get_ivars(dev); - struct resource_list *rl = &dinfo->resources; u_int32_t map; u_int64_t base; u_int8_t ln2size; @@ -910,14 +951,14 @@ pci_add_map(device_t dev, pcicfgregs* cfg, int reg) int type; - map = pci_cfgread(cfg, reg, 4); + map = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4); if (map == 0 || map == 0xffffffff) return 1; /* skip invalid entry */ - pci_cfgwrite(cfg, reg, 0xffffffff, 4); - testval = pci_cfgread(cfg, reg, 4); - pci_cfgwrite(cfg, reg, map, 4); + PCIB_WRITE_CONFIG(pcib, b, s, f, reg, 0xffffffff, 4); + testval = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4); + PCIB_WRITE_CONFIG(pcib, b, s, f, reg, map, 4); base = pci_mapbase(map); if (pci_maptype(map) & PCI_MAPMEM) @@ -928,72 +969,24 @@ pci_add_map(device_t dev, pcicfgregs* cfg, int reg) ln2range = pci_maprange(testval); if (ln2range == 64) { /* Read the other half of a 64bit map register */ - base |= (u_int64_t) pci_cfgread(cfg, reg + 4, 4) << 32; + base |= (u_int64_t) PCIB_READ_CONFIG(pcib, b, s, f, reg + 4, 4) << 32; } -#ifdef __alpha__ - /* - * XXX: encode hose number in the base addr, - * This will go away once the bus_space functions - * can deal with multiple hoses - */ - - if (cfg->hose) { - u_int32_t mask, shift, maxh; - - switch (hwrpb->rpb_type) { - case ST_DEC_4100: - mask = 0xc0000000; - shift = 30; - maxh = 4; /* not a hose. MCPCIA instance # */ - break; - case ST_DEC_21000: - mask = 0xf8000000; - shift = 27; - maxh = 32; - break; - case ST_DEC_6600: - mask = 0x80000000; - shift = 31; - maxh = 2; - break; - default: - mask = 0; - shift = 0; - maxh = 0; - break; - } - if (base & mask) { - printf("base addr = 0x%llx\n", (long long) base); - printf("mask addr = 0x%lx\n", (long) mask); - printf("hacked addr = 0x%llx\n", (long long) - (base | ((u_int64_t)cfg->hose << shift))); - panic("hose encoding hack would clobber base addr"); - /* NOTREACHED */ - } - if (cfg->hose >= maxh) { - panic("Hose %d - can only encode %d hose(s)", - cfg->hose, maxh); - /* NOTREACHED */ - } - base |= ((u_int64_t)cfg->hose << shift); - } -#endif if (bootverbose) { printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d", reg, pci_maptype(map), ln2range, (unsigned int) base, ln2size); - if (type == SYS_RES_IOPORT && !pci_porten(cfg)) + if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f)) printf(", port disabled\n"); - else if (type == SYS_RES_MEMORY && !pci_memen(cfg)) + else if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f)) printf(", memory disabled\n"); else printf(", enabled\n"); } - if (type == SYS_RES_IOPORT && !pci_porten(cfg)) + if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f)) return 1; - if (type == SYS_RES_MEMORY && !pci_memen(cfg)) + if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f)) return 1; resource_list_add(rl, type, reg, @@ -1004,21 +997,22 @@ pci_add_map(device_t dev, pcicfgregs* cfg, int reg) } static void -pci_add_resources(device_t dev, pcicfgregs* cfg) +pci_add_resources(device_t pcib, int b, int s, int f, device_t dev) { struct pci_devinfo *dinfo = device_get_ivars(dev); + pcicfgregs *cfg = &dinfo->cfg; struct resource_list *rl = &dinfo->resources; struct pci_quirk *q; int i; for (i = 0; i < cfg->nummaps;) { - i += pci_add_map(dev, cfg, PCIR_MAPS + i*4); + i += pci_add_map(pcib, b, s, f, PCIR_MAPS + i*4, rl); } for (q = &pci_quirks[0]; q->devid; q++) { if (q->devid == ((cfg->device << 16) | cfg->vendor) && q->type == PCI_QUIRK_MAP_REG) - pci_add_map(dev, cfg, q->arg1); + pci_add_map(pcib, b, s, f, q->arg1, rl); } if (cfg->intpin > 0 && cfg->intline != 255) @@ -1029,26 +1023,17 @@ pci_add_resources(device_t dev, pcicfgregs* cfg) static void pci_add_children(device_t dev, int busno) { - pcicfgregs probe; - -#ifdef SIMOS -#undef PCI_SLOTMAX -#define PCI_SLOTMAX 0 -#endif + device_t pcib = device_get_parent(dev); + int maxslots; + int s, f; - bzero(&probe, sizeof probe); -#ifdef __alpha__ - probe.hose = pcib_get_hose(dev); -#endif -#ifdef __i386__ - probe.hose = 0; -#endif - probe.bus = busno; - - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + maxslots = PCIB_MAXSLOTS(pcib); + + for (s = 0; s <= maxslots; s++) { int pcifunchigh = 0; - for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) { - struct pci_devinfo *dinfo = pci_readcfg(&probe); + for (f = 0; f <= pcifunchigh; f++) { + struct pci_devinfo *dinfo = + pci_read_device(pcib, busno, s, f); if (dinfo != NULL) { if (dinfo->cfg.mfdev) pcifunchigh = 7; @@ -1056,19 +1041,31 @@ pci_add_children(device_t dev, int busno) pci_print_verbose(dinfo); dinfo->cfg.dev = device_add_child(dev, NULL, -1); device_set_ivars(dinfo->cfg.dev, dinfo); - pci_add_resources(dinfo->cfg.dev, &dinfo->cfg); + pci_add_resources(pcib, busno, s, f, + dinfo->cfg.dev); } } } } static int -pci_new_probe(device_t dev) +pci_probe(device_t dev) { static int once; device_set_desc(dev, "PCI bus"); - pci_add_children(dev, device_get_unit(dev)); + + if (bootverbose) + device_printf(dev, "physical bus=%d\n", pcib_get_bus(dev)); + + /* + * Since there can be multiple independantly numbered PCI + * busses on some large alpha systems, we can't use the unit + * number to decide what bus we are probing. We ask the parent + * pcib what our bus number is. + */ + pci_add_children(dev, pcib_get_bus(dev)); + if (!once) { make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644, "pci"); once++; @@ -1227,12 +1224,6 @@ pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) case PCI_IVAR_SUBORDINATEBUS: *result = cfg->subordinatebus; break; - case PCI_IVAR_HOSE: - /* - * Pass up to parent bridge. - */ - *result = pcib_get_hose(dev); - break; default: return ENOENT; } @@ -1340,7 +1331,10 @@ pci_read_config_method(device_t dev, device_t child, int reg, int width) { struct pci_devinfo *dinfo = device_get_ivars(child); pcicfgregs *cfg = &dinfo->cfg; - return pci_cfgread(cfg, reg, width); + + return PCIB_READ_CONFIG(device_get_parent(dev), + cfg->bus, cfg->slot, cfg->func, + reg, width); } static void @@ -1349,7 +1343,10 @@ pci_write_config_method(device_t dev, device_t child, int reg, { struct pci_devinfo *dinfo = device_get_ivars(child); pcicfgregs *cfg = &dinfo->cfg; - pci_cfgwrite(cfg, reg, val, width); + + PCIB_WRITE_CONFIG(device_get_parent(dev), + cfg->bus, cfg->slot, cfg->func, + reg, val, width); } static int @@ -1369,7 +1366,7 @@ pci_modevent(module_t mod, int what, void *arg) static device_method_t pci_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, pci_new_probe), + DEVMETHOD(device_probe, pci_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), diff --git a/sys/dev/pci/pcib_if.m b/sys/dev/pci/pcib_if.m new file mode 100644 index 0000000..b50df4b --- /dev/null +++ b/sys/dev/pci/pcib_if.m @@ -0,0 +1,71 @@ +# +# 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> + +INTERFACE pcib; + +# +# Return the number of slots on the attached PCI bus. +# +METHOD int maxslots { + device_t dev; +}; + +# +# Read configuration space on the PCI bus. The bus, slot and func +# arguments determine the device which is being read and the reg +# argument is a byte offset into configuration space for that +# device. The width argument (which should be 1, 2 or 4) specifies how +# many byte of configuration space to read from that offset. +# +METHOD u_int32_t read_config { + device_t dev; + int bus; + int slot; + int func; + int reg; + int width; +}; + +# +# Write configuration space on the PCI bus. The bus, slot and func +# arguments determine the device which is being written and the reg +# argument is a byte offset into configuration space for that +# device. The value field is written to the configuration space, with +# the number of bytes written depending on the width argument. +# +METHOD void write_config { + device_t dev; + int bus; + int slot; + int func; + int reg; + u_int32_t value; + int width; +}; diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index b767616..34df379 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -82,7 +82,6 @@ typedef struct pcicfg { u_int8_t mfdev; /* multi-function device (from hdrtype reg) */ u_int8_t nummaps; /* actual number of PCI maps used */ - u_int8_t hose; /* hose which bus is attached to */ u_int8_t bus; /* config space bus address */ u_int8_t slot; /* config space slot address */ u_int8_t func; /* config space function number */ @@ -156,6 +155,7 @@ const char *pci_chip_match(struct device *dev); int pci_cfgread (pcicfgregs *cfg, int reg, int bytes); void pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes); + #ifdef __alpha__ vm_offset_t pci_cvt_to_dense (vm_offset_t); vm_offset_t pci_cvt_to_bwx (vm_offset_t); @@ -192,7 +192,6 @@ enum pci_device_ivars { PCI_IVAR_FUNCTION, PCI_IVAR_SECONDARYBUS, PCI_IVAR_SUBORDINATEBUS, - PCI_IVAR_HOSE, }; /* @@ -229,7 +228,6 @@ PCI_ACCESSOR(slot, SLOT, u_int8_t) PCI_ACCESSOR(function, FUNCTION, u_int8_t) PCI_ACCESSOR(secondarybus, SECONDARYBUS, u_int8_t) PCI_ACCESSOR(subordinatebus, SUBORDINATEBUS, u_int8_t) -PCI_ACCESSOR(hose, HOSE, u_int32_t) static __inline u_int32_t pci_read_config(device_t dev, int reg, int width) @@ -249,7 +247,7 @@ pci_write_config(device_t dev, int reg, u_int32_t val, int width) /*typedef enum pci_device_ivars pcib_device_ivars;*/ enum pcib_device_ivars { - PCIB_IVAR_HOSE, + PCIB_IVAR_BUS }; #define PCIB_ACCESSOR(A, B, T) \ @@ -267,7 +265,7 @@ static __inline void pcib_set_ ## A(device_t dev, T t) \ BUS_WRITE_IVAR(device_get_parent(dev), dev, PCIB_IVAR_ ## B, v); \ } -PCIB_ACCESSOR(hose, HOSE, u_int32_t) +PCIB_ACCESSOR(bus, BUS, u_int32_t) #endif diff --git a/sys/dev/syscons/scgfbrndr.c b/sys/dev/syscons/scgfbrndr.c index 462de90..7461525 100644 --- a/sys/dev/syscons/scgfbrndr.c +++ b/sys/dev/syscons/scgfbrndr.c @@ -34,6 +34,7 @@ #include <sys/kernel.h> #include <machine/console.h> +#include <machine/bus.h> #include <dev/fb/fbreg.h> #include <dev/fb/vgareg.h> diff --git a/sys/dev/syscons/scvgarndr.c b/sys/dev/syscons/scvgarndr.c index 462de90..7461525 100644 --- a/sys/dev/syscons/scvgarndr.c +++ b/sys/dev/syscons/scvgarndr.c @@ -34,6 +34,7 @@ #include <sys/kernel.h> #include <machine/console.h> +#include <machine/bus.h> #include <dev/fb/fbreg.h> #include <dev/fb/vgareg.h> diff --git a/sys/dev/syscons/scvtb.c b/sys/dev/syscons/scvtb.c index dc5155b..de9dfca 100644 --- a/sys/dev/syscons/scvtb.c +++ b/sys/dev/syscons/scvtb.c @@ -34,6 +34,7 @@ #include <machine/console.h> #include <machine/md_var.h> +#include <machine/bus.h> #include <dev/fb/fbreg.h> #include <dev/syscons/syscons.h> diff --git a/sys/dev/ti/if_ti.c b/sys/dev/ti/if_ti.c index 56847f4..f1cfee5 100644 --- a/sys/dev/ti/if_ti.c +++ b/sys/dev/ti/if_ti.c @@ -1505,7 +1505,7 @@ static int ti_attach(dev) rid = TI_PCI_LOMEM; sc->ti_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - 0, ~0, 1, RF_ACTIVE); + 0, ~0, 1, RF_ACTIVE|PCI_RF_DENSE); if (sc->ti_res == NULL) { printf ("ti%d: couldn't map memory\n", unit); @@ -1517,22 +1517,6 @@ static int ti_attach(dev) sc->ti_bhandle = rman_get_bushandle(sc->ti_res); sc->ti_vhandle = (vm_offset_t)rman_get_virtual(sc->ti_res); - /* - * XXX FIXME: rman_get_virtual() on the alpha is currently - * broken and returns a physical address instead of a kernel - * virtual address. Consequently, we need to do a little - * extra mangling of the vhandle on the alpha. This should - * eventually be fixed! The whole idea here is to get rid - * of platform dependencies. - */ -#ifdef __alpha__ - if (pci_cvt_to_bwx(sc->ti_vhandle)) - sc->ti_vhandle = pci_cvt_to_bwx(sc->ti_vhandle); - else - sc->ti_vhandle = pci_cvt_to_dense(sc->ti_vhandle); - sc->ti_vhandle = ALPHA_PHYS_TO_K0SEG(sc->ti_vhandle); -#endif - /* Allocate interrupt */ rid = 0; diff --git a/sys/i386/isa/pcibus.c b/sys/i386/isa/pcibus.c index 990b418..ceff6a5 100644 --- a/sys/i386/isa/pcibus.c +++ b/sys/i386/isa/pcibus.c @@ -41,35 +41,49 @@ #include <machine/segments.h> #include <machine/pc/bios.h> +#include "pcib_if.h" + static int cfgmech; static int devmax; static int usebios; -static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcibios_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcibios_cfgopen(void); -static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcireg_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcireg_cfgopen(void); /* read configuration space register */ -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +nexus_pcib_maxslots(device_t dev) +{ + return 31; +} + +static u_int32_t +nexus_pcib_read_config(device_t dev, int bus, int slot, int func, + int reg, int bytes) { return(usebios ? - pcibios_cfgread(cfg, reg, bytes) : - pcireg_cfgread(cfg, reg, bytes)); + pcibios_cfgread(bus, slot, func, reg, bytes) : + pcireg_cfgread(bus, slot, func, reg, bytes)); } /* write configuration space register */ -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +nexus_pcib_write_config(device_t dev, int bus, int slot, int func, + int reg, u_int32_t data, int bytes) { return(usebios ? - pcibios_cfgwrite(cfg, reg, data, bytes) : - pcireg_cfgwrite(cfg, reg, data, bytes)); + pcibios_cfgwrite(bus, slot, func, reg, data, bytes) : + pcireg_cfgwrite(bus, slot, func, reg, data, bytes)); } /* initialise access to PCI configuration space */ @@ -89,7 +103,7 @@ pci_cfgopen(void) /* config space access using BIOS functions */ static int -pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcibios_cfgread(int bus, int slot, int func, int reg, int bytes) { struct bios_regs args; u_int mask; @@ -110,7 +124,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) default: return(-1); } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); /* check call results? */ @@ -118,7 +132,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcibios_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { struct bios_regs args; @@ -135,7 +149,7 @@ pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) default: return; } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.ecx = data; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); @@ -200,12 +214,12 @@ pci_cfgdisable(void) } static int -pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcireg_cfgread(int bus, int slot, int func, int reg, int bytes) { int data = -1; int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { @@ -225,11 +239,11 @@ pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { case 1: @@ -373,7 +387,7 @@ pcireg_cfgopen(void) static devclass_t pcib_devclass; static const char * -nexus_pcib_is_host_bridge(pcicfgregs *cfg, +nexus_pcib_is_host_bridge(int bus, int slot, int func, u_int32_t id, u_int8_t class, u_int8_t subclass, u_int8_t *busnum) { @@ -386,8 +400,8 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, case 0x12258086: s = "Intel 824?? host to PCI bridge"; /* XXX This is a guess */ - /* *busnum = pci_cfgread(cfg, 0x41, 1); */ - *busnum = cfg->bus; + /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */ + *busnum = bus; break; case 0x71208086: s = "Intel 82810 (i810 GMCH) Host To Hub bridge"; @@ -421,7 +435,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, break; case 0x84c48086: s = "Intel 82454KX/GX (Orion) host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x4a, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1); break; case 0x84ca8086: /* @@ -435,13 +449,17 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, * Since the MIOC doesn't have a pci bus attached, we * pretend it wasn't there. */ - pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ - pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ - pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ - pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + pxb[0] = nexus_pcib_read_config(0, bus, slot, func, + 0xd0, 1); /* BUSNO[0] */ + pxb[1] = nexus_pcib_read_config(0, bus, slot, func, + 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = nexus_pcib_read_config(0, bus, slot, func, + 0xd3, 1); /* BUSNO[1] */ + pxb[3] = nexus_pcib_read_config(0, bus, slot, func, + 0xd4, 1) + 1; /* SUBA[1]+1 */ return NULL; case 0x84cb8086: - switch (cfg->slot) { + switch (slot) { case 0x12: s = "Intel 82454NX PXB#0, Bus#A"; *busnum = pxb[0]; @@ -513,19 +531,19 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, /* RCC -- vendor 0x1166 */ case 0x00051166: s = "RCC HE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00061166: /* FALLTHROUGH */ case 0x00081166: s = "RCC host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00091166: s = "RCC LE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; /* Integrated Micro Solutions -- vendor 0x10e0 */ @@ -549,7 +567,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, static void nexus_pcib_identify(driver_t *driver, device_t parent) { - pcicfgregs probe; + int bus, slot, func; u_int8_t hdrtype; int found = 0; int pcifunchigh; @@ -557,19 +575,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) if (pci_cfgopen() == 0) return; - probe.hose = 0; - probe.bus = 0; + bus = 0; retry: - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { - probe.func = 0; - hdrtype = pci_cfgread(&probe, PCIR_HEADERTYPE, 1); + for (slot = 0; slot <= PCI_SLOTMAX; slot++) { + func = 0; + hdrtype = nexus_pcib_read_config(0, bus, slot, func, + PCIR_HEADERTYPE, 1); if (hdrtype & PCIM_MFDEV) pcifunchigh = 7; else pcifunchigh = 0; - for (probe.func = 0; - probe.func <= pcifunchigh; - probe.func++) { + for (func = 0; func <= pcifunchigh; func++) { /* * Read the IDs and class from the device. */ @@ -578,14 +594,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) device_t child; const char *s; - id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + id = nexus_pcib_read_config(0, bus, slot, func, + PCIR_DEVVENDOR, 4); if (id == -1) continue; - class = pci_cfgread(&probe, PCIR_CLASS, 1); - subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + class = nexus_pcib_read_config(0, bus, slot, func, + PCIR_CLASS, 1); + subclass = nexus_pcib_read_config(0, bus, slot, func, + PCIR_SUBCLASS, 1); - s = nexus_pcib_is_host_bridge(&probe, id, - class, subclass, + s = nexus_pcib_is_host_bridge(bus, slot, func, + id, class, subclass, &busnum); if (s) { /* @@ -601,8 +620,8 @@ nexus_pcib_identify(driver_t *driver, device_t parent) } } } - if (found824xx && probe.bus == 0) { - probe.bus++; + if (found824xx && bus == 0) { + bus++; goto retry; } @@ -629,6 +648,17 @@ nexus_pcib_probe(device_t dev) return ENXIO; } +static int +nexus_pcib_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 device_method_t nexus_pcib_methods[] = { /* Device interface */ DEVMETHOD(device_identify, nexus_pcib_identify), @@ -640,6 +670,7 @@ static device_method_t nexus_pcib_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, nexus_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), @@ -647,6 +678,11 @@ static device_method_t nexus_pcib_methods[] = { DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* pcib interface */ + DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots), + DEVMETHOD(pcib_read_config, nexus_pcib_read_config), + DEVMETHOD(pcib_write_config, nexus_pcib_write_config), + { 0, 0 } }; diff --git a/sys/i386/pci/pci_bus.c b/sys/i386/pci/pci_bus.c index 990b418..ceff6a5 100644 --- a/sys/i386/pci/pci_bus.c +++ b/sys/i386/pci/pci_bus.c @@ -41,35 +41,49 @@ #include <machine/segments.h> #include <machine/pc/bios.h> +#include "pcib_if.h" + static int cfgmech; static int devmax; static int usebios; -static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcibios_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcibios_cfgopen(void); -static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcireg_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcireg_cfgopen(void); /* read configuration space register */ -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +nexus_pcib_maxslots(device_t dev) +{ + return 31; +} + +static u_int32_t +nexus_pcib_read_config(device_t dev, int bus, int slot, int func, + int reg, int bytes) { return(usebios ? - pcibios_cfgread(cfg, reg, bytes) : - pcireg_cfgread(cfg, reg, bytes)); + pcibios_cfgread(bus, slot, func, reg, bytes) : + pcireg_cfgread(bus, slot, func, reg, bytes)); } /* write configuration space register */ -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +nexus_pcib_write_config(device_t dev, int bus, int slot, int func, + int reg, u_int32_t data, int bytes) { return(usebios ? - pcibios_cfgwrite(cfg, reg, data, bytes) : - pcireg_cfgwrite(cfg, reg, data, bytes)); + pcibios_cfgwrite(bus, slot, func, reg, data, bytes) : + pcireg_cfgwrite(bus, slot, func, reg, data, bytes)); } /* initialise access to PCI configuration space */ @@ -89,7 +103,7 @@ pci_cfgopen(void) /* config space access using BIOS functions */ static int -pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcibios_cfgread(int bus, int slot, int func, int reg, int bytes) { struct bios_regs args; u_int mask; @@ -110,7 +124,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) default: return(-1); } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); /* check call results? */ @@ -118,7 +132,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcibios_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { struct bios_regs args; @@ -135,7 +149,7 @@ pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) default: return; } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.ecx = data; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); @@ -200,12 +214,12 @@ pci_cfgdisable(void) } static int -pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcireg_cfgread(int bus, int slot, int func, int reg, int bytes) { int data = -1; int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { @@ -225,11 +239,11 @@ pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { case 1: @@ -373,7 +387,7 @@ pcireg_cfgopen(void) static devclass_t pcib_devclass; static const char * -nexus_pcib_is_host_bridge(pcicfgregs *cfg, +nexus_pcib_is_host_bridge(int bus, int slot, int func, u_int32_t id, u_int8_t class, u_int8_t subclass, u_int8_t *busnum) { @@ -386,8 +400,8 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, case 0x12258086: s = "Intel 824?? host to PCI bridge"; /* XXX This is a guess */ - /* *busnum = pci_cfgread(cfg, 0x41, 1); */ - *busnum = cfg->bus; + /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */ + *busnum = bus; break; case 0x71208086: s = "Intel 82810 (i810 GMCH) Host To Hub bridge"; @@ -421,7 +435,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, break; case 0x84c48086: s = "Intel 82454KX/GX (Orion) host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x4a, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1); break; case 0x84ca8086: /* @@ -435,13 +449,17 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, * Since the MIOC doesn't have a pci bus attached, we * pretend it wasn't there. */ - pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ - pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ - pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ - pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + pxb[0] = nexus_pcib_read_config(0, bus, slot, func, + 0xd0, 1); /* BUSNO[0] */ + pxb[1] = nexus_pcib_read_config(0, bus, slot, func, + 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = nexus_pcib_read_config(0, bus, slot, func, + 0xd3, 1); /* BUSNO[1] */ + pxb[3] = nexus_pcib_read_config(0, bus, slot, func, + 0xd4, 1) + 1; /* SUBA[1]+1 */ return NULL; case 0x84cb8086: - switch (cfg->slot) { + switch (slot) { case 0x12: s = "Intel 82454NX PXB#0, Bus#A"; *busnum = pxb[0]; @@ -513,19 +531,19 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, /* RCC -- vendor 0x1166 */ case 0x00051166: s = "RCC HE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00061166: /* FALLTHROUGH */ case 0x00081166: s = "RCC host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00091166: s = "RCC LE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; /* Integrated Micro Solutions -- vendor 0x10e0 */ @@ -549,7 +567,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, static void nexus_pcib_identify(driver_t *driver, device_t parent) { - pcicfgregs probe; + int bus, slot, func; u_int8_t hdrtype; int found = 0; int pcifunchigh; @@ -557,19 +575,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) if (pci_cfgopen() == 0) return; - probe.hose = 0; - probe.bus = 0; + bus = 0; retry: - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { - probe.func = 0; - hdrtype = pci_cfgread(&probe, PCIR_HEADERTYPE, 1); + for (slot = 0; slot <= PCI_SLOTMAX; slot++) { + func = 0; + hdrtype = nexus_pcib_read_config(0, bus, slot, func, + PCIR_HEADERTYPE, 1); if (hdrtype & PCIM_MFDEV) pcifunchigh = 7; else pcifunchigh = 0; - for (probe.func = 0; - probe.func <= pcifunchigh; - probe.func++) { + for (func = 0; func <= pcifunchigh; func++) { /* * Read the IDs and class from the device. */ @@ -578,14 +594,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) device_t child; const char *s; - id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + id = nexus_pcib_read_config(0, bus, slot, func, + PCIR_DEVVENDOR, 4); if (id == -1) continue; - class = pci_cfgread(&probe, PCIR_CLASS, 1); - subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + class = nexus_pcib_read_config(0, bus, slot, func, + PCIR_CLASS, 1); + subclass = nexus_pcib_read_config(0, bus, slot, func, + PCIR_SUBCLASS, 1); - s = nexus_pcib_is_host_bridge(&probe, id, - class, subclass, + s = nexus_pcib_is_host_bridge(bus, slot, func, + id, class, subclass, &busnum); if (s) { /* @@ -601,8 +620,8 @@ nexus_pcib_identify(driver_t *driver, device_t parent) } } } - if (found824xx && probe.bus == 0) { - probe.bus++; + if (found824xx && bus == 0) { + bus++; goto retry; } @@ -629,6 +648,17 @@ nexus_pcib_probe(device_t dev) return ENXIO; } +static int +nexus_pcib_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 device_method_t nexus_pcib_methods[] = { /* Device interface */ DEVMETHOD(device_identify, nexus_pcib_identify), @@ -640,6 +670,7 @@ static device_method_t nexus_pcib_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, nexus_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), @@ -647,6 +678,11 @@ static device_method_t nexus_pcib_methods[] = { DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* pcib interface */ + DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots), + DEVMETHOD(pcib_read_config, nexus_pcib_read_config), + DEVMETHOD(pcib_write_config, nexus_pcib_write_config), + { 0, 0 } }; diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c index 990b418..ceff6a5 100644 --- a/sys/i386/pci/pci_cfgreg.c +++ b/sys/i386/pci/pci_cfgreg.c @@ -41,35 +41,49 @@ #include <machine/segments.h> #include <machine/pc/bios.h> +#include "pcib_if.h" + static int cfgmech; static int devmax; static int usebios; -static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcibios_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcibios_cfgopen(void); -static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcireg_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcireg_cfgopen(void); /* read configuration space register */ -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +nexus_pcib_maxslots(device_t dev) +{ + return 31; +} + +static u_int32_t +nexus_pcib_read_config(device_t dev, int bus, int slot, int func, + int reg, int bytes) { return(usebios ? - pcibios_cfgread(cfg, reg, bytes) : - pcireg_cfgread(cfg, reg, bytes)); + pcibios_cfgread(bus, slot, func, reg, bytes) : + pcireg_cfgread(bus, slot, func, reg, bytes)); } /* write configuration space register */ -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +nexus_pcib_write_config(device_t dev, int bus, int slot, int func, + int reg, u_int32_t data, int bytes) { return(usebios ? - pcibios_cfgwrite(cfg, reg, data, bytes) : - pcireg_cfgwrite(cfg, reg, data, bytes)); + pcibios_cfgwrite(bus, slot, func, reg, data, bytes) : + pcireg_cfgwrite(bus, slot, func, reg, data, bytes)); } /* initialise access to PCI configuration space */ @@ -89,7 +103,7 @@ pci_cfgopen(void) /* config space access using BIOS functions */ static int -pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcibios_cfgread(int bus, int slot, int func, int reg, int bytes) { struct bios_regs args; u_int mask; @@ -110,7 +124,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) default: return(-1); } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); /* check call results? */ @@ -118,7 +132,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcibios_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { struct bios_regs args; @@ -135,7 +149,7 @@ pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) default: return; } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.ecx = data; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); @@ -200,12 +214,12 @@ pci_cfgdisable(void) } static int -pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcireg_cfgread(int bus, int slot, int func, int reg, int bytes) { int data = -1; int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { @@ -225,11 +239,11 @@ pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { case 1: @@ -373,7 +387,7 @@ pcireg_cfgopen(void) static devclass_t pcib_devclass; static const char * -nexus_pcib_is_host_bridge(pcicfgregs *cfg, +nexus_pcib_is_host_bridge(int bus, int slot, int func, u_int32_t id, u_int8_t class, u_int8_t subclass, u_int8_t *busnum) { @@ -386,8 +400,8 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, case 0x12258086: s = "Intel 824?? host to PCI bridge"; /* XXX This is a guess */ - /* *busnum = pci_cfgread(cfg, 0x41, 1); */ - *busnum = cfg->bus; + /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */ + *busnum = bus; break; case 0x71208086: s = "Intel 82810 (i810 GMCH) Host To Hub bridge"; @@ -421,7 +435,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, break; case 0x84c48086: s = "Intel 82454KX/GX (Orion) host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x4a, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1); break; case 0x84ca8086: /* @@ -435,13 +449,17 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, * Since the MIOC doesn't have a pci bus attached, we * pretend it wasn't there. */ - pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ - pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ - pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ - pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + pxb[0] = nexus_pcib_read_config(0, bus, slot, func, + 0xd0, 1); /* BUSNO[0] */ + pxb[1] = nexus_pcib_read_config(0, bus, slot, func, + 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = nexus_pcib_read_config(0, bus, slot, func, + 0xd3, 1); /* BUSNO[1] */ + pxb[3] = nexus_pcib_read_config(0, bus, slot, func, + 0xd4, 1) + 1; /* SUBA[1]+1 */ return NULL; case 0x84cb8086: - switch (cfg->slot) { + switch (slot) { case 0x12: s = "Intel 82454NX PXB#0, Bus#A"; *busnum = pxb[0]; @@ -513,19 +531,19 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, /* RCC -- vendor 0x1166 */ case 0x00051166: s = "RCC HE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00061166: /* FALLTHROUGH */ case 0x00081166: s = "RCC host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00091166: s = "RCC LE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; /* Integrated Micro Solutions -- vendor 0x10e0 */ @@ -549,7 +567,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, static void nexus_pcib_identify(driver_t *driver, device_t parent) { - pcicfgregs probe; + int bus, slot, func; u_int8_t hdrtype; int found = 0; int pcifunchigh; @@ -557,19 +575,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) if (pci_cfgopen() == 0) return; - probe.hose = 0; - probe.bus = 0; + bus = 0; retry: - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { - probe.func = 0; - hdrtype = pci_cfgread(&probe, PCIR_HEADERTYPE, 1); + for (slot = 0; slot <= PCI_SLOTMAX; slot++) { + func = 0; + hdrtype = nexus_pcib_read_config(0, bus, slot, func, + PCIR_HEADERTYPE, 1); if (hdrtype & PCIM_MFDEV) pcifunchigh = 7; else pcifunchigh = 0; - for (probe.func = 0; - probe.func <= pcifunchigh; - probe.func++) { + for (func = 0; func <= pcifunchigh; func++) { /* * Read the IDs and class from the device. */ @@ -578,14 +594,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) device_t child; const char *s; - id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + id = nexus_pcib_read_config(0, bus, slot, func, + PCIR_DEVVENDOR, 4); if (id == -1) continue; - class = pci_cfgread(&probe, PCIR_CLASS, 1); - subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + class = nexus_pcib_read_config(0, bus, slot, func, + PCIR_CLASS, 1); + subclass = nexus_pcib_read_config(0, bus, slot, func, + PCIR_SUBCLASS, 1); - s = nexus_pcib_is_host_bridge(&probe, id, - class, subclass, + s = nexus_pcib_is_host_bridge(bus, slot, func, + id, class, subclass, &busnum); if (s) { /* @@ -601,8 +620,8 @@ nexus_pcib_identify(driver_t *driver, device_t parent) } } } - if (found824xx && probe.bus == 0) { - probe.bus++; + if (found824xx && bus == 0) { + bus++; goto retry; } @@ -629,6 +648,17 @@ nexus_pcib_probe(device_t dev) return ENXIO; } +static int +nexus_pcib_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 device_method_t nexus_pcib_methods[] = { /* Device interface */ DEVMETHOD(device_identify, nexus_pcib_identify), @@ -640,6 +670,7 @@ static device_method_t nexus_pcib_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, nexus_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), @@ -647,6 +678,11 @@ static device_method_t nexus_pcib_methods[] = { DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* pcib interface */ + DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots), + DEVMETHOD(pcib_read_config, nexus_pcib_read_config), + DEVMETHOD(pcib_write_config, nexus_pcib_write_config), + { 0, 0 } }; diff --git a/sys/i386/pci/pci_pir.c b/sys/i386/pci/pci_pir.c index 990b418..ceff6a5 100644 --- a/sys/i386/pci/pci_pir.c +++ b/sys/i386/pci/pci_pir.c @@ -41,35 +41,49 @@ #include <machine/segments.h> #include <machine/pc/bios.h> +#include "pcib_if.h" + static int cfgmech; static int devmax; static int usebios; -static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcibios_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcibios_cfgopen(void); -static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); -static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgread(int bus, int slot, int func, int reg, + int bytes); +static void pcireg_cfgwrite(int bus, int slot, int func, int reg, + int data, int bytes); static int pcireg_cfgopen(void); /* read configuration space register */ -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +nexus_pcib_maxslots(device_t dev) +{ + return 31; +} + +static u_int32_t +nexus_pcib_read_config(device_t dev, int bus, int slot, int func, + int reg, int bytes) { return(usebios ? - pcibios_cfgread(cfg, reg, bytes) : - pcireg_cfgread(cfg, reg, bytes)); + pcibios_cfgread(bus, slot, func, reg, bytes) : + pcireg_cfgread(bus, slot, func, reg, bytes)); } /* write configuration space register */ -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +nexus_pcib_write_config(device_t dev, int bus, int slot, int func, + int reg, u_int32_t data, int bytes) { return(usebios ? - pcibios_cfgwrite(cfg, reg, data, bytes) : - pcireg_cfgwrite(cfg, reg, data, bytes)); + pcibios_cfgwrite(bus, slot, func, reg, data, bytes) : + pcireg_cfgwrite(bus, slot, func, reg, data, bytes)); } /* initialise access to PCI configuration space */ @@ -89,7 +103,7 @@ pci_cfgopen(void) /* config space access using BIOS functions */ static int -pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcibios_cfgread(int bus, int slot, int func, int reg, int bytes) { struct bios_regs args; u_int mask; @@ -110,7 +124,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) default: return(-1); } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); /* check call results? */ @@ -118,7 +132,7 @@ pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcibios_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { struct bios_regs args; @@ -135,7 +149,7 @@ pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) default: return; } - args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ebx = (bus << 8) | (slot << 3) | func; args.ecx = data; args.edi = reg; bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); @@ -200,12 +214,12 @@ pci_cfgdisable(void) } static int -pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) +pcireg_cfgread(int bus, int slot, int func, int reg, int bytes) { int data = -1; int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { @@ -225,11 +239,11 @@ pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) } static void -pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes) { int port; - port = pci_cfgenable(cfg->bus, cfg->slot, cfg->func, reg, bytes); + port = pci_cfgenable(bus, slot, func, reg, bytes); if (port != 0) { switch (bytes) { case 1: @@ -373,7 +387,7 @@ pcireg_cfgopen(void) static devclass_t pcib_devclass; static const char * -nexus_pcib_is_host_bridge(pcicfgregs *cfg, +nexus_pcib_is_host_bridge(int bus, int slot, int func, u_int32_t id, u_int8_t class, u_int8_t subclass, u_int8_t *busnum) { @@ -386,8 +400,8 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, case 0x12258086: s = "Intel 824?? host to PCI bridge"; /* XXX This is a guess */ - /* *busnum = pci_cfgread(cfg, 0x41, 1); */ - *busnum = cfg->bus; + /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */ + *busnum = bus; break; case 0x71208086: s = "Intel 82810 (i810 GMCH) Host To Hub bridge"; @@ -421,7 +435,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, break; case 0x84c48086: s = "Intel 82454KX/GX (Orion) host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x4a, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1); break; case 0x84ca8086: /* @@ -435,13 +449,17 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, * Since the MIOC doesn't have a pci bus attached, we * pretend it wasn't there. */ - pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ - pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ - pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ - pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + pxb[0] = nexus_pcib_read_config(0, bus, slot, func, + 0xd0, 1); /* BUSNO[0] */ + pxb[1] = nexus_pcib_read_config(0, bus, slot, func, + 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = nexus_pcib_read_config(0, bus, slot, func, + 0xd3, 1); /* BUSNO[1] */ + pxb[3] = nexus_pcib_read_config(0, bus, slot, func, + 0xd4, 1) + 1; /* SUBA[1]+1 */ return NULL; case 0x84cb8086: - switch (cfg->slot) { + switch (slot) { case 0x12: s = "Intel 82454NX PXB#0, Bus#A"; *busnum = pxb[0]; @@ -513,19 +531,19 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, /* RCC -- vendor 0x1166 */ case 0x00051166: s = "RCC HE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00061166: /* FALLTHROUGH */ case 0x00081166: s = "RCC host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; case 0x00091166: s = "RCC LE host to PCI bridge"; - *busnum = pci_cfgread(cfg, 0x44, 1); + *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1); break; /* Integrated Micro Solutions -- vendor 0x10e0 */ @@ -549,7 +567,7 @@ nexus_pcib_is_host_bridge(pcicfgregs *cfg, static void nexus_pcib_identify(driver_t *driver, device_t parent) { - pcicfgregs probe; + int bus, slot, func; u_int8_t hdrtype; int found = 0; int pcifunchigh; @@ -557,19 +575,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) if (pci_cfgopen() == 0) return; - probe.hose = 0; - probe.bus = 0; + bus = 0; retry: - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { - probe.func = 0; - hdrtype = pci_cfgread(&probe, PCIR_HEADERTYPE, 1); + for (slot = 0; slot <= PCI_SLOTMAX; slot++) { + func = 0; + hdrtype = nexus_pcib_read_config(0, bus, slot, func, + PCIR_HEADERTYPE, 1); if (hdrtype & PCIM_MFDEV) pcifunchigh = 7; else pcifunchigh = 0; - for (probe.func = 0; - probe.func <= pcifunchigh; - probe.func++) { + for (func = 0; func <= pcifunchigh; func++) { /* * Read the IDs and class from the device. */ @@ -578,14 +594,17 @@ nexus_pcib_identify(driver_t *driver, device_t parent) device_t child; const char *s; - id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + id = nexus_pcib_read_config(0, bus, slot, func, + PCIR_DEVVENDOR, 4); if (id == -1) continue; - class = pci_cfgread(&probe, PCIR_CLASS, 1); - subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + class = nexus_pcib_read_config(0, bus, slot, func, + PCIR_CLASS, 1); + subclass = nexus_pcib_read_config(0, bus, slot, func, + PCIR_SUBCLASS, 1); - s = nexus_pcib_is_host_bridge(&probe, id, - class, subclass, + s = nexus_pcib_is_host_bridge(bus, slot, func, + id, class, subclass, &busnum); if (s) { /* @@ -601,8 +620,8 @@ nexus_pcib_identify(driver_t *driver, device_t parent) } } } - if (found824xx && probe.bus == 0) { - probe.bus++; + if (found824xx && bus == 0) { + bus++; goto retry; } @@ -629,6 +648,17 @@ nexus_pcib_probe(device_t dev) return ENXIO; } +static int +nexus_pcib_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 device_method_t nexus_pcib_methods[] = { /* Device interface */ DEVMETHOD(device_identify, nexus_pcib_identify), @@ -640,6 +670,7 @@ static device_method_t nexus_pcib_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, nexus_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), @@ -647,6 +678,11 @@ static device_method_t nexus_pcib_methods[] = { DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* pcib interface */ + DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots), + DEVMETHOD(pcib_read_config, nexus_pcib_read_config), + DEVMETHOD(pcib_write_config, nexus_pcib_write_config), + { 0, 0 } }; diff --git a/sys/isa/pnp.c b/sys/isa/pnp.c index f9266bb..4c1993c 100644 --- a/sys/isa/pnp.c +++ b/sys/isa/pnp.c @@ -37,6 +37,7 @@ #include <isa/pnpreg.h> #include <isa/pnpvar.h> #include <machine/clock.h> +#include <machine/bus.h> typedef struct _pnp_id { u_int32_t vendor_id; diff --git a/sys/pci/if_ti.c b/sys/pci/if_ti.c index 56847f4..f1cfee5 100644 --- a/sys/pci/if_ti.c +++ b/sys/pci/if_ti.c @@ -1505,7 +1505,7 @@ static int ti_attach(dev) rid = TI_PCI_LOMEM; sc->ti_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - 0, ~0, 1, RF_ACTIVE); + 0, ~0, 1, RF_ACTIVE|PCI_RF_DENSE); if (sc->ti_res == NULL) { printf ("ti%d: couldn't map memory\n", unit); @@ -1517,22 +1517,6 @@ static int ti_attach(dev) sc->ti_bhandle = rman_get_bushandle(sc->ti_res); sc->ti_vhandle = (vm_offset_t)rman_get_virtual(sc->ti_res); - /* - * XXX FIXME: rman_get_virtual() on the alpha is currently - * broken and returns a physical address instead of a kernel - * virtual address. Consequently, we need to do a little - * extra mangling of the vhandle on the alpha. This should - * eventually be fixed! The whole idea here is to get rid - * of platform dependencies. - */ -#ifdef __alpha__ - if (pci_cvt_to_bwx(sc->ti_vhandle)) - sc->ti_vhandle = pci_cvt_to_bwx(sc->ti_vhandle); - else - sc->ti_vhandle = pci_cvt_to_dense(sc->ti_vhandle); - sc->ti_vhandle = ALPHA_PHYS_TO_K0SEG(sc->ti_vhandle); -#endif - /* Allocate interrupt */ rid = 0; diff --git a/sys/pci/isp_pci.c b/sys/pci/isp_pci.c index 6189077..86ee964 100644 --- a/sys/pci/isp_pci.c +++ b/sys/pci/isp_pci.c @@ -216,15 +216,6 @@ static struct ispmdvec mdvec_2200 = { static int isp_pci_probe (device_t); static int isp_pci_attach (device_t); -/* This distinguishing define is not right, but it does work */ -#ifdef __alpha__ -#define IO_SPACE_MAPPING ALPHA_BUS_SPACE_IO -#define MEM_SPACE_MAPPING ALPHA_BUS_SPACE_MEM -#else -#define IO_SPACE_MAPPING I386_BUS_SPACE_IO -#define MEM_SPACE_MAPPING I386_BUS_SPACE_MEM -#endif - struct isp_pcisoftc { struct ispsoftc pci_isp; device_t pci_dev; diff --git a/sys/pci/pci.c b/sys/pci/pci.c index cfda6c7..b31667c 100644 --- a/sys/pci/pci.c +++ b/sys/pci/pci.c @@ -56,6 +56,8 @@ #include <pci/pcireg.h> #include <pci/pcivar.h> +#include "pcib_if.h" + #ifdef __alpha__ #include <machine/rpb.h> #endif @@ -64,6 +66,8 @@ #include <machine/smp.h> #endif /* APIC_IO */ +static devclass_t pci_devclass; + struct pci_quirk { u_int32_t devid; /* Vendor/device of the card */ int type; @@ -177,7 +181,7 @@ pci_fixancient(pcicfgregs *cfg) /* read config data specific to header type 1 device (PCI to PCI bridge) */ static void * -pci_readppb(pcicfgregs *cfg) +pci_readppb(device_t pcib, int b, int s, int f) { pcih1cfgregs *p; @@ -187,35 +191,43 @@ pci_readppb(pcicfgregs *cfg) bzero(p, sizeof *p); - p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2); - p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2); + p->secstat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECSTAT_1, 2); + p->bridgectl = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_BRIDGECTL_1, 2); - p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1); + p->seclat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECLAT_1, 1); - p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2), - pci_cfgread(cfg, PCIR_IOBASEL_1, 1)); - p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2), - pci_cfgread(cfg, PCIR_IOLIMITL_1, 1)); + p->iobase = PCI_PPBIOBASE (PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_IOBASEH_1, 2), + PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_IOBASEL_1, 1)); + p->iolimit = PCI_PPBIOLIMIT (PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_IOLIMITH_1, 2), + PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_IOLIMITL_1, 1)); p->membase = PCI_PPBMEMBASE (0, - pci_cfgread(cfg, PCIR_MEMBASE_1, 2)); + PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_MEMBASE_1, 2)); p->memlimit = PCI_PPBMEMLIMIT (0, - pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2)); + PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_MEMLIMIT_1, 2)); p->pmembase = PCI_PPBMEMBASE ( - (pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4), - pci_cfgread(cfg, PCIR_PMBASEL_1, 2)); + (pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEH_1, 4), + PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMBASEL_1, 2)); p->pmemlimit = PCI_PPBMEMLIMIT ( - (pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4), - pci_cfgread(cfg, PCIR_PMLIMITL_1, 2)); + (pci_addr_t)PCIB_READ_CONFIG(pcib, b, s, f, + PCIR_PMLIMITH_1, 4), + PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PMLIMITL_1, 2)); + return (p); } /* read config data specific to header type 2 device (PCI to CardBus bridge) */ static void * -pci_readpcb(pcicfgregs *cfg) +pci_readpcb(device_t pcib, int b, int s, int f) { pcih2cfgregs *p; @@ -225,60 +237,63 @@ pci_readpcb(pcicfgregs *cfg) bzero(p, sizeof *p); - p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2); - p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2); + p->secstat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECSTAT_2, 2); + p->bridgectl = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_BRIDGECTL_2, 2); - p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1); + p->seclat = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_SECLAT_2, 1); - p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4); - p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4); - p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4); - p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4); + p->membase0 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMBASE0_2, 4); + p->memlimit0 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMLIMIT0_2, 4); + p->membase1 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMBASE1_2, 4); + p->memlimit1 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_MEMLIMIT1_2, 4); - p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4); - p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4); - p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4); - p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4); + p->iobase0 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOBASE0_2, 4); + p->iolimit0 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOLIMIT0_2, 4); + p->iobase1 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOBASE1_2, 4); + p->iolimit1 = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_IOLIMIT1_2, 4); - p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4); + p->pccardif = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_PCCARDIF_2, 4); return p; } /* extract header type specific config data */ static void -pci_hdrtypedata(pcicfgregs *cfg) +pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg) { +#define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) switch (cfg->hdrtype) { case 0: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_0, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_0, 2); + cfg->subvendor = REG(PCIR_SUBVEND_0, 2); + cfg->subdevice = REG(PCIR_SUBDEV_0, 2); cfg->nummaps = PCI_MAXMAPS_0; break; case 1: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_1, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_1, 2); - cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_1, 1); - cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1); + cfg->subvendor = REG(PCIR_SUBVEND_1, 2); + cfg->subdevice = REG(PCIR_SUBDEV_1, 2); + cfg->secondarybus = REG(PCIR_SECBUS_1, 1); + cfg->subordinatebus = REG(PCIR_SUBBUS_1, 1); cfg->nummaps = PCI_MAXMAPS_1; - cfg->hdrspec = pci_readppb(cfg); + cfg->hdrspec = pci_readppb(pcib, b, s, f); break; case 2: - cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_2, 2); - cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_2, 2); - cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_2, 1); - cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1); + cfg->subvendor = REG(PCIR_SUBVEND_2, 2); + cfg->subdevice = REG(PCIR_SUBDEV_2, 2); + cfg->secondarybus = REG(PCIR_SECBUS_2, 1); + cfg->subordinatebus = REG(PCIR_SUBBUS_2, 1); cfg->nummaps = PCI_MAXMAPS_2; - cfg->hdrspec = pci_readpcb(cfg); + cfg->hdrspec = pci_readpcb(pcib, b, s, f); break; } +#undef REG } /* read configuration header into pcicfgrect structure */ static struct pci_devinfo * -pci_readcfg(pcicfgregs *probe) +pci_read_device(device_t pcib, int b, int s, int f) { +#define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) pcicfgregs *cfg = NULL; struct pci_devinfo *devlist_entry; struct devlist *devlist_head; @@ -287,8 +302,7 @@ pci_readcfg(pcicfgregs *probe) devlist_entry = NULL; - if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) { - + if (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVVENDOR, 4) != -1) { devlist_entry = malloc(sizeof(struct pci_devinfo), M_DEVBUF, M_WAITOK); if (devlist_entry == NULL) @@ -297,23 +311,22 @@ pci_readcfg(pcicfgregs *probe) cfg = &devlist_entry->cfg; - cfg->hose = probe->hose; - cfg->bus = probe->bus; - cfg->slot = probe->slot; - cfg->func = probe->func; - cfg->vendor = pci_cfgread(cfg, PCIR_VENDOR, 2); - cfg->device = pci_cfgread(cfg, PCIR_DEVICE, 2); - cfg->cmdreg = pci_cfgread(cfg, PCIR_COMMAND, 2); - cfg->statreg = pci_cfgread(cfg, PCIR_STATUS, 2); - cfg->baseclass = pci_cfgread(cfg, PCIR_CLASS, 1); - cfg->subclass = pci_cfgread(cfg, PCIR_SUBCLASS, 1); - cfg->progif = pci_cfgread(cfg, PCIR_PROGIF, 1); - cfg->revid = pci_cfgread(cfg, PCIR_REVID, 1); - cfg->hdrtype = pci_cfgread(cfg, PCIR_HEADERTYPE, 1); - cfg->cachelnsz = pci_cfgread(cfg, PCIR_CACHELNSZ, 1); - cfg->lattimer = pci_cfgread(cfg, PCIR_LATTIMER, 1); - cfg->intpin = pci_cfgread(cfg, PCIR_INTPIN, 1); - cfg->intline = pci_cfgread(cfg, PCIR_INTLINE, 1); + cfg->bus = b; + cfg->slot = s; + cfg->func = f; + cfg->vendor = REG(PCIR_VENDOR, 2); + cfg->device = REG(PCIR_DEVICE, 2); + cfg->cmdreg = REG(PCIR_COMMAND, 2); + cfg->statreg = REG(PCIR_STATUS, 2); + cfg->baseclass = REG(PCIR_CLASS, 1); + cfg->subclass = REG(PCIR_SUBCLASS, 1); + cfg->progif = REG(PCIR_PROGIF, 1); + cfg->revid = REG(PCIR_REVID, 1); + cfg->hdrtype = REG(PCIR_HEADERTYPE, 1); + cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1); + cfg->lattimer = REG(PCIR_LATTIMER, 1); + cfg->intpin = REG(PCIR_INTPIN, 1); + cfg->intline = REG(PCIR_INTLINE, 1); #ifdef __alpha__ alpha_platform_assign_pciintr(cfg); #endif @@ -346,14 +359,14 @@ pci_readcfg(pcicfgregs *probe) } #endif /* APIC_IO */ - cfg->mingnt = pci_cfgread(cfg, PCIR_MINGNT, 1); - cfg->maxlat = pci_cfgread(cfg, PCIR_MAXLAT, 1); + cfg->mingnt = REG(PCIR_MINGNT, 1); + cfg->maxlat = REG(PCIR_MAXLAT, 1); cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; cfg->hdrtype &= ~PCIM_MFDEV; pci_fixancient(cfg); - pci_hdrtypedata(cfg); + pci_hdrtypedata(pcib, b, s, f, cfg); STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links); @@ -376,6 +389,7 @@ pci_readcfg(pcicfgregs *probe) pci_generation++; } return (devlist_entry); +#undef REG } #if 0 @@ -541,6 +555,7 @@ pci_devlist_get_parent(pcicfgregs *cfg) static int pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { + device_t pci, pcib; struct pci_io *io; const char *name; int error; @@ -782,17 +797,30 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case PCIOCREAD: io = (struct pci_io *)data; switch(io->pi_width) { - pcicfgregs probe; case 4: case 2: case 1: - probe.hose = -1; - probe.bus = io->pi_sel.pc_bus; - probe.slot = io->pi_sel.pc_dev; - probe.func = io->pi_sel.pc_func; - io->pi_data = pci_cfgread(&probe, - io->pi_reg, io->pi_width); - error = 0; + /* + * Assume that the user-level bus number is + * actually the pciN instance number. We map + * from that to the real pcib+bus combination. + */ + pci = devclass_get_device(pci_devclass, + io->pi_sel.pc_bus); + if (pci) { + int b = pcib_get_bus(pci); + pcib = device_get_parent(pci); + io->pi_data = + PCIB_READ_CONFIG(pcib, + b, + io->pi_sel.pc_dev, + io->pi_sel.pc_func, + io->pi_reg, + io->pi_width); + error = 0; + } else { + error = ENODEV; + } break; default: error = ENODEV; @@ -803,17 +831,30 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) case PCIOCWRITE: io = (struct pci_io *)data; switch(io->pi_width) { - pcicfgregs probe; case 4: case 2: case 1: - probe.hose = -1; - probe.bus = io->pi_sel.pc_bus; - probe.slot = io->pi_sel.pc_dev; - probe.func = io->pi_sel.pc_func; - pci_cfgwrite(&probe, - io->pi_reg, io->pi_data, io->pi_width); - error = 0; + /* + * Assume that the user-level bus number is + * actually the pciN instance number. We map + * from that to the real pcib+bus combination. + */ + pci = devclass_get_device(pci_devclass, + io->pi_sel.pc_bus); + if (pci) { + int b = pcib_get_bus(pci); + pcib = device_get_parent(pci); + PCIB_WRITE_CONFIG(pcib, + b, + io->pi_sel.pc_dev, + io->pi_sel.pc_func, + io->pi_reg, + io->pi_data, + io->pi_width); + error = 0; + } else { + error = ENODEV; + } break; default: error = ENODEV; @@ -850,7 +891,6 @@ static struct cdevsw pcicdev = { #include "pci_if.h" - /* * New style pci driver. Parent device is either a pci-host-bridge or a * pci-pci-bridge. Both kinds are represented by instances of pcib. @@ -882,15 +922,17 @@ pci_print_verbose(struct pci_devinfo *dinfo) } static int -pci_porten(pcicfgregs *cfg) +pci_porten(device_t pcib, int b, int s, int f) { - return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0); + return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2) + & PCIM_CMD_PORTEN) != 0; } static int -pci_memen(pcicfgregs *cfg) +pci_memen(device_t pcib, int b, int s, int f) { - return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0); + return (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_COMMAND, 2) + & PCIM_CMD_MEMEN) != 0; } /* @@ -898,10 +940,9 @@ pci_memen(pcicfgregs *cfg) * register is a 32bit map register or 2 if it is a 64bit register. */ static int -pci_add_map(device_t dev, pcicfgregs* cfg, int reg) +pci_add_map(device_t pcib, int b, int s, int f, int reg, + struct resource_list *rl) { - struct pci_devinfo *dinfo = device_get_ivars(dev); - struct resource_list *rl = &dinfo->resources; u_int32_t map; u_int64_t base; u_int8_t ln2size; @@ -910,14 +951,14 @@ pci_add_map(device_t dev, pcicfgregs* cfg, int reg) int type; - map = pci_cfgread(cfg, reg, 4); + map = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4); if (map == 0 || map == 0xffffffff) return 1; /* skip invalid entry */ - pci_cfgwrite(cfg, reg, 0xffffffff, 4); - testval = pci_cfgread(cfg, reg, 4); - pci_cfgwrite(cfg, reg, map, 4); + PCIB_WRITE_CONFIG(pcib, b, s, f, reg, 0xffffffff, 4); + testval = PCIB_READ_CONFIG(pcib, b, s, f, reg, 4); + PCIB_WRITE_CONFIG(pcib, b, s, f, reg, map, 4); base = pci_mapbase(map); if (pci_maptype(map) & PCI_MAPMEM) @@ -928,72 +969,24 @@ pci_add_map(device_t dev, pcicfgregs* cfg, int reg) ln2range = pci_maprange(testval); if (ln2range == 64) { /* Read the other half of a 64bit map register */ - base |= (u_int64_t) pci_cfgread(cfg, reg + 4, 4) << 32; + base |= (u_int64_t) PCIB_READ_CONFIG(pcib, b, s, f, reg + 4, 4) << 32; } -#ifdef __alpha__ - /* - * XXX: encode hose number in the base addr, - * This will go away once the bus_space functions - * can deal with multiple hoses - */ - - if (cfg->hose) { - u_int32_t mask, shift, maxh; - - switch (hwrpb->rpb_type) { - case ST_DEC_4100: - mask = 0xc0000000; - shift = 30; - maxh = 4; /* not a hose. MCPCIA instance # */ - break; - case ST_DEC_21000: - mask = 0xf8000000; - shift = 27; - maxh = 32; - break; - case ST_DEC_6600: - mask = 0x80000000; - shift = 31; - maxh = 2; - break; - default: - mask = 0; - shift = 0; - maxh = 0; - break; - } - if (base & mask) { - printf("base addr = 0x%llx\n", (long long) base); - printf("mask addr = 0x%lx\n", (long) mask); - printf("hacked addr = 0x%llx\n", (long long) - (base | ((u_int64_t)cfg->hose << shift))); - panic("hose encoding hack would clobber base addr"); - /* NOTREACHED */ - } - if (cfg->hose >= maxh) { - panic("Hose %d - can only encode %d hose(s)", - cfg->hose, maxh); - /* NOTREACHED */ - } - base |= ((u_int64_t)cfg->hose << shift); - } -#endif if (bootverbose) { printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d", reg, pci_maptype(map), ln2range, (unsigned int) base, ln2size); - if (type == SYS_RES_IOPORT && !pci_porten(cfg)) + if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f)) printf(", port disabled\n"); - else if (type == SYS_RES_MEMORY && !pci_memen(cfg)) + else if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f)) printf(", memory disabled\n"); else printf(", enabled\n"); } - if (type == SYS_RES_IOPORT && !pci_porten(cfg)) + if (type == SYS_RES_IOPORT && !pci_porten(pcib, b, s, f)) return 1; - if (type == SYS_RES_MEMORY && !pci_memen(cfg)) + if (type == SYS_RES_MEMORY && !pci_memen(pcib, b, s, f)) return 1; resource_list_add(rl, type, reg, @@ -1004,21 +997,22 @@ pci_add_map(device_t dev, pcicfgregs* cfg, int reg) } static void -pci_add_resources(device_t dev, pcicfgregs* cfg) +pci_add_resources(device_t pcib, int b, int s, int f, device_t dev) { struct pci_devinfo *dinfo = device_get_ivars(dev); + pcicfgregs *cfg = &dinfo->cfg; struct resource_list *rl = &dinfo->resources; struct pci_quirk *q; int i; for (i = 0; i < cfg->nummaps;) { - i += pci_add_map(dev, cfg, PCIR_MAPS + i*4); + i += pci_add_map(pcib, b, s, f, PCIR_MAPS + i*4, rl); } for (q = &pci_quirks[0]; q->devid; q++) { if (q->devid == ((cfg->device << 16) | cfg->vendor) && q->type == PCI_QUIRK_MAP_REG) - pci_add_map(dev, cfg, q->arg1); + pci_add_map(pcib, b, s, f, q->arg1, rl); } if (cfg->intpin > 0 && cfg->intline != 255) @@ -1029,26 +1023,17 @@ pci_add_resources(device_t dev, pcicfgregs* cfg) static void pci_add_children(device_t dev, int busno) { - pcicfgregs probe; - -#ifdef SIMOS -#undef PCI_SLOTMAX -#define PCI_SLOTMAX 0 -#endif + device_t pcib = device_get_parent(dev); + int maxslots; + int s, f; - bzero(&probe, sizeof probe); -#ifdef __alpha__ - probe.hose = pcib_get_hose(dev); -#endif -#ifdef __i386__ - probe.hose = 0; -#endif - probe.bus = busno; - - for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + maxslots = PCIB_MAXSLOTS(pcib); + + for (s = 0; s <= maxslots; s++) { int pcifunchigh = 0; - for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) { - struct pci_devinfo *dinfo = pci_readcfg(&probe); + for (f = 0; f <= pcifunchigh; f++) { + struct pci_devinfo *dinfo = + pci_read_device(pcib, busno, s, f); if (dinfo != NULL) { if (dinfo->cfg.mfdev) pcifunchigh = 7; @@ -1056,19 +1041,31 @@ pci_add_children(device_t dev, int busno) pci_print_verbose(dinfo); dinfo->cfg.dev = device_add_child(dev, NULL, -1); device_set_ivars(dinfo->cfg.dev, dinfo); - pci_add_resources(dinfo->cfg.dev, &dinfo->cfg); + pci_add_resources(pcib, busno, s, f, + dinfo->cfg.dev); } } } } static int -pci_new_probe(device_t dev) +pci_probe(device_t dev) { static int once; device_set_desc(dev, "PCI bus"); - pci_add_children(dev, device_get_unit(dev)); + + if (bootverbose) + device_printf(dev, "physical bus=%d\n", pcib_get_bus(dev)); + + /* + * Since there can be multiple independantly numbered PCI + * busses on some large alpha systems, we can't use the unit + * number to decide what bus we are probing. We ask the parent + * pcib what our bus number is. + */ + pci_add_children(dev, pcib_get_bus(dev)); + if (!once) { make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644, "pci"); once++; @@ -1227,12 +1224,6 @@ pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) case PCI_IVAR_SUBORDINATEBUS: *result = cfg->subordinatebus; break; - case PCI_IVAR_HOSE: - /* - * Pass up to parent bridge. - */ - *result = pcib_get_hose(dev); - break; default: return ENOENT; } @@ -1340,7 +1331,10 @@ pci_read_config_method(device_t dev, device_t child, int reg, int width) { struct pci_devinfo *dinfo = device_get_ivars(child); pcicfgregs *cfg = &dinfo->cfg; - return pci_cfgread(cfg, reg, width); + + return PCIB_READ_CONFIG(device_get_parent(dev), + cfg->bus, cfg->slot, cfg->func, + reg, width); } static void @@ -1349,7 +1343,10 @@ pci_write_config_method(device_t dev, device_t child, int reg, { struct pci_devinfo *dinfo = device_get_ivars(child); pcicfgregs *cfg = &dinfo->cfg; - pci_cfgwrite(cfg, reg, val, width); + + PCIB_WRITE_CONFIG(device_get_parent(dev), + cfg->bus, cfg->slot, cfg->func, + reg, val, width); } static int @@ -1369,7 +1366,7 @@ pci_modevent(module_t mod, int what, void *arg) static device_method_t pci_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, pci_new_probe), + DEVMETHOD(device_probe, pci_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), diff --git a/sys/pci/pci_compat.c b/sys/pci/pci_compat.c index 4635342..bf833b1 100644 --- a/sys/pci/pci_compat.c +++ b/sys/pci/pci_compat.c @@ -73,6 +73,18 @@ pci_conf_write(pcici_t cfg, u_long reg, u_long data) } int +pci_cfgread (pcicfgregs *cfg, int reg, int bytes) +{ + return (pci_read_config(cfg->dev, reg, bytes)); +} + +void +pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes) +{ + pci_write_config(cfg->dev, reg, data, bytes); +} + +int pci_map_port(pcici_t cfg, u_long reg, pci_port_t* pa) { int rid; diff --git a/sys/pci/pcib_if.m b/sys/pci/pcib_if.m new file mode 100644 index 0000000..b50df4b --- /dev/null +++ b/sys/pci/pcib_if.m @@ -0,0 +1,71 @@ +# +# 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> + +INTERFACE pcib; + +# +# Return the number of slots on the attached PCI bus. +# +METHOD int maxslots { + device_t dev; +}; + +# +# Read configuration space on the PCI bus. The bus, slot and func +# arguments determine the device which is being read and the reg +# argument is a byte offset into configuration space for that +# device. The width argument (which should be 1, 2 or 4) specifies how +# many byte of configuration space to read from that offset. +# +METHOD u_int32_t read_config { + device_t dev; + int bus; + int slot; + int func; + int reg; + int width; +}; + +# +# Write configuration space on the PCI bus. The bus, slot and func +# arguments determine the device which is being written and the reg +# argument is a byte offset into configuration space for that +# device. The value field is written to the configuration space, with +# the number of bytes written depending on the width argument. +# +METHOD void write_config { + device_t dev; + int bus; + int slot; + int func; + int reg; + u_int32_t value; + int width; +}; diff --git a/sys/pci/pcisupport.c b/sys/pci/pcisupport.c index e0a72e1..374a168 100644 --- a/sys/pci/pcisupport.c +++ b/sys/pci/pcisupport.c @@ -58,6 +58,8 @@ #include <vm/vm_object.h> #include <vm/pmap.h> +#include "pcib_if.h" + /*--------------------------------------------------------- ** ** Intel chipsets for 486 / Pentium processor @@ -762,7 +764,9 @@ static int pcib_attach(device_t dev) secondary = pci_get_secondarybus(dev); if (secondary) { - device_add_child(dev, "pci", secondary); + device_t child; + child = device_add_child(dev, "pci", -1); + pcib_set_bus(child, secondary); return bus_generic_attach(dev); } else return 0; @@ -771,16 +775,55 @@ static int pcib_attach(device_t dev) static int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { - if (which == PCIB_IVAR_HOSE) { - /* - * Pass up to parent bus. - */ - *result = pci_get_hose(dev); - return(0); + switch (which) { + case PCIB_IVAR_BUS: + *result = *(int*) device_get_softc(dev); + return 0; + } + return ENOENT; +} + +static int +pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) +{ + switch (which) { + case PCIB_IVAR_BUS: + *(int*) device_get_softc(dev) = value; + return 0; } return ENOENT; } +static int +pcib_maxslots(device_t dev) +{ + return 31; +} + +static u_int32_t +pcib_read_config(device_t dev, int b, int s, int f, + int reg, int width) +{ + /* + * Pass through to the next ppb up the chain (i.e. our + * grandparent). + */ + return PCIB_READ_CONFIG(device_get_parent(device_get_parent(dev)), + b, s, f, reg, width); +} + +static void +pcib_write_config(device_t dev, int b, int s, int f, + int reg, u_int32_t val, int width) +{ + /* + * Pass through to the next ppb up the chain (i.e. our + * grandparent). + */ + PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(dev)), + b, s, f, reg, val, width); +} + static device_method_t pcib_methods[] = { /* Device interface */ DEVMETHOD(device_probe, pcib_probe), @@ -792,6 +835,7 @@ static device_method_t pcib_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), DEVMETHOD(bus_read_ivar, pcib_read_ivar), + DEVMETHOD(bus_write_ivar, pcib_write_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), @@ -799,13 +843,18 @@ static device_method_t pcib_methods[] = { DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* pcib interface */ + DEVMETHOD(pcib_maxslots, pcib_maxslots), + DEVMETHOD(pcib_read_config, pcib_read_config), + DEVMETHOD(pcib_write_config, pcib_write_config), + { 0, 0 } }; static driver_t pcib_driver = { "pcib", pcib_methods, - 1, + sizeof(int), }; static devclass_t pcib_devclass; diff --git a/sys/pci/pcivar.h b/sys/pci/pcivar.h index b767616..34df379 100644 --- a/sys/pci/pcivar.h +++ b/sys/pci/pcivar.h @@ -82,7 +82,6 @@ typedef struct pcicfg { u_int8_t mfdev; /* multi-function device (from hdrtype reg) */ u_int8_t nummaps; /* actual number of PCI maps used */ - u_int8_t hose; /* hose which bus is attached to */ u_int8_t bus; /* config space bus address */ u_int8_t slot; /* config space slot address */ u_int8_t func; /* config space function number */ @@ -156,6 +155,7 @@ const char *pci_chip_match(struct device *dev); int pci_cfgread (pcicfgregs *cfg, int reg, int bytes); void pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes); + #ifdef __alpha__ vm_offset_t pci_cvt_to_dense (vm_offset_t); vm_offset_t pci_cvt_to_bwx (vm_offset_t); @@ -192,7 +192,6 @@ enum pci_device_ivars { PCI_IVAR_FUNCTION, PCI_IVAR_SECONDARYBUS, PCI_IVAR_SUBORDINATEBUS, - PCI_IVAR_HOSE, }; /* @@ -229,7 +228,6 @@ PCI_ACCESSOR(slot, SLOT, u_int8_t) PCI_ACCESSOR(function, FUNCTION, u_int8_t) PCI_ACCESSOR(secondarybus, SECONDARYBUS, u_int8_t) PCI_ACCESSOR(subordinatebus, SUBORDINATEBUS, u_int8_t) -PCI_ACCESSOR(hose, HOSE, u_int32_t) static __inline u_int32_t pci_read_config(device_t dev, int reg, int width) @@ -249,7 +247,7 @@ pci_write_config(device_t dev, int reg, u_int32_t val, int width) /*typedef enum pci_device_ivars pcib_device_ivars;*/ enum pcib_device_ivars { - PCIB_IVAR_HOSE, + PCIB_IVAR_BUS }; #define PCIB_ACCESSOR(A, B, T) \ @@ -267,7 +265,7 @@ static __inline void pcib_set_ ## A(device_t dev, T t) \ BUS_WRITE_IVAR(device_get_parent(dev), dev, PCIB_IVAR_ ## B, v); \ } -PCIB_ACCESSOR(hose, HOSE, u_int32_t) +PCIB_ACCESSOR(bus, BUS, u_int32_t) #endif |