Module Name: src Committed By: riastradh Date: Sun Dec 19 11:33:31 UTC 2021
Modified Files: src/sys/external/bsd/drm2/dist/drm: drm_prime.c src/sys/external/bsd/drm2/dist/drm/i915: i915_gem_gtt.c i915_gem_gtt.h i915_scatterlist.h i915_vma.h i915_vma_types.h src/sys/external/bsd/drm2/dist/drm/i915/gem: i915_gem_clflush.c i915_gem_dmabuf.c i915_gem_execbuffer.c i915_gem_internal.c i915_gem_mman.c i915_gem_mman.h i915_gem_object.c i915_gem_object.h i915_gem_object_types.h i915_gem_pages.c i915_gem_phys.c i915_gem_pm.c i915_gem_shmem.c i915_gem_stolen.c src/sys/external/bsd/drm2/dist/drm/i915/gt: intel_gtt.h src/sys/external/bsd/drm2/dist/include/drm: drm_cache.h drm_prime.h src/sys/external/bsd/drm2/drm: drm_cache.c src/sys/external/bsd/drm2/include/asm: uaccess.h src/sys/external/bsd/drm2/include/drm: bus_dma_hacks.h src/sys/external/bsd/drm2/include/linux: bitmap.h dma-buf.h dma-mapping.h mutex.h radix-tree.h scatterlist.h src/sys/external/bsd/drm2/linux: files.drmkms_linux linux_dma_buf.c Added Files: src/sys/external/bsd/drm2/linux: linux_sg.c Log Message: drm: Another pass over i915 and some supporting logic. This makes a shim around sg_table, which essentially represents two things: 1. an array of pages (roughly corresponding to bus_dma_segment_t[]) 2. an array of DMA addresses stored in a bus_dmamap_t Both parts are optional; different parts of i915 use sg_tables to pass around one or both of the two parts. This helps to reduce the ifdefs by quite a bit, although it's not always clear which part of an sg_table any particular interface is actually using which is why I was reluctant to do this before. To generate a diff of this commit: cvs rdiff -u -r1.15 -r1.16 src/sys/external/bsd/drm2/dist/drm/drm_prime.c cvs rdiff -u -r1.22 -r1.23 \ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.c cvs rdiff -u -r1.10 -r1.11 \ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.h cvs rdiff -u -r1.5 -r1.6 \ src/sys/external/bsd/drm2/dist/drm/i915/i915_scatterlist.h \ src/sys/external/bsd/drm2/dist/drm/i915/i915_vma.h cvs rdiff -u -r1.3 -r1.4 \ src/sys/external/bsd/drm2/dist/drm/i915/i915_vma_types.h cvs rdiff -u -r1.4 -r1.5 \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_clflush.c \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.h \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pages.c cvs rdiff -u -r1.5 -r1.6 \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_dmabuf.c \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.h \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h cvs rdiff -u -r1.3 -r1.4 \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_execbuffer.c \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.c \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c cvs rdiff -u -r1.6 -r1.7 \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_shmem.c cvs rdiff -u -r1.2 -r1.3 \ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pm.c cvs rdiff -u -r1.10 -r1.11 \ src/sys/external/bsd/drm2/dist/drm/i915/gt/intel_gtt.h cvs rdiff -u -r1.9 -r1.10 \ src/sys/external/bsd/drm2/dist/include/drm/drm_cache.h cvs rdiff -u -r1.6 -r1.7 \ src/sys/external/bsd/drm2/dist/include/drm/drm_prime.h cvs rdiff -u -r1.17 -r1.18 src/sys/external/bsd/drm2/drm/drm_cache.c cvs rdiff -u -r1.9 -r1.10 src/sys/external/bsd/drm2/include/asm/uaccess.h cvs rdiff -u -r1.21 -r1.22 \ src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h cvs rdiff -u -r1.11 -r1.12 src/sys/external/bsd/drm2/include/linux/bitmap.h cvs rdiff -u -r1.10 -r1.11 src/sys/external/bsd/drm2/include/linux/dma-buf.h cvs rdiff -u -r1.8 -r1.9 \ src/sys/external/bsd/drm2/include/linux/dma-mapping.h cvs rdiff -u -r1.16 -r1.17 src/sys/external/bsd/drm2/include/linux/mutex.h cvs rdiff -u -r1.4 -r1.5 src/sys/external/bsd/drm2/include/linux/radix-tree.h cvs rdiff -u -r1.3 -r1.4 \ src/sys/external/bsd/drm2/include/linux/scatterlist.h cvs rdiff -u -r1.31 -r1.32 src/sys/external/bsd/drm2/linux/files.drmkms_linux cvs rdiff -u -r1.9 -r1.10 src/sys/external/bsd/drm2/linux/linux_dma_buf.c cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/linux/linux_sg.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/dist/drm/drm_prime.c diff -u src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.15 src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.16 --- src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.15 Sun Dec 19 11:32:53 2021 +++ src/sys/external/bsd/drm2/dist/drm/drm_prime.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: drm_prime.c,v 1.15 2021/12/19 11:32:53 riastradh Exp $ */ +/* $NetBSD: drm_prime.c,v 1.16 2021/12/19 11:33:30 riastradh Exp $ */ /* * Copyright © 2012 Red Hat @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.15 2021/12/19 11:32:53 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.16 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/export.h> #include <linux/dma-buf.h> @@ -52,72 +52,6 @@ __KERNEL_RCSID(0, "$NetBSD: drm_prime.c, #include <linux/nbsd-namespace.h> -/* - * We use struct sg_table just to pass around an array of pages from - * one device to another in drm prime. Since this is _not_ a complete - * implementation of Linux's sg table abstraction (e.g., it does not - * remember DMA addresses and RAM pages separately, and it doesn't - * support the nested chained iteration of Linux scatterlists), we - * isolate it to this file and make all callers go through a few extra - * subroutines (drm_prime_sg_size, drm_prime_sg_free, &c.) to use it. - * Don't use this outside drm prime! - */ - -struct sg_table { - paddr_t *sgt_pgs; - unsigned sgt_npgs; -}; - -static int -sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages, - unsigned npages, bus_size_t offset, bus_size_t size, gfp_t gfp) -{ - unsigned i; - - KASSERT(offset == 0); - KASSERT(size == npages << PAGE_SHIFT); - - sgt->sgt_pgs = kcalloc(npages, sizeof(sgt->sgt_pgs[0]), gfp); - if (sgt->sgt_pgs == NULL) - return -ENOMEM; - sgt->sgt_npgs = npages; - - for (i = 0; i < npages; i++) - sgt->sgt_pgs[i] = VM_PAGE_TO_PHYS(&pages[i]->p_vmp); - - return 0; -} - -static int -sg_alloc_table_from_bus_dmamem(struct sg_table *sgt, bus_dma_tag_t dmat, - const bus_dma_segment_t *segs, int nsegs, gfp_t gfp) -{ - int ret; - - KASSERT(nsegs > 0); - sgt->sgt_pgs = kcalloc(nsegs, sizeof(sgt->sgt_pgs[0]), gfp); - if (sgt->sgt_pgs == NULL) - return -ENOMEM; - sgt->sgt_npgs = nsegs; - - /* XXX errno NetBSD->Linux */ - ret = -bus_dmamem_export_pages(dmat, segs, nsegs, sgt->sgt_pgs, - sgt->sgt_npgs); - if (ret) - return ret; - - return 0; -} - -static void -sg_free_table(struct sg_table *sgt) -{ - - kfree(sgt->sgt_pgs); - sgt->sgt_pgs = NULL; - sgt->sgt_npgs = 0; -} - #endif /* __NetBSD__ */ /** @@ -827,14 +761,12 @@ struct sg_table *drm_gem_map_dma_buf(str else sgt = obj->dev->driver->gem_prime_get_sg_table(obj); -#ifndef __NetBSD__ /* We map/unmap elsewhere. */ if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, DMA_ATTR_SKIP_CPU_SYNC)) { sg_free_table(sgt); kfree(sgt); sgt = ERR_PTR(-ENOMEM); } -#endif return sgt; } @@ -855,10 +787,8 @@ void drm_gem_unmap_dma_buf(struct dma_bu if (!sgt) return; -#ifndef __NetBSD__ /* We map/unmap elsewhere. */ dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, DMA_ATTR_SKIP_CPU_SYNC); -#endif sg_free_table(sgt); kfree(sgt); } @@ -1111,9 +1041,15 @@ EXPORT_SYMBOL(drm_gem_prime_export); * Drivers must arrange to call drm_prime_gem_destroy() from their * &drm_gem_object_funcs.free hook when using this function. */ +#ifdef __NetBSD__ +struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev, + struct dma_buf *dma_buf, + bus_dma_tag_t attach_dev) +#else struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev, struct dma_buf *dma_buf, struct device *attach_dev) +#endif { struct dma_buf_attachment *attach; struct sg_table *sgt; @@ -1184,7 +1120,11 @@ EXPORT_SYMBOL(drm_gem_prime_import_dev); struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf) { +#ifdef __NetBSD__ + return drm_gem_prime_import_dev(dev, dma_buf, dev->dmat); +#else return drm_gem_prime_import_dev(dev, dma_buf, dev->dev); +#endif } EXPORT_SYMBOL(drm_gem_prime_import); @@ -1218,7 +1158,7 @@ bus_size_t drm_prime_sg_size(struct sg_table *sg) { - return sg->sgt_npgs << PAGE_SHIFT; + return sg->sgl->sg_npgs << PAGE_SHIFT; } void @@ -1235,8 +1175,8 @@ drm_prime_sg_to_bus_dmamem(bus_dma_tag_t { /* XXX errno NetBSD->Linux */ - return -bus_dmamem_import_pages(dmat, segs, nsegs, rsegs, sgt->sgt_pgs, - sgt->sgt_npgs); + return -bus_dmamem_import_pages(dmat, segs, nsegs, rsegs, + sgt->sgl->sg_pgs, sgt->sgl->sg_npgs); } int @@ -1245,10 +1185,10 @@ drm_prime_bus_dmamap_load_sgt(bus_dma_ta { bus_dma_segment_t *segs; bus_size_t size = drm_prime_sg_size(sgt); - int nsegs = sgt->sgt_npgs; + int nsegs = sgt->sgl->sg_npgs; int ret; - segs = kcalloc(sgt->sgt_npgs, sizeof(segs[0]), GFP_KERNEL); + segs = kcalloc(sgt->sgl->sg_npgs, sizeof(segs[0]), GFP_KERNEL); if (segs == NULL) { ret = -ENOMEM; goto out0; @@ -1257,7 +1197,7 @@ drm_prime_bus_dmamap_load_sgt(bus_dma_ta ret = drm_prime_sg_to_bus_dmamem(dmat, segs, nsegs, &nsegs, sgt); if (ret) goto out1; - KASSERT(nsegs <= sgt->sgt_npgs); + KASSERT(nsegs <= sgt->sgl->sg_npgs); /* XXX errno NetBSD->Linux */ ret = -bus_dmamap_load_raw(dmat, map, segs, nsegs, size, @@ -1274,8 +1214,9 @@ drm_prime_sg_importable(bus_dma_tag_t dm { unsigned i; - for (i = 0; i < sgt->sgt_npgs; i++) { - if (bus_dmatag_bounces_paddr(dmat, sgt->sgt_pgs[i])) + for (i = 0; i < sgt->sgl->sg_npgs; i++) { + if (bus_dmatag_bounces_paddr(dmat, + VM_PAGE_TO_PHYS(&sgt->sgl->sg_pgs[i]->p_vmp))) return false; } return true; Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.c:1.22 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.c:1.23 --- src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.c:1.22 Sun Dec 19 11:32:54 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_gtt.c,v 1.22 2021/12/19 11:32:54 riastradh Exp $ */ +/* $NetBSD: i915_gem_gtt.c,v 1.23 2021/12/19 11:33:30 riastradh Exp $ */ // SPDX-License-Identifier: MIT /* @@ -6,7 +6,7 @@ * Copyright © 2020 Intel Corporation */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_gtt.c,v 1.22 2021/12/19 11:32:54 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_gtt.c,v 1.23 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/slab.h> /* fault-inject.h is not standalone! */ @@ -41,23 +41,15 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_gtt #define _PAGE_PAT PTE_PAT /* 0x80 page attribute table on PTE */ #endif -#ifdef __NetBSD__ -int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, - bus_dmamap_t pages) -#else int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) -#endif { do { #ifdef __NetBSD__ - /* - * XXX Not sure whether caller should be passing DMA - * map or page list. - */ - if (bus_dmamap_load_pages(obj->base.dev->dmat, pages, - obj->mm.pagearray, obj->base.size, BUS_DMA_NOWAIT) - == 0) + if (dma_map_sg_attrs(obj->base.dev->dmat, + pages->sgl, pages->nents, + PCI_DMA_BIDIRECTIONAL, + DMA_ATTR_NO_WARN)) return 0; #else if (dma_map_sg_attrs(&obj->base.dev->pdev->dev, @@ -83,17 +75,12 @@ int i915_gem_gtt_prepare_pages(struct dr return -ENOSPC; } -#ifdef __NetBSD__ -void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, - bus_dmamap_t pages) -#else void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) -#endif { struct drm_i915_private *dev_priv = to_i915(obj->base.dev); #ifdef __NetBSD__ - bus_dma_tag_t dmat = dev_priv->drm.dmat; + bus_dma_tag_t kdev = dev_priv->drm.dmat; #else struct device *kdev = &dev_priv->drm.pdev->dev; #endif @@ -109,11 +96,7 @@ void i915_gem_gtt_finish_pages(struct dr } } -#ifdef __NetBSD__ - bus_dmamap_unload(dmat, pages); -#else dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL); -#endif } /** Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.h diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.h:1.10 src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.h:1.11 --- src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.h:1.10 Sun Dec 19 11:31:40 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/i915_gem_gtt.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_gtt.h,v 1.10 2021/12/19 11:31:40 riastradh Exp $ */ +/* $NetBSD: i915_gem_gtt.h,v 1.11 2021/12/19 11:33:30 riastradh Exp $ */ /* SPDX-License-Identifier: MIT */ /* @@ -19,17 +19,10 @@ struct drm_i915_gem_object; struct i915_address_space; -#ifdef __NetBSD__ -int __must_check i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, - bus_dmamap_t pages); -void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, - bus_dmamap_t pages); -#else int __must_check i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, struct sg_table *pages); void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, struct sg_table *pages); -#endif int i915_gem_gtt_reserve(struct i915_address_space *vm, struct drm_mm_node *node, Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_scatterlist.h diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_scatterlist.h:1.5 src/sys/external/bsd/drm2/dist/drm/i915/i915_scatterlist.h:1.6 --- src/sys/external/bsd/drm2/dist/drm/i915/i915_scatterlist.h:1.5 Sun Dec 19 11:11:35 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/i915_scatterlist.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_scatterlist.h,v 1.5 2021/12/19 11:11:35 riastradh Exp $ */ +/* $NetBSD: i915_scatterlist.h,v 1.6 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -15,7 +15,32 @@ #include "i915_gem.h" -#ifdef __linux__ +#ifdef __NetBSD__ + +struct sgt_iter { + unsigned i; +}; + +#define for_each_sgt_page(pp, iter, sgt) \ + for ((iter)->i = 0; \ + ((iter)->i < (sgt)->sgt_npgs \ + ? ((pp) = (sgt)->sgt_pgs[(iter)->i], 1) \ + : 0); \ + (iter)->i++) + +static inline unsigned +i915_sg_page_sizes(struct scatterlist *sg) +{ + unsigned i, page_sizes = 0; + + for (i = 0; i < sg->sg_dmamap->dm_nsegs; i++) + page_sizes |= sg->sg_dmamap->dm_segs[i].ds_len; + + return page_sizes; +} + +#else + /* * Optimised SGL iterator for GEM objects */ @@ -124,6 +149,7 @@ static inline unsigned int i915_sg_segme return size; } + #endif bool i915_sg_trim(struct sg_table *orig_st); Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_vma.h diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_vma.h:1.5 src/sys/external/bsd/drm2/dist/drm/i915/i915_vma.h:1.6 --- src/sys/external/bsd/drm2/dist/drm/i915/i915_vma.h:1.5 Sun Dec 19 11:12:06 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/i915_vma.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_vma.h,v 1.5 2021/12/19 11:12:06 riastradh Exp $ */ +/* $NetBSD: i915_vma.h,v 1.6 2021/12/19 11:33:30 riastradh Exp $ */ /* * Copyright © 2016 Intel Corporation @@ -62,19 +62,21 @@ int __must_check i915_vma_move_to_active #ifdef __linux__ #define __i915_vma_flags(v) ((unsigned long *)&(v)->flags.counter) +#define __i915_vma_flags_const(v) ((const unsigned long *)&(v)->flags.counter) #else #define __i915_vma_flags(v) ((unsigned long *)&(v)->flags) +#define __i915_vma_flags_const(v) ((const unsigned long *)&(v)->flags) #endif -static inline bool i915_vma_is_ggtt(struct i915_vma *vma) +static inline bool i915_vma_is_ggtt(const struct i915_vma *vma) { - return test_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma)); + return test_bit(I915_VMA_GGTT_BIT, __i915_vma_flags_const(vma)); } -static inline bool i915_vma_has_ggtt_write(struct i915_vma *vma) +static inline bool i915_vma_has_ggtt_write(const struct i915_vma *vma) { - return test_bit(I915_VMA_GGTT_WRITE_BIT, __i915_vma_flags(vma)); + return test_bit(I915_VMA_GGTT_WRITE_BIT, __i915_vma_flags_const(vma)); } static inline void i915_vma_set_ggtt_write(struct i915_vma *vma) @@ -91,9 +93,9 @@ static inline bool i915_vma_unset_ggtt_w void i915_vma_flush_writes(struct i915_vma *vma); -static inline bool i915_vma_is_map_and_fenceable(struct i915_vma *vma) +static inline bool i915_vma_is_map_and_fenceable(const struct i915_vma *vma) { - return test_bit(I915_VMA_CAN_FENCE_BIT, __i915_vma_flags(vma)); + return test_bit(I915_VMA_CAN_FENCE_BIT, __i915_vma_flags_const(vma)); } static inline bool i915_vma_set_userfault(struct i915_vma *vma) @@ -107,17 +109,17 @@ static inline void i915_vma_unset_userfa return clear_bit(I915_VMA_USERFAULT_BIT, __i915_vma_flags(vma)); } -static inline bool i915_vma_has_userfault(struct i915_vma *vma) +static inline bool i915_vma_has_userfault(const struct i915_vma *vma) { - return test_bit(I915_VMA_USERFAULT_BIT, __i915_vma_flags(vma)); + return test_bit(I915_VMA_USERFAULT_BIT, __i915_vma_flags_const(vma)); } -static inline bool i915_vma_is_closed(struct i915_vma *vma) +static inline bool i915_vma_is_closed(const struct i915_vma *vma) { return !list_empty(&vma->closed_link); } -static inline u32 i915_ggtt_offset(struct i915_vma *vma) +static inline u32 i915_ggtt_offset(const struct i915_vma *vma) { GEM_BUG_ON(!i915_vma_is_ggtt(vma)); GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); @@ -126,7 +128,7 @@ static inline u32 i915_ggtt_offset(struc return lower_32_bits(vma->node.start); } -static inline u32 i915_ggtt_pin_bias(struct i915_vma *vma) +static inline u32 i915_ggtt_pin_bias(const struct i915_vma *vma) { return i915_vm_to_ggtt(vma->vm)->pin_bias; } @@ -322,9 +324,7 @@ static inline struct page *i915_vma_firs { GEM_BUG_ON(!vma->pages); #ifdef __NetBSD__ - GEM_BUG_ON(!vma->segs); - return container_of(PHYS_TO_VM_PAGE(vma->segs[0].ds_addr), struct page, - p_vmp); + return vma->pages->sgl->sg_pgs[0]; #else return sg_page(vma->pages->sgl); #endif Index: src/sys/external/bsd/drm2/dist/drm/i915/i915_vma_types.h diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_vma_types.h:1.3 src/sys/external/bsd/drm2/dist/drm/i915/i915_vma_types.h:1.4 --- src/sys/external/bsd/drm2/dist/drm/i915/i915_vma_types.h:1.3 Sun Dec 19 01:24:26 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/i915_vma_types.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_vma_types.h,v 1.3 2021/12/19 01:24:26 riastradh Exp $ */ +/* $NetBSD: i915_vma_types.h,v 1.4 2021/12/19 11:33:30 riastradh Exp $ */ /* SPDX-License-Identifier: MIT */ /* @@ -183,13 +183,7 @@ struct i915_vma { struct drm_i915_gem_object *obj; struct dma_resv *resv; /** Alias of obj->resv */ -#ifdef __NetBSD__ - bus_dma_segment_t *segs; - int nsegs; - bus_dmamap_t pages; -#else struct sg_table *pages; -#endif void __iomem *iomap; void *private; /* owned by creator */ Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_clflush.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_clflush.c:1.4 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_clflush.c:1.5 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_clflush.c:1.4 Sun Dec 19 11:32:53 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_clflush.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_clflush.c,v 1.4 2021/12/19 11:32:53 riastradh Exp $ */ +/* $NetBSD: i915_gem_clflush.c,v 1.5 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_clflush.c,v 1.4 2021/12/19 11:32:53 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_clflush.c,v 1.5 2021/12/19 11:33:30 riastradh Exp $"); #include "display/intel_frontbuffer.h" @@ -24,11 +24,7 @@ struct clflush { static void __do_clflush(struct drm_i915_gem_object *obj) { GEM_BUG_ON(!i915_gem_object_has_pages(obj)); -#ifdef __NetBSD__ - drm_clflush_pages(obj->mm.pagearray, obj->base.size >> PAGE_SHIFT); -#else drm_clflush_sg(obj->mm.pages); -#endif i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); } Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.h diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.h:1.4 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.h:1.5 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.h:1.4 Sun Dec 19 11:10:56 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_object.h,v 1.4 2021/12/19 11:10:56 riastradh Exp $ */ +/* $NetBSD: i915_gem_object.h,v 1.5 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -37,11 +37,7 @@ i915_gem_object_create_shmem_from_data(s extern const struct drm_i915_gem_object_ops i915_gem_shmem_ops; void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, -#ifdef __NetBSD__ - bus_dmamap_t pages, -#else struct sg_table *pages, -#endif bool needs_clflush); int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align); @@ -280,13 +276,8 @@ i915_gem_object_get_dma_address(struct d unsigned long n); void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, -#ifdef __NetBSD__ - bus_dmamap_t pages -#else struct sg_table *pages, - unsigned int sg_page_sizes -#endif - ); + unsigned int sg_page_sizes); int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj); int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj); Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pages.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pages.c:1.4 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pages.c:1.5 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pages.c:1.4 Sun Dec 19 01:34:08 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pages.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_pages.c,v 1.4 2021/12/19 01:34:08 riastradh Exp $ */ +/* $NetBSD: i915_gem_pages.c,v 1.5 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_pages.c,v 1.4 2021/12/19 01:34:08 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_pages.c,v 1.5 2021/12/19 11:33:30 riastradh Exp $"); #include "i915_drv.h" #include "i915_gem_object.h" @@ -15,14 +15,14 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_pag #include "i915_gem_lmem.h" #include "i915_gem_mman.h" -void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, #ifdef __NetBSD__ - bus_dmamap_t pages, -#else - struct sg_table *pages, - unsigned int sg_page_sizes +#include <sys/param.h> +#include <uvm/uvm_extern.h> #endif - ) + +void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, + struct sg_table *pages, + unsigned int sg_page_sizes) { struct drm_i915_private *i915 = to_i915(obj->base.dev); unsigned long supported = INTEL_INFO(i915)->page_sizes; @@ -55,10 +55,8 @@ void __i915_gem_object_set_pages(struct obj->mm.quirked = true; } -#ifndef __NetBSD__ GEM_BUG_ON(!sg_page_sizes); obj->mm.page_sizes.phys = sg_page_sizes; -#endif /* * Calculate the supported page-sizes which fit into the given @@ -172,10 +170,14 @@ static void __i915_gem_object_reset_page static void unmap_object(struct drm_i915_gem_object *obj, void *ptr) { +#ifdef __NetBSD__ + uvm_km_free(kernel_map, (vaddr_t)ptr, obj->base.size, UVM_KMF_VAONLY); +#else if (is_vmalloc_addr(ptr)) vunmap(ptr); else kunmap(kmap_to_page(ptr)); +#endif } struct sg_table * @@ -248,17 +250,67 @@ unlock: return err; } +#ifndef __NetBSD__ static inline pte_t iomap_pte(resource_size_t base, dma_addr_t offset, pgprot_t prot) { return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot)); } +#endif /* The 'mapping' part of i915_gem_object_pin_map() below */ static void *i915_gem_object_map(struct drm_i915_gem_object *obj, enum i915_map_type type) { +#ifdef __NetBSD__ + vaddr_t va; + struct page *page; + paddr_t pa; + unsigned i; + int kmflags = UVM_KMF_VAONLY|UVM_KMF_WAITVA; + int prot = VM_PROT_READ|VM_PROT_WRITE; + int flags = 0; + + /* + * XXX Be nice if we had bus_dmamem segments so we could use + * bus_dmamem_map, but we don't so we can't. + */ + + /* Verify the object is reasonable to map. */ + /* XXX sync with below */ + if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC) + return NULL; + + /* Incorporate mapping type into pmap flags. */ + switch (type) { + case I915_MAP_WC: + flags |= PMAP_WRITE_COMBINE; + break; + case I915_MAP_WB: + default: + break; + } + + /* Allow failure if >1 page. */ + if (obj->base.size > PAGE_SIZE) + kmflags |= UVM_KMF_CANFAIL; + + /* Allocate a contiguous chunk of KVA. */ + va = uvm_km_alloc(kernel_map, obj->base.size, PAGE_SIZE, kmflags); + if (va == 0) + return NULL; + + /* Wire the KVA to the right physical addresses. */ + for (i = 0; i < obj->base.size >> PAGE_SHIFT; i++) { + page = obj->mm.pages->sgl->sg_pgs[i]; + pa = VM_PAGE_TO_PHYS(&page->p_vmp); + pmap_kenter_pa(va + i*PAGE_SIZE, pa, prot, flags); + } + pmap_update(pmap_kernel()); + + return (void *)va; +#else unsigned long n_pte = obj->base.size >> PAGE_SHIFT; struct sg_table *sgt = obj->mm.pages; pte_t *stack[32], **mem; @@ -323,6 +375,7 @@ static void *i915_gem_object_map(struct kvfree(mem); return area->addr; +#endif } /* get, pin, and map the pages of the object into kernel space */ @@ -540,28 +593,9 @@ struct page * i915_gem_object_get_page(struct drm_i915_gem_object *obj, unsigned int n) { #ifdef __NetBSD__ - struct vm_page *page; - - if (obj->phys_handle) { - vaddr_t va = (vaddr_t)obj->phys_handle->vaddr; - paddr_t pa; - if (!pmap_extract(pmap_kernel(), va + n*PAGE_SIZE, &pa)) - panic("i915 gem object phys-attached but not mapped:" - " obj=%p pgno=%d va=%p", obj, n, - obj->phys_handle->vaddr); - page = PHYS_TO_VM_PAGE(pa); - } else { - /* - * Pages must be pinned so that we need not hold the - * lock to prevent them from disappearing. - */ - KASSERT(obj->mm.pages != NULL); - mutex_enter(obj->base.filp->vmobjlock); - page = uvm_pagelookup(obj->base.filp, ptoa(n)); - mutex_exit(obj->base.filp->vmobjlock); - } - KASSERT(page != NULL); - return container_of(page, struct page, p_vmp); + GEM_BUG_ON(!i915_gem_object_has_struct_page(obj)); + KASSERT(n < obj->mm.pages->sgl->sg_npgs); + return obj->mm.pages->sgl->sg_pgs[n]; #else struct scatterlist *sg; unsigned int offset; @@ -593,13 +627,16 @@ i915_gem_object_get_dma_address_len(stru unsigned int *len) { #ifdef __NetBSD__ + bus_dmamap_t map = obj->mm.pages->sgl->sg_dmamap; bus_addr_t poff = (bus_addr_t)n << PAGE_SHIFT; unsigned seg; - for (seg = 0; seg < obj->mm.pages->dm_nsegs; seg++) { - if (poff <= obj->mm.pages->dm_segs[seg].ds_len) - return obj->mm.pages->dm_segs[seg].ds_addr + poff; - poff -= obj->mm.pages->dm_segs[seg].ds_len; + for (seg = 0; seg < map->dm_nsegs; seg++) { + if (poff < map->dm_segs[seg].ds_len) { + *len = map->dm_segs[seg].ds_len - poff; + return map->dm_segs[seg].ds_addr + poff; + } + poff -= map->dm_segs[seg].ds_len; } KASSERT(0); return 0; Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_dmabuf.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_dmabuf.c:1.5 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_dmabuf.c:1.6 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_dmabuf.c:1.5 Sun Dec 19 11:32:53 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_dmabuf.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_dmabuf.c,v 1.5 2021/12/19 11:32:53 riastradh Exp $ */ +/* $NetBSD: i915_gem_dmabuf.c,v 1.6 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_dmabuf.c,v 1.5 2021/12/19 11:32:53 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_dmabuf.c,v 1.6 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/dma-buf.h> #include <linux/highmem.h> @@ -29,23 +29,13 @@ static struct sg_table *i915_gem_map_dma { struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf); struct sg_table *st; -#ifdef __NetBSD__ - int ret; -#else struct scatterlist *src, *dst; int ret, i; -#endif ret = i915_gem_object_pin_pages(obj); if (ret) goto err; -#ifdef __NetBSD__ - st = drm_prime_pages_to_sg(obj->mm.pagearray, - obj->base.size >> PAGE_SHIFT); - if (IS_ERR(st)) - goto err_unpin_pages; -#else /* Copy sg so that we make an independent mapping */ st = kmalloc(sizeof(struct sg_table), GFP_KERNEL); if (st == NULL) { @@ -57,6 +47,14 @@ static struct sg_table *i915_gem_map_dma if (ret) goto err_free; +#ifdef __NetBSD__ + __USE(i); + __USE(src); + __USE(dst); + memcpy(st->sgl->sg_pgs, obj->mm.pages->sgl->sg_pgs, + obj->mm.pages->nents * sizeof(st->sgl->sg_pgs[0])); +#else + src = obj->mm.pages->sgl; dst = st->sgl; for (i = 0; i < obj->mm.pages->nents; i++) { @@ -64,21 +62,19 @@ static struct sg_table *i915_gem_map_dma dst = sg_next(dst); src = sg_next(src); } +#endif if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { ret = -ENOMEM; goto err_free_sg; } -#endif return st; -#ifndef __NetBSD__ err_free_sg: sg_free_table(st); err_free: kfree(st); -#endif err_unpin_pages: i915_gem_object_unpin_pages(obj); err: @@ -91,13 +87,9 @@ static void i915_gem_unmap_dma_buf(struc { struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf); -#ifdef __NetBSD__ - drm_prime_sg_free(sg); -#else dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir); sg_free_table(sg); kfree(sg); -#endif i915_gem_object_unpin_pages(obj); } @@ -282,7 +274,7 @@ struct drm_gem_object *i915_gem_prime_im } /* need to attach */ - attach = dma_buf_attach(dma_buf, dev->dev); + attach = dma_buf_attach(dma_buf, dev->dmat); if (IS_ERR(attach)) return ERR_CAST(attach); Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.h diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.h:1.5 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.h:1.6 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.h:1.5 Sun Dec 19 11:19:40 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_mman.h,v 1.5 2021/12/19 11:19:40 riastradh Exp $ */ +/* $NetBSD: i915_gem_mman.h,v 1.6 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -21,6 +21,7 @@ struct mutex; int i915_gem_mmap_gtt_version(void); #ifdef __NetBSD__ +const struct uvm_pagerops *const i915_gem_uvm_ops; int i915_gem_mmap_object(struct drm_device *, off_t, size_t, int, struct uvm_object **, voff_t *, struct file *); #else Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h:1.5 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h:1.6 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h:1.5 Sun Dec 19 11:32:53 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object_types.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_object_types.h,v 1.5 2021/12/19 11:32:53 riastradh Exp $ */ +/* $NetBSD: i915_gem_object_types.h,v 1.6 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -214,15 +214,21 @@ struct drm_i915_gem_object { struct list_head region_link; #ifdef __NetBSD__ - struct page **pagearray;/* wired pages of normal objects */ - struct sg_table *sg; /* drm prime objects */ - bus_dma_segment_t *segs;/* internal objects */ - unsigned nsegs; - int rsegs; - bus_dmamap_t pages; /* expedient misnomer */ -#else - struct sg_table *pages; + /* internal objects */ + union { + struct { + bus_dma_segment_t *segs; + int nsegs; + int rsegs; + } internal; + struct { + bus_dma_segment_t seg; + void *kva; + } phys; + } u; #endif + + struct sg_table *pages; void *mapping; struct i915_page_sizes { Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_execbuffer.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_execbuffer.c:1.3 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_execbuffer.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_execbuffer.c:1.3 Sun Dec 19 01:39:57 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_execbuffer.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_execbuffer.c,v 1.3 2021/12/19 01:39:57 riastradh Exp $ */ +/* $NetBSD: i915_gem_execbuffer.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_execbuffer.c,v 1.3 2021/12/19 01:39:57 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_execbuffer.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/intel-iommu.h> #include <linux/dma-resv.h> @@ -17,6 +17,10 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_exe #include <drm/drm_syncobj.h> #include <drm/i915_drm.h> +#ifdef __NetBSD__ +#include <sys/filedesc.h> +#endif + #include "display/intel_frontbuffer.h" #include "gem/i915_gem_ioctls.h" @@ -2667,7 +2671,7 @@ i915_gem_do_execbuffer(struct drm_device #ifdef __NetBSD__ err = -fd_allocfile(&fp, &out_fence_fd); if (err) - goto err_in_fence; + goto err_exec_fence; #else out_fence_fd = get_unused_fd_flags(O_CLOEXEC); if (out_fence_fd < 0) { @@ -2817,7 +2821,11 @@ err_request: if (out_fence) { if (err == 0) { +#ifdef __NetBSD__ + fd_affix(curproc, fp, out_fence_fd); +#else fd_install(out_fence_fd, out_fence->file); +#endif args->rsvd2 &= GENMASK_ULL(31, 0); /* keep in-fence */ args->rsvd2 |= (u64)out_fence_fd << 32; out_fence_fd = -1; Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c:1.3 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c:1.3 Sun Dec 19 01:38:51 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_internal.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_internal.c,v 1.3 2021/12/19 01:38:51 riastradh Exp $ */ +/* $NetBSD: i915_gem_internal.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_internal.c,v 1.3 2021/12/19 01:38:51 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_internal.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/scatterlist.h> #include <linux/slab.h> @@ -44,55 +44,80 @@ static int i915_gem_object_get_pages_int struct drm_i915_private *i915 = to_i915(obj->base.dev); #ifdef __NetBSD__ bus_dma_tag_t dmat = i915->drm.dmat; - bus_dmamap_t map; + struct sg_table *sgt = NULL; size_t nsegs; - unsigned sizes, seg; + bool alloced = false, prepared = false; int ret; - KASSERT(obj->mm.segs == NULL); - nsegs = obj->mm.nsegs = obj->base.size/PAGE_SIZE; - if (nsegs > UINT_MAX || nsegs > SIZE_MAX/sizeof(obj->mm.segs[0])) - return -ENOMEM; - obj->mm.segs = kmem_alloc(nsegs * sizeof(obj->mm.segs[0]), KM_NOSLEEP); - if (obj->mm.segs == NULL) - return -ENOMEM; + obj->mm.u.internal.rsegs = obj->mm.u.internal.nsegs = 0; - /* XXX errno NetBSD->Linux */ - ret = -bus_dmamem_alloc(dmat, obj->base.size, PAGE_SIZE, 0, - obj->mm.segs, nsegs, &obj->mm.rsegs, BUS_DMA_NOWAIT); - if (ret) - goto out0; + KASSERT(obj->mm.u.internal.segs == NULL); + nsegs = obj->base.size >> PAGE_SHIFT; + if (nsegs > INT_MAX || + nsegs > SIZE_MAX/sizeof(obj->mm.u.internal.segs[0])) { + ret = -ENOMEM; + goto out; + } + obj->mm.u.internal.segs = kmem_alloc( + nsegs * sizeof(obj->mm.u.internal.segs[0]), + KM_NOSLEEP); + if (obj->mm.u.internal.segs == NULL) { + ret = -ENOMEM; + goto out; + } + obj->mm.u.internal.nsegs = nsegs; /* XXX errno NetBSD->Linux */ - ret = -bus_dmamap_create(dmat, obj->base.size, obj->mm.rsegs, - obj->base.size, 0, BUS_DMA_NOWAIT, &map); + ret = -bus_dmamem_alloc(dmat, obj->base.size, PAGE_SIZE, 0, + obj->mm.u.internal.segs, nsegs, &obj->mm.u.internal.rsegs, + BUS_DMA_NOWAIT); if (ret) - goto out1; + goto out; - /* XXX errno NetBSD->Linux */ - ret = -bus_dmamap_load_raw(dmat, map, obj->mm.segs, obj->mm.rsegs, - obj->base.size, BUS_DMA_NOWAIT); - if (ret) - goto out2; + sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + if (sgt == NULL) { + ret = -ENOMEM; + goto out; + } + if (sg_alloc_table_from_bus_dmamem(sgt, dmat, obj->mm.u.internal.segs, + obj->mm.u.internal.rsegs, GFP_KERNEL)) { + ret = -ENOMEM; + goto out; + } + alloced = true; - ret = i915_gem_gtt_prepare_pages(obj, map); + ret = i915_gem_gtt_prepare_pages(obj, sgt); if (ret) - goto out3; - - for (sizes = 0, seg = 0; seg < map->dm_nsegs; seg++) - sizes |= map->dm_segs[seg].ds_len; + goto out; + prepared = true; obj->mm.madv = I915_MADV_DONTNEED; - __i915_gem_object_set_pages(obj, map, sizes); + __i915_gem_object_set_pages(obj, sgt, i915_sg_page_sizes(sgt->sgl)); return 0; -out4: __unused - i915_gem_gtt_finish_pages(obj, map); -out3: bus_dmamap_unload(dmat, obj->mm.pages); -out2: bus_dmamap_destroy(dmat, obj->mm.pages); -out1: bus_dmamem_free(dmat, obj->mm.segs, obj->mm.rsegs); -out0: kmem_free(obj->mm.segs, nsegs * sizeof(obj->mm.segs[0])); +out: if (ret) { + if (prepared) + i915_gem_gtt_finish_pages(obj, sgt); + if (alloced) + sg_free_table(sgt); + if (sgt) { + kfree(sgt); + sgt = NULL; + } + if (obj->mm.u.internal.rsegs) { + bus_dmamem_free(dmat, obj->mm.u.internal.segs, + obj->mm.u.internal.rsegs); + obj->mm.u.internal.rsegs = 0; + } + if (obj->mm.u.internal.nsegs) { + kmem_free(obj->mm.u.internal.segs, + (obj->mm.u.internal.nsegs * + sizeof(obj->mm.u.internal.segs[0]))); + obj->mm.u.internal.nsegs = 0; + obj->mm.u.internal.segs = NULL; + } + } return ret; #else struct sg_table *st; @@ -190,24 +215,20 @@ err: #endif } -#ifdef __NetBSD__ -static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj, - bus_dmamap_t pages) -#else static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj, struct sg_table *pages) -#endif { i915_gem_gtt_finish_pages(obj, pages); #ifdef __NetBSD__ - bus_dma_tag_t dmat = obj->base.dev->dmat; - bus_dmamap_unload(dmat, pages); - bus_dmamap_destroy(dmat, pages); - bus_dmamem_free(dmat, obj->mm.segs, obj->mm.rsegs); - obj->mm.rsegs = 0; - kmem_free(obj->mm.segs, obj->mm.nsegs * sizeof(obj->mm.segs[0])); - obj->mm.segs = NULL; - obj->mm.nsegs = 0; + sg_free_table(pages); + kfree(pages); + bus_dmamem_free(obj->base.dev->dmat, obj->mm.u.internal.segs, + obj->mm.u.internal.rsegs); + obj->mm.u.internal.rsegs = 0; + kmem_free(obj->mm.u.internal.segs, + obj->mm.u.internal.nsegs * sizeof(obj->mm.u.internal.segs[0])); + obj->mm.u.internal.nsegs = 0; + obj->mm.u.internal.segs = NULL; #else internal_free_pages(pages); #endif Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.c:1.3 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.c:1.3 Sun Dec 19 01:34:08 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_object.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_object.c,v 1.3 2021/12/19 01:34:08 riastradh Exp $ */ +/* $NetBSD: i915_gem_object.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $ */ /* * Copyright © 2017 Intel Corporation @@ -25,8 +25,9 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_object.c,v 1.3 2021/12/19 01:34:08 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_object.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $"); +#include <linux/bitmap.h> #include <linux/sched/mm.h> #include "display/intel_frontbuffer.h" @@ -39,6 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_obj #include "i915_globals.h" #include "i915_trace.h" +#include <linux/nbsd-namespace.h> + static struct i915_global_object { struct i915_global base; struct kmem_cache *slab_objects; @@ -68,7 +71,11 @@ void i915_gem_object_init(struct drm_i91 INIT_LIST_HEAD(&obj->lut_list); spin_lock_init(&obj->mmo.lock); +#ifdef __NetBSD__ + memset(obj->mmo.offsets, 0, sizeof(obj->mmo.offsets)); +#else obj->mmo.offsets = RB_ROOT; +#endif init_rcu_head(&obj->rcu); @@ -124,8 +131,17 @@ void i915_gem_close_object(struct drm_ge i915_gem_object_unlock(obj); spin_lock(&obj->mmo.lock); +#ifdef __NetBSD__ + __USE(mn); + for (enum i915_mmap_type t = 0; t < I915_MMAP_NTYPES; t++) { + if ((mmo = obj->mmo.offsets[t]) == NULL) + continue; + drm_vma_node_revoke(&mmo->vma_node, file); + } +#else rbtree_postorder_for_each_entry_safe(mmo, mn, &obj->mmo.offsets, offset) drm_vma_node_revoke(&mmo->vma_node, file); +#endif spin_unlock(&obj->mmo.lock); list_for_each_entry_safe(lut, ln, &close, obj_link) { @@ -204,6 +220,17 @@ static void __i915_gem_free_objects(stru i915_gem_object_release_mmap(obj); +#ifdef __NetBSD__ + __USE(mn); + for (enum i915_mmap_type t = 0; t < I915_MMAP_NTYPES; t++) { + if ((mmo = obj->mmo.offsets[t]) == NULL) + continue; + drm_vma_offset_remove(obj->base.dev->vma_offset_manager, + &mmo->vma_node); + kfree(mmo); + } + memset(obj->mmo.offsets, 0, sizeof(obj->mmo.offsets)); +#else rbtree_postorder_for_each_entry_safe(mmo, mn, &obj->mmo.offsets, offset) { @@ -212,6 +239,7 @@ static void __i915_gem_free_objects(stru kfree(mmo); } obj->mmo.offsets = RB_ROOT; +#endif GEM_BUG_ON(atomic_read(&obj->bind_count)); GEM_BUG_ON(obj->userfault_count); Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c:1.3 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c:1.3 Sun Dec 19 01:34:08 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_phys.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_phys.c,v 1.3 2021/12/19 01:34:08 riastradh Exp $ */ +/* $NetBSD: i915_gem_phys.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_phys.c,v 1.3 2021/12/19 01:34:08 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_phys.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/highmem.h> #include <linux/shmem_fs.h> @@ -24,9 +24,15 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_phy #include "i915_gem_region.h" #include "i915_scatterlist.h" +#include <linux/nbsd-namespace.h> + static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) { +#ifdef __NetBSD__ + struct uvm_object *uobj = obj->base.filp; +#else struct address_space *mapping = obj->base.filp->f_mapping; +#endif struct scatterlist *sg; struct sg_table *st; dma_addr_t dma; @@ -37,16 +43,40 @@ static int i915_gem_object_get_pages_phy if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj))) return -EINVAL; + /* * Always aligning to the object size, allows a single allocation * to handle all possible callers, and given typical object sizes, * the alignment of the buddy allocation will naturally match. */ +#ifdef __NetBSD__ + __USE(dma); + bus_dma_tag_t dmat = obj->base.dev->dmat; + bool loaded = false; + int rsegs = 0; + int ret; + + vaddr = NULL; + + /* XXX errno NetBSD->Linux */ + ret = -bus_dmamem_alloc(dmat, roundup_pow_of_two(obj->base.size), + roundup_pow_of_two(obj->base.size), 0, &obj->mm.u.phys.seg, 1, + &rsegs, BUS_DMA_WAITOK); + if (ret) + return -ENOMEM; + KASSERT(rsegs == 1); + ret = -bus_dmamem_map(dmat, &obj->mm.u.phys.seg, 1, + roundup_pow_of_two(obj->base.size), &vaddr, BUS_DMA_WAITOK); + if (ret) + goto err_pci; + obj->mm.u.phys.kva = vaddr; +#else vaddr = dma_alloc_coherent(&obj->base.dev->pdev->dev, roundup_pow_of_two(obj->base.size), &dma, GFP_KERNEL); if (!vaddr) return -ENOMEM; +#endif st = kmalloc(sizeof(*st), GFP_KERNEL); if (!st) @@ -56,43 +86,96 @@ static int i915_gem_object_get_pages_phy goto err_st; sg = st->sgl; +#ifdef __NetBSD__ + /* XXX errno NetBSD->Linux */ + ret = -bus_dmamap_create(dmat, roundup_pow_of_two(obj->base.size), 1, + roundup_pow_of_two(obj->base.size), 0, BUS_DMA_WAITOK, + &sg->sg_dmamap); + if (ret) + goto err_st; + /* XXX errno NetBSD->Linux */ + ret = -bus_dmamap_load_raw(dmat, sg->sg_dmamap, &obj->mm.u.phys.seg, 1, + roundup_pow_of_two(obj->base.size), BUS_DMA_WAITOK); + if (ret) + goto err_st; + loaded = true; +#else sg->offset = 0; sg->length = obj->base.size; sg_assign_page(sg, (struct page *)vaddr); sg_dma_address(sg) = dma; sg_dma_len(sg) = obj->base.size; +#endif dst = vaddr; for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { struct page *page; void *src; +#ifdef __NetBSD__ + struct vm_page *vm_page; + + /* XXX errno NetBSD->Linux */ + ret = -uvm_obj_wirepages(uobj, i*PAGE_SIZE, (i + 1)*PAGE_SIZE, + NULL); + if (ret) + goto err_st; + rw_enter(uobj->vmobjlock, RW_READER); + vm_page = uvm_pagelookup(uobj, i*PAGE_SIZE); + rw_exit(uobj->vmobjlock); + KASSERT(vm_page); + page = container_of(vm_page, struct page, p_vmp); +#else page = shmem_read_mapping_page(mapping, i); if (IS_ERR(page)) goto err_st; +#endif src = kmap_atomic(page); memcpy(dst, src, PAGE_SIZE); drm_clflush_virt_range(dst, PAGE_SIZE); kunmap_atomic(src); +#ifdef __NetBSD__ + uvm_obj_unwirepages(uobj, i*PAGE_SIZE, (i + 1)*PAGE_SIZE); +#else put_page(page); +#endif dst += PAGE_SIZE; } intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt); - __i915_gem_object_set_pages(obj, st, sg->length); + __i915_gem_object_set_pages(obj, st, obj->base.size); return 0; err_st: +#ifdef __NetBSD__ + if (loaded) + bus_dmamap_unload(dmat, st->sgl->sg_dmamap); + if (st->sgl->sg_dmamap) { + bus_dmamap_destroy(dmat, st->sgl->sg_dmamap); + st->sgl->sg_dmamap = NULL; + } +#endif kfree(st); + sg_free_table(st); err_pci: +#ifdef __NetBSD__ + if (vaddr) { + bus_dmamem_unmap(dmat, vaddr, + roundup_pow_of_two(obj->base.size)); + } + obj->mm.u.phys.kva = NULL; + if (rsegs) + bus_dmamem_free(dmat, &obj->mm.u.phys.seg, rsegs); +#else dma_free_coherent(&obj->base.dev->pdev->dev, roundup_pow_of_two(obj->base.size), vaddr, dma); +#endif return -ENOMEM; } @@ -100,13 +183,23 @@ static void i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, struct sg_table *pages) { +#ifdef __NetBSD__ + bus_dma_tag_t dmat = obj->base.dev->dmat; + void *vaddr = obj->mm.u.phys.kva; +#else dma_addr_t dma = sg_dma_address(pages->sgl); void *vaddr = sg_page(pages->sgl); +#endif __i915_gem_object_release_shmem(obj, pages, false); if (obj->mm.dirty) { +#ifdef __NetBSD__ + struct uvm_object *uobj = obj->base.filp; + struct vm_page *vm_page; +#else struct address_space *mapping = obj->base.filp->f_mapping; +#endif void *src = vaddr; int i; @@ -114,9 +207,20 @@ i915_gem_object_put_pages_phys(struct dr struct page *page; char *dst; +#ifdef __NetBSD__ + if (uvm_obj_wirepages(uobj, i*PAGE_SIZE, + (i + 1)*PAGE_SIZE, NULL) != 0) + continue; + rw_enter(uobj->vmobjlock, RW_READER); + vm_page = uvm_pagelookup(uobj, i*PAGE_SIZE); + rw_exit(uobj->vmobjlock); + KASSERT(vm_page); + page = container_of(vm_page, struct page, p_vmp); +#else page = shmem_read_mapping_page(mapping, i); if (IS_ERR(page)) continue; +#endif dst = kmap_atomic(page); drm_clflush_virt_range(src, PAGE_SIZE); @@ -124,26 +228,49 @@ i915_gem_object_put_pages_phys(struct dr kunmap_atomic(dst); set_page_dirty(page); +#ifdef __NetBSD__ + uvm_obj_unwirepages(uobj, i*PAGE_SIZE, + (i + 1)*PAGE_SIZE); +#else if (obj->mm.madv == I915_MADV_WILLNEED) mark_page_accessed(page); put_page(page); +#endif src += PAGE_SIZE; } obj->mm.dirty = false; } +#ifdef __NetBSD__ + bus_dmamap_unload(dmat, pages->sgl->sg_dmamap); + bus_dmamap_destroy(dmat, pages->sgl->sg_dmamap); + pages->sgl->sg_dmamap = NULL; +#endif + sg_free_table(pages); kfree(pages); +#ifdef __NetBSD__ + bus_dmamem_unmap(dmat, obj->mm.u.phys.kva, + roundup_pow_of_two(obj->base.size)); + obj->mm.u.phys.kva = NULL; + bus_dmamem_free(dmat, &obj->mm.u.phys.seg, 1); +#else dma_free_coherent(&obj->base.dev->pdev->dev, roundup_pow_of_two(obj->base.size), vaddr, dma); +#endif } static void phys_release(struct drm_i915_gem_object *obj) { +#ifdef __NetBSD__ + /* XXX Who acquires the reference? */ + uao_detach(obj->base.filp); +#else fput(obj->base.filp); +#endif } static const struct drm_i915_gem_object_ops i915_gem_phys_ops = { @@ -155,11 +282,7 @@ static const struct drm_i915_gem_object_ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align) { -#ifdef __NetBSD__ - bus_dmamap_t pages; -#else struct sg_table *pages; -#endif int err; if (align > obj->base.size) @@ -213,13 +336,7 @@ int i915_gem_object_attach_phys(struct d err_xfer: obj->ops = &i915_gem_shmem_ops; if (!IS_ERR_OR_NULL(pages)) { -#ifdef __NetBSD__ - unsigned int sg_page_sizes = 0, seg; - for (seg = 0; seg < pages->dm_nsegs; seg++) - sg_page_sizes |= pages->dm_segs[seg].ds_len; -#else unsigned int sg_page_sizes = i915_sg_page_sizes(pages->sgl); -#endif __i915_gem_object_set_pages(obj, pages, sg_page_sizes); } Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c:1.3 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c:1.3 Sun Dec 19 01:40:12 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_stolen.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_stolen.c,v 1.3 2021/12/19 01:40:12 riastradh Exp $ */ +/* $NetBSD: i915_gem_stolen.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_stolen.c,v 1.3 2021/12/19 01:40:12 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_stolen.c,v 1.4 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/errno.h> #include <linux/mutex.h> @@ -122,7 +122,9 @@ static int i915_adjust_stolen(struct drm } } -#ifndef __NetBSD__ /* XXX */ +#ifdef __NetBSD__ /* XXX */ + __USE(r); +#else /* * Verify that nothing else uses this physical address. Stolen * memory should be reserved by the BIOS and hidden from the @@ -498,35 +500,45 @@ static int i915_gem_init_stolen(struct d return 0; } -#ifdef __NetBSD__ -static bus_dmamap_t -#else static struct sg_table * -#endif i915_pages_create_for_stolen(struct drm_device *dev, resource_size_t offset, resource_size_t size) { struct drm_i915_private *i915 = to_i915(dev); + struct sg_table *st; #ifdef __NetBSD__ bus_dma_tag_t dmat = i915->drm.dmat; - bus_dmamap_t dmamap = NULL; - bus_dma_segment_t *seg; - int nseg, i; + bus_dma_segment_t *seg = NULL; + int nseg = 0, i; + bool loaded = false; int ret; #else - struct sg_table *st; struct scatterlist *sg; #endif GEM_BUG_ON(range_overflows(offset, size, resource_size(&i915->dsm))); + /* We hide that we have no struct page backing our stolen object + * by wrapping the contiguous physical allocation with a fake + * dma mapping in a single scatterlist. + */ + + st = kmalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) + return ERR_PTR(-ENOMEM); + + if (sg_alloc_table(st, 1, GFP_KERNEL)) { + kfree(st); + return ERR_PTR(-ENOMEM); + } + #ifdef __NetBSD__ KASSERT((size % PAGE_SIZE) == 0); nseg = size / PAGE_SIZE; seg = kmem_alloc(nseg * sizeof(seg[0]), KM_SLEEP); /* - * x86 bus_dmamap_load_raw fails to respect the maxsegsz we + * XXX x86 bus_dmamap_load_raw fails to respect the maxsegsz we * pass to bus_dmamap_create, so we have to create page-sized * segments to begin with. */ @@ -538,60 +550,50 @@ i915_pages_create_for_stolen(struct drm_ /* XXX errno NetBSD->Linux */ ret = -bus_dmamap_create(dmat, size, nseg, PAGE_SIZE, 0, - BUS_DMA_WAITOK, &dmamap); + BUS_DMA_WAITOK, &st->sgl->sg_dmamap); if (ret) { DRM_ERROR("failed to create DMA map for stolen object: %d\n", ret); -fail0: dmamap = NULL; /* paranoia */ + st->sgl->sg_dmamap = NULL; goto out; } /* XXX errno NetBSD->Liux */ - ret = -bus_dmamap_load_raw(dmat, dmamap, seg, nseg, size, + ret = -bus_dmamap_load_raw(dmat, st->sgl->sg_dmamap, seg, nseg, size, BUS_DMA_WAITOK); if (ret) { DRM_ERROR("failed to load DMA map for stolen object: %d\n", ret); -fail1: __unused - bus_dmamap_destroy(dmat, dmamap); - goto fail0; + goto out; } + loaded = true; -out: kmem_free(seg, nseg*sizeof(seg[0])); - return ret ? ERR_PTR(ret) : dmamap; -#else - /* We hide that we have no struct page backing our stolen object - * by wrapping the contiguous physical allocation with a fake - * dma mapping in a single scatterlist. - */ - - st = kmalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) - return ERR_PTR(-ENOMEM); - - if (sg_alloc_table(st, 1, GFP_KERNEL)) { +out: if (ret) { + if (loaded) + bus_dmamap_unload(dmat, st->sgl->sg_dmamap); + if (st->sgl->sg_dmamap) { + bus_dmamap_destroy(dmat, st->sgl->sg_dmamap); + st->sgl->sg_dmamap = NULL; + } + sg_free_table(st); kfree(st); - return ERR_PTR(-ENOMEM); + return ERR_PTR(ret); } - +#else sg = st->sgl; sg->offset = 0; sg->length = size; sg_dma_address(sg) = (dma_addr_t)i915->dsm.start + offset; sg_dma_len(sg) = size; +#endif return st; -#endif } static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj) { -#ifdef __NetBSD__ - bus_dmamap_t pages = -#else struct sg_table *pages = -#endif i915_pages_create_for_stolen(obj->base.dev, obj->stolen->start, obj->stolen->size); @@ -608,12 +610,12 @@ static void i915_gem_object_put_pages_st { /* Should only be called from i915_gem_object_release_stolen() */ #ifdef __NetBSD__ - bus_dmamap_unload(obj->base.dev->dmat, pages); - bus_dmamap_destroy(obj->base.dev->dmat, pages); -#else + bus_dmamap_unload(obj->base.dev->dmat, pages->sgl->sg_dmamap); + bus_dmamap_destroy(obj->base.dev->dmat, pages->sgl->sg_dmamap); + pages->sgl->sg_dmamap = NULL; +#endif sg_free_table(pages); kfree(pages); -#endif } static void Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c:1.6 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c:1.7 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c:1.6 Sun Dec 19 11:33:02 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_mman.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_mman.c,v 1.6 2021/12/19 11:33:02 riastradh Exp $ */ +/* $NetBSD: i915_gem_mman.c,v 1.7 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_mman.c,v 1.6 2021/12/19 11:33:02 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_mman.c,v 1.7 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/anon_inodes.h> #include <linux/mman.h> @@ -79,7 +79,7 @@ i915_gem_mmap_ioctl(struct drm_device *d #ifdef __NetBSD__ struct drm_i915_private *i915 = to_i915(obj->base.dev); - if (dev->quirks & QUIRK_NETBSD_VERSION_CALLED) + if (i915->quirks & QUIRK_NETBSD_VERSION_CALLED) args->flags = 0; #endif @@ -244,8 +244,7 @@ static int i915_gem_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr, struct vm_page **pps, int npages, int centeridx, vm_prot_t access_type, int flags) { - struct uvm_object *uobj = ufi->entry->object.uvm_obj; - struct ... + panic("NYI"); } #else @@ -514,7 +513,7 @@ void i915_gem_object_release_mmap_offset (void)mmo; (void)mn; - for (t = 0; t < I915_MMA_NTYPES; t++) { + for (t = 0; t < I915_MMAP_NTYPES; t++) { if (t == I915_MMAP_TYPE_GTT) continue; /* @@ -522,7 +521,7 @@ void i915_gem_object_release_mmap_offset * spin lock, probably? */ for (i = 0; i < obj->base.size >> PAGE_SHIFT; i++) { - page = obj->mm.pagearray[i]; + page = obj->mm.pages->sgl->sg_pgs[i]; vm_page = &page->p_vmp; pmap_page_protect(vm_page, VM_PROT_NONE); } @@ -669,7 +668,11 @@ mmap_offset_attach(struct drm_i915_gem_o mmo->obj = obj; mmo->mmap_type = mmap_type; +#ifdef __NetBSD__ + drm_vma_node_init(&mmo->vma_node); +#else drm_vma_node_reset(&mmo->vma_node); +#endif err = drm_vma_offset_add(obj->base.dev->vma_offset_manager, &mmo->vma_node, obj->base.size / PAGE_SIZE); @@ -696,6 +699,7 @@ out: return mmo; err: + drm_vma_node_destroy(&mmo->vma_node); kfree(mmo); return ERR_PTR(err); } @@ -833,6 +837,7 @@ int i915_gem_mmap_object(struct drm_device *dev, off_t byte_offset, size_t nbytes, int prot, struct uvm_object **uobjp, voff_t *uoffsetp, struct file *fp) { + __USE(i915_gem_fault); panic("NYI"); } Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_shmem.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_shmem.c:1.6 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_shmem.c:1.7 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_shmem.c:1.6 Sun Dec 19 11:32:53 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_shmem.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_shmem.c,v 1.6 2021/12/19 11:32:53 riastradh Exp $ */ +/* $NetBSD: i915_gem_shmem.c,v 1.7 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_shmem.c,v 1.6 2021/12/19 11:32:53 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_shmem.c,v 1.7 2021/12/19 11:33:30 riastradh Exp $"); #include <linux/pagevec.h> #include <linux/swap.h> @@ -282,11 +282,7 @@ put: void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, -#ifdef __NetBSD__ - bus_dmamap_t pages, -#else struct sg_table *pages, -#endif bool needs_clflush) { GEM_BUG_ON(obj->mm.madv == __I915_MADV_PURGED); @@ -297,27 +293,13 @@ __i915_gem_object_release_shmem(struct d if (needs_clflush && (obj->read_domains & I915_GEM_DOMAIN_CPU) == 0 && !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) -#ifdef __NetBSD__ - /* - * XXX Should maybe use bus_dmamap_sync instead -- - * shouldn't really touch obj->mm here since the caller - * already pulled off the pages. - */ - drm_clflush_pages(obj->mm.pagearray, - obj->base.size >> PAGE_SHIFT); -#else drm_clflush_sg(pages); -#endif __start_cpu_write(obj); } static void -#ifdef __NetBSD__ -shmem_put_pages(struct drm_i915_gem_object *obj, bus_dmamap_t map) -#else shmem_put_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) -#endif { struct sgt_iter sgt_iter; struct pagevec pvec; @@ -445,7 +427,12 @@ static void shmem_release(struct drm_i91 { i915_gem_object_release_memory_region(obj); +#ifdef __NetBSD__ + /* XXX Who acquires the reference? */ + uao_detach(obj->base.filp); +#else fput(obj->base.filp); +#endif } const struct drm_i915_gem_object_ops i915_gem_shmem_ops = { Index: src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pm.c diff -u src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pm.c:1.2 src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pm.c:1.3 --- src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pm.c:1.2 Sat Dec 18 23:45:30 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gem/i915_gem_pm.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: i915_gem_pm.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $ */ +/* $NetBSD: i915_gem_pm.c,v 1.3 2021/12/19 11:33:30 riastradh Exp $ */ /* * SPDX-License-Identifier: MIT @@ -7,7 +7,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i915_gem_pm.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_gem_pm.c,v 1.3 2021/12/19 11:33:30 riastradh Exp $"); #include "gem/i915_gem_pm.h" #include "gt/intel_gt.h" @@ -16,6 +16,8 @@ __KERNEL_RCSID(0, "$NetBSD: i915_gem_pm. #include "i915_drv.h" +#include <linux/nbsd-namespace.h> + void i915_gem_suspend(struct drm_i915_private *i915) { GEM_TRACE("%s\n", dev_name(i915->drm.dev)); Index: src/sys/external/bsd/drm2/dist/drm/i915/gt/intel_gtt.h diff -u src/sys/external/bsd/drm2/dist/drm/i915/gt/intel_gtt.h:1.10 src/sys/external/bsd/drm2/dist/drm/i915/gt/intel_gtt.h:1.11 --- src/sys/external/bsd/drm2/dist/drm/i915/gt/intel_gtt.h:1.10 Sun Dec 19 11:24:08 2021 +++ src/sys/external/bsd/drm2/dist/drm/i915/gt/intel_gtt.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: intel_gtt.h,v 1.10 2021/12/19 11:24:08 riastradh Exp $ */ +/* $NetBSD: intel_gtt.h,v 1.11 2021/12/19 11:33:30 riastradh Exp $ */ /* SPDX-License-Identifier: MIT */ /* @@ -643,7 +643,7 @@ struct sgt_dma { static inline struct sgt_dma sgt_dma(struct i915_vma *vma) { - return (struct sgt_dma) { vma->pages, 0, 0 }; + return (struct sgt_dma) { vma->pages->sgl->sg_dmamap, 0, 0 }; } #else static inline struct sgt_dma { Index: src/sys/external/bsd/drm2/dist/include/drm/drm_cache.h diff -u src/sys/external/bsd/drm2/dist/include/drm/drm_cache.h:1.9 src/sys/external/bsd/drm2/dist/include/drm/drm_cache.h:1.10 --- src/sys/external/bsd/drm2/dist/include/drm/drm_cache.h:1.9 Sun Dec 19 11:32:54 2021 +++ src/sys/external/bsd/drm2/dist/include/drm/drm_cache.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: drm_cache.h,v 1.9 2021/12/19 11:32:54 riastradh Exp $ */ +/* $NetBSD: drm_cache.h,v 1.10 2021/12/19 11:33:30 riastradh Exp $ */ /************************************************************************** * @@ -40,13 +40,8 @@ struct page; void drm_clflush_pages(struct page *pages[], unsigned long num_pages); -#ifdef __NetBSD__ /* XXX drm clflush */ -void drm_clflush_page(struct page *); -void drm_clflush_virt_range(const void *, size_t); -#else void drm_clflush_sg(struct sg_table *st); void drm_clflush_virt_range(void *addr, unsigned long length); -#endif bool drm_need_swiotlb(int dma_bits); Index: src/sys/external/bsd/drm2/dist/include/drm/drm_prime.h diff -u src/sys/external/bsd/drm2/dist/include/drm/drm_prime.h:1.6 src/sys/external/bsd/drm2/dist/include/drm/drm_prime.h:1.7 --- src/sys/external/bsd/drm2/dist/include/drm/drm_prime.h:1.6 Sun Dec 19 11:32:54 2021 +++ src/sys/external/bsd/drm2/dist/include/drm/drm_prime.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: drm_prime.h,v 1.6 2021/12/19 11:32:54 riastradh Exp $ */ +/* $NetBSD: drm_prime.h,v 1.7 2021/12/19 11:33:30 riastradh Exp $ */ /* * Copyright © 2012 Red Hat @@ -102,9 +102,15 @@ struct dma_buf *drm_gem_prime_export(str int flags); /* helper functions for importing */ +#ifdef __NetBSD__ +struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev, + struct dma_buf *dma_buf, + bus_dma_tag_t attach_dev); +#else struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev, struct dma_buf *dma_buf, struct device *attach_dev); +#endif struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf); Index: src/sys/external/bsd/drm2/drm/drm_cache.c diff -u src/sys/external/bsd/drm2/drm/drm_cache.c:1.17 src/sys/external/bsd/drm2/drm/drm_cache.c:1.18 --- src/sys/external/bsd/drm2/drm/drm_cache.c:1.17 Sun Dec 19 11:32:54 2021 +++ src/sys/external/bsd/drm2/drm/drm_cache.c Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: drm_cache.c,v 1.17 2021/12/19 11:32:54 riastradh Exp $ */ +/* $NetBSD: drm_cache.c,v 1.18 2021/12/19 11:33:30 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: drm_cache.c,v 1.17 2021/12/19 11:32:54 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: drm_cache.c,v 1.18 2021/12/19 11:33:30 riastradh Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -72,21 +72,13 @@ drm_clflush_pages(struct page **pages, u } void -drm_clflush_page(struct page *page) +drm_clflush_sg(struct sg_table *sgt) { -#if defined(DRM_CLFLUSH) - if (drm_md_clflush_finegrained_p()) { - drm_md_clflush_begin(); - drm_md_clflush_page(page); - drm_md_clflush_commit(); - } else { - drm_md_clflush_all(); - } -#endif + drm_clflush_pages(sgt->sgl->sg_pgs, sgt->sgl->sg_npgs); } void -drm_clflush_virt_range(const void *vaddr, size_t nbytes) +drm_clflush_virt_range(void *vaddr, unsigned long nbytes) { #if defined(DRM_CLFLUSH) if (drm_md_clflush_finegrained_p()) { Index: src/sys/external/bsd/drm2/include/asm/uaccess.h diff -u src/sys/external/bsd/drm2/include/asm/uaccess.h:1.9 src/sys/external/bsd/drm2/include/asm/uaccess.h:1.10 --- src/sys/external/bsd/drm2/include/asm/uaccess.h:1.9 Sun Dec 19 11:24:14 2021 +++ src/sys/external/bsd/drm2/include/asm/uaccess.h Sun Dec 19 11:33:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: uaccess.h,v 1.9 2021/12/19 11:24:14 riastradh Exp $ */ +/* $NetBSD: uaccess.h,v 1.10 2021/12/19 11:33:30 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -76,7 +76,7 @@ copy_to_user(void *user_addr, const void #define __get_user get_user #define __put_user put_user -#define user_access_begin() __nothing +#define user_access_begin(P,N) access_ok(P,N) #define user_access_end() __nothing #define unsafe_put_user(KERNEL_RVAL, USER_PTR, LABEL) do { \ Index: src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h diff -u src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.21 src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.22 --- src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.21 Sun Dec 19 11:32:54 2021 +++ src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_dma_hacks.h,v 1.21 2021/12/19 11:32:54 riastradh Exp $ */ +/* $NetBSD: bus_dma_hacks.h,v 1.22 2021/12/19 11:33:31 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -194,7 +194,7 @@ out: if (segs != stacksegs) { static inline int bus_dmamem_export_pages(bus_dma_tag_t dmat, const bus_dma_segment_t *segs, - int nsegs, paddr_t *pgs, unsigned npgs) + int nsegs, struct page **pgs, unsigned npgs) { int seg; unsigned i; @@ -208,7 +208,8 @@ bus_dmamem_export_pages(bus_dma_tag_t dm paddr_t paddr = BUS_MEM_TO_PHYS(dmat, baddr); KASSERT(i < npgs); - pgs[i++] = paddr; + pgs[i++] = container_of(PHYS_TO_VM_PAGE(paddr), + struct page, p_vmp); baddr += PAGE_SIZE; len -= PAGE_SIZE; @@ -222,14 +223,14 @@ bus_dmamem_export_pages(bus_dma_tag_t dm static inline int bus_dmamem_import_pages(bus_dma_tag_t dmat, bus_dma_segment_t *segs, - int nsegs, int *rsegs, const paddr_t *pgs, unsigned npgs) + int nsegs, int *rsegs, struct page *const *pgs, unsigned npgs) { int seg; unsigned i; seg = 0; for (i = 0; i < npgs; i++) { - paddr_t paddr = pgs[i]; + paddr_t paddr = VM_PAGE_TO_PHYS(&pgs[i]->p_vmp); bus_addr_t baddr = PHYS_TO_BUS_MEM(dmat, paddr); if (seg > 0 && segs[seg - 1].ds_addr + PAGE_SIZE == baddr) { Index: src/sys/external/bsd/drm2/include/linux/bitmap.h diff -u src/sys/external/bsd/drm2/include/linux/bitmap.h:1.11 src/sys/external/bsd/drm2/include/linux/bitmap.h:1.12 --- src/sys/external/bsd/drm2/include/linux/bitmap.h:1.11 Sun Dec 19 11:17:02 2021 +++ src/sys/external/bsd/drm2/include/linux/bitmap.h Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: bitmap.h,v 1.11 2021/12/19 11:17:02 riastradh Exp $ */ +/* $NetBSD: bitmap.h,v 1.12 2021/12/19 11:33:31 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -226,4 +226,11 @@ bitmap_zalloc(size_t nbits, gfp_t gfp) return kcalloc(n, sizeof(unsigned long), gfp); } +static inline void +bitmap_free(unsigned long *bitmap) +{ + + kfree(bitmap); +} + #endif /* _LINUX_BITMAP_H_ */ Index: src/sys/external/bsd/drm2/include/linux/dma-buf.h diff -u src/sys/external/bsd/drm2/include/linux/dma-buf.h:1.10 src/sys/external/bsd/drm2/include/linux/dma-buf.h:1.11 --- src/sys/external/bsd/drm2/include/linux/dma-buf.h:1.10 Sun Dec 19 10:38:23 2021 +++ src/sys/external/bsd/drm2/include/linux/dma-buf.h Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: dma-buf.h,v 1.10 2021/12/19 10:38:23 riastradh Exp $ */ +/* $NetBSD: dma-buf.h,v 1.11 2021/12/19 11:33:31 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -37,7 +37,9 @@ #include <sys/mutex.h> #include <linux/err.h> +#include <linux/dma-mapping.h> #include <linux/dma-resv.h> +#include <linux/scatterlist.h> struct device; struct dma_buf; @@ -50,13 +52,6 @@ struct dma_resv; struct sg_table; struct uvm_object; -enum dma_data_direction { - DMA_NONE = 0, - DMA_TO_DEVICE = 1, - DMA_FROM_DEVICE = 2, - DMA_BIDIRECTIONAL = 3, -}; - struct dma_buf_ops { bool cache_sgt_mapping; int (*attach)(struct dma_buf *, struct dma_buf_attachment *); @@ -90,7 +85,7 @@ struct dma_buf { struct dma_buf_attachment { void *priv; struct dma_buf *dmabuf; - struct device *dev; + bus_dma_tag_t dev; /* XXX expedient misnomer */ }; struct dma_buf_export_info { @@ -128,7 +123,7 @@ void get_dma_buf(struct dma_buf *); void dma_buf_put(struct dma_buf *); struct dma_buf_attachment * - dma_buf_attach(struct dma_buf *, struct device *); + dma_buf_attach(struct dma_buf *, bus_dma_tag_t); void dma_buf_detach(struct dma_buf *, struct dma_buf_attachment *); struct sg_table * Index: src/sys/external/bsd/drm2/include/linux/dma-mapping.h diff -u src/sys/external/bsd/drm2/include/linux/dma-mapping.h:1.8 src/sys/external/bsd/drm2/include/linux/dma-mapping.h:1.9 --- src/sys/external/bsd/drm2/include/linux/dma-mapping.h:1.8 Sun Dec 19 09:57:01 2021 +++ src/sys/external/bsd/drm2/include/linux/dma-mapping.h Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: dma-mapping.h,v 1.8 2021/12/19 09:57:01 riastradh Exp $ */ +/* $NetBSD: dma-mapping.h,v 1.9 2021/12/19 11:33:31 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -39,6 +39,23 @@ #include <linux/types.h> +enum dma_data_direction { + DMA_NONE = 0, + DMA_TO_DEVICE = 1, + DMA_FROM_DEVICE = 2, + DMA_BIDIRECTIONAL = 3, + + PCI_DMA_NONE = DMA_NONE, + PCI_TO_DEVICE = DMA_TO_DEVICE, + PCI_FROM_DEVICE = DMA_FROM_DEVICE, + PCI_DMA_BIDIRECTIONAL = DMA_BIDIRECTIONAL, +}; + +enum { + DMA_ATTR_NO_WARN = __BIT(0), + DMA_ATTR_SKIP_CPU_SYNC = __BIT(1), +}; + static inline uintmax_t DMA_BIT_MASK(unsigned nbits) { Index: src/sys/external/bsd/drm2/include/linux/mutex.h diff -u src/sys/external/bsd/drm2/include/linux/mutex.h:1.16 src/sys/external/bsd/drm2/include/linux/mutex.h:1.17 --- src/sys/external/bsd/drm2/include/linux/mutex.h:1.16 Sun Dec 19 01:21:22 2021 +++ src/sys/external/bsd/drm2/include/linux/mutex.h Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: mutex.h,v 1.16 2021/12/19 01:21:22 riastradh Exp $ */ +/* $NetBSD: mutex.h,v 1.17 2021/12/19 11:33:31 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -115,6 +115,13 @@ mutex_lock_nested(struct mutex *mutex, u mutex_lock(mutex); } +static inline int +mutex_lock_interruptible_nested(struct mutex *mutex, + unsigned subclass __unused) +{ + return mutex_lock_interruptible(mutex); +} + /* * `recursive locking is bad, do not use this ever.' * -- linux/scripts/checkpath.pl Index: src/sys/external/bsd/drm2/include/linux/radix-tree.h diff -u src/sys/external/bsd/drm2/include/linux/radix-tree.h:1.4 src/sys/external/bsd/drm2/include/linux/radix-tree.h:1.5 --- src/sys/external/bsd/drm2/include/linux/radix-tree.h:1.4 Sun Dec 19 01:35:18 2021 +++ src/sys/external/bsd/drm2/include/linux/radix-tree.h Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: radix-tree.h,v 1.4 2021/12/19 01:35:18 riastradh Exp $ */ +/* $NetBSD: radix-tree.h,v 1.5 2021/12/19 11:33:31 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -49,6 +49,7 @@ struct radix_tree_root { }; struct radix_tree_iter { + unsigned long index; }; void INIT_RADIX_TREE(struct radix_tree_root *, gfp_t); Index: src/sys/external/bsd/drm2/include/linux/scatterlist.h diff -u src/sys/external/bsd/drm2/include/linux/scatterlist.h:1.3 src/sys/external/bsd/drm2/include/linux/scatterlist.h:1.4 --- src/sys/external/bsd/drm2/include/linux/scatterlist.h:1.3 Sun Dec 19 10:51:24 2021 +++ src/sys/external/bsd/drm2/include/linux/scatterlist.h Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: scatterlist.h,v 1.3 2021/12/19 10:51:24 riastradh Exp $ */ +/* $NetBSD: scatterlist.h,v 1.4 2021/12/19 11:33:31 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -32,7 +32,44 @@ #ifndef _LINUX_SCATTERLIST_H_ #define _LINUX_SCATTERLIST_H_ +#include <sys/bus.h> + #include <linux/mm.h> +#include <linux/mm_types.h> +#include <linux/gfp.h> #include <linux/types.h> +/* namespace */ +#define dma_map_sg linux_dma_map_sg +#define dma_map_sg_attrs linux_dma_map_sg_attrs +#define dma_unmap_sg linux_dma_unmap_sg +#define dma_unmap_sg_attrs linux_dma_unmap_sg_attrs +#define sg_alloc_table linux_sg_alloc_table +#define sg_alloc_table_from_bus_dmamem linux_sg_alloc_table_from_bus_dmamem +#define sg_alloc_table_from_pages linux_sg_alloc_table_from_pages +#define sg_free_table linux_sg_free_table + +struct page; + +struct sg_table { + struct scatterlist { + struct page **sg_pgs; + unsigned sg_npgs; + bus_dmamap_t sg_dmamap; + } sgl[1]; + unsigned nents; +}; + +int sg_alloc_table(struct sg_table *, unsigned, gfp_t); +int sg_alloc_table_from_pages(struct sg_table *, struct page **, unsigned, + bus_size_t, bus_size_t, gfp_t); +int sg_alloc_table_from_bus_dmamem(struct sg_table *, bus_dma_tag_t, + const bus_dma_segment_t *, int, gfp_t); +void sg_free_table(struct sg_table *); + +int dma_map_sg(bus_dma_tag_t, struct scatterlist *, int, int); +int dma_map_sg_attrs(bus_dma_tag_t, struct scatterlist *, int, int, int); +void dma_unmap_sg(bus_dma_tag_t, struct scatterlist *, int, int); +void dma_unmap_sg_attrs(bus_dma_tag_t, struct scatterlist *, int, int, int); + #endif /* _LINUX_SCATTERLIST_H_ */ Index: src/sys/external/bsd/drm2/linux/files.drmkms_linux diff -u src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.31 src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.32 --- src/sys/external/bsd/drm2/linux/files.drmkms_linux:1.31 Sun Dec 19 11:23:52 2021 +++ src/sys/external/bsd/drm2/linux/files.drmkms_linux Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -# $NetBSD: files.drmkms_linux,v 1.31 2021/12/19 11:23:52 riastradh Exp $ +# $NetBSD: files.drmkms_linux,v 1.32 2021/12/19 11:33:31 riastradh Exp $ define drmkms_linux: i2cexec, i2c_bitbang @@ -21,6 +21,7 @@ file external/bsd/drm2/linux/linux_list_ file external/bsd/drm2/linux/linux_module.c drmkms_linux file external/bsd/drm2/linux/linux_pci.c drmkms_linux file external/bsd/drm2/linux/linux_rwsem.c drmkms_linux +file external/bsd/drm2/linux/linux_sg.c drmkms_linux file external/bsd/drm2/linux/linux_stop_machine.c drmkms_linux file external/bsd/drm2/linux/linux_sync_file.c drmkms_linux file external/bsd/drm2/linux/linux_wait_bit.c drmkms_linux Index: src/sys/external/bsd/drm2/linux/linux_dma_buf.c diff -u src/sys/external/bsd/drm2/linux/linux_dma_buf.c:1.9 src/sys/external/bsd/drm2/linux/linux_dma_buf.c:1.10 --- src/sys/external/bsd/drm2/linux/linux_dma_buf.c:1.9 Sun Dec 19 10:19:53 2021 +++ src/sys/external/bsd/drm2/linux/linux_dma_buf.c Sun Dec 19 11:33:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_dma_buf.c,v 1.9 2021/12/19 10:19:53 riastradh Exp $ */ +/* $NetBSD: linux_dma_buf.c,v 1.10 2021/12/19 11:33:31 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_dma_buf.c,v 1.9 2021/12/19 10:19:53 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_dma_buf.c,v 1.10 2021/12/19 11:33:31 riastradh Exp $"); #include <sys/types.h> #include <sys/atomic.h> @@ -177,14 +177,14 @@ dma_buf_put(struct dma_buf *dmabuf) } struct dma_buf_attachment * -dma_buf_attach(struct dma_buf *dmabuf, struct device *dev) +dma_buf_attach(struct dma_buf *dmabuf, bus_dma_tag_t dmat) { struct dma_buf_attachment *attach; int ret = 0; attach = kmem_zalloc(sizeof(*attach), KM_SLEEP); attach->dmabuf = dmabuf; - attach->dev = dev; + attach->dev = dmat; mutex_enter(&dmabuf->db_lock); if (dmabuf->ops->attach) Added files: Index: src/sys/external/bsd/drm2/linux/linux_sg.c diff -u /dev/null src/sys/external/bsd/drm2/linux/linux_sg.c:1.1 --- /dev/null Sun Dec 19 11:33:31 2021 +++ src/sys/external/bsd/drm2/linux/linux_sg.c Sun Dec 19 11:33:31 2021 @@ -0,0 +1,187 @@ +/* $NetBSD: linux_sg.c,v 1.1 2021/12/19 11:33:31 riastradh Exp $ */ + +/*- + * Copyright (c) 2021 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: linux_sg.c,v 1.1 2021/12/19 11:33:31 riastradh Exp $"); + +#include <sys/bus.h> +#include <sys/errno.h> + +#include <drm/bus_dma_hacks.h> + +#include <linux/dma-mapping.h> +#include <linux/gfp.h> +#include <linux/mm_types.h> +#include <linux/scatterlist.h> +#include <linux/slab.h> + +int +sg_alloc_table(struct sg_table *sgt, unsigned npgs, gfp_t gfp) +{ + + sgt->sgl->sg_pgs = kcalloc(npgs, sizeof(sgt->sgl->sg_pgs[0]), gfp); + if (sgt->sgl->sg_pgs == NULL) + return -ENOMEM; + sgt->sgl->sg_npgs = sgt->nents = npgs; + sgt->sgl->sg_dmamap = NULL; + + return 0; +} + +int +sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pgs, + unsigned npgs, bus_size_t offset, bus_size_t size, gfp_t gfp) +{ + unsigned i; + int ret; + + KASSERT(offset == 0); + KASSERT(size == (bus_size_t)npgs << PAGE_SHIFT); + + ret = sg_alloc_table(sgt, npgs, gfp); + if (ret) + return ret; + + for (i = 0; i < npgs; i++) + sgt->sgl->sg_pgs[i] = pgs[i]; + + return 0; +} + +int +sg_alloc_table_from_bus_dmamem(struct sg_table *sgt, bus_dma_tag_t dmat, + const bus_dma_segment_t *seg, int nseg, gfp_t gfp) +{ + int ret; + + KASSERT(nseg >= 1); + + ret = sg_alloc_table(sgt, nseg, gfp); + if (ret) + return ret; + + /* XXX errno NetBSD->Linux */ + ret = -bus_dmamem_export_pages(dmat, seg, nseg, sgt->sgl->sg_pgs, + sgt->sgl->sg_npgs); + if (ret) + goto out; + + /* Success! */ + ret = 0; + +out: if (ret) + sg_free_table(sgt); + return ret; +} + +void +sg_free_table(struct sg_table *sgt) +{ + + KASSERT(sgt->sgl->sg_dmamap == NULL); + kfree(sgt->sgl->sg_pgs); + sgt->sgl->sg_pgs = NULL; + sgt->sgl->sg_npgs = 0; +} + +int +dma_map_sg(bus_dma_tag_t dmat, struct scatterlist *sg, int nents, int dir) +{ + + return dma_map_sg_attrs(dmat, sg, nents, dir, 0); +} + +int +dma_map_sg_attrs(bus_dma_tag_t dmat, struct scatterlist *sg, int nents, + int dir, int attrs) +{ + int flags = 0; + bool loaded = false; + int ret, error = 0; + + KASSERT(sg->sg_dmamap == NULL); + KASSERT(nents >= 1); + + switch (dir) { + case DMA_TO_DEVICE: + flags |= BUS_DMA_WRITE; + break; + case DMA_FROM_DEVICE: + flags |= BUS_DMA_READ; + break; + case DMA_BIDIRECTIONAL: + break; + case DMA_NONE: + panic("invalid DMA direction %d", dir); + } + + error = bus_dmamap_create(dmat, (bus_size_t)sg->sg_npgs << PAGE_SHIFT, + nents, PAGE_SIZE, 0, BUS_DMA_WAITOK, &sg->sg_dmamap); + if (error) + goto out; + KASSERT(sg->sg_dmamap); + + error = bus_dmamap_load_pages(dmat, sg->sg_dmamap, sg->sg_pgs, + (bus_size_t)sg->sg_npgs << PAGE_SHIFT, BUS_DMA_WAITOK|flags); + if (error) + goto out; + loaded = true; + + /* Success! */ + KASSERT(sg->sg_dmamap->dm_nsegs > 0); + KASSERT(sg->sg_dmamap->dm_nsegs <= nents); + ret = sg->sg_dmamap->dm_nsegs; + +out: if (error) { + if (loaded) + bus_dmamap_unload(dmat, sg->sg_dmamap); + loaded = false; + if (sg->sg_dmamap) + bus_dmamap_destroy(dmat, sg->sg_dmamap); + sg->sg_dmamap = NULL; + ret = 0; + } + return ret; +} + +void +dma_unmap_sg(bus_dma_tag_t dmat, struct scatterlist *sg, int nents, int dir) +{ + + dma_unmap_sg_attrs(dmat, sg, nents, dir, 0); +} + +void +dma_unmap_sg_attrs(bus_dma_tag_t dmat, struct scatterlist *sg, int nents, + int dir, int attrs) +{ + + bus_dmamap_unload(dmat, sg->sg_dmamap); + bus_dmamap_destroy(dmat, sg->sg_dmamap); + sg->sg_dmamap = NULL; +}