From owner-svn-src-projects@FreeBSD.ORG Mon Jun 4 18:45:18 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A5E03106564A; Mon, 4 Jun 2012 18:45:18 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 90CF38FC17; Mon, 4 Jun 2012 18:45:18 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q54IjIv4058988; Mon, 4 Jun 2012 18:45:18 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q54IjI1S058985; Mon, 4 Jun 2012 18:45:18 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201206041845.q54IjI1S058985@svn.freebsd.org> From: Marcel Moolenaar Date: Mon, 4 Jun 2012 18:45:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r236576 - projects/altix2/sys/kern X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 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: Mon, 04 Jun 2012 18:45:18 -0000 Author: marcel Date: Mon Jun 4 18:45:18 2012 New Revision: 236576 URL: http://svn.freebsd.org/changeset/base/236576 Log: Implement BUSDMA_IOMMU_MAP. We want to map starting with the root and ending with the leaf. In other words, we want to map top-down (root to leaf) and not bottom-up (learfd to root). Given that we have a fairly shallow device tree, use recursion to walk up to the root first and then call the BUSDMA_IOMMU_MAP on the device on the way back down (i.e. while unwinding from the recursion. At the root, bus addresses are the same as CPU (physical addresses), so we assign the CPU address to the bus address. Modified: projects/altix2/sys/kern/busdma_if.m projects/altix2/sys/kern/subr_busdma.c Modified: projects/altix2/sys/kern/busdma_if.m ============================================================================== --- projects/altix2/sys/kern/busdma_if.m Mon Jun 4 18:43:51 2012 (r236575) +++ projects/altix2/sys/kern/busdma_if.m Mon Jun 4 18:45:18 2012 (r236576) @@ -38,6 +38,12 @@ CODE { { return (0); } + + static int + default_iommu_map_unmap(device_t dev, busdma_md_t md) + { + return (0); + } }; METHOD int iommu_xlate { @@ -48,9 +54,9 @@ METHOD int iommu_xlate { METHOD int iommu_map { device_t dev; busdma_md_t md; -}; +} DEFAULT default_iommu_map_unmap; METHOD int iommu_unmap { device_t dev; busdma_md_t md; -}; +} DEFAULT default_iommu_map_unmap; Modified: projects/altix2/sys/kern/subr_busdma.c ============================================================================== --- projects/altix2/sys/kern/subr_busdma.c Mon Jun 4 18:43:51 2012 (r236575) +++ projects/altix2/sys/kern/subr_busdma.c Mon Jun 4 18:45:18 2012 (r236576) @@ -131,15 +131,17 @@ _busdma_tag_dump(const char *func, devic } static void -_busdma_md_dump(const char *func, struct busdma_md *md) +_busdma_md_dump(const char *func, device_t dev, struct busdma_md *md) { struct busdma_tag *tag; struct busdma_md_seg *seg; int idx; tag = md->md_tag; + if (dev == NULL) + dev = tag->dt_device; printf("[%s: %s: md=%p (tag=%p, flags=%x, nsegs=%u)", func, - device_get_nameunit(tag->dt_device), md, tag, md->md_flags, + device_get_nameunit(dev), md, tag, md->md_flags, md->md_nsegs); if (md->md_nsegs == 0) { printf(" -- UNUSED]\n"); @@ -221,12 +223,14 @@ _busdma_md_create(struct busdma_tag *tag } static int -_busdma_iommu_xlate(device_t dev, struct busdma_mtag *mtag) +_busdma_iommu_xlate(device_t leaf, struct busdma_mtag *mtag) { + device_t dev; int error; error = 0; - while (!error && dev != NULL) { + dev = device_get_parent(leaf); + while (!error && dev != root_bus) { _busdma_mtag_dump(__func__, dev, mtag); error = BUSDMA_IOMMU_XLATE(dev, mtag); if (!error) @@ -236,6 +240,44 @@ _busdma_iommu_xlate(device_t dev, struct return (error); } +static int +_busdma_iommu_map_r(device_t dev, struct busdma_md *md) +{ + struct busdma_md_seg *seg; + u_int idx; + int error; + + if (dev == root_bus) { + /* + * A bus address and a physical address are one and the same + * at this level. + */ + for (idx = 0; idx < md->md_nsegs; idx++) { + seg = &md->md_seg[idx]; + seg->mds_busaddr = seg->mds_paddr; + } + _busdma_md_dump(__func__, dev, md); + return (0); + } + + error = _busdma_iommu_map_r(device_get_parent(dev), md); + if (!error) { + error = BUSDMA_IOMMU_MAP(dev, md); + _busdma_md_dump(__func__, dev, md); + } + return (error); +} + +static int +_busdma_iommu_map(device_t leaf, struct busdma_md *md) +{ + int error; + + _busdma_md_dump(__func__, leaf, md); + error = _busdma_iommu_map_r(device_get_parent(leaf), md); + return (error); +} + int busdma_tag_create(device_t dev, bus_addr_t align, bus_addr_t bndry, bus_addr_t maxaddr, bus_size_t maxsz, u_int nsegs, bus_size_t maxsegsz, @@ -298,7 +340,7 @@ busdma_md_create(struct busdma_tag *tag, if (md == NULL) return (ENOMEM); - _busdma_md_dump(__func__, md); + _busdma_md_dump(__func__, NULL, md); *md_p = md; return (0); } @@ -442,16 +484,14 @@ busdma_mem_alloc(struct busdma_tag *tag, goto fail; } seg->mds_paddr = pmap_kextract(seg->mds_vaddr); - seg->mds_busaddr = seg->mds_paddr; maxsz -= seg->mds_size; idx++; } if (maxsz == 0) { md->md_nsegs = idx; - error = BUSDMA_IOMMU_MAP(tag->dt_device, md); + error = _busdma_iommu_map(tag->dt_device, md); if (error) - printf("BUSDMA_IOMMU_MAP: error=%d\n", error); - _busdma_md_dump(__func__, md); + printf("_busdma_iommu_map: error=%d\n", error); *md_p = md; return (0); }