summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakuya ASADA <syuu@cvs.openbsd.org>2010-10-28 22:52:11 +0000
committerTakuya ASADA <syuu@cvs.openbsd.org>2010-10-28 22:52:11 +0000
commitbffe3d2ae277153004d100387fe68485268ad916 (patch)
treed6a4239f864828bdbce09b692e8aac21fe5158c1
parent686b74e04c56cd1edd86b0f6786787c0d6d2f376 (diff)
Inital commit of PCI and SATA support for OCTEON
-rw-r--r--sys/arch/octeon/dev/obio.c3
-rw-r--r--sys/arch/octeon/dev/octeon_bus_space.c187
-rw-r--r--sys/arch/octeon/dev/octeon_pcibus.c570
-rw-r--r--sys/arch/octeon/dev/octeon_pcibus.h114
-rw-r--r--sys/arch/octeon/dev/octeon_pcibus_irq.h60
-rw-r--r--sys/arch/octeon/dev/octeon_pcibusvar.h66
-rw-r--r--sys/arch/octeon/include/bus.h33
-rw-r--r--sys/arch/octeon/include/pci_machdep.h120
-rw-r--r--sys/arch/octeon/octeon/pciide_machdep.c64
9 files changed, 1215 insertions, 2 deletions
diff --git a/sys/arch/octeon/dev/obio.c b/sys/arch/octeon/dev/obio.c
index 9b00c4de71f..d6a478c99e6 100644
--- a/sys/arch/octeon/dev/obio.c
+++ b/sys/arch/octeon/dev/obio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: obio.c,v 1.4 2010/10/26 00:02:01 syuu Exp $ */
+/* $OpenBSD: obio.c,v 1.5 2010/10/28 22:52:10 syuu Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -166,6 +166,7 @@ uint64_t obio_imask[MAXCPUS][NIPLS];
{ name, &obio_tag, &obio_tag, &obio_bus_dma_tag, addr, i }
struct obio_attach_args obio_children[] = {
OBIODEV("octcf", OCTEON_CF_BASE, 0),
+ OBIODEV("pcibus", 0, 0),
};
#undef OBIODEV
diff --git a/sys/arch/octeon/dev/octeon_bus_space.c b/sys/arch/octeon/dev/octeon_bus_space.c
new file mode 100644
index 00000000000..7fb70165326
--- /dev/null
+++ b/sys/arch/octeon/dev/octeon_bus_space.c
@@ -0,0 +1,187 @@
+/* $OpenBSD: octeon_bus_space.c,v 1.1 2010/10/28 22:52:10 syuu Exp $ */
+
+/*
+ * Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
+ *
+ * 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 ``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 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.
+ *
+ */
+
+/*
+ * Simple generic bus access primitives.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+
+uint8_t
+generic_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+ return *(volatile uint8_t *)(h + o);
+}
+
+uint16_t
+generic_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+ return *(volatile uint16_t *)(h + o);
+}
+
+uint32_t
+generic_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+ return *(volatile uint32_t *)(h + o);
+}
+
+uint64_t
+generic_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
+{
+ return *(volatile uint64_t *)(h + o);
+}
+
+void
+generic_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+ uint8_t v)
+{
+ *(volatile uint8_t *)(h + o) = v;
+}
+
+void
+generic_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+ uint16_t v)
+{
+ *(volatile uint16_t *)(h + o) = v;
+}
+
+void
+generic_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+ uint32_t v)
+{
+ *(volatile uint32_t *)(h + o) = v;
+}
+
+void
+generic_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
+ uint64_t v)
+{
+ *(volatile uint64_t *)(h + o) = v;
+}
+
+void
+generic_space_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
+ uint8_t *buf, bus_size_t len)
+{
+ volatile uint16_t *addr = (volatile uint16_t *)(h + o);
+ len >>= 1;
+ while (len-- != 0) {
+ *(uint16_t *)buf = *addr;
+ buf += 2;
+ }
+}
+
+void
+generic_space_write_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
+ const uint8_t *buf, bus_size_t len)
+{
+ volatile uint16_t *addr = (volatile uint16_t *)(h + o);
+ len >>= 1;
+ while (len-- != 0) {
+ *addr = *(uint16_t *)buf;
+ buf += 2;
+ }
+}
+
+void
+generic_space_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
+ uint8_t *buf, bus_size_t len)
+{
+ volatile uint32_t *addr = (volatile uint32_t *)(h + o);
+ len >>= 2;
+ while (len-- != 0) {
+ *(uint32_t *)buf = *addr;
+ buf += 4;
+ }
+}
+
+void
+generic_space_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
+ const uint8_t *buf, bus_size_t len)
+{
+ volatile uint32_t *addr = (volatile uint32_t *)(h + o);
+ len >>= 2;
+ while (len-- != 0) {
+ *addr = *(uint32_t *)buf;
+ buf += 4;
+ }
+}
+
+void
+generic_space_read_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
+ uint8_t *buf, bus_size_t len)
+{
+ volatile uint64_t *addr = (volatile uint64_t *)(h + o);
+ len >>= 3;
+ while (len-- != 0) {
+ *(uint64_t *)buf = *addr;
+ buf += 8;
+ }
+}
+
+void
+generic_space_write_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
+ const uint8_t *buf, bus_size_t len)
+{
+ volatile uint64_t *addr = (volatile uint64_t *)(h + o);
+ len >>= 3;
+ while (len-- != 0) {
+ *addr = *(uint64_t *)buf;
+ buf += 8;
+ }
+}
+
+int
+generic_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
+ int flags, bus_space_handle_t *bshp)
+{
+ *bshp = t->bus_base + offs;
+ return 0;
+}
+
+void
+generic_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
+{
+}
+
+int
+generic_space_region(bus_space_tag_t t, bus_space_handle_t bsh,
+ bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
+{
+ *nbshp = bsh + offset;
+ return 0;
+}
+
+void *
+generic_space_vaddr(bus_space_tag_t t, bus_space_handle_t h)
+{
+ return (void *)h;
+}
diff --git a/sys/arch/octeon/dev/octeon_pcibus.c b/sys/arch/octeon/dev/octeon_pcibus.c
new file mode 100644
index 00000000000..9240f16a758
--- /dev/null
+++ b/sys/arch/octeon/dev/octeon_pcibus.c
@@ -0,0 +1,570 @@
+/* $OpenBSD: octeon_pcibus.c,v 1.1 2010/10/28 22:52:10 syuu Exp $ */
+/* $OpenBSD: octeon_pcibus.c,v 1.1 2010/10/28 22:52:10 syuu Exp $ */
+/* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */
+/* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */
+
+/*
+ * Copyright (c) 2009, 2010 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/extent.h>
+#include <sys/malloc.h>
+
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/ppbreg.h>
+
+#include <octeon/dev/obiovar.h>
+#include <octeon/dev/octeon_pcibus.h>
+#include <octeon/dev/octeon_pcibusvar.h>
+
+#include <uvm/uvm_extern.h>
+
+#if 1
+#define OCTEON_PCIBUS_DEBUG
+#endif
+
+#ifdef OCTEON_PCIBUS_DEBUG
+#define DEBUG_PRINT(p) printf p
+#else
+#define DEBUG_PRINT(p)
+#endif
+
+#define REG_READ32(addr) (*(volatile uint32_t *)(addr))
+#define REG_WRITE32(addr, data) (*(volatile uint32_t *)(addr) = (uint32_t)(data))
+
+int octeon_pcibus_match(struct device *, void *, void *);
+void octeon_pcibus_attach(struct device *, struct device *, void *);
+int octeon_pcibus_intr_map(int dev, int fn, int pin);
+void octeon_pcibus_pci_attach_hook(pci_chipset_tag_t pc);
+
+const struct cfattach pcibus_ca = {
+ sizeof(struct octeon_pcibus_softc),
+ octeon_pcibus_match, octeon_pcibus_attach
+};
+
+struct cfdriver pcibus_cd = {
+ NULL, "pcibus", DV_DULL
+};
+
+bus_addr_t octeon_pcibus_pa_to_device(paddr_t);
+paddr_t octeon_pcibus_device_to_pa(bus_addr_t);
+void octeon_pcibus_attach_hook(struct device *, struct device *,
+ struct pcibus_attach_args *);
+int octeon_pcibus_bus_maxdevs(void *, int);
+pcitag_t octeon_pcibus_make_tag(void *, int, int, int);
+void octeon_pcibus_decompose_tag(void *, pcitag_t, int *, int *, int *);
+pcireg_t octeon_pcibus_pci_conf_read(void *, pcitag_t, int);
+pcireg_t octeon_pcibus_pci_conf_read_internal(pcitag_t, int);
+void octeon_pcibus_pci_conf_write(void *, pcitag_t, int, pcireg_t);
+int octeon_pcibus_pci_intr_map(struct pci_attach_args *,
+ pci_intr_handle_t *);
+const char *octeon_pcibus_pci_intr_string(void *, pci_intr_handle_t);
+void *octeon_pcibus_pci_intr_establish(void *, pci_intr_handle_t, int,
+ int (*)(void *), void *, char *);
+void octeon_pcibus_pci_intr_disestablish(void *, void *);
+
+
+struct machine_bus_dma_tag octeon_pcibus_bus_dma_tag = {
+ ._cookie = NULL,
+ ._dmamap_create = _dmamap_create,
+ ._dmamap_destroy = _dmamap_destroy,
+ ._dmamap_load = _dmamap_load,
+ ._dmamap_load_mbuf = _dmamap_load_mbuf,
+ ._dmamap_load_uio = _dmamap_load_uio,
+ ._dmamap_load_raw = _dmamap_load_raw,
+ ._dmamap_load_buffer = _dmamap_load_buffer,
+ ._dmamap_unload = _dmamap_unload,
+ ._dmamap_sync = _dmamap_sync,
+ ._dmamem_alloc = _dmamem_alloc,
+ ._dmamem_free = _dmamem_free,
+ ._dmamem_map = _dmamem_map,
+ ._dmamem_unmap = _dmamem_unmap,
+ ._dmamem_mmap = _dmamem_mmap,
+ ._pa_to_device = octeon_pcibus_pa_to_device,
+ ._device_to_pa = octeon_pcibus_device_to_pa
+};
+
+int octeon_pcibus_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
+ bus_space_handle_t *);
+int octeon_pcibus_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
+ bus_space_handle_t *);
+
+#define _OCTEON_PCIBUS_PCIIO_BASE 0x00001000
+#define _OCTEON_PCIBUS_PCIIO_SIZE 0x08000000
+#define _OCTEON_PCIBUS_PCIMEM_BASE 0x80000000
+#define _OCTEON_PCIBUS_PCIMEM_SIZE 0x40000000
+
+bus_space_t octeon_pcibus_pci_io_space_tag = {
+ .bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIIO_BASE, CCA_NC),
+ .bus_private = NULL,
+ ._space_read_1 = generic_space_read_1,
+ ._space_write_1 = generic_space_write_1,
+ ._space_read_2 = generic_space_read_2,
+ ._space_write_2 = generic_space_write_2,
+ ._space_read_4 = generic_space_read_4,
+ ._space_write_4 = generic_space_write_4,
+ ._space_read_8 = generic_space_read_8,
+ ._space_write_8 = generic_space_write_8,
+ ._space_read_raw_2 = generic_space_read_raw_2,
+ ._space_write_raw_2 = generic_space_write_raw_2,
+ ._space_read_raw_4 = generic_space_read_raw_4,
+ ._space_write_raw_4 = generic_space_write_raw_4,
+ ._space_read_raw_8 = generic_space_read_raw_8,
+ ._space_write_raw_8 = generic_space_write_raw_8,
+ ._space_map = octeon_pcibus_io_map,
+ ._space_unmap = generic_space_unmap,
+ ._space_subregion = generic_space_region,
+ ._space_vaddr = generic_space_vaddr
+};
+
+bus_space_t octeon_pcibus_pci_mem_space_tag = {
+ .bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIMEM_BASE, CCA_NC),
+ .bus_private = NULL,
+ ._space_read_1 = generic_space_read_1,
+ ._space_write_1 = generic_space_write_1,
+ ._space_read_2 = generic_space_read_2,
+ ._space_write_2 = generic_space_write_2,
+ ._space_read_4 = generic_space_read_4,
+ ._space_write_4 = generic_space_write_4,
+ ._space_read_8 = generic_space_read_8,
+ ._space_write_8 = generic_space_write_8,
+ ._space_read_raw_2 = generic_space_read_raw_2,
+ ._space_write_raw_2 = generic_space_write_raw_2,
+ ._space_read_raw_4 = generic_space_read_raw_4,
+ ._space_write_raw_4 = generic_space_write_raw_4,
+ ._space_read_raw_8 = generic_space_read_raw_8,
+ ._space_write_raw_8 = generic_space_write_raw_8,
+ ._space_map = octeon_pcibus_mem_map,
+ ._space_unmap = generic_space_unmap,
+ ._space_subregion = generic_space_region,
+ ._space_vaddr = generic_space_vaddr
+};
+
+int
+octeon_pcibus_match(struct device *parent, void *vcf, void *aux)
+{
+ struct obio_attach_args *oba = aux;
+
+ if (strcmp(oba->oba_name, pcibus_cd.cd_name) == 0)
+ return 1;
+
+ return 0;
+}
+
+void
+octeon_pcibus_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct octeon_pcibus_softc *sc;
+ struct obio_attach_args *oba;
+ struct pcibus_attach_args pba;
+
+ sc = (struct octeon_pcibus_softc *)self;
+ oba = aux;
+ sc->sc_oba = oba;
+
+ SLIST_INIT(&sc->sc_hook);
+
+ /*
+ * Attach PCI bus.
+ */
+ sc->sc_pc.pc_attach_hook = octeon_pcibus_attach_hook;
+ sc->sc_pc.pc_bus_maxdevs = octeon_pcibus_bus_maxdevs;
+ sc->sc_pc.pc_make_tag = octeon_pcibus_make_tag;
+ sc->sc_pc.pc_decompose_tag = octeon_pcibus_decompose_tag;
+
+ sc->sc_pc.pc_conf_v = sc;
+ sc->sc_pc.pc_conf_read = octeon_pcibus_pci_conf_read;
+ sc->sc_pc.pc_conf_write = octeon_pcibus_pci_conf_write;
+
+ sc->sc_pc.pc_intr_v = sc;
+ sc->sc_pc.pc_intr_map = octeon_pcibus_pci_intr_map;
+ sc->sc_pc.pc_intr_string = octeon_pcibus_pci_intr_string;
+ sc->sc_pc.pc_intr_establish = octeon_pcibus_pci_intr_establish;
+ sc->sc_pc.pc_intr_disestablish = octeon_pcibus_pci_intr_disestablish;
+
+ bzero(&pba, sizeof pba);
+ pba.pba_busname = "pci";
+ pba.pba_iot = &octeon_pcibus_pci_io_space_tag;
+ pba.pba_memt = &octeon_pcibus_pci_mem_space_tag;
+ pba.pba_dmat = &octeon_pcibus_bus_dma_tag;
+ pba.pba_pc = &sc->sc_pc;
+ pba.pba_domain = pci_ndomains++;
+ pba.pba_bus = 0;
+ pba.pba_ioex = octeon_pcibus_get_resource_extent(&sc->sc_pc, 1);
+ pba.pba_memex = octeon_pcibus_get_resource_extent(&sc->sc_pc, 0);
+
+ config_found(&sc->sc_dev, &pba, octeon_pcibus_print);
+}
+
+bus_addr_t
+octeon_pcibus_pa_to_device(paddr_t pa)
+{
+ printf("%s:%d: pa=%p\n", __func__, __LINE__, pa);
+
+ return pa & 0x1ffffffffffffUL;
+}
+
+paddr_t
+octeon_pcibus_device_to_pa(bus_addr_t addr)
+{
+ printf("%s:%d: addr=%p\n", __func__, __LINE__, addr);
+
+ return PHYS_TO_XKPHYS(addr, CCA_NC);
+}
+
+int
+octeon_pcibus_print(void *aux, const char *pnp)
+{
+ struct pcibus_attach_args *pba = aux;
+
+ if (pnp)
+ printf("%s at %s", pba->pba_busname, pnp);
+ printf(" bus %d", pba->pba_bus);
+
+ return UNCONF;
+}
+
+/*
+ * various PCI helpers
+ */
+void
+octeon_pcibus_attach_hook(struct device *parent, struct device *self,
+ struct pcibus_attach_args *pba)
+{
+}
+
+/*
+ * PCI configuration space access routines
+ */
+int
+octeon_pcibus_bus_maxdevs(void *v, int busno)
+{
+ /* XXX */
+ return 32;
+}
+
+pcitag_t
+octeon_pcibus_make_tag(void *unused, int b, int d, int f)
+{
+ return (b << 16) | (d << 11) | (f << 8);
+}
+
+void
+octeon_pcibus_decompose_tag(void *unused, pcitag_t tag, int *bp, int *dp, int *fp)
+{
+ if (bp != NULL)
+ *bp = (tag >> 16) & 0xff;
+ if (dp != NULL)
+ *dp = (tag >> 11) & 0x1f;
+ if (fp != NULL)
+ *fp = (tag >> 8) & 0x7;
+}
+
+/* PCI Configuration Space access hook structure */
+struct octeon_pcibus_cfg_hook {
+ SLIST_ENTRY(octeon_pcibus_cfg_hook) next;
+ int (*read)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *);
+ int (*write)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t);
+ void *cookie;
+};
+
+int
+octeon_pcibus_pci_hook(pci_chipset_tag_t pc, void *cookie,
+ int (*r)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *),
+ int (*w)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t))
+{
+ struct octeon_pcibus_softc *sc = pc->pc_conf_v;
+ struct octeon_pcibus_cfg_hook *och;
+
+ DEBUG_PRINT(("%s:%s:%d:\n", __FILE__, __FUNCTION__, __LINE__));
+ och = malloc(sizeof *och, M_DEVBUF, M_NOWAIT);
+ if (och == NULL)
+ return ENOMEM;
+
+ och->read = r;
+ och->write = w;
+ och->cookie = cookie;
+ SLIST_INSERT_HEAD(&sc->sc_hook, och, next);
+ return 0;
+}
+
+pcireg_t
+octeon_pcibus_pci_conf_read(void *v, pcitag_t tag, int offset)
+{
+ struct octeon_pcibus_softc *sc = v;
+ struct octeon_pcibus_cfg_hook *hook;
+ pcireg_t data;
+
+ SLIST_FOREACH(hook, &sc->sc_hook, next) {
+ if (hook->read != NULL &&
+ (*hook->read)(hook->cookie, &sc->sc_pc, tag, offset,
+ &data) != 0)
+ return data;
+ }
+
+ return octeon_pcibus_pci_conf_read_internal(tag, offset);
+}
+
+pcireg_t
+octeon_pcibus_pci_conf_read_internal(pcitag_t tag, int offset)
+{
+ pcireg_t data;
+ uint64_t cfgoff;
+
+ if (tag == 0){
+ if (offset & 0x4){
+ cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8);
+ } else {
+ cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8);
+ }
+ } else {
+ cfgoff = tag + offset;
+ if (offset & 0x4) {
+ cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8);
+ } else {
+ cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8);
+ }
+ }
+
+ data = REG_READ32(cfgoff);
+ return data;
+}
+
+void
+octeon_pcibus_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
+{
+ uint64_t cfgoff;
+
+ if (tag == 0){
+ if (offset & 0x4){
+ cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8);
+ } else {
+ cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8);
+ }
+ } else {
+ cfgoff = tag + offset;
+ if (offset & 0x4){
+ cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8);
+ } else {
+ cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8);
+ }
+ }
+
+ REG_WRITE32(cfgoff, data);
+}
+
+
+/*
+ * PCI Interrupt handling
+ */
+int
+octeon_pcibus_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
+{
+#if 0
+ struct octeon_pcibus_softc *sc = pa->pa_pc->pc_intr_v;
+#endif
+ int bus, dev, fn, pin;
+
+ *ihp = (pci_intr_handle_t)-1;
+
+ if (pa->pa_intrpin == 0) /* no interrupt needed */
+ return 1;
+
+#ifdef DIAGNOSTIC
+ if (pa->pa_intrpin > 4) {
+ printf("%s: bad interrupt pin %d\n", __func__, pa->pa_intrpin);
+ return 1;
+ }
+#endif
+
+ pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &fn);
+ if (pa->pa_bridgetag) {
+ pin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev);
+ *ihp = pa->pa_bridgeih[pin - 1];
+ } else {
+ if (bus == 0)
+ *ihp = octeon_pcibus_intr_map(dev, fn, pa->pa_intrpin);
+
+ if (*ihp == (pci_intr_handle_t)-1)
+ return 1;
+ }
+
+ return 0;
+}
+
+const char *
+octeon_pcibus_pci_intr_string(void *cookie, pci_intr_handle_t ih)
+{
+ static char irqstr[sizeof("irq 0123456789")];
+
+ snprintf(irqstr, sizeof irqstr, "irq %d", ih);
+ return irqstr;
+}
+
+void *
+octeon_pcibus_pci_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
+ int (*cb)(void *), void *cbarg, char *name)
+{
+ struct octeon_pcibus_softc *sc;
+ struct obio_attach_args *oba;
+
+ sc = (struct octeon_pcibus_softc *)cookie;
+ oba = sc->sc_oba;
+
+ return obio_intr_establish(oba->oba_intr, level, cb, cbarg, name);
+}
+
+void
+octeon_pcibus_pci_intr_disestablish(void *cookie, void *ihp)
+{
+ struct octeon_pcibus_softc *sc;
+ struct obio_attach_args *oba;
+
+ sc = (struct octeon_pcibus_softc *)cookie;
+ oba = sc->sc_oba;
+
+// XXX: this cause panic...
+// obio_intr_disestablish(ihp);
+}
+
+/*
+ * bus_space mapping routines.
+ */
+int
+octeon_pcibus_io_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
+ bus_space_handle_t *bshp)
+{
+ if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) {
+ offs +=
+ PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
+ }
+ *bshp = t->bus_base + offs;
+ return 0;
+}
+
+int
+octeon_pcibus_mem_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
+ bus_space_handle_t *bshp)
+{
+ if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) {
+ offs +=
+ PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
+ }
+ *bshp = t->bus_base + offs;
+ return 0;
+}
+
+/*
+ * PCI resource handling
+ */
+struct extent *
+octeon_pcibus_get_resource_extent(pci_chipset_tag_t pc, int io)
+{
+ struct octeon_pcibus_softc *sc = pc->pc_conf_v;
+ struct extent *ex;
+ char *exname;
+ int exnamesz;
+ int errors;
+
+ exnamesz = 1 + 16 + 4;
+ exname = (char *)malloc(exnamesz, M_DEVBUF, M_NOWAIT);
+ if (exname == NULL)
+ return NULL;
+ snprintf(exname, exnamesz, "%s%s", sc->sc_dev.dv_xname,
+ io ? "_io" : "_mem");
+
+ ex = extent_create(exname, 0, 0xffffffffffffffff, M_DEVBUF, NULL, 0,
+ EX_NOWAIT | EX_FILLED);
+ if (ex == NULL)
+ goto out;
+
+ exname = NULL;
+ errors = 0;
+ if (io) {
+ if (extent_free(ex, _OCTEON_PCIBUS_PCIIO_BASE, _OCTEON_PCIBUS_PCIIO_SIZE,
+ EX_NOWAIT) != 0)
+ errors++;
+ } else {
+ if (extent_free(ex, _OCTEON_PCIBUS_PCIMEM_BASE, _OCTEON_PCIBUS_PCIMEM_SIZE,
+ EX_NOWAIT) != 0)
+ errors++;
+ }
+
+ if (errors != 0) {
+ extent_destroy(ex);
+ ex = NULL;
+ }
+
+#ifdef OCTEON_PCIBUS_DEBUG
+ extent_print(ex);
+#endif
+
+out:
+ if (exname != NULL)
+ free(exname, M_DEVBUF);
+
+ return ex;
+}
+
+/*
+ * PCI model specific routines
+ */
+void
+octeon_pcibus_pci_attach_hook(pci_chipset_tag_t pc)
+{
+}
+
+int
+octeon_pcibus_intr_map(int dev, int fn, int pin)
+{
+ return CIU_INT_PCI_INTA + ((pin - 1) & 3);
+}
diff --git a/sys/arch/octeon/dev/octeon_pcibus.h b/sys/arch/octeon/dev/octeon_pcibus.h
new file mode 100644
index 00000000000..879350316f1
--- /dev/null
+++ b/sys/arch/octeon/dev/octeon_pcibus.h
@@ -0,0 +1,114 @@
+/* $OpenBSD: octeon_pcibus.h,v 1.1 2010/10/28 22:52:10 syuu Exp $ */
+
+/*
+ * Copyright (c) 2003-2004 Opsycon AB (www.opsycon.com).
+ *
+ * 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 ``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 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.
+ *
+ */
+
+
+#ifndef ___OCTEON_PCIBUS_H__
+#define ___OCTEON_PCIBUS_H__
+
+#include "octeonreg.h"
+
+#define OCTEON_PCIBUS_PCIIO_BASE 0x11A0000000000ULL
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define OCTEON_PCI_CFG0 0x80011F0000001804ULL
+#define OCTEON_PCI_CFG1 0x80011F0000001800ULL
+#define OCTEON_PCI_CONFIG_BASE0 0x8001190000000004ULL
+#define OCTEON_PCI_CONFIG_BASE1 0x8001190000000000ULL
+#else
+#define OCTEON_PCI_CFG0 0x80011F0000001800ULL
+#define OCTEON_PCI_CFG1 0x80011F0000001804ULL
+#define OCTEON_PCI_CONFIG_BASE0 0x8001190000000000ULL
+#define OCTEON_PCI_CONFIG_BASE1 0x8001190000000004ULL
+#endif
+
+#define OCTEON_PCI_CFG2 (OCTEON_PCI_CFG0 + 0x08UL)
+#define OCTEON_PCI_CFG3 (OCTEON_PCI_CFG1 + 0x08UL)
+#define OCTEON_PCI_CFG4 (OCTEON_PCI_CFG0 + 0x10UL)
+#define OCTEON_PCI_CFG5 (OCTEON_PCI_CFG1 + 0x10UL)
+#define OCTEON_PCI_CFG6 (OCTEON_PCI_CFG0 + 0x18UL)
+#define OCTEON_PCI_CFG7 (OCTEON_PCI_CFG1 + 0x18UL)
+#define OCTEON_PCI_CFG8 (OCTEON_PCI_CFG0 + 0x20UL)
+#define OCTEON_PCI_CFG9 (OCTEON_PCI_CFG1 + 0x20UL)
+#define OCTEON_PCI_CFG10 (OCTEON_PCI_CFG0 + 0x28UL)
+#define OCTEON_PCI_CFG11 (OCTEON_PCI_CFG1 + 0x28UL)
+#define OCTEON_PCI_CFG12 (OCTEON_PCI_CFG0 + 0x30UL)
+#define OCTEON_PCI_CFG13 (OCTEON_PCI_CFG1 + 0x30UL)
+#define OCTEON_PCI_CFG14 (OCTEON_PCI_CFG0 + 0x38UL)
+#define OCTEON_PCI_CFG15 (OCTEON_PCI_CFG1 + 0x38UL)
+#define OCTEON_PCI_CFG16 (OCTEON_PCI_CFG0 + 0x40UL)
+#define OCTEON_PCI_CFG17 (OCTEON_PCI_CFG1 + 0x40UL)
+#define OCTEON_PCI_CFG18 (OCTEON_PCI_CFG0 + 0x48UL)
+#define OCTEON_PCI_CFG19 (OCTEON_PCI_CFG1 + 0x48UL)
+#define OCTEON_PCI_CFG20 (OCTEON_PCI_CFG0 + 0x50UL)
+#define OCTEON_PCI_CFG21 (OCTEON_PCI_CFG1 + 0x50UL)
+#define OCTEON_PCI_CFG22 (OCTEON_PCI_CFG0 + 0x58UL)
+#define OCTEON_PCI_CFG23 (OCTEON_PCI_CFG1 + 0x58UL)
+#define OCTEON_PCI_CFG24 (OCTEON_PCI_CFG0 + 0x60UL)
+#define OCTEON_PCI_CFG25 (OCTEON_PCI_CFG1 + 0x60UL)
+#define OCTEON_PCI_CFG26 (OCTEON_PCI_CFG0 + 0x68UL)
+#define OCTEON_PCI_CFG27 (OCTEON_PCI_CFG1 + 0x68UL)
+#define OCTEON_PCI_CFG28 (OCTEON_PCI_CFG0 + 0x70UL)
+#define OCTEON_PCI_CFG29 (OCTEON_PCI_CFG1 + 0x70UL)
+#define OCTEON_PCI_CFG30 (OCTEON_PCI_CFG0 + 0x78UL)
+#define OCTEON_PCI_CFG31 (OCTEON_PCI_CFG1 + 0x78UL)
+#define OCTEON_PCI_CFG32 (OCTEON_PCI_CFG0 + 0x80UL)
+#define OCTEON_PCI_CFG33 (OCTEON_PCI_CFG1 + 0x80UL)
+#define OCTEON_PCI_CFG34 (OCTEON_PCI_CFG0 + 0x88UL)
+#define OCTEON_PCI_CFG35 (OCTEON_PCI_CFG1 + 0x88UL)
+#define OCTEON_PCI_CFG36 (OCTEON_PCI_CFG0 + 0x90UL)
+#define OCTEON_PCI_CFG37 (OCTEON_PCI_CFG1 + 0x90UL)
+#define OCTEON_PCI_CFG38 (OCTEON_PCI_CFG0 + 0x98UL)
+#define OCTEON_PCI_CFG39 (OCTEON_PCI_CFG1 + 0x98UL)
+#define OCTEON_PCI_CFG40 (OCTEON_PCI_CFG0 + 0xA0UL)
+#define OCTEON_PCI_CFG41 (OCTEON_PCI_CFG1 + 0xA0UL)
+#define OCTEON_PCI_CFG42 (OCTEON_PCI_CFG0 + 0xA8UL)
+#define OCTEON_PCI_CFG43 (OCTEON_PCI_CFG1 + 0xA8UL)
+#define OCTEON_PCI_CFG44 (OCTEON_PCI_CFG0 + 0xB0UL)
+#define OCTEON_PCI_CFG45 (OCTEON_PCI_CFG1 + 0xB0UL)
+#define OCTEON_PCI_CFG46 (OCTEON_PCI_CFG0 + 0xB8UL)
+#define OCTEON_PCI_CFG47 (OCTEON_PCI_CFG1 + 0xB8UL)
+#define OCTEON_PCI_CFG48 (OCTEON_PCI_CFG0 + 0xC0UL)
+#define OCTEON_PCI_CFG49 (OCTEON_PCI_CFG1 + 0xC0UL)
+#define OCTEON_PCI_CFG50 (OCTEON_PCI_CFG0 + 0xC8UL)
+#define OCTEON_PCI_CFG51 (OCTEON_PCI_CFG1 + 0xC8UL)
+#define OCTEON_PCI_CFG52 (OCTEON_PCI_CFG0 + 0xD0UL)
+#define OCTEON_PCI_CFG53 (OCTEON_PCI_CFG1 + 0xD0UL)
+#define OCTEON_PCI_CFG54 (OCTEON_PCI_CFG0 + 0xD8UL)
+#define OCTEON_PCI_CFG55 (OCTEON_PCI_CFG1 + 0xD8UL)
+#define OCTEON_PCI_CFG56 (OCTEON_PCI_CFG0 + 0xE0UL)
+#define OCTEON_PCI_CFG57 (OCTEON_PCI_CFG1 + 0xE0UL)
+#define OCTEON_PCI_CFG58 (OCTEON_PCI_CFG0 + 0xE8UL)
+#define OCTEON_PCI_CFG59 (OCTEON_PCI_CFG1 + 0xE8UL)
+#define OCTEON_PCI_CFG60 (OCTEON_PCI_CFG0 + 0xF0UL)
+#define OCTEON_PCI_CFG61 (OCTEON_PCI_CFG1 + 0xF0UL)
+#define OCTEON_PCI_CFG62 (OCTEON_PCI_CFG0 + 0xF8UL)
+#define OCTEON_PCI_CFG63 (OCTEON_PCI_CFG1 + 0xF8UL)
+
+#define OCTEON_PCIBUS_PCIMAPCFG_TYPE1 0x00010000
+
+#endif /* ___OCTEON_PCIBUS_H__ */
diff --git a/sys/arch/octeon/dev/octeon_pcibus_irq.h b/sys/arch/octeon/dev/octeon_pcibus_irq.h
new file mode 100644
index 00000000000..dadfd0f57c2
--- /dev/null
+++ b/sys/arch/octeon/dev/octeon_pcibus_irq.h
@@ -0,0 +1,60 @@
+/* $OpenBSD: octeon_pcibus_irq.h,v 1.1 2010/10/28 22:52:10 syuu Exp $ */
+
+/*
+ * Copyright (c) 2009, 2010 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Octeon_Pcibus interrupt assignments
+ */
+
+#define OCTEON_PCIBUS_INTRMASK_MBOX 0x0000000f
+#define OCTEON_PCIBUS_INTR_MBOX 0
+#define OCTEON_PCIBUS_INTRMASK_DMARDY 0x00000010
+#define OCTEON_PCIBUS_INTRMASK_DMAEMPTY 0x00000020
+#define OCTEON_PCIBUS_INTRMASK_COPYRDY 0x00000040
+#define OCTEON_PCIBUS_INTRMASK_COPYEMPTY 0x00000080
+#define OCTEON_PCIBUS_INTRMASK_COPYERR 0x00000100
+#define OCTEON_PCIBUS_INTRMASK_PCIIRQ 0x00000200
+#define OCTEON_PCIBUS_INTRMASK_MASTERERR 0x00000400
+#define OCTEON_PCIBUS_INTRMASK_SYSTEMERR 0x00000800
+#define OCTEON_PCIBUS_INTRMASK_DRAMPERR 0x00001000
+#define OCTEON_PCIBUS_INTRMASK_RETRYERR 0x00002000
+#define OCTEON_PCIBUS_INTRMASK_GPIO 0x01ff0000
+#define OCTEON_PCIBUS_INTR_GPIO 16
+#define OCTEON_PCIBUS_INTRMASK_GPIN 0x7e000000
+#define OCTEON_PCIBUS_INTR_GPIN 25
+
+/*
+ * Octeon_Pcibus interrupt handling recipes:
+ */
+
+#define INTPRI_OCTEON_PCIBUS (INTPRI_CLOCK + 1)
+#define INTPRI_ISA (INTPRI_OCTEON_PCIBUS + 1)
+
+#define OCTEON_PCIBUS_NDIRECT 32
+#define OCTEON_PCIBUS_NISA 16
+#define OCTEON_PCIBUS_NINTS (OCTEON_PCIBUS_NDIRECT + OCTEON_PCIBUS_NISA)
+#define OCTEON_PCIBUS_ISA_IRQ(i) ((i) + OCTEON_PCIBUS_NDIRECT)
+#define OCTEON_PCIBUS_DIRECT_IRQ(i) (i)
+#define OCTEON_PCIBUS_IRQ_IS_ISA(i) ((i) >= OCTEON_PCIBUS_NDIRECT)
+#define OCTEON_PCIBUS_IRQ_TO_ISA(i) ((i) - OCTEON_PCIBUS_NDIRECT)
+
+#define OCTEON_PCIBUS_DIRECT_MASK(imask) ((imask) & ((1L << OCTEON_PCIBUS_NDIRECT) - 1))
+#define OCTEON_PCIBUS_ISA_MASK(imask) ((imask) >> OCTEON_PCIBUS_NDIRECT)
+
+extern struct intrhand *octeon_pcibus_intrhand[OCTEON_PCIBUS_NINTS];
+extern uint64_t octeon_pcibus_intem;
+extern uint64_t octeon_pcibus_imask[NIPLS];
diff --git a/sys/arch/octeon/dev/octeon_pcibusvar.h b/sys/arch/octeon/dev/octeon_pcibusvar.h
new file mode 100644
index 00000000000..c66a3959bee
--- /dev/null
+++ b/sys/arch/octeon/dev/octeon_pcibusvar.h
@@ -0,0 +1,66 @@
+/* $OpenBSD: octeon_pcibusvar.h,v 1.1 2010/10/28 22:52:10 syuu Exp $ */
+/* $NetBSD: octeon_pcibusvar.h,v 1.4 2008/04/28 20:23:28 martin Exp $ */
+
+/*-
+ * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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 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.
+ */
+
+#ifndef _OCTEON_PCIBUSVAR_H_
+#define _OCTEON_PCIBUSVAR_H_
+
+struct octeon_pcibus_cfg_hook;
+struct extent;
+
+struct octeon_pcibus_config {
+ int oc_adbase; /* AD line base for config access */
+};
+
+struct octeon_pcibus_softc {
+ struct device sc_dev;
+ const struct octeon_pcibus_config *sc_octeon_pcibus;
+ struct mips_pci_chipset sc_pc;
+ struct obio_attach_args *sc_oba;
+
+ /* PCI Configuration Space access hooks */
+ SLIST_HEAD(, octeon_pcibus_cfg_hook) sc_hook;
+};
+
+#ifdef _KERNEL
+void octeon_pcibus_intr_disestablish(void *);
+void *octeon_pcibus_intr_establish(int, int, int, int (*)(void *), void *,
+ const char *);
+int octeon_pcibus_pci_hook(pci_chipset_tag_t, void *,
+ int (*)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *),
+ int (*)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t));
+int octeon_pcibus_print(void *, const char *);
+struct extent
+ *octeon_pcibus_get_resource_extent(pci_chipset_tag_t, int);
+void octeon_pcibus_setintrmask(int);
+#endif /* _KERNEL */
+
+#endif /* _OCTEON_PCIBUSVAR_H_ */
diff --git a/sys/arch/octeon/include/bus.h b/sys/arch/octeon/include/bus.h
index 0fed3200dae..3072ca2aa92 100644
--- a/sys/arch/octeon/include/bus.h
+++ b/sys/arch/octeon/include/bus.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus.h,v 1.2 2010/10/10 16:38:55 syuu Exp $ */
+/* $OpenBSD: bus.h,v 1.3 2010/10/28 22:52:10 syuu Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB Sweden. All rights reserved.
@@ -467,4 +467,35 @@ struct machine_bus_dmamap {
bus_dma_segment_t dm_segs[1]; /* segments; variable length */
};
+int generic_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
+ bus_space_handle_t *);
+void generic_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+int generic_space_region(bus_space_tag_t, bus_space_handle_t, bus_size_t,
+ bus_size_t, bus_space_handle_t *);
+void *generic_space_vaddr(bus_space_tag_t, bus_space_handle_t);
+uint8_t generic_space_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+uint16_t generic_space_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+uint32_t generic_space_read_4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+uint64_t generic_space_read_8(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+void generic_space_read_raw_2(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, uint8_t *, bus_size_t);
+void generic_space_write_1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
+ uint8_t);
+void generic_space_write_2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
+ uint16_t);
+void generic_space_write_4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
+ uint32_t);
+void generic_space_write_8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
+ uint64_t);
+void generic_space_write_raw_2(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, const uint8_t *, bus_size_t);
+void generic_space_read_raw_4(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, uint8_t *, bus_size_t);
+void generic_space_write_raw_4(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, const uint8_t *, bus_size_t);
+void generic_space_read_raw_8(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, uint8_t *, bus_size_t);
+void generic_space_write_raw_8(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, const uint8_t *, bus_size_t);
+
#endif /* _MACHINE_BUS_H_ */
diff --git a/sys/arch/octeon/include/pci_machdep.h b/sys/arch/octeon/include/pci_machdep.h
new file mode 100644
index 00000000000..5d506f6e3fc
--- /dev/null
+++ b/sys/arch/octeon/include/pci_machdep.h
@@ -0,0 +1,120 @@
+/* $OpenBSD: pci_machdep.h,v 1.1 2010/10/28 22:52:10 syuu Exp $ */
+
+/*
+ * Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
+ *
+ * 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 ``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 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/systm.h>
+
+typedef struct mips_pci_chipset *pci_chipset_tag_t;
+typedef u_long pcitag_t;
+typedef u_long pci_intr_handle_t;
+
+struct pci_attach_args;
+
+/*
+ * mips-specific PCI structure and type definitions.
+ * NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE.
+ */
+struct mips_pci_chipset {
+ void *pc_conf_v;
+ void (*pc_attach_hook)(struct device *,
+ struct device *, struct pcibus_attach_args *);
+ int (*pc_bus_maxdevs)(void *, int);
+ pcitag_t (*pc_make_tag)(void *, int, int, int);
+ void (*pc_decompose_tag)(void *, pcitag_t, int *,
+ int *, int *);
+ pcireg_t (*pc_conf_read)(void *, pcitag_t, int);
+ void (*pc_conf_write)(void *, pcitag_t, int, pcireg_t);
+
+ void *pc_intr_v;
+ int (*pc_intr_map)(struct pci_attach_args *, pci_intr_handle_t *);
+ const char *(*pc_intr_string)(void *, pci_intr_handle_t);
+ void *(*pc_intr_establish)(void *, pci_intr_handle_t,
+ int, int (*)(void *), void *, char *);
+ void (*pc_intr_disestablish)(void *, void *);
+};
+
+/*
+ * Functions provided to machine-independent PCI code.
+ */
+//#define DEBUG_PCI_CONF
+
+#define pci_attach_hook(p, s, pba) \
+ (*(pba)->pba_pc->pc_attach_hook)((p), (s), (pba))
+#define pci_bus_maxdevs(c, b) \
+ (*(c)->pc_bus_maxdevs)((c)->pc_conf_v, (b))
+#define pci_make_tag(c, b, d, f) \
+ (*(c)->pc_make_tag)((c)->pc_conf_v, (b), (d), (f))
+#define pci_decompose_tag(c, t, bp, dp, fp) \
+ (*(c)->pc_decompose_tag)((c)->pc_conf_v, (t), (bp), (dp), (fp))
+
+#ifdef DEBUG_PCI_CONF
+static inline pcireg_t pci_conf_read_db(void * c, pcitag_t t, int r,
+ char* f,char* func,int l)
+{
+ pcireg_t v;
+ struct mips_pci_chipset *pc = c;
+ v = (*(pc)->pc_conf_read)(pc->pc_conf_v, t, r);
+ printf("%s:%s:%d:pci_conf_read(%x,%x) = %x\n",f,func,l,t,r,v);
+ return v;
+}
+
+static inline void pci_conf_write_db(void * c, pcitag_t t, int r, pcireg_t v,
+ char* f,char* func,int l)
+{
+ struct mips_pci_chipset *pc = c;
+ printf("%s:%s:%d:pci_conf_write(%x,%x,%x)\n",f,func,l,t,r,v);
+ (*(pc)->pc_conf_write)(pc->pc_conf_v, t, r, v);
+}
+
+
+#define pci_conf_read(c, t, r) pci_conf_read_db(c, t, r,__FILE__,__FUNCTION__,__LINE__)
+#define pci_conf_write(c, t, r, v) pci_conf_write_db(c, t, r, v,__FILE__,__FUNCTION__,__LINE__)
+#else
+#define pci_conf_read(c, t, r) \
+ (*(c)->pc_conf_read)((c)->pc_conf_v, (t), (r))
+#define pci_conf_write(c, t, r, v) \
+ (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
+#endif
+#define pci_intr_map(c, ihp) \
+ (*(c)->pa_pc->pc_intr_map)((c), (ihp))
+#define pci_intr_string(c, ih) \
+ (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
+#define pci_intr_establish(c, ih, l, h, a, nm) \
+ (*(c)->pc_intr_establish)((c)->pc_intr_v, (ih), (l), (h), (a), (nm))
+#define pci_intr_disestablish(c, iv) \
+ (*(c)->pc_intr_disestablish)((c)->pc_intr_v, (iv))
+
+/* PCI view of CPU memory */
+extern paddr_t loongson_dma_base;
+
+/*
+ * Functions used during early system configuration.
+ */
+
+pcitag_t pci_make_tag_early(int, int, int);
+pcireg_t pci_conf_read_early(pcitag_t, int);
+
+#define pci_dev_postattach(a, b)
diff --git a/sys/arch/octeon/octeon/pciide_machdep.c b/sys/arch/octeon/octeon/pciide_machdep.c
new file mode 100644
index 00000000000..b26073274d6
--- /dev/null
+++ b/sys/arch/octeon/octeon/pciide_machdep.c
@@ -0,0 +1,64 @@
+/* $OpenBSD: pciide_machdep.c,v 1.1 2010/10/28 22:52:10 syuu Exp $ */
+/* $NetBSD: pciide_machdep.c,v 1.2 1999/02/19 18:01:27 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1998 Christopher G. Demetriou. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+/*
+ * PCI IDE controller driver
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pciidereg.h>
+#include <dev/pci/pciidevar.h>
+
+#include <machine/autoconf.h>
+
+void *
+pciide_machdep_compat_intr_establish(struct device *dev,
+ struct pci_attach_args *pa, int chan, int (*func)(void *), void *arg)
+{
+ void *cookie = NULL;
+
+ printf("%s:%d\n",__FUNCTION__,__LINE__);
+
+ return (cookie);
+}
+
+void
+pciide_machdep_compat_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
+{
+ printf("%s:%d\n",__FUNCTION__,__LINE__);
+}