Module Name:    src
Committed By:   riastradh
Date:           Mon Aug 27 14:47:53 UTC 2018

Modified Files:
        src/sys/external/bsd/drm2/dist/drm/nouveau: nouveau_drm.c
            nouveau_nvif.c
        src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif: driver.h
            object.h
        src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core: client.h
            device.h
        src/sys/external/bsd/drm2/dist/drm/nouveau/nvif: nouveau_nvif_object.c
        src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device:
            nouveau_nvkm_engine_device_base.c

Log Message:
Allow nvkm_client_map to map subregions.

Linux ioremap does not care about overlapping mapped regions, but
bus_space_map does.  Since nouveau ioremaps the entire register space
of BAR 0, and separately some subregions of it, we need to convey the
bus addresses in question to it in order to bus_space_subregion.

Kinda kludgey, but we don't care about running this in userland or
anything.

While here: initialize object->map.tag.  Not physically necessary on
x86 as long as the x86_io_mem_tag is nonull, so this won't fix any
symptoms on x86, but it is wrong to leave it null.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c
cvs rdiff -u -r1.3 -r1.4 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c
cvs rdiff -u -r1.4 -r1.5 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h
cvs rdiff -u -r1.6 -r1.7 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h
cvs rdiff -u -r1.4 -r1.5 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h
cvs rdiff -u -r1.5 -r1.6 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h
cvs rdiff -u -r1.3 -r1.4 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c
cvs rdiff -u -r1.6 -r1.7 \
    
src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.13 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.14
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.13	Mon Aug 27 14:19:08 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c	Mon Aug 27 14:47:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_drm.c,v 1.13 2018/08/27 14:19:08 riastradh Exp $	*/
+/*	$NetBSD: nouveau_drm.c,v 1.14 2018/08/27 14:47:53 riastradh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_drm.c,v 1.13 2018/08/27 14:19:08 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_drm.c,v 1.14 2018/08/27 14:47:53 riastradh Exp $");
 
 #include <linux/console.h>
 #include <linux/delay.h>
@@ -467,6 +467,18 @@ nouveau_drm_load(struct drm_device *dev,
 		nvxx_client(&drm->client.base)->vm = drm->client.vm;
 	}
 
+#ifdef __NetBSD__
+    {
+	/* XXX Kludge to make register subregion mapping work.  */
+	struct nvkm_client *client = nvxx_client(&drm->client.base);
+	struct nvkm_device *device = nvxx_device(&drm->device);
+	client->mmiot = device->mmiot;
+	client->mmioh = device->mmioh;
+	client->mmioaddr = device->mmioaddr;
+	client->mmiosz = device->mmiosz;
+    }
+#endif
+
 	ret = nouveau_ttm_init(drm);
 	if (ret)
 		goto fail_ttm;

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c:1.3 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c:1.4
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c:1.3	Mon Aug 27 07:35:56 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_nvif.c	Mon Aug 27 14:47:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_nvif.c,v 1.3 2018/08/27 07:35:56 riastradh Exp $	*/
+/*	$NetBSD: nouveau_nvif.c,v 1.4 2018/08/27 14:47:53 riastradh Exp $	*/
 
 /*
  * Copyright 2014 Red Hat Inc.
@@ -29,7 +29,7 @@
  ******************************************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_nvif.c,v 1.3 2018/08/27 07:35:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_nvif.c,v 1.4 2018/08/27 14:47:53 riastradh Exp $");
 
 #include <core/client.h>
 #include <core/notify.h>
@@ -50,8 +50,25 @@ static int
 nvkm_client_map(void *priv, bus_space_tag_t tag, u64 busaddr, u32 size,
     bus_space_handle_t *handlep, void __iomem **ptrp)
 {
+	struct nvkm_client *client = nvxx_client(priv);
 	int ret;
 
+	if (tag == client->mmiot &&
+	    client->mmioaddr <= busaddr &&
+	    busaddr - client->mmioaddr <= client->mmiosz) {
+		const bus_size_t offset = busaddr - client->mmioaddr;
+		if (size > client->mmiosz - offset) {
+			DRM_ERROR("Invalid register access\n");
+			return -EFAULT;
+		}
+		ret = -bus_space_subregion(client->mmiot, client->mmioh,
+		    offset, size, handlep);
+		if (ret)
+			return ret;
+		*ptrp = bus_space_vaddr(tag, *handlep);
+		return 0;
+	}
+
 	ret = -bus_space_map(tag, busaddr, size, BUS_SPACE_MAP_LINEAR,
 	    handlep);
 	if (ret)
@@ -62,8 +79,22 @@ nvkm_client_map(void *priv, bus_space_ta
 
 static void
 nvkm_client_unmap(void *priv, bus_space_tag_t tag, bus_space_handle_t handle,
-    u32 size)
+    bus_addr_t busaddr, void __iomem *ptr, u32 size)
 {
+	struct nvkm_client *client = nvxx_client(priv);
+
+	KASSERTMSG(ptr == bus_space_vaddr(tag, handle),
+	    "nvkm_client ptr %p != %p [bus_space_vaddr(%p, %"PRIxVADDR")]",
+	    ptr, bus_space_vaddr(tag, handle), tag, handle);
+
+	if (tag == client->mmiot &&
+	    client->mmioaddr <= busaddr &&
+	    busaddr - client->mmioaddr <= client->mmiosz) {
+		const bus_size_t offset = busaddr - client->mmioaddr;
+		KASSERT(size <= client->mmiosz - offset);
+		/* Nothing to do to release a subregion.  */
+		return;
+	}
 
 	bus_space_unmap(tag, handle, size);
 }

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h:1.4 src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h:1.5
--- src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h:1.4	Mon Aug 27 07:35:56 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/driver.h	Mon Aug 27 14:47:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: driver.h,v 1.4 2018/08/27 07:35:56 riastradh Exp $	*/
+/*	$NetBSD: driver.h,v 1.5 2018/08/27 14:47:53 riastradh Exp $	*/
 
 #ifndef __NVIF_DRIVER_H__
 #define __NVIF_DRIVER_H__
@@ -20,7 +20,8 @@ struct nvif_driver {
 	int (*map)(void *priv, bus_space_tag_t tag, u64 handle, u32 size,
 	    bus_space_handle_t *handlep, void __iomem **ptrp);
 	void (*unmap)(void *priv, bus_space_tag_t tag,
-	    bus_space_handle_t handle, u32 size);
+	    bus_space_handle_t handle, bus_addr_t addr, void __iomem *ptr,
+	    u32 size);
 #else
 	void __iomem *(*map)(void *priv, u64 handle, u32 size);
 	void (*unmap)(void *priv, void __iomem *ptr, u32 size);

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h:1.6 src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h:1.7
--- src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h:1.6	Mon Aug 27 14:47:29 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvif/object.h	Mon Aug 27 14:47:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: object.h,v 1.6 2018/08/27 14:47:29 riastradh Exp $	*/
+/*	$NetBSD: object.h,v 1.7 2018/08/27 14:47:53 riastradh Exp $	*/
 
 #ifndef __NVIF_OBJECT_H__
 #define __NVIF_OBJECT_H__
@@ -25,6 +25,7 @@ struct nvif_object {
 #ifdef __NetBSD__
 		bus_space_tag_t tag;
 		bus_space_handle_t handle;
+		bus_addr_t addr;
 #endif
 		void __iomem *ptr;
 		u32 size;

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h:1.4 src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h:1.5
--- src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h:1.4	Mon Aug 27 07:36:07 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/client.h	Mon Aug 27 14:47:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: client.h,v 1.4 2018/08/27 07:36:07 riastradh Exp $	*/
+/*	$NetBSD: client.h,v 1.5 2018/08/27 14:47:53 riastradh Exp $	*/
 
 #ifndef __NVKM_CLIENT_H__
 #define __NVKM_CLIENT_H__
@@ -24,6 +24,13 @@ struct nvkm_client {
 	int (*ntfy)(const void *, u32, const void *, u32);
 
 	struct nvkm_vm *vm;
+
+#ifdef __NetBSD__
+	bus_space_tag_t mmiot;
+	bus_space_handle_t mmioh;
+	bus_addr_t mmioaddr;
+	bus_size_t mmiosz;
+#endif
 };
 
 extern const rb_tree_ops_t nvkm_client_dmatree_ops;

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h:1.5 src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h:1.6
--- src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h:1.5	Mon Aug 27 13:43:52 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/include/nvkm/core/device.h	Mon Aug 27 14:47:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: device.h,v 1.5 2018/08/27 13:43:52 riastradh Exp $	*/
+/*	$NetBSD: device.h,v 1.6 2018/08/27 14:47:53 riastradh Exp $	*/
 
 #ifndef __NVKM_DEVICE_H__
 #define __NVKM_DEVICE_H__
@@ -77,6 +77,7 @@ struct nvkm_device {
 #ifdef __NetBSD__
 	bus_space_tag_t mmiot;
 	bus_space_handle_t mmioh;
+	bus_addr_t mmioaddr;
 	bus_size_t mmiosz;
 #else
 	void __iomem *pri;

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c:1.3 src/sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c:1.4
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c:1.3	Mon Aug 27 07:35:56 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nvif/nouveau_nvif_object.c	Mon Aug 27 14:47:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_nvif_object.c,v 1.3 2018/08/27 07:35:56 riastradh Exp $	*/
+/*	$NetBSD: nouveau_nvif_object.c,v 1.4 2018/08/27 14:47:53 riastradh Exp $	*/
 
 /*
  * Copyright 2014 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_nvif_object.c,v 1.3 2018/08/27 07:35:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_nvif_object.c,v 1.4 2018/08/27 14:47:53 riastradh Exp $");
 
 #include <nvif/object.h>
 #include <nvif/client.h>
@@ -185,6 +185,8 @@ nvif_object_unmap(struct nvif_object *ob
 		if (object->map.ptr) {
 			client->driver->unmap(client, object->map.tag,
 						      object->map.handle,
+						      object->map.addr,
+						      object->map.ptr,
 						      object->map.size);
 			object->map.ptr = NULL;
 		}
@@ -216,6 +218,8 @@ nvif_object_map(struct nvif_object *obje
 	if (ret == 0) {
 		object->map.size = args.map.length;
 #ifdef __NetBSD__
+		object->map.tag = args.map.tag;
+		object->map.addr = args.map.handle;
 		ret = client->driver->map(client, args.map.tag,
 		    args.map.handle, object->map.size, &object->map.handle,
 		    &object->map.ptr);

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c:1.6 src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c:1.7
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c:1.6	Mon Aug 27 13:43:52 2018
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/engine/device/nouveau_nvkm_engine_device_base.c	Mon Aug 27 14:47:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_nvkm_engine_device_base.c,v 1.6 2018/08/27 13:43:52 riastradh Exp $	*/
+/*	$NetBSD: nouveau_nvkm_engine_device_base.c,v 1.7 2018/08/27 14:47:53 riastradh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -24,7 +24,7 @@
  * Authors: Ben Skeggs
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_device_base.c,v 1.6 2018/08/27 13:43:52 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_device_base.c,v 1.7 2018/08/27 14:47:53 riastradh Exp $");
 
 #include "priv.h"
 #include "acpi.h"
@@ -2570,6 +2570,7 @@ nvkm_device_ctor(const struct nvkm_devic
 		}
 		device->mmiot = mmiot;
 		device->mmioh = mmioh;
+		device->mmioaddr = mmio_base;
 		device->mmiosz = mmio_size;
 #else
 		device->pri = ioremap(mmio_base, mmio_size);

Reply via email to