Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64 sun4v: vpci driver - initial (and incomplet...
details: https://anonhg.NetBSD.org/src/rev/5c680dd62ce4
branches: trunk
changeset: 336095:5c680dd62ce4
user: palle <palle%NetBSD.org@localhost>
date: Thu Feb 12 04:48:37 2015 +0000
description:
sun4v: vpci driver - initial (and incomplete) version of virtual PCIe host bridge driver for sun4v systems. Based on the NetBSD pyro driver and OpenBSD vpci driver. Future work will include
integrating code from the OpenBSD vpci driver.
diffstat:
sys/arch/sparc64/conf/GENERIC | 6 +-
sys/arch/sparc64/dev/vpci.c | 623 +++++++++++++++++++++++++++++++++++++++++
sys/arch/sparc64/dev/vpcivar.h | 76 +++++
3 files changed, 703 insertions(+), 2 deletions(-)
diffs (truncated from 739 to 300 lines):
diff -r 43811470d7b0 -r 5c680dd62ce4 sys/arch/sparc64/conf/GENERIC
--- a/sys/arch/sparc64/conf/GENERIC Wed Feb 11 23:39:07 2015 +0000
+++ b/sys/arch/sparc64/conf/GENERIC Thu Feb 12 04:48:37 2015 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.179 2015/01/07 09:50:05 macallan Exp $
+# $NetBSD: GENERIC,v 1.180 2015/02/12 04:48:37 palle Exp $
#
# GENERIC machine description file
#
@@ -22,7 +22,7 @@
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
-#ident "GENERIC-$Revision: 1.179 $"
+#ident "GENERIC-$Revision: 1.180 $"
maxusers 64
@@ -238,11 +238,13 @@
psycho* at mainbus0 # PCI-based systems
schizo* at mainbus?
pyro* at mainbus?
+vpci* at mainbus0
central* at mainbus?
fhc* at mainbus?
pci* at psycho?
pci* at schizo?
pci* at pyro?
+pci* at vpci?
pci* at ppb?
ppb* at pci?
fhc* at central?
diff -r 43811470d7b0 -r 5c680dd62ce4 sys/arch/sparc64/dev/vpci.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sparc64/dev/vpci.c Thu Feb 12 04:48:37 2015 +0000
@@ -0,0 +1,623 @@
+/* $NetBSD: vpci.c,v 1.1 2015/02/12 04:48:37 palle Exp $ */
+/*
+ * Copyright (c) 2015 Palle Lyckegaard
+ * All rights reserved.
+ *
+ * Driver for virtual PCIe host bridge on sun4v systems.
+ *
+ * Based on NetBSD pyro and OpenBSD vpci drivers.
+ *
+ * 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/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: vpci.c,v 1.1 2015/02/12 04:48:37 palle Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#define _SPARC_BUS_DMA_PRIVATE
+#include <sys/bus.h>
+#include <machine/autoconf.h>
+
+#ifdef DDB
+#include <machine/db_machdep.h>
+#endif
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <sparc64/dev/iommureg.h>
+#include <sparc64/dev/iommuvar.h>
+#include <sparc64/dev/vpcivar.h>
+
+#include <sparc64/hypervisor.h>
+
+#ifdef DEBUG
+#define VDB_PROM 0x01
+#define VDB_BUSMAP 0x02
+#define VDB_INTR 0x04
+#define VDB_CONF 0x08
+int vpci_debug = 0xff;
+#define DPRINTF(l, s) do { if (vpci_debug & l) printf s; } while (0)
+#else
+#define DPRINTF(l, s)
+#endif
+
+#if 0
+FIXME
+#define FIRE_RESET_GEN 0x7010
+
+#define FIRE_RESET_GEN_XIR 0x0000000000000002L
+
+#define FIRE_INTRMAP_INT_CNTRL_NUM_MASK 0x000003c0
+#define FIRE_INTRMAP_INT_CNTRL_NUM0 0x00000040
+#define FIRE_INTRMAP_INT_CNTRL_NUM1 0x00000080
+#define FIRE_INTRMAP_INT_CNTRL_NUM2 0x00000100
+#define FIRE_INTRMAP_INT_CNTRL_NUM3 0x00000200
+#define FIRE_INTRMAP_T_JPID_SHIFT 26
+#define FIRE_INTRMAP_T_JPID_MASK 0x7c000000
+
+#define OBERON_INTRMAP_T_DESTID_SHIFT 21
+#define OBERON_INTRMAP_T_DESTID_MASK 0x7fe00000
+#endif
+
+extern struct sparc_pci_chipset _sparc_pci_chipset;
+
+int vpci_match(device_t, cfdata_t, void *);
+void vpci_attach(device_t, device_t, void *);
+int vpci_print(void *, const char *);
+
+CFATTACH_DECL_NEW(vpci, sizeof(struct vpci_softc),
+ vpci_match, vpci_attach, NULL, NULL);
+
+void vpci_init(struct vpci_softc */*FIXME, int*/, struct mainbus_attach_args *);
+#if 0
+FIXME
+void vpci_init_iommu(struct vpci_softc *, struct vpci_pbm *);
+#endif
+pci_chipset_tag_t vpci_alloc_chipset(struct vpci_pbm *, int,
+ pci_chipset_tag_t);
+bus_space_tag_t vpci_alloc_mem_tag(struct vpci_pbm *);
+bus_space_tag_t vpci_alloc_io_tag(struct vpci_pbm *);
+bus_space_tag_t vpci_alloc_config_tag(struct vpci_pbm *);
+bus_space_tag_t vpci_alloc_bus_tag(struct vpci_pbm *, const char *, int);
+bus_dma_tag_t vpci_alloc_dma_tag(struct vpci_pbm *);
+
+#if 0
+int vpci_conf_size(pci_chipset_tag_t, pcitag_t);
+#endif
+pcireg_t vpci_conf_read(pci_chipset_tag_t, pcitag_t, int);
+void vpci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
+
+static void * vpci_pci_intr_establish(pci_chipset_tag_t pc,
+ pci_intr_handle_t ih, int level,
+ int (*func)(void *), void *arg);
+
+int vpci_intr_map(const struct pci_attach_args *, pci_intr_handle_t *);
+int vpci_bus_map(bus_space_tag_t, bus_addr_t,
+ bus_size_t, int, vaddr_t, bus_space_handle_t *);
+paddr_t vpci_bus_mmap(bus_space_tag_t, bus_addr_t, off_t,
+ int, int);
+void *vpci_intr_establish(bus_space_tag_t, int, int,
+ int (*)(void *), void *, void (*)(void));
+
+int vpci_dmamap_create(bus_dma_tag_t, bus_size_t, int,
+ bus_size_t, bus_size_t, int, bus_dmamap_t *);
+
+int
+vpci_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct mainbus_attach_args *ma = aux;
+ char compat[32];
+
+ if (strcmp(ma->ma_name, "pci") != 0)
+ return (0);
+
+ if (OF_getprop(ma->ma_node, "compatible", compat, sizeof(compat)) == -1)
+ return (0);
+
+ if (strcmp(compat, "SUNW,sun4v-pci") == 0)
+ return (1);
+
+ return (0);
+}
+
+void
+vpci_attach(device_t parent, device_t self, void *aux)
+{
+ struct vpci_softc *sc = device_private(self);
+ struct mainbus_attach_args *ma = aux;
+#if 0
+FIXME
+ char *str;
+ int busa;
+#endif
+ sc->sc_dev = self;
+ sc->sc_node = ma->ma_node;
+ sc->sc_dmat = ma->ma_dmatag;
+ sc->sc_bustag = ma->ma_bustag;
+ sc->sc_csr = ma->ma_reg[0].ur_paddr;
+#if 0
+FIXME
+ sc->sc_xbc = ma->ma_reg[1].ur_paddr;
+ sc->sc_ign = INTIGN(ma->ma_upaid << INTMAP_IGN_SHIFT);
+
+ if ((ma->ma_reg[0].ur_paddr & 0x00700000) == 0x00600000)
+ busa = 1;
+ else
+ busa = 0;
+#endif
+#if 0
+FIXME
+ if (bus_space_map(sc->sc_bustag, sc->sc_csr,
+ ma->ma_reg[0].ur_len, BUS_SPACE_MAP_LINEAR, &sc->sc_csrh)) {
+ printf(": failed to map csr registers\n");
+ return;
+ }
+#endif
+#if 0
+FIXME
+ if (bus_space_map(sc->sc_bustag, sc->sc_xbc,
+ ma->ma_reg[1].ur_len, 0, &sc->sc_xbch)) {
+ printf(": failed to map xbc registers\n");
+ return;
+ }
+
+ str = prom_getpropstring(ma->ma_node, "compatible");
+ if (strcmp(str, "pciex108e,80f8") == 0)
+ sc->sc_oberon = 1;
+
+#endif
+ vpci_init(sc/*FIXME, busa*/, ma);
+}
+
+void
+vpci_init(struct vpci_softc *sc/*FIXME, int busa*/, struct mainbus_attach_args *ma)
+{
+ struct vpci_pbm *pbm;
+ struct pcibus_attach_args pba;
+ int *busranges = NULL, nranges;
+
+ pbm = malloc(sizeof(*pbm), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (pbm == NULL)
+ panic("vpci: can't alloc vpci pbm");
+
+ pbm->vp_sc = sc;
+ pbm->vp_devhandle = (ma->ma_reg[0].ur_paddr >> 32) & 0x0fffffff;
+#if 0
+FiXME
+ pbm->vp_bus_a = busa;
+#endif
+
+ if (prom_getprop(sc->sc_node, "ranges", sizeof(struct vpci_range),
+ &pbm->vp_nrange, (void **)&pbm->vp_range))
+ panic("vpci: can't get ranges");
+ for (int range = 0; range < pbm->vp_nrange; range++)
+ DPRINTF(VDB_PROM,
+ ("\nvpci_attach: range %d cspace %08x "
+ "child_hi %08x child_lo %08x phys_hi %08x phys_lo %08x "
+ "size_hi %08x size_lo %08x", range,
+ pbm->vp_range[range].cspace,
+ pbm->vp_range[range].child_hi,
+ pbm->vp_range[range].child_lo,
+ pbm->vp_range[range].phys_hi,
+ pbm->vp_range[range].phys_lo,
+ pbm->vp_range[range].size_hi,
+ pbm->vp_range[range].size_lo));
+
+ if (prom_getprop(sc->sc_node, "bus-range", sizeof(int), &nranges,
+ (void **)&busranges))
+ panic("vpci: can't get bus-range");
+ for (int range = 0; range < nranges; range++)
+ DPRINTF(VDB_PROM, ("\nvpci_attach: bus-range %d %08x", range, busranges[range]));
+#if 0
+FIXME
+ printf(": \"%s\", rev %d, ign %x, bus %c %d to %d\n",
+ sc->sc_oberon ? "Oberon" : "Fire",
+ prom_getpropint(sc->sc_node, "module-revision#", 0), sc->sc_ign,
+ busa ? 'A' : 'B', busranges[0], busranges[1]);
+#else
+ printf(": ign %x, bus %d to %d\n", sc->sc_ign, busranges[0], busranges[1]);
+#endif
+ printf("%s: ", device_xname(sc->sc_dev));
+#if 0
+FIXME
+ vpci_init_iommu(sc, pbm);
+#endif
+ pbm->vp_memt = vpci_alloc_mem_tag(pbm);
+ pbm->vp_iot = vpci_alloc_io_tag(pbm);
+ pbm->vp_cfgt = vpci_alloc_config_tag(pbm);
+ pbm->vp_dmat = vpci_alloc_dma_tag(pbm);
+ pbm->vp_flags = (pbm->vp_memt ? PCI_FLAGS_MEM_OKAY : 0) |
+ (pbm->vp_iot ? PCI_FLAGS_IO_OKAY : 0);
+#if 0
+FIXME
+ if (bus_space_map(pbm->vp_cfgt, 0, 0x10000000, 0, &pbm->vp_cfgh))
+ panic("vpci: can't map config space");
+#endif
+ pbm->vp_pc = vpci_alloc_chipset(pbm, sc->sc_node, &_sparc_pci_chipset);
+ pbm->vp_pc->spc_busmax = busranges[1];
+ pbm->vp_pc->spc_busnode = malloc(sizeof(*pbm->vp_pc->spc_busnode),
+ M_DEVBUF, M_NOWAIT | M_ZERO);
Home |
Main Index |
Thread Index |
Old Index