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/43df1d4b1b5c
branches:  trunk
changeset: 806237:43df1d4b1b5c
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 39ed1562f8ba -r 43df1d4b1b5c 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 39ed1562f8ba -r 43df1d4b1b5c 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