Date: Mon, 4 Jun 2012 06:06:10 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r236537 - projects/altix2/sys/ia64/sgisn Message-ID: <201206040606.q5466Ap3008482@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marcel Date: Mon Jun 4 06:06:10 2012 New Revision: 236537 URL: http://svn.freebsd.org/changeset/base/236537 Log: Implement the BUSDMA_IOMMU_XLATE method for the pcib and shub devices: o The pcib device selects between 32-bit or 64-bit direct mapped addresses. For 32-bit this means that the address is limited to 2G. o The shub device limits the addresses to be offsets within an address space and then transposes the range to lie within the cacheable memory space. In combination this guarantees that DMA memory will be allocated from memory local to the device and lie within the 2G translation window for 32-bit direct mapped DMA. Modified: projects/altix2/sys/ia64/sgisn/sgisn_pcib.c projects/altix2/sys/ia64/sgisn/sgisn_shub.c Modified: projects/altix2/sys/ia64/sgisn/sgisn_pcib.c ============================================================================== --- projects/altix2/sys/ia64/sgisn/sgisn_pcib.c Mon Jun 4 06:00:57 2012 (r236536) +++ projects/altix2/sys/ia64/sgisn/sgisn_pcib.c Mon Jun 4 06:06:10 2012 (r236537) @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/malloc.h> #include <sys/bus.h> +#include <sys/busdma.h> #include <sys/pcpu.h> #include <sys/rman.h> @@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcireg.h> #include <dev/pci/pcib_private.h> +#include "busdma_if.h" #include "pcib_if.h" #include <vm/vm.h> @@ -94,6 +96,8 @@ static uint32_t sgisn_pcib_cfgread(devic static void sgisn_pcib_cfgwrite(device_t, u_int, u_int, u_int, u_int, uint32_t, int); +static int sgisn_pcib_iommu_xlate(device_t, busdma_mtag_t); + /* * Bus interface definitions. */ @@ -123,6 +127,9 @@ static device_method_t sgisn_pcib_method DEVMETHOD(pcib_write_config, sgisn_pcib_cfgwrite), DEVMETHOD(pcib_route_interrupt, pcib_route_interrupt), + /* busdma interface */ + DEVMETHOD(busdma_iommu_xlate, sgisn_pcib_iommu_xlate), + { 0, 0 } }; @@ -425,3 +432,16 @@ sgisn_pcib_write_ivar(device_t dev, devi } return (ENOENT); } + +static int +sgisn_pcib_iommu_xlate(device_t dev, busdma_mtag_t mtag) +{ + + /* + * Use a 31-bit direct-mapped window for PCI devices that are not + * 64-bit capable. + */ + if (mtag->dmt_maxaddr < ~0UL) + mtag->dmt_maxaddr &= 0x7fffffffUL; + return (0); +} Modified: projects/altix2/sys/ia64/sgisn/sgisn_shub.c ============================================================================== --- projects/altix2/sys/ia64/sgisn/sgisn_shub.c Mon Jun 4 06:00:57 2012 (r236536) +++ projects/altix2/sys/ia64/sgisn/sgisn_shub.c Mon Jun 4 06:06:10 2012 (r236537) @@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$"); #include <contrib/dev/acpica/include/actables.h> #include <dev/acpica/acpivar.h> +#include "busdma_if.h" + #include <ia64/sgisn/sgisn_shub.h> struct sgisn_shub_softc { @@ -60,7 +62,6 @@ struct sgisn_shub_softc { bus_addr_t sc_mmraddr; bus_space_tag_t sc_tag; bus_space_handle_t sc_hndl; - busdma_tag_t sc_dmatag; u_int sc_domain; u_int sc_hubtype; /* SHub type (0=SHub1, 1=SHub2) */ u_int sc_nasid_mask; @@ -86,6 +87,8 @@ static int sgisn_shub_set_resource(devic u_long); static int sgisn_shub_write_ivar(device_t, device_t, int, uintptr_t); +static int sgisn_shub_iommu_xlate(device_t, busdma_mtag_t); + /* * Bus interface definitions. */ @@ -109,6 +112,9 @@ static device_method_t sgisn_shub_method DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* busdma interface */ + DEVMETHOD(busdma_iommu_xlate, sgisn_shub_iommu_xlate), + { 0, 0 } }; @@ -353,7 +359,6 @@ sgisn_shub_attach(device_t dev) void *ptr; u_long addr; u_int bus, seg, wdgt; - int error; sc = device_get_softc(dev); sc->sc_dev = dev; @@ -398,15 +403,6 @@ sgisn_shub_attach(device_t dev) device_printf(dev, "NASID=%#x\n", sc->sc_nasid); /* - * Create a DMA tag to contribute constraints for our children. - */ - addr = 1UL << (sc->sc_nasid_shft - 2); - error = busdma_tag_create(dev, addr - 1UL, 1, 0, addr, ~0U, addr, 0, - &sc->sc_dmatag); - if (error) - return (error); - - /* * Allocate contiguous memory, local to the SHub, for collecting * SHub information from the PROM and for discovering the PCI * host controllers connected to the SHub. @@ -488,3 +484,28 @@ sgisn_shub_write_ivar(device_t dev, devi __func__, child, ev, value); return (0); } + +static int +sgisn_shub_iommu_xlate(device_t dev, busdma_mtag_t mtag) +{ + struct sgisn_shub_softc *sc; + vm_paddr_t maxaddr; + + sc = device_get_softc(dev); + + /* + * Always limit the maximum address to the maximum offset within + * this node's cacheable memory space. + */ + maxaddr = (1UL << (sc->sc_nasid_shft - 2)) - 1; + if (mtag->dmt_maxaddr > maxaddr) + mtag->dmt_maxaddr = maxaddr; + + /* + * Transpose the address range into the current node's cacheable + * memory space. + */ + mtag->dmt_minaddr += sc->sc_membase; + mtag->dmt_maxaddr += sc->sc_membase; + return (0); +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206040606.q5466Ap3008482>