From owner-svn-src-projects@FreeBSD.ORG Sat Nov 16 20:42:29 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 08FEEA5; Sat, 16 Nov 2013 20:42:29 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id DA8DC2479; Sat, 16 Nov 2013 20:42:28 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rAGKgSmZ063260; Sat, 16 Nov 2013 20:42:28 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rAGKgReS063249; Sat, 16 Nov 2013 20:42:27 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201311162042.rAGKgReS063249@svn.freebsd.org> From: Marcel Moolenaar Date: Sat, 16 Nov 2013 20:42:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r258236 - in projects/altix2/sys/sparc64: include pci sbus sparc64 X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Nov 2013 20:42:29 -0000 Author: marcel Date: Sat Nov 16 20:42:26 2013 New Revision: 258236 URL: http://svnweb.freebsd.org/changeset/base/258236 Log: Add support to busdma/mi to host controllers that have or need I/O MMU support. Since all host controllers use the same I/O MMU implementation, have it implement the busdma I/F methods directly. For this to work, we need to be able to get from the device to the iommu_state structure. We do this by using the softc as an indirection. The device_get_softc() returns the softc of the host controller driver. By forcing the first field in that structure to point to the iommu state structure that goes with the device, we established the indirection. Implement iommu_xlate(). It does nothing anyway. Start some trivial bits in iommu_sync(), but not yet the important parts. The iommu_map() and iommu_unmap() methods are saved for last. The intend is to have the new methods work alongside the existing functions. This way isp(4), which uses busdma/mi, works alongside gem(4) which uses the old busdma code. Modified: projects/altix2/sys/sparc64/include/iommuvar.h projects/altix2/sys/sparc64/pci/fire.c projects/altix2/sys/sparc64/pci/firevar.h projects/altix2/sys/sparc64/pci/psycho.c projects/altix2/sys/sparc64/pci/psychovar.h projects/altix2/sys/sparc64/pci/schizo.c projects/altix2/sys/sparc64/pci/schizovar.h projects/altix2/sys/sparc64/sbus/sbus.c projects/altix2/sys/sparc64/sparc64/iommu.c Modified: projects/altix2/sys/sparc64/include/iommuvar.h ============================================================================== --- projects/altix2/sys/sparc64/include/iommuvar.h Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/include/iommuvar.h Sat Nov 16 20:42:26 2013 (r258236) @@ -108,6 +108,12 @@ void iommu_init(const char *name, struct void iommu_reset(struct iommu_state *is); void iommu_decode_fault(struct iommu_state *is, vm_offset_t phys); +/* busdma I/O MMU methods. */ +int iommu_xlate(device_t, device_t, busdma_mtag_t); +int iommu_map(device_t, device_t, busdma_md_t, u_int, bus_addr_t *); +int iommu_unmap(device_t, device_t, busdma_md_t, u_int); +int iommu_sync(device_t, device_t, busdma_md_t, u_int, bus_addr_t, bus_size_t); + extern struct bus_dma_methods iommu_dma_methods; #endif /* !_MACHINE_IOMMUVAR_H_ */ Modified: projects/altix2/sys/sparc64/pci/fire.c ============================================================================== --- projects/altix2/sys/sparc64/pci/fire.c Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/pci/fire.c Sat Nov 16 20:42:26 2013 (r258236) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -81,6 +82,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include "busdma_if.h" #include "pcib_if.h" struct fire_msiqarg; @@ -164,6 +166,12 @@ static device_method_t fire_methods[] = /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_node, fire_get_node), + /* busdma I/O MMU interface. */ + DEVMETHOD(busdma_iommu_xlate, iommu_xlate), + DEVMETHOD(busdma_iommu_map, iommu_map), + DEVMETHOD(busdma_iommu_unmap, iommu_unmap), + DEVMETHOD(busdma_iommu_sync, iommu_sync), + DEVMETHOD_END }; @@ -701,6 +709,7 @@ fire_attach(device_t dev) */ memcpy(&sc->sc_dma_methods, &iommu_dma_methods, sizeof(sc->sc_dma_methods)); + sc->sc_is_ptr = &sc->sc_is; /* For busdma/mi */ sc->sc_is.is_flags = IOMMU_FIRE | IOMMU_PRESERVE_PROM; if (sc->sc_mode == FIRE_MODE_OBERON) { sc->sc_is.is_flags |= IOMMU_FLUSH_CACHE; Modified: projects/altix2/sys/sparc64/pci/firevar.h ============================================================================== --- projects/altix2/sys/sparc64/pci/firevar.h Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/pci/firevar.h Sat Nov 16 20:42:26 2013 (r258236) @@ -32,6 +32,12 @@ #define _SPARC64_PCI_FIREVAR_H_ struct fire_softc { + /* + * The iommu state pointer must be the first field + * in the softc so that the iommu code can get to + * it from within the busdma I/F methods. + */ + struct iommu_state *sc_is_ptr; struct iommu_state sc_is; struct bus_dma_methods sc_dma_methods; Modified: projects/altix2/sys/sparc64/pci/psycho.c ============================================================================== --- projects/altix2/sys/sparc64/pci/psycho.c Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/pci/psycho.c Sat Nov 16 20:42:26 2013 (r258236) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -75,6 +76,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include "busdma_if.h" #include "pcib_if.h" static const struct psycho_desc *psycho_find_desc(const struct psycho_desc *, @@ -154,6 +156,12 @@ static device_method_t psycho_methods[] /* ofw_pci interface */ DEVMETHOD(ofw_pci_setup_device, psycho_setup_device), + /* busdma I/O MMU interface. */ + DEVMETHOD(busdma_iommu_xlate, iommu_xlate), + DEVMETHOD(busdma_iommu_map, iommu_map), + DEVMETHOD(busdma_iommu_unmap, iommu_unmap), + DEVMETHOD(busdma_iommu_sync, iommu_sync), + DEVMETHOD_END }; Modified: projects/altix2/sys/sparc64/pci/psychovar.h ============================================================================== --- projects/altix2/sys/sparc64/pci/psychovar.h Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/pci/psychovar.h Sat Nov 16 20:42:26 2013 (r258236) @@ -36,6 +36,12 @@ * per pair of psychos. */ struct psycho_softc { + /* + * The iommu state pointer must be the first field + * in the softc so that the iommu code can get to + * it from within the busdma I/F methods. + */ + struct iommu_state *sc_is; struct bus_dma_methods *sc_dma_methods; device_t sc_dev; @@ -55,8 +61,6 @@ struct psycho_softc { /* Bus A or B of a psycho pair? */ u_int sc_half; - struct iommu_state *sc_is; - struct resource *sc_mem_res; struct resource *sc_irq_res[PSYCHO_NINTR]; void *sc_ihand[PSYCHO_NINTR]; Modified: projects/altix2/sys/sparc64/pci/schizo.c ============================================================================== --- projects/altix2/sys/sparc64/pci/schizo.c Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/pci/schizo.c Sat Nov 16 20:42:26 2013 (r258236) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -75,6 +76,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include "busdma_if.h" #include "pcib_if.h" static const struct schizo_desc *schizo_get_desc(device_t); @@ -152,6 +154,12 @@ static device_method_t schizo_methods[] /* ofw_pci interface */ DEVMETHOD(ofw_pci_setup_device, schizo_setup_device), + /* busdma I/O MMU interface. */ + DEVMETHOD(busdma_iommu_xlate, iommu_xlate), + DEVMETHOD(busdma_iommu_map, iommu_map), + DEVMETHOD(busdma_iommu_unmap, iommu_unmap), + DEVMETHOD(busdma_iommu_sync, iommu_sync), + DEVMETHOD_END }; @@ -506,6 +514,7 @@ schizo_attach(device_t dev) */ memcpy(&sc->sc_dma_methods, &iommu_dma_methods, sizeof(sc->sc_dma_methods)); + sc->sc_is_ptr = &sc->sc_is.sis_is; /* For busdma/mi */ sc->sc_is.sis_sc = sc; sc->sc_is.sis_is.is_flags = IOMMU_PRESERVE_PROM; sc->sc_is.sis_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS); Modified: projects/altix2/sys/sparc64/pci/schizovar.h ============================================================================== --- projects/altix2/sys/sparc64/pci/schizovar.h Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/pci/schizovar.h Sat Nov 16 20:42:26 2013 (r258236) @@ -39,6 +39,12 @@ struct schizo_iommu_state { }; struct schizo_softc { + /* + * The iommu state pointer must be the first field + * in the softc so that the iommu code can get to + * it from within the busdma I/F methods. + */ + struct iommu_state *sc_is_ptr; struct bus_dma_methods sc_dma_methods; device_t sc_dev; Modified: projects/altix2/sys/sparc64/sbus/sbus.c ============================================================================== --- projects/altix2/sys/sparc64/sbus/sbus.c Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/sbus/sbus.c Sat Nov 16 20:42:26 2013 (r258236) @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -84,6 +85,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "busdma_if.h" + struct sbus_devinfo { int sdi_burstsz; int sdi_clockfreq; @@ -106,6 +109,13 @@ struct sbus_rd { }; struct sbus_softc { + /* + * The iommu state pointer must be the first field + * in the softc so that the iommu code can get to + * it from within the busdma I/F methods. + */ + struct iommu_state *sc_is_ptr; + device_t sc_dev; bus_dma_tag_t sc_cdmatag; int sc_clockfreq; /* clock frequency (in Hz) */ @@ -188,6 +198,12 @@ static device_method_t sbus_methods[] = DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), + /* busdma I/O MMU interface. */ + DEVMETHOD(busdma_iommu_xlate, iommu_xlate), + DEVMETHOD(busdma_iommu_map, iommu_map), + DEVMETHOD(busdma_iommu_unmap, iommu_unmap), + DEVMETHOD(busdma_iommu_sync, iommu_sync), + DEVMETHOD_END }; @@ -344,6 +360,7 @@ sbus_attach(device_t dev) /* initalise the IOMMU */ /* punch in our copies */ + sc->sc_is_ptr = &sc->sc_is; /* For busdma/mi */ sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(SBUS_IOMMU_BITS); sc->sc_is.is_bustag = rman_get_bustag(sc->sc_sysio_res); sc->sc_is.is_bushandle = rman_get_bushandle(sc->sc_sysio_res); Modified: projects/altix2/sys/sparc64/sparc64/iommu.c ============================================================================== --- projects/altix2/sys/sparc64/sparc64/iommu.c Sat Nov 16 19:57:56 2013 (r258235) +++ projects/altix2/sys/sparc64/sparc64/iommu.c Sat Nov 16 20:42:26 2013 (r258236) @@ -84,6 +84,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include @@ -1165,6 +1167,53 @@ iommu_dvmamap_sync(bus_dma_tag_t dt, bus membar(Sync); } + + + +int +iommu_xlate(device_t bus __unused, device_t dev __unused, + busdma_mtag_t mtag __unused) +{ + + /* No translation necessary */ + return (0); +} + +int +iommu_map(device_t bus __unused, device_t dev __unused, + busdma_md_t md __unused, u_int idx __unused, bus_addr_t *ba_p __unused) +{ + + return (ENOSYS); +} + +int +iommu_unmap(device_t bus __unused, device_t dev __unused, + busdma_md_t md __unused, u_int idx __unused) +{ + + return (ENOSYS); +} + +int +iommu_sync(device_t bus, device_t dev __unused, + busdma_md_t md __unused, u_int op __unused, bus_addr_t addr __unused, + bus_size_t size __unused) +{ + struct iommu_state *is, **isp; + + isp = device_get_softc(bus); + is = *isp; + + if ((op & BUSDMA_SYNC_PREWRITE) == BUSDMA_SYNC_PREWRITE) + membar(Sync); + + return (0); +} + + + + #ifdef IOMMU_DIAG /*