Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc64/dev sun4v: iommu setup seems to work now - ...



details:   https://anonhg.NetBSD.org/src/rev/1aac14d55d74
branches:  trunk
changeset: 340415:1aac14d55d74
user:      palle <palle%NetBSD.org@localhost>
date:      Thu Sep 03 19:43:35 2015 +0000

description:
sun4v: iommu setup seems to work now - device detection is now possible - parts from OpenBSD - ok mrg@, martin@

diffstat:

 sys/arch/sparc64/dev/iommu.c    |  109 +++++++++++++++++++++++++++++++++++----
 sys/arch/sparc64/dev/iommuvar.h |    3 +-
 sys/arch/sparc64/dev/vpci.c     |   80 ++++++++++++++---------------
 3 files changed, 139 insertions(+), 53 deletions(-)

diffs (truncated from 412 to 300 lines):

diff -r 397d7b36bb4b -r 1aac14d55d74 sys/arch/sparc64/dev/iommu.c
--- a/sys/arch/sparc64/dev/iommu.c      Thu Sep 03 15:01:19 2015 +0000
+++ b/sys/arch/sparc64/dev/iommu.c      Thu Sep 03 19:43:35 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommu.c,v 1.108 2014/08/24 19:09:43 palle Exp $        */
+/*     $NetBSD: iommu.c,v 1.109 2015/09/03 19:43:35 palle Exp $        */
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: iommu.c,v 1.108 2014/08/24 19:09:43 palle Exp $");
+__KERNEL_RCSID(0, "$NetBSD: iommu.c,v 1.109 2015/09/03 19:43:35 palle Exp $");
 
 #include "opt_ddb.h"
 
@@ -101,6 +101,10 @@
 static int iommu_strbuf_flush_done(struct strbuf_ctl *);
 static void _iommu_dvmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
                bus_size_t, int);
+static void iommu_enter_sun4u(struct strbuf_ctl *sb, vaddr_t va, int64_t pa, int flags);
+static void iommu_enter_sun4v(struct strbuf_ctl *sb, vaddr_t va, int64_t pa, int flags);
+static void iommu_remove_sun4u(struct iommu_state *is, vaddr_t va, size_t len);
+static void iommu_remove_sun4v(struct iommu_state *is, vaddr_t va, size_t len);
 
 /*
  * initialise the UltraSPARC IOMMU (SBUS or PCI):
@@ -118,6 +122,8 @@
        struct vm_page *pg;
        struct pglist pglist;
 
+       DPRINTF(IDB_INFO, ("iommu_init: tsbsize %x iovabase %x\n", tsbsize, iovabase));
+       
        /*
         * Setup the iommu.
         *
@@ -181,17 +187,18 @@
        if (iommudebug & IDB_INFO)
        {
                /* Probe the iommu */
-
-               printf("iommu cr=%llx tsb=%llx\n",
-                       (unsigned long long)bus_space_read_8(is->is_bustag,
+               if (!CPU_ISSUN4V) {
+                       printf("iommu cr=%llx tsb=%llx\n",
+                           (unsigned long long)bus_space_read_8(is->is_bustag,
                                is->is_iommu,
                                offsetof(struct iommureg, iommu_cr)),
-                       (unsigned long long)bus_space_read_8(is->is_bustag,
+                           (unsigned long long)bus_space_read_8(is->is_bustag,
                                is->is_iommu,
                                offsetof(struct iommureg, iommu_tsb)));
-               printf("TSB base %p phys %llx\n", (void *)is->is_tsb,
-                       (unsigned long long)is->is_ptsb);
-               delay(1000000); /* 1 s */
+                       printf("TSB base %p phys %llx\n", (void *)is->is_tsb,
+                           (unsigned long long)is->is_ptsb);
+                       delay(1000000); /* 1 s */
+               }
        }
 #endif
 
@@ -207,8 +214,9 @@
        is->is_dvmamap = extent_create(name,
            is->is_dvmabase, is->is_dvmaend,
            0, 0, EX_NOWAIT);
-       /* XXXMRG Check is_dvmamap is valid. */
-
+       if (!is->is_dvmamap)
+               panic("iommu_init: extent_create() failed");
+         
        mutex_init(&is->is_lock, MUTEX_DEFAULT, IPL_HIGH);
 
        /*
@@ -237,6 +245,9 @@
        int i;
        struct strbuf_ctl *sb;
 
+       if (CPU_ISSUN4V)
+               return;
+       
        IOMMUREG_WRITE(is, iommu_tsb, is->is_ptsb);
 
        /* Enable IOMMU in diagnostic mode */
@@ -276,9 +287,22 @@
 /*
  * Here are the iommu control routines.
  */
+
 void
 iommu_enter(struct strbuf_ctl *sb, vaddr_t va, int64_t pa, int flags)
 {
+       DPRINTF(IDB_IOMMU, ("iommu_enter: va %lx pa %lx flags %x\n",
+           va, (long)pa, flags));
+       if (!CPU_ISSUN4V)
+               iommu_enter_sun4u(sb, va, pa, flags);
+       else
+               iommu_enter_sun4v(sb, va, pa, flags);
+}
+
+
+void
+iommu_enter_sun4u(struct strbuf_ctl *sb, vaddr_t va, int64_t pa, int flags)
+{
        struct iommu_state *is = sb->sb_is;
        int strbuf = (flags & BUS_DMA_STREAMING);
        int64_t tte;
@@ -311,6 +335,35 @@
                (u_long)tte));
 }
 
+void
+iommu_enter_sun4v(struct strbuf_ctl *sb, vaddr_t va, int64_t pa, int flags)
+{
+       struct iommu_state *is = sb->sb_is;
+       u_int64_t tsbid = IOTSBSLOT(va, is->is_tsbsize);
+       paddr_t page_list[1], addr;
+       u_int64_t attr, nmapped;
+       int err;
+
+#ifdef DIAGNOSTIC
+       if (va < is->is_dvmabase || (va + PAGE_MASK) > is->is_dvmaend)
+               panic("viommu_enter: va %#lx not in DVMA space", va);
+#endif
+
+       attr = PCI_MAP_ATTR_READ | PCI_MAP_ATTR_WRITE;
+       if (flags & BUS_DMA_READ)
+               attr &= ~PCI_MAP_ATTR_READ;
+       if (flags & BUS_DMA_WRITE)
+               attr &= ~PCI_MAP_ATTR_WRITE;
+
+       page_list[0] = trunc_page(pa);
+       if (!pmap_extract(pmap_kernel(), (vaddr_t)page_list, &addr))
+               panic("viommu_enter: pmap_extract failed");
+       err = hv_pci_iommu_map(is->is_devhandle, tsbid, 1, attr,
+           addr, &nmapped);
+       if (err != H_EOK || nmapped != 1)
+               panic("hv_pci_iommu_map: err=%d, nmapped=%lu", err, (long unsigned int)nmapped);
+}
+
 /*
  * Find the value of a DVMA address (debug routine).
  */
@@ -334,9 +387,22 @@
  *
  * XXX: this function needs better internal error checking.
  */
+
+
 void
 iommu_remove(struct iommu_state *is, vaddr_t va, size_t len)
 {
+       DPRINTF(IDB_IOMMU, ("iommu_remove: va %lx len %zu\n", va, len));
+       if (!CPU_ISSUN4V)
+               iommu_remove_sun4u(is, va, len);
+       else
+               iommu_remove_sun4v(is, va, len);
+}
+
+void
+iommu_remove_sun4u(struct iommu_state *is, vaddr_t va, size_t len)
+{
+
        int slot;
 
 #ifdef DIAGNOSTIC
@@ -389,6 +455,27 @@
        }
 }
 
+void
+iommu_remove_sun4v(struct iommu_state *is, vaddr_t va, size_t len)
+{
+       u_int64_t tsbid = IOTSBSLOT(va, is->is_tsbsize);
+       u_int64_t ndemapped;
+       int err;
+
+#ifdef DIAGNOSTIC
+       if (va < is->is_dvmabase || (va + PAGE_MASK) > is->is_dvmaend)
+               panic("iommu_remove: va 0x%lx not in DVMA space", (u_long)va);
+       if (va != trunc_page(va)) {
+               printf("iommu_remove: unaligned va: %lx\n", va);
+               va = trunc_page(va);
+       }
+#endif
+
+       err = hv_pci_iommu_demap(is->is_devhandle, tsbid, 1, &ndemapped);
+       if (err != H_EOK || ndemapped != 1)
+               panic("hv_pci_iommu_unmap: err=%d", err);
+}
+
 static int
 iommu_strbuf_flush_done(struct strbuf_ctl *sb)
 {
diff -r 397d7b36bb4b -r 1aac14d55d74 sys/arch/sparc64/dev/iommuvar.h
--- a/sys/arch/sparc64/dev/iommuvar.h   Thu Sep 03 15:01:19 2015 +0000
+++ b/sys/arch/sparc64/dev/iommuvar.h   Thu Sep 03 19:43:35 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iommuvar.h,v 1.21 2012/03/25 03:51:33 mrg Exp $        */
+/*     $NetBSD: iommuvar.h,v 1.22 2015/09/03 19:43:35 palle Exp $      */
 
 /*
  * Copyright (c) 1999 Matthew R. Green
@@ -65,6 +65,7 @@
        /* copies of our parents state, to allow us to be self contained */
        bus_space_tag_t         is_bustag;      /* our bus tag */
        bus_space_handle_t      is_iommu;       /* IOMMU registers */
+       uint64_t                is_devhandle;   /* for sun4v hypervisor calls */
 };
 
 /* interfaces for PCI/SBUS code */
diff -r 397d7b36bb4b -r 1aac14d55d74 sys/arch/sparc64/dev/vpci.c
--- a/sys/arch/sparc64/dev/vpci.c       Thu Sep 03 15:01:19 2015 +0000
+++ b/sys/arch/sparc64/dev/vpci.c       Thu Sep 03 19:43:35 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vpci.c,v 1.1 2015/02/12 04:48:37 palle Exp $   */
+/*     $NetBSD: vpci.c,v 1.2 2015/09/03 19:43:35 palle Exp $   */
 /*
  * Copyright (c) 2015 Palle Lyckegaard
  * All rights reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vpci.c,v 1.1 2015/02/12 04:48:37 palle Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vpci.c,v 1.2 2015/09/03 19:43:35 palle Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -56,11 +56,13 @@
 #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 VDB_PROM             0x01
+#define VDB_BUSMAP           0x02
+#define VDB_INTR             0x04
+#define VDB_CONF_READ        0x08
+#define VDB_CONF_WRITE       0x10
+#define VDB_CONF             VDB_CONF_READ|VDB_CONF_WRITE
+int vpci_debug = 0x00;
 #define DPRINTF(l, s)   do { if (vpci_debug & l) printf s; } while (0)
 #else
 #define DPRINTF(l, s)
@@ -94,10 +96,7 @@
     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 *);
@@ -233,20 +232,9 @@
                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);
@@ -284,14 +272,15 @@
        config_found(sc->sc_dev, &pba, vpci_print);
 }
 
-#if 0
-FIXME  
 void
 vpci_init_iommu(struct vpci_softc *sc, struct vpci_pbm *pbm)
 {
        struct iommu_state *is = &pbm->vp_is;
-       int tsbsize = 7;
+       int *vdma = NULL;
+       int nitem;
+       int tsbsize = 0;
        u_int32_t iobase = -1;
+       u_int32_t iolen = 0;



Home | Main Index | Thread Index | Old Index