svn commit: r236537 - projects/altix2/sys/ia64/sgisn

Marcel Moolenaar marcel at FreeBSD.org
Mon Jun 4 06:06:11 UTC 2012


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);
+}


More information about the svn-src-projects mailing list