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_ */