Module Name: src Committed By: riastradh Date: Thu Feb 17 01:21:03 UTC 2022
Modified Files: src/sys/external/bsd/common/include/linux: compiler.h src/sys/external/bsd/drm2/dist/drm/vmwgfx: ttm_lock.c ttm_lock.h ttm_object.c vmwgfx_cmdbuf.c vmwgfx_drv.c vmwgfx_drv.h vmwgfx_resource.c vmwgfx_validation.h src/sys/external/bsd/drm2/pci: files.drmkms_pci Added Files: src/sys/external/bsd/drm2/include/asm: hypervisor.h vmware.h src/sys/external/bsd/drm2/include/linux: dmapool.h frame.h pci_ids.h src/sys/external/bsd/drm2/vmwgfx: files.vmwgfx vmware_pack_begin.h vmware_pack_end.h vmwgfx2netbsd vmwgfx_module.c vmwgfx_pci.c vmwgfx_task.h vmwgfxfb.c vmwgfxfb.h Log Message: drm/vmwgfx: First draft. Passes make depend, doesn't build yet. To generate a diff of this commit: cvs rdiff -u -r1.6 -r1.7 src/sys/external/bsd/common/include/linux/compiler.h cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.c \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.h \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_object.c \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_validation.h cvs rdiff -u -r1.3 -r1.4 \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cmdbuf.c \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_resource.c cvs rdiff -u -r1.4 -r1.5 \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c cvs rdiff -u -r1.5 -r1.6 \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/include/asm/hypervisor.h \ src/sys/external/bsd/drm2/include/asm/vmware.h cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/include/linux/dmapool.h \ src/sys/external/bsd/drm2/include/linux/frame.h \ src/sys/external/bsd/drm2/include/linux/pci_ids.h cvs rdiff -u -r1.15 -r1.16 src/sys/external/bsd/drm2/pci/files.drmkms_pci cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/vmwgfx/files.vmwgfx \ src/sys/external/bsd/drm2/vmwgfx/vmware_pack_begin.h \ src/sys/external/bsd/drm2/vmwgfx/vmware_pack_end.h \ src/sys/external/bsd/drm2/vmwgfx/vmwgfx2netbsd \ src/sys/external/bsd/drm2/vmwgfx/vmwgfx_module.c \ src/sys/external/bsd/drm2/vmwgfx/vmwgfx_pci.c \ src/sys/external/bsd/drm2/vmwgfx/vmwgfx_task.h \ src/sys/external/bsd/drm2/vmwgfx/vmwgfxfb.c \ src/sys/external/bsd/drm2/vmwgfx/vmwgfxfb.h 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/common/include/linux/compiler.h diff -u src/sys/external/bsd/common/include/linux/compiler.h:1.6 src/sys/external/bsd/common/include/linux/compiler.h:1.7 --- src/sys/external/bsd/common/include/linux/compiler.h:1.6 Sun Dec 19 11:26:57 2021 +++ src/sys/external/bsd/common/include/linux/compiler.h Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: compiler.h,v 1.6 2021/12/19 11:26:57 riastradh Exp $ */ +/* $NetBSD: compiler.h,v 1.7 2022/02/17 01:21:02 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -50,6 +50,8 @@ #define __maybe_unused __unused #define noinline __noinline #define __deprecated /* nothing */ +#define __acquire(X) /* nothing */ +#define __release(X) /* nothing */ #define barrier() __insn_barrier() #define likely(X) __predict_true(X) Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.c:1.2 src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.c:1.3 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.c:1.2 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.c Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ttm_lock.c,v 1.2 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: ttm_lock.c,v 1.3 2022/02/17 01:21:02 riastradh Exp $ */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /************************************************************************** @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ttm_lock.c,v 1.2 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ttm_lock.c,v 1.3 2022/02/17 01:21:02 riastradh Exp $"); #include <linux/atomic.h> #include <linux/errno.h> @@ -50,7 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: ttm_lock.c,v void ttm_lock_init(struct ttm_lock *lock) { spin_lock_init(&lock->lock); - init_waitqueue_head(&lock->queue); + DRM_INIT_WAITQUEUE(&lock->queue, "ttmlock"); lock->rw = 0; lock->flags = 0; } @@ -59,7 +59,7 @@ void ttm_read_unlock(struct ttm_lock *lo { spin_lock(&lock->lock); if (--lock->rw == 0) - wake_up_all(&lock->queue); + DRM_SPIN_WAKEUP_ALL(&lock->queue, &lock->lock); spin_unlock(&lock->lock); } @@ -67,12 +67,10 @@ static bool __ttm_read_lock(struct ttm_l { bool locked = false; - spin_lock(&lock->lock); if (lock->rw >= 0 && lock->flags == 0) { ++lock->rw; locked = true; } - spin_unlock(&lock->lock); return locked; } @@ -80,11 +78,15 @@ int ttm_read_lock(struct ttm_lock *lock, { int ret = 0; + spin_lock(&lock->lock); if (interruptible) - ret = wait_event_interruptible(lock->queue, - __ttm_read_lock(lock)); + DRM_SPIN_WAIT_UNTIL(ret, &lock->queue, &lock->lock, + __ttm_read_lock(lock)); else - wait_event(lock->queue, __ttm_read_lock(lock)); + DRM_SPIN_WAIT_NOINTR_UNTIL(ret, &lock->queue, &lock->lock, + __ttm_read_lock(lock)); + spin_unlock(&lock->lock); + return ret; } @@ -112,11 +114,14 @@ int ttm_read_trylock(struct ttm_lock *lo int ret = 0; bool locked; + spin_lock(&lock->lock); if (interruptible) - ret = wait_event_interruptible - (lock->queue, __ttm_read_trylock(lock, &locked)); + DRM_SPIN_WAIT_UNTIL(ret, &lock->queue, &lock->lock, + __ttm_read_trylock(lock, &locked)); else - wait_event(lock->queue, __ttm_read_trylock(lock, &locked)); + DRM_SPIN_WAIT_NOINTR_UNTIL(ret, &lock->queue, &lock->lock, + __ttm_read_trylock(lock, &locked)); + spin_unlock(&lock->lock); if (unlikely(ret != 0)) { BUG_ON(locked); @@ -130,7 +135,7 @@ void ttm_write_unlock(struct ttm_lock *l { spin_lock(&lock->lock); lock->rw = 0; - wake_up_all(&lock->queue); + DRM_SPIN_WAKEUP_ALL(&lock->queue, &lock->lock); spin_unlock(&lock->lock); } @@ -154,17 +159,18 @@ int ttm_write_lock(struct ttm_lock *lock { int ret = 0; + spin_lock(&lock->lock); if (interruptible) { - ret = wait_event_interruptible(lock->queue, - __ttm_write_lock(lock)); + DRM_SPIN_WAIT_UNTIL(ret, &lock->queue, &lock->lock, + __ttm_write_lock(lock)); if (unlikely(ret != 0)) { - spin_lock(&lock->lock); lock->flags &= ~TTM_WRITE_LOCK_PENDING; - wake_up_all(&lock->queue); - spin_unlock(&lock->lock); + DRM_SPIN_WAKEUP_ONE(&lock->queue, &lock->lock); } } else - wait_event(lock->queue, __ttm_write_lock(lock)); + DRM_SPIN_WAIT_NOINTR_UNTIL(ret, &lock->queue, &lock->lock, + __ttm_write_lock(lock)); + spin_unlock(&lock->lock); return ret; } @@ -173,7 +179,7 @@ void ttm_suspend_unlock(struct ttm_lock { spin_lock(&lock->lock); lock->flags &= ~TTM_SUSPEND_LOCK; - wake_up_all(&lock->queue); + DRM_SPIN_WAKEUP_ALL(&lock->queue, &lock->lock); spin_unlock(&lock->lock); } @@ -181,7 +187,6 @@ static bool __ttm_suspend_lock(struct tt { bool locked = false; - spin_lock(&lock->lock); if (lock->rw == 0) { lock->flags &= ~TTM_SUSPEND_LOCK_PENDING; lock->flags |= TTM_SUSPEND_LOCK; @@ -189,11 +194,15 @@ static bool __ttm_suspend_lock(struct tt } else { lock->flags |= TTM_SUSPEND_LOCK_PENDING; } - spin_unlock(&lock->lock); return locked; } void ttm_suspend_lock(struct ttm_lock *lock) { - wait_event(lock->queue, __ttm_suspend_lock(lock)); + int ret; + + spin_lock(&lock->lock); + DRM_SPIN_WAIT_UNTIL(ret, &lock->queue, &lock->lock, + __ttm_suspend_lock(lock)); + spin_unlock(&lock->lock); } Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.h diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.h:1.2 src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.h:1.3 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.h:1.2 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.h Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ttm_lock.h,v 1.2 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: ttm_lock.h,v 1.3 2022/02/17 01:21:02 riastradh Exp $ */ /************************************************************************** * @@ -56,6 +56,10 @@ #include "ttm_object.h" +#ifdef __NetBSD__ +#include "drm_wait_netbsd.h" /* XXX */ +#endif + /** * struct ttm_lock * @@ -69,7 +73,7 @@ struct ttm_lock { struct ttm_base_object base; - wait_queue_head_t queue; + drm_waitqueue_t queue; spinlock_t lock; int32_t rw; uint32_t flags; Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_object.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_object.c:1.2 src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_object.c:1.3 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_object.c:1.2 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/ttm_object.c Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ttm_object.c,v 1.2 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: ttm_object.c,v 1.3 2022/02/17 01:21:02 riastradh Exp $ */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /************************************************************************** @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ttm_object.c,v 1.2 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ttm_object.c,v 1.3 2022/02/17 01:21:02 riastradh Exp $"); #define pr_fmt(fmt) "[TTM] " fmt @@ -71,6 +71,8 @@ __KERNEL_RCSID(0, "$NetBSD: ttm_object.c #include <linux/atomic.h> #include "ttm_object.h" +#include <linux/nbsd-namespace.h> + struct ttm_object_file { struct ttm_object_device *tdev; spinlock_t lock; @@ -586,7 +588,19 @@ void ttm_object_device_release(struct tt */ static bool __must_check get_dma_buf_unless_doomed(struct dma_buf *dmabuf) { +#ifdef __NetBSD__ + /* XXX move this to linux_dma_buf.c */ + unsigned cnt; + + do { + cnt = atomic_load_relaxed(&dmabuf->db_refcnt); + if (cnt == 0) + return false; + } while (atomic_cas_uint(&dmabuf->db_refcnt, cnt, cnt + 1) != cnt); + return true; +#else return atomic_long_inc_not_zero(&dmabuf->file->f_count) != 0L; +#endif } /** Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_validation.h diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_validation.h:1.2 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_validation.h:1.3 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_validation.h:1.2 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_validation.h Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_validation.h,v 1.2 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: vmwgfx_validation.h,v 1.3 2022/02/17 01:21:02 riastradh Exp $ */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /************************************************************************** @@ -216,7 +216,7 @@ vmw_validation_context_init(struct vmw_v */ static inline unsigned int vmw_validation_align(unsigned int val) { - return ALIGN(val, sizeof(long)); + return round_up(val, sizeof(long)); } int vmw_validation_add_bo(struct vmw_validation_context *ctx, Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cmdbuf.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cmdbuf.c:1.3 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cmdbuf.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cmdbuf.c:1.3 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cmdbuf.c Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_cmdbuf.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: vmwgfx_cmdbuf.c,v 1.4 2022/02/17 01:21:02 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -28,7 +28,7 @@ **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_cmdbuf.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_cmdbuf.c,v 1.4 2022/02/17 01:21:02 riastradh Exp $"); #include <linux/dmapool.h> #include <linux/pci.h> @@ -37,6 +37,8 @@ __KERNEL_RCSID(0, "$NetBSD: vmwgfx_cmdbu #include "vmwgfx_drv.h" +#include <linux/nbsd-namespace.h> + /* * Size of inline command buffers. Try to make sure that a page size is a * multiple of the DMA pool allocation size. Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_resource.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_resource.c:1.3 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_resource.c:1.4 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_resource.c:1.3 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_resource.c Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_resource.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: vmwgfx_resource.c,v 1.4 2022/02/17 01:21:02 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -28,7 +28,7 @@ **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_resource.c,v 1.3 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_resource.c,v 1.4 2022/02/17 01:21:02 riastradh Exp $"); #include <drm/ttm/ttm_placement.h> @@ -51,6 +51,9 @@ void vmw_resource_mob_attach(struct vmw_ res->used_prio = (res->res_dirty) ? res->func->dirty_prio : res->func->prio; +#ifdef __NetBSD__ + rb_tree_insert_node etc etc etc +#else while (*new) { struct vmw_resource *this = container_of(*new, struct vmw_resource, mob_node); @@ -62,6 +65,8 @@ void vmw_resource_mob_attach(struct vmw_ rb_link_node(&res->mob_node, parent, new); rb_insert_color(&res->mob_node, &backup->res_tree); +#endif + res->mob_attached = true; vmw_bo_prio_add(backup, res->used_prio); } @@ -76,6 +81,7 @@ void vmw_resource_mob_detach(struct vmw_ dma_resv_assert_held(backup->base.base.resv); if (vmw_resource_mob_attached(res)) { + res->mob_attached = false; rb_erase(&res->mob_node, &backup->res_tree); RB_CLEAR_NODE(&res->mob_node); vmw_bo_prio_del(backup, res->used_prio); Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c:1.4 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c:1.5 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c:1.4 Sat Dec 18 23:45:45 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_drv.c,v 1.4 2021/12/18 23:45:45 riastradh Exp $ */ +/* $NetBSD: vmwgfx_drv.c,v 1.5 2022/02/17 01:21:02 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -28,7 +28,7 @@ **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_drv.c,v 1.4 2021/12/18 23:45:45 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_drv.c,v 1.5 2022/02/17 01:21:02 riastradh Exp $"); #include <linux/console.h> #include <linux/dma-mapping.h> @@ -1430,6 +1430,14 @@ static struct drm_driver driver = { .patchlevel = VMWGFX_DRIVER_PATCHLEVEL }; +#ifdef __NetBSD__ + +static const struct drm_driver *const vmwgfx_driver = &driver; +static const struct pci_device_id *const vmwgfx_pci_ids = vmw_pci_id_list; +static const size_t vmwgfx_n_pci_ids = __arraycount(vmw_pci_id_list); + +#else + static struct pci_driver vmw_pci_driver = { .name = VMWGFX_DRIVER_NAME, .id_table = vmw_pci_id_list, @@ -1495,6 +1503,8 @@ static void __exit vmwgfx_exit(void) pci_unregister_driver(&vmw_pci_driver); } +#endif + module_init(vmwgfx_init); module_exit(vmwgfx_exit); Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.5 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.6 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.5 Sun Dec 19 00:25:04 2021 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_drv.h,v 1.5 2021/12/19 00:25:04 riastradh Exp $ */ +/* $NetBSD: vmwgfx_drv.h,v 1.6 2022/02/17 01:21:02 riastradh Exp $ */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /************************************************************************** @@ -30,6 +30,7 @@ #ifndef _VMWGFX_DRV_H_ #define _VMWGFX_DRV_H_ +#include <linux/notifier.h> #include <linux/suspend.h> #include <linux/sync_file.h> @@ -185,6 +186,7 @@ struct vmw_resource { unsigned long pin_count; const struct vmw_res_func *func; struct rb_node mob_node; + bool mob_attached; struct list_head lru_head; struct list_head binding_head; struct vmw_resource_dirty *dirty; @@ -329,7 +331,9 @@ struct vmw_sg_table { struct vmw_piter { struct page **pages; const dma_addr_t *addrs; +#ifndef __NetBSD__ /* XXX */ struct sg_dma_page_iter iter; +#endif unsigned long i; unsigned long num_pages; bool (*next)(struct vmw_piter *); @@ -451,7 +455,13 @@ struct vmw_private { struct drm_device *dev; struct drm_vma_offset_manager vma_manager; unsigned long vmw_chipset; +#ifdef __NetBSD__ + bus_space_tag_t iot; + bus_space_handle_t ioh; + bus_size_t iosz; +#else unsigned int io_start; +#endif uint32_t vram_start; uint32_t vram_size; uint32_t prim_bb_mem; @@ -527,8 +537,8 @@ struct vmw_private { */ atomic_t marker_seq; - wait_queue_head_t fence_queue; - wait_queue_head_t fifo_queue; + drm_waitqueue_t fence_queue; + drm_waitqueue_t fifo_queue; spinlock_t waiter_lock; int fence_queue_waiters; /* Protected by waiter_lock */ int goal_queue_waiters; /* Protected by waiter_lock */ @@ -645,8 +655,15 @@ static inline void vmw_write(struct vmw_ unsigned int offset, uint32_t value) { spin_lock(&dev_priv->hw_lock); +#ifdef __NetBSD__ + bus_space_write_4(dev_priv->iot, dev_priv->ioh, VMWGFX_INDEX_PORT, + offset); + bus_space_write_4(dev_priv->iot, dev_priv->ioh, VMWGFX_VALUE_PORT, + value); +#else outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT); +#endif spin_unlock(&dev_priv->hw_lock); } @@ -656,8 +673,15 @@ static inline uint32_t vmw_read(struct v u32 val; spin_lock(&dev_priv->hw_lock); +#ifdef __NetBSD__ + bus_space_write_4(dev_priv->iot, dev_priv->ioh, VMWGFX_INDEX_PORT, + offset); + val = bus_space_read_4(dev_priv->iot, dev_priv->ioh, + VMWGFX_VALUE_PORT); +#else outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT); +#endif spin_unlock(&dev_priv->hw_lock); return val; @@ -742,7 +766,7 @@ int vmw_resources_clean(struct vmw_buffe */ static inline bool vmw_resource_mob_attached(const struct vmw_resource *res) { - return !RB_EMPTY_NODE(&res->mob_node); + return res->mob_attached; } /** @@ -883,10 +907,13 @@ extern int vmw_present_ioctl(struct drm_ struct drm_file *file_priv); extern int vmw_present_readback_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +#ifdef __NetBSD__ +#else extern __poll_t vmw_fops_poll(struct file *filp, struct poll_table_struct *wait); extern ssize_t vmw_fops_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset); +#endif /** * Fifo utilities - vmwgfx_fifo.c @@ -927,7 +954,13 @@ extern int vmw_fifo_flush(struct vmw_pri * TTM glue - vmwgfx_ttm_glue.c */ +#ifdef __NetBSD__ +struct uvm_object; +extern int vmw_mmap_object(struct drm_device *, off_t, size_t, vm_prot_t, + struct uvm_object **, voff_t, struct file *); +#else extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma); +#endif extern void vmw_validation_mem_init_ttm(struct vmw_private *dev_priv, size_t gran); @@ -1430,8 +1463,17 @@ void vmw_bo_dirty_clear_res(struct vmw_r void vmw_bo_dirty_release(struct vmw_buffer_object *vbo); void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo, pgoff_t start, pgoff_t end); +#ifdef __NetBSD__ +struct uvm_fault_info; +struct vm_page; +int vmw_bo_vm_fault(struct uvm_fault_info *, vaddr_t, struct vm_page **, + int, int, vm_prot_t, int); +int vmw_bo_vm_mkwrite(struct uvm_fault_info *, vaddr_t, struct vm_page **, + int, int, vm_prot_t, int); +#else vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf); vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf); +#endif /** * VMW_DEBUG_KMS - Debug output for kernel mode-setting Index: src/sys/external/bsd/drm2/pci/files.drmkms_pci diff -u src/sys/external/bsd/drm2/pci/files.drmkms_pci:1.15 src/sys/external/bsd/drm2/pci/files.drmkms_pci:1.16 --- src/sys/external/bsd/drm2/pci/files.drmkms_pci:1.15 Sun Dec 19 10:55:37 2021 +++ src/sys/external/bsd/drm2/pci/files.drmkms_pci Thu Feb 17 01:21:02 2022 @@ -1,4 +1,4 @@ -# $NetBSD: files.drmkms_pci,v 1.15 2021/12/19 10:55:37 riastradh Exp $ +# $NetBSD: files.drmkms_pci,v 1.16 2022/02/17 01:21:02 riastradh Exp $ define drmkms_pci: drmkms @@ -15,3 +15,4 @@ include "external/bsd/drm2/i915drm/files include "external/bsd/drm2/radeon/files.radeon" include "external/bsd/drm2/nouveau/files.nouveau" include "external/bsd/drm2/via/files.via" +include "external/bsd/drm2/vmwgfx/files.vmwgfx" Added files: Index: src/sys/external/bsd/drm2/vmwgfx/files.vmwgfx diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/files.vmwgfx:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/files.vmwgfx Thu Feb 17 01:21:03 2022 @@ -0,0 +1,69 @@ +# $NetBSD: files.vmwgfx,v 1.1 2022/02/17 01:21:03 riastradh Exp $ + +version 20180827 + +define vmwgfxfbbus { } +device vmwgfx: drmkms, drmkms_pci, drmkms_ttm, vmwgfxfbbus +attach vmwgfx at pci + +device vmwgfxfb: vmwgfxfbbus, drmfb, drmfb_pci, wsemuldisplaydev +attach vmwgfxfb at vmwgfxfbbus + +# This code comes from the Linux kernel, which assumes signed +# overflow is OK. +makeoptions vmwgfx "COPTS.vmwgfx"+="-fwrapv" + +makeoptions vmwgfxfb "CPPFLAGS.vmwgfxfb"+="${CPPFLAGS.vmwgfx}" + +# Our overrides first. +makeoptions vmwgfx "CPPFLAGS.vmwgfx"+="-I$S/external/bsd/drm2/vmwgfx" + +# Then their header files. +makeoptions vmwgfx "CPPFLAGS.vmwgfx"+="-I$S/external/bsd/drm2/dist/drm/vmwgfx" + +makeoptions vmwgfx "CWARNFLAGS.vmwgfx"+="-Wno-missing-field-initializers" + +file external/bsd/drm2/vmwgfx/vmwgfx_module.c vmwgfx +file external/bsd/drm2/vmwgfx/vmwgfx_pci.c vmwgfx + +file external/bsd/drm2/vmwgfx/vmwgfxfb.c vmwgfxfb + +# Generated from vmwgfx2netbsd. Tweaked to avoid renaming ttm_*.c to +# vmwgfx_ttm_*.c -- do that on the next import. +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_binding.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_blit.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_bo.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cmdbuf.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cmdbuf_res.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_context.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_cotable.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_execbuf.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fb.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fence.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_fifo.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_gmr.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_gmrid_manager.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_ioctl.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_kms.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_ldu.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_marker.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_mob.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_msg.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_overlay.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_page_dirty.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_prime.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_resource.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_scrn.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_shader.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_simple_resource.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_so.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_stdu.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_surface.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_ttm_buffer.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_ttm_glue.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/ttm_lock.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/ttm_object.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_va.c vmwgfx +file external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_validation.c vmwgfx Index: src/sys/external/bsd/drm2/vmwgfx/vmware_pack_begin.h diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/vmware_pack_begin.h:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/vmware_pack_begin.h Thu Feb 17 01:21:03 2022 @@ -0,0 +1 @@ +#include <linux/compiler.h> Index: src/sys/external/bsd/drm2/vmwgfx/vmware_pack_end.h diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/vmware_pack_end.h:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/vmware_pack_end.h Thu Feb 17 01:21:03 2022 @@ -0,0 +1 @@ +__packed Index: src/sys/external/bsd/drm2/vmwgfx/vmwgfx2netbsd diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/vmwgfx2netbsd:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/vmwgfx2netbsd Thu Feb 17 01:21:03 2022 @@ -0,0 +1,65 @@ +#!/bin/sh + +# $NetBSD: vmwgfx2netbsd,v 1.1 2022/02/17 01:21:03 riastradh Exp $ +# +# $ /path/to/vmwgfx2netbsd > /path/to/files.vmwgfx.new +# +# Run from the top-level vmwgfx source directory. + +set -Ceu + +: ${MV:=mv} + +# Location of the vmwgfx sources relative to $NETBSDSRCDIR. +vmwgfx_top=external/bsd/drm2/dist/drm/vmwgfx + +# config(5) flag for the vmwgfx driver. +vmwgfx_flag=vmwgfx + +env CONFIG_ACPI=y \ +env src=. \ +make -f Makefile -V '$(vmwgfx-y)' \ +| tr ' ' '\n' \ +| grep -v -e '^[[:space:]]*$' \ +| sed -e 's,\.o$,.c,' \ +| sort -u \ +| awk ' + BEGIN { + duplicates = 0 + } + { + if (index($1, "/")) { + dir = $1 + sub("/[^/]*$", "/", dir) + base = $1 + sub("^.*/", "", base) + } else { + dir = "" + base = $1 + } + fqbase = (base ~ "^vmwgfx_" ? "" : "vmwgfx_") base + if (seen[fqbase]) { + printf("Duplicate basename: %s %s\n", fqbase, + seen[fqbase]) >"/dev/stderr" + duplicates = 1 + } + if (duplicates) + next + printf("%s %s\n", $1, dir fqbase) + } + END { + if (duplicates) { + printf("Time to rewite me!\n") > "/dev/stderr" + exit 1 + } + } +' \ +| while read from to; do + # If the move already happened, that's fine: the makefile + # detects duplicates. + if [ "x$from" != "x$to" -a \! -f "$to" ]; then + ${MV} -f -- "$from" "$to" + fi + printf 'file\t%s\t%s\n' "$vmwgfx_top/$to" "$vmwgfx_flag" +done \ +| sort -u Index: src/sys/external/bsd/drm2/vmwgfx/vmwgfx_module.c diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/vmwgfx_module.c:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/vmwgfx_module.c Thu Feb 17 01:21:03 2022 @@ -0,0 +1,133 @@ +/* $NetBSD: vmwgfx_module.c,v 1.1 2022/02/17 01:21:03 riastradh Exp $ */ + +/*- + * Copyright (c) 2022 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: vmwgfx_module.c,v 1.1 2022/02/17 01:21:03 riastradh Exp $"); + +#include <sys/types.h> +#include <sys/module.h> +#ifndef _MODULE +#include <sys/once.h> +#endif +#include <sys/systm.h> + +#include <drm/drm_device.h> +#include <drm/drm_drv.h> +#include <drm/drm_sysctl.h> + +#include "vmwgfx_drv.h" + +MODULE(MODULE_CLASS_DRIVER, vmwgfx, "drmkms,drmkms_pci"); /* XXX drmkms_i2c, drmkms_ttm */ + +#ifdef _MODULE +#include "ioconf.c" +#endif + +struct drm_sysctl_def vmwgfx_def = DRM_SYSCTL_INIT(); + +static int +vmwgfx_init(void) +{ + int error; + + error = drm_guarantee_initialized(); + if (error) + return error; + + drm_sysctl_init(&vmwgfx_def); + + return 0; +} + +int vmwgfx_guarantee_initialized(void); /* XXX */ +int +vmwgfx_guarantee_initialized(void) +{ +#ifdef _MODULE + return 0; +#else + static ONCE_DECL(vmwgfx_init_once); + + return RUN_ONCE(&vmwgfx_init_once, &vmwgfx_init); +#endif +} + +static void +vmwgfx_fini(void) +{ + + drm_sysctl_fini(&vmwgfx_def); +} + +static int +vmwgfx_modcmd(modcmd_t cmd, void *arg __unused) +{ + int error; + + switch (cmd) { + case MODULE_CMD_INIT: + /* XXX Kludge it up... Must happen before attachment. */ +#ifdef _MODULE + error = vmwgfx_init(); +#else + error = vmwgfx_guarantee_initialized(); +#endif + if (error) { + aprint_error("vmwgfx: failed to initialize: %d\n", + error); + return error; + } +#ifdef _MODULE + error = config_init_component(cfdriver_ioconf_vmwgfx, + cfattach_ioconf_vmwgfx, cfdata_ioconf_vmwgfx); + if (error) { + aprint_error("vmwgfx: failed to init component" + ": %d\n", error); + vmwgfx_fini(); + return error; + } +#endif + return 0; + + case MODULE_CMD_FINI: +#ifdef _MODULE + error = config_fini_component(cfdriver_ioconf_vmwgfx, + cfattach_ioconf_vmwgfx, cfdata_ioconf_vmwgfx); + if (error) { + aprint_error("vmwgfx: failed to fini component" + ": %d\n", error); + return error; + } +#endif + vmwgfx_fini(); + return 0; + + default: + return ENOTTY; + } +} Index: src/sys/external/bsd/drm2/vmwgfx/vmwgfx_pci.c diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/vmwgfx_pci.c:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/vmwgfx_pci.c Thu Feb 17 01:21:03 2022 @@ -0,0 +1,336 @@ +/* $NetBSD: vmwgfx_pci.c,v 1.1 2022/02/17 01:21:03 riastradh Exp $ */ + +/*- + * Copyright (c) 2022 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: vmwgfx_pci.c,v 1.1 2022/02/17 01:21:03 riastradh Exp $"); + +#ifdef _KERNEL_OPT +#include "vga.h" +#endif + +#include <sys/types.h> +#include <sys/atomic.h> +#include <sys/queue.h> +#include <sys/systm.h> +#include <sys/workqueue.h> + +#include <dev/pci/pciio.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> + +#include <dev/pci/wsdisplay_pci.h> +#include <dev/wsfb/genfbvar.h> + +#include <drm/drm_device.h> +#include <drm/drm_drv.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_pci.h> + +#include "vmwgfx_drv.h" +#include "vmwgfx_task.h" + +SIMPLEQ_HEAD(vmwgfx_task_head, vmwgfx_task); + +struct vmwgfx_softc { + device_t sc_dev; + struct pci_attach_args sc_pa; + struct lwp *sc_task_thread; + struct vmwgfx_task_head sc_tasks; + struct workqueue *sc_task_wq; + struct drm_device *sc_drm_dev; + struct pci_dev sc_pci_dev; + bool sc_pci_attached; + bool sc_dev_registered; +#if defined(__i386__) +#define VMWGFX_PCI_UGLY_MAP_HACK + /* XXX Used to claim the VGA device before attach_real */ + bus_space_handle_t sc_temp_memh; + bool sc_temp_set; +#endif +}; + +static bool vmwgfx_pci_lookup(const struct pci_attach_args *, + unsigned long *); + +static int vmwgfx_match(device_t, cfdata_t, void *); +static void vmwgfx_attach(device_t, device_t, void *); +static void vmwgfx_attach_real(device_t); +static int vmwgfx_detach(device_t, int); +static bool vmwgfx_do_suspend(device_t, const pmf_qual_t *); +static bool vmwgfx_do_resume(device_t, const pmf_qual_t *); + +static void vmwgfx_task_work(struct work *, void *); + +CFATTACH_DECL_NEW(vmwgfx, sizeof(struct vmwgfx_softc), + vmwgfx_match, vmwgfx_attach, vmwgfx_detach, NULL); + +/* XXX Kludge to get these from vmwgfx_drv.c. */ +extern struct drm_driver *const vmwgfx_drm_driver; +extern const struct pci_device_id *const vmwgfx_device_ids; +extern const size_t vmwgfx_n_device_ids; + +static bool +vmwgfx_pci_lookup(const struct pci_attach_args *pa, unsigned long *flags) +{ + size_t i; + + for (i = 0; i < vmwgfx_n_device_ids; i++) { + if ((PCI_VENDOR(pa->pa_id) == vmwgfx_device_ids[i].vendor) && + (PCI_PRODUCT(pa->pa_id) == vmwgfx_device_ids[i].device)) + break; + } + + /* Did we find it? */ + if (i == vmwgfx_n_device_ids) + return false; + + if (flags) + *flags = vmwgfx_device_ids[i].driver_data; + return true; +} + +static int +vmwgfx_match(device_t parent, cfdata_t match, void *aux) +{ + extern int vmwgfx_guarantee_initialized(void); + const struct pci_attach_args *const pa = aux; + int error; + + error = vmwgfx_guarantee_initialized(); + if (error) { + aprint_error("vmwgfx: failed to initialize: %d\n", error); + return 0; + } + + if (!vmwgfx_pci_lookup(pa, NULL)) + return 0; + + return 6; /* XXX Beat genfb_pci... */ +} + +static void +vmwgfx_attach(device_t parent, device_t self, void *aux) +{ + struct vmwgfx_softc *const sc = device_private(self); + const struct pci_attach_args *const pa = aux; + int error; + + pci_aprint_devinfo(pa, NULL); + + /* Initialize the Linux PCI device descriptor. */ + linux_pci_dev_init(&sc->sc_pci_dev, self, device_parent(self), pa, 0); + + sc->sc_dev = self; + sc->sc_pa = *pa; + sc->sc_task_thread = NULL; + SIMPLEQ_INIT(&sc->sc_tasks); + error = workqueue_create(&sc->sc_task_wq, "vmwgfxfb", + &vmwgfx_task_work, NULL, PRI_NONE, IPL_NONE, WQ_MPSAFE); + if (error) { + aprint_error_dev(self, "unable to create workqueue: %d\n", + error); + sc->sc_task_wq = NULL; + return; + } + +#ifdef VMWGFX_PCI_UGLY_MAP_HACK + /* + * XXX + * We try to map the VGA registers, in case we can prevent vga@isa or + * pcdisplay@isa attaching, and stealing wsdisplay0. This only works + * with serial console, as actual VGA console has already mapped them. + * The only way to handle that is for vga@isa to not attach. + */ + int rv = bus_space_map(pa->pa_memt, 0xb0000, 0x10000, 0, + &sc->sc_temp_memh); + sc->sc_temp_set = rv == 0; + if (rv != 0) + aprint_error_dev(self, "unable to reserve VGA registers for " + "i386 vmwgfxdrmkms hack\n"); +#endif + + /* + * Defer the remainder of initialization until we have mounted + * the root file system and can load firmware images. + */ + config_mountroot(self, &vmwgfx_attach_real); +} + +static void +vmwgfx_attach_real(device_t self) +{ + struct vmwgfx_softc *const sc = device_private(self); + const struct pci_attach_args *const pa = &sc->sc_pa; + bool ok __diagused; + unsigned long flags = 0 /*XXXGCC*/; + int error; + + ok = vmwgfx_pci_lookup(pa, &flags); + KASSERT(ok); + +#ifdef VMWGFX_PCI_UGLY_MAP_HACK + /* + * XXX + * Unmap the VGA registers. + */ + if (sc->sc_temp_set) + bus_space_unmap(pa->pa_memt, sc->sc_temp_memh, 0x10000); +#endif + + /* + * Cause any tasks issued synchronously during attach to be + * processed at the end of this function. + */ + sc->sc_task_thread = curlwp; + + sc->sc_drm_dev = drm_dev_alloc(vmwgfx_drm_driver, self); + if (IS_ERR(sc->sc_drm_dev)) { + aprint_error_dev(self, "unable to create drm device: %ld\n", + PTR_ERR(sc->sc_drm_dev)); + sc->sc_drm_dev = NULL; + goto out; + } + + /* XXX errno Linux->NetBSD */ + error = -drm_pci_attach(sc->sc_drm_dev, &sc->sc_pci_dev); + if (error) { + aprint_error_dev(self, "unable to attach drm: %d\n", error); + goto out; + } + sc->sc_pci_attached = true; + + /* XXX errno Linux->NetBSD */ + error = -drm_dev_register(sc->sc_drm_dev, flags); + if (error) { + aprint_error_dev(self, "unable to register drm: %d\n", error); + goto out; + } + sc->sc_dev_registered = true; + + if (!pmf_device_register(self, &vmwgfx_do_suspend, &vmwgfx_do_resume)) + aprint_error_dev(self, "unable to establish power handler\n"); + + /* + * Process asynchronous tasks queued synchronously during + * attach. This will be for display detection to attach a + * framebuffer, so we have the opportunity for a console device + * to attach before autoconf has completed, in time for init(8) + * to find that console without panicking. + */ + while (!SIMPLEQ_EMPTY(&sc->sc_tasks)) { + struct vmwgfx_task *const task = SIMPLEQ_FIRST(&sc->sc_tasks); + + SIMPLEQ_REMOVE_HEAD(&sc->sc_tasks, vt_u.queue); + (*task->vt_fn)(task); + } + +out: /* Cause any subesquent tasks to be processed by the workqueue. */ + atomic_store_relaxed(&sc->sc_task_thread, NULL); +} + +static int +vmwgfx_detach(device_t self, int flags) +{ + struct vmwgfx_softc *const sc = device_private(self); + int error; + + /* XXX Check for in-use before tearing it all down... */ + error = config_detach_children(self, flags); + if (error) + return error; + + KASSERT(sc->sc_task_thread == NULL); + KASSERT(SIMPLEQ_EMPTY(&sc->sc_tasks)); + + pmf_device_deregister(self); + if (sc->sc_dev_registered) + drm_dev_unregister(sc->sc_drm_dev); + if (sc->sc_pci_attached) + drm_pci_detach(sc->sc_drm_dev); + if (sc->sc_drm_dev) { + drm_dev_put(sc->sc_drm_dev); + sc->sc_drm_dev = NULL; + } + if (sc->sc_task_wq) { + workqueue_destroy(sc->sc_task_wq); + sc->sc_task_wq = NULL; + } + linux_pci_dev_destroy(&sc->sc_pci_dev); + + return 0; +} + +static bool +vmwgfx_do_suspend(device_t self, const pmf_qual_t *qual) +{ + struct vmwgfx_softc *const sc = device_private(self); + struct drm_device *const dev = sc->sc_drm_dev; + int ret; + + ret = vmw_kms_suspend(dev); + if (ret) + return false; + + return true; +} + +static bool +vmwgfx_do_resume(device_t self, const pmf_qual_t *qual) +{ + struct vmwgfx_softc *const sc = device_private(self); + struct drm_device *const dev = sc->sc_drm_dev; + int ret; + + ret = vmw_kms_resume(dev); + if (ret) + return false; + + return true; +} + +static void +vmwgfx_task_work(struct work *work, void *cookie __unused) +{ + struct vmwgfx_task *const task = container_of(work, struct vmwgfx_task, + vt_u.work); + + (*task->vt_fn)(task); +} + +int +vmwgfx_task_schedule(device_t self, struct vmwgfx_task *task) +{ + struct vmwgfx_softc *const sc = device_private(self); + + if (atomic_load_relaxed(&sc->sc_task_thread) == curlwp) + SIMPLEQ_INSERT_TAIL(&sc->sc_tasks, task, vt_u.queue); + else + workqueue_enqueue(sc->sc_task_wq, &task->vt_u.work, NULL); + + return 0; +} Index: src/sys/external/bsd/drm2/vmwgfx/vmwgfx_task.h diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/vmwgfx_task.h:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/vmwgfx_task.h Thu Feb 17 01:21:03 2022 @@ -0,0 +1,52 @@ +/* $NetBSD: vmwgfx_task.h,v 1.1 2022/02/17 01:21:03 riastradh Exp $ */ + +/*- + * Copyright (c) 2022 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. + */ + +#ifndef _VMWGFX_VMWGFX_TASK_H_ +#define _VMWGFX_VMWGFX_TASK_H_ + +#include <sys/queue.h> +#include <sys/workqueue.h> + +struct vmwgfx_task { + union { + SIMPLEQ_ENTRY(vmwgfx_task) queue; + struct work work; + } vt_u; + void (*vt_fn)(struct vmwgfx_task *); +}; + +static inline void +vmwgfx_task_init(struct vmwgfx_task *task, void (*fn)(struct vmwgfx_task *)) +{ + + task->vt_fn = fn; +} + +int vmwgfx_task_schedule(device_t, struct vmwgfx_task *); + +#endif /* _VMWGFX_VMWGFX_TASK_H_ */ Index: src/sys/external/bsd/drm2/vmwgfx/vmwgfxfb.c diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/vmwgfxfb.c:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/vmwgfxfb.c Thu Feb 17 01:21:03 2022 @@ -0,0 +1,210 @@ +/* $NetBSD: vmwgfxfb.c,v 1.1 2022/02/17 01:21:03 riastradh Exp $ */ + +/*- + * Copyright (c) 2022 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: vmwgfxfb.c,v 1.1 2022/02/17 01:21:03 riastradh Exp $"); + +#include <sys/types.h> +#include <sys/device.h> + +#include <drm/drm_fb_helper.h> +#include <drm/drmfb.h> +#include <drm/drmfb_pci.h> + +#include "vmwgfx_drv.h" +#include "vmwgfx_task.h" +#include "vmwgfxfb.h" + +struct vmwgfxfb_softc { + struct drmfb_softc sc_drmfb; /* XXX Must be first. */ + device_t sc_dev; + struct vmwgfxfb_attach_args sc_vfa; + struct vmwgfx_task sc_attach_task; + bool sc_scheduled:1; + bool sc_attached:1; +}; + +static int vmwgfxfb_match(device_t, cfdata_t, void *); +static void vmwgfxfb_attach(device_t, device_t, void *); +static int vmwgfxfb_detach(device_t, int); + +static void vmwgfxfb_attach_task(struct vmwgfx_task *); + +static paddr_t vmwgfxfb_drmfb_mmapfb(struct drmfb_softc *, off_t, int); +static bool vmwgfxfb_shutdown(device_t, int); + +CFATTACH_DECL_NEW(vmwgfxfb, sizeof(struct vmwgfxfb_softc), + vmwgfxfb_match, vmwgfxfb_attach, vmwgfxfb_detach, NULL); + +static const struct drmfb_params vmwgfxfb_drmfb_params = { + .dp_mmapfb = vmwgfxfb_drmfb_mmapfb, + .dp_mmap = drmfb_pci_mmap, + .dp_ioctl = drmfb_pci_ioctl, + .dp_is_vga_console = drmfb_pci_is_vga_console, +}; + +static int +vmwgfxfb_match(device_t parent, cfdata_t match, void *aux) +{ + + return 1; +} + +static void +vmwgfxfb_attach(device_t parent, device_t self, void *aux) +{ + struct vmwgfxfb_softc *const sc = device_private(self); + const struct vmwgfxfb_attach_args *const vfa = aux; + int error; + + sc->sc_dev = self; + sc->sc_vfa = *vfa; + sc->sc_scheduled = false; + sc->sc_attached = false; + + aprint_naive("\n"); + aprint_normal("\n"); + + vmwgfx_task_init(&sc->sc_attach_task, &vmwgfxfb_attach_task); + error = vmwgfx_task_schedule(parent, &sc->sc_attach_task); + if (error) { + aprint_error_dev(self, "failed to schedule mode set: %d\n", + error); + goto fail0; + } + sc->sc_scheduled = true; + + /* Success! */ + return; + +fail0: return; +} + +static int +vmwgfxfb_detach(device_t self, int flags) +{ + struct vmwgfxfb_softc *const sc = device_private(self); + int error; + + if (sc->sc_scheduled) + return EBUSY; + + if (sc->sc_attached) { + pmf_device_deregister(self); + error = drmfb_detach(&sc->sc_drmfb, flags); + if (error) { + /* XXX Ugh. */ + (void)pmf_device_register1(self, NULL, NULL, + &vmwgfxfb_shutdown); + return error; + } + sc->sc_attached = false; + } + + return 0; +} + +static void +vmwgfxfb_attach_task(struct vmwgfx_task *task) +{ + struct vmwgfxfb_softc *const sc = container_of(task, + struct vmwgfxfb_softc, sc_attach_task); + const struct vmwgfxfb_attach_args *const vfa = &sc->sc_vfa; + const struct drmfb_attach_args da = { + .da_dev = sc->sc_dev, + .da_fb_helper = vfa->vfa_fb_helper, + .da_fb_sizes = &vfa->vfa_fb_sizes, + .da_fb_vaddr = __UNVOLATILE(vfa->vfa_fb_ptr), + .da_fb_linebytes = vfa->vfa_fb_linebytes, + .da_params = &vmwgfxfb_drmfb_params, + }; + device_t parent = device_parent(sc->sc_dev); + bool is_console; + int error; + + KASSERT(sc->sc_scheduled); + + /* + * MD device enumeration logic may choose the vmwgfxN PCI + * device as the console. If so, propagate that down to the + * vmwgfxfbN device for genfb. + */ + if (prop_dictionary_get_bool(device_properties(parent), + "is_console", &is_console) && + !prop_dictionary_set_bool(device_properties(sc->sc_dev), + "is_console", is_console)) { + aprint_error_dev(sc->sc_dev, "failed to set is_console\n"); + } + + error = drmfb_attach(&sc->sc_drmfb, &da); + if (error) { + aprint_error_dev(sc->sc_dev, "failed to attach drmfb: %d\n", + error); + return; + } + if (!pmf_device_register1(sc->sc_dev, NULL, NULL, &vmwgfxfb_shutdown)) + aprint_error_dev(sc->sc_dev, + "failed to register shutdown handler\n"); + + sc->sc_attached = true; +} + +static bool +vmwgfxfb_shutdown(device_t self, int flags) +{ + struct vmwgfxfb_softc *const sc = device_private(self); + + return drmfb_shutdown(&sc->sc_drmfb, flags); +} + +static paddr_t +vmwgfxfb_drmfb_mmapfb(struct drmfb_softc *drmfb, off_t offset, int prot) +{ + struct vmwgfxfb_softc *const sc = container_of(drmfb, + struct vmwgfxfb_softc, sc_drmfb); + struct drm_fb_helper *const helper = sc->sc_vfa.vfa_fb_helper; + struct drm_framebuffer *const fb = helper->fb; + struct vmw_buffer_object *const vbo = /*XXX MAGIC HERE*/; + int flags = 0; + + if (offset < 0) + return -1; + + const unsigned num_pages __diagused = vbo->base.num_pages; + + KASSERT(offset < (num_pages << PAGE_SHIFT)); + KASSERT(vbo->base.mem.bus.is_iomem); + + if (ISSET(vbo->base.mem.placement, TTM_PL_FLAG_WC)) + flags |= BUS_SPACE_MAP_PREFETCHABLE; + + return bus_space_mmap(vbo->base.bdev->memt, + vbo->base.mem.bus.base, vbo->base.mem.bus.offset + offset, + prot, flags); +} Index: src/sys/external/bsd/drm2/vmwgfx/vmwgfxfb.h diff -u /dev/null src/sys/external/bsd/drm2/vmwgfx/vmwgfxfb.h:1.1 --- /dev/null Thu Feb 17 01:21:03 2022 +++ src/sys/external/bsd/drm2/vmwgfx/vmwgfxfb.h Thu Feb 17 01:21:03 2022 @@ -0,0 +1,43 @@ +/* $NetBSD: vmwgfxfb.h,v 1.1 2022/02/17 01:21:03 riastradh Exp $ */ + +/*- + * Copyright (c) 2022 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. + */ + +#ifndef _VMWGFX_VMWGFXFB_H_ +#define _VMWGFX_VMWGFXFB_H_ + +#include <drm/drm_fb_helper.h> + +struct drm_device; + +struct vmwgfxfb_attach_args { + struct drm_fb_helper *vfa_fb_helper; + struct drm_fb_helper_surface_size vfa_fb_sizes; + void *vfa_fb_ptr; + uint32_t vfa_fb_linebytes; +}; + +#endif /* _VMWGFX_VMWGFX_H_ */