Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

gdev: added gmap() and gunmap() - TODO: wrapper library for OS runtime

cuda: added cuMemMap() and cuMemUnmap()
  • Loading branch information...
commit 87bf6a78d6a65e6a1a8dc1c5addb9ebf7a998198 1 parent da47997
Shinpei Kato authored
View
46 common/gdev_api.c
@@ -775,6 +775,52 @@ uint64_t gfree_dma(struct gdev_handle *h, void *buf)
}
/**
+ * gmap():
+ * map device memory to host DMA memory.
+ */
+void *gmap(struct gdev_handle *h, uint64_t addr)
+{
+ gdev_vas_t *vas = h->vas;
+ gdev_mem_t *mem;
+ void *buf;
+
+ if (!(mem = gdev_mem_lookup(vas, addr, GDEV_MEM_DEVICE)))
+ goto fail;
+
+ buf = gdev_mem_get_buf(mem);
+
+ /* if not mapped yet, map here. */
+ if (!buf) {
+ buf = gdev_mem_map(mem);
+ }
+
+ return buf;
+
+fail:
+ return NULL;
+}
+
+/**
+ * gunmap():
+ * unmap device memory from host DMA memory.
+ */
+int gunmap(struct gdev_handle *h, void *buf)
+{
+ gdev_vas_t *vas = h->vas;
+ gdev_mem_t *mem;
+
+ if (!(mem = gdev_mem_lookup(vas, (uint64_t)buf, GDEV_MEM_DMA)))
+ goto fail;
+
+ gdev_mem_unmap(mem);
+
+ return 0;
+
+fail:
+ return -ENOENT;
+}
+
+/**
* gmemcpy_to_device():
* copy data from @buf to device memory at @addr.
*/
View
2  common/gdev_api.h
@@ -48,6 +48,8 @@ uint64_t gmalloc(Ghandle h, uint64_t size);
uint64_t gfree(Ghandle h, uint64_t addr);
void *gmalloc_dma(Ghandle h, uint64_t size);
uint64_t gfree_dma(Ghandle h, void *buf);
+void *gmap(Ghandle h, uint64_t addr);
+int gunmap(Ghandle h, void *buf);
int gmemcpy_to_device(Ghandle h, uint64_t dst_addr, const void *src_buf, uint64_t size);
int gmemcpy_to_device_async(Ghandle h, uint64_t dst_addr, const void *src_buf, uint64_t size, uint32_t *id);
int gmemcpy_user_to_device(Ghandle h, uint64_t dst_addr, const void *src_buf, uint64_t size);
View
2  common/gdev_arch.h
@@ -77,6 +77,8 @@ gdev_mem_t *gdev_mem_alloc(gdev_vas_t *vas, uint64_t size, int type);
gdev_mem_t *gdev_mem_share(gdev_vas_t *vas, uint64_t size);
void gdev_mem_free(gdev_mem_t *mem);
void gdev_mem_gc(gdev_vas_t *vas);
+void *gdev_mem_map(gdev_mem_t *mem);
+void gdev_mem_unmap(gdev_mem_t *mem);
gdev_mem_t *gdev_mem_lookup(gdev_vas_t *vas, uint64_t addr, int type);
void *gdev_mem_get_buf(gdev_mem_t *mem);
uint64_t gdev_mem_get_addr(gdev_mem_t *mem);
View
2  common/gdev_nvidia.h
@@ -232,6 +232,8 @@ struct gdev_mem *gdev_raw_swap_alloc(struct gdev_device *gdev, uint64_t size);
void gdev_raw_swap_free(struct gdev_mem *mem);
struct gdev_mem *gdev_raw_mem_share(struct gdev_vas *vas, struct gdev_mem *mem, uint64_t *addr, uint64_t *size, void **map);
void gdev_raw_mem_unshare(struct gdev_mem *mem);
+void *gdev_raw_mem_map(struct gdev_mem *mem);
+void gdev_raw_mem_unmap(struct gdev_mem *mem);
uint32_t gdev_raw_read32(struct gdev_mem *mem, uint64_t addr);
void gdev_raw_write32(struct gdev_mem *mem, uint64_t addr, uint32_t val);
int gdev_raw_read(struct gdev_mem *mem, void *buf, uint64_t addr, uint32_t size);
View
12 common/gdev_nvidia_mem.c
@@ -222,6 +222,18 @@ void gdev_mem_gc(struct gdev_vas *vas)
#endif
}
+/* map device memory to host DMA memory. */
+void *gdev_mem_map(struct gdev_mem *mem)
+{
+ return gdev_raw_mem_map(mem);
+}
+
+/* unmap device memory from host DMA memory. */
+void gdev_mem_unmap(struct gdev_mem *mem)
+{
+ gdev_raw_mem_unmap(mem);
+}
+
/* look up the memory object allocated at the specified address. */
struct gdev_mem *gdev_mem_lookup(struct gdev_vas *vas, uint64_t addr, int type)
{
View
4 cuda/driver_api/cuda.h
@@ -762,8 +762,10 @@ CUresult cuMemcpyDtoHAsync(void *dstHost, CUdeviceptr srcDevice, unsigned int By
CUresult cuMemcpyHtoD(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount);
CUresult cuMemcpyHtoDAsync(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount, CUstream hStream);
CUresult cuMemcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, unsigned int ByteCount);
+CUresult cuMemMap(CUdeviceptr dptr, void **buf); /* Gdev extension */
+CUresult cuMemUnmap(void *buf); /* Gdev extension */
-/* Inter-Process Communication (IPC) */
+/* Inter-Process Communication (IPC) - Gdev extension */
CUresult cuShmGet(int *ptr, int key, size_t size, int flags);
CUresult cuShmAt(CUdeviceptr *dptr, int id, int flags);
CUresult cuShmDt(CUdeviceptr dptr);
View
63 cuda/driver_api/memory.c
@@ -352,3 +352,66 @@ CUresult cuMemcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, unsigned int
return CUDA_SUCCESS;
}
+
+/**
+ * Gdev extension: maps device memory to host memory.
+ *
+ * Parameters:
+ * dptr - Device pointer
+ * buf - Pointer to user buffer
+ *
+ * Returns:
+ * CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
+ * CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
+ */
+CUresult cuMemMap(CUdeviceptr dptr, void **buf)
+{
+ Ghandle handle;
+ uint64_t addr = dptr;
+ void *map;
+
+ if (!gdev_initialized)
+ return CUDA_ERROR_NOT_INITIALIZED;
+ if (!gdev_ctx_current)
+ return CUDA_ERROR_INVALID_CONTEXT;
+ if (!addr || !buf)
+ return CUDA_ERROR_INVALID_VALUE;
+
+ handle = gdev_ctx_current->gdev_handle;
+
+ if (!(map = gmap(handle, addr)))
+ return CUDA_ERROR_UNKNOWN;
+
+ *buf = map;
+
+ return CUDA_SUCCESS;
+}
+
+/**
+ * Gdev extension: unmaps device memory from host memory.
+ *
+ * Parameters:
+ * buf - User buffer
+ *
+ * Returns:
+ * CUDA_SUCCESS, CUDA_ERROR_DEINITIALIZED, CUDA_ERROR_NOT_INITIALIZED,
+ * CUDA_ERROR_INVALID_CONTEXT, CUDA_ERROR_INVALID_VALUE
+ */
+CUresult cuMemUnmap(void *buf)
+{
+ Ghandle handle;
+
+ if (!gdev_initialized)
+ return CUDA_ERROR_NOT_INITIALIZED;
+ if (!gdev_ctx_current)
+ return CUDA_ERROR_INVALID_CONTEXT;
+ if (!buf)
+ return CUDA_ERROR_INVALID_VALUE;
+
+ handle = gdev_ctx_current->gdev_handle;
+
+ if (gunmap(handle, buf))
+ return CUDA_ERROR_UNKNOWN;
+
+ return CUDA_SUCCESS;
+}
View
14 driver/pscnv/pscnv_drm.h
@@ -158,6 +158,12 @@ struct drm_pscnv_vm_rw {
const void *buf_wr; /* < */
};
+struct drm_pscnv_vm_map {
+ uint32_t vid; /* < */
+ uint32_t handle; /* < */
+ uint64_t map_handle; /* > < */
+};
+
#define DRM_PSCNV_GETPARAM 0x00 /* get some information from the card */
#define DRM_PSCNV_GEM_NEW 0x20 /* create a new BO */
#define DRM_PSCNV_GEM_INFO 0x21 /* get info about a BO */
@@ -176,6 +182,8 @@ struct drm_pscnv_vm_rw {
#define DRM_PSCNV_VM_WRITE32 0x2d /* Write to virtual memory */
#define DRM_PSCNV_VM_READ 0x2e /* Read from virtual memory */
#define DRM_PSCNV_VM_WRITE 0x2f /* Write to virtual memory */
+#define DRM_PSCNV_VM_MAP 0x30 /* Map virtual memory */
+#define DRM_PSCNV_VM_UNMAP 0x31 /* Unmap virtual memory */
#define DRM_IOCTL_PSCNV_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_PSCNV_GETPARAM, struct drm_pscnv_getparam)
#define DRM_IOCTL_PSCNV_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_PSCNV_GEM_NEW, struct drm_pscnv_gem_info)
@@ -193,7 +201,9 @@ struct drm_pscnv_vm_rw {
#define DRM_IOCTL_PSCNV_FIFO_INIT_IB DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_FIFO_INIT_IB, struct drm_pscnv_fifo_init_ib)
#define DRM_IOCTL_PSCNV_VM_READ32 DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_VM_READ32, struct drm_pscnv_vm_rw32)
#define DRM_IOCTL_PSCNV_VM_WRITE32 DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_VM_WRITE32, struct drm_pscnv_vm_rw32)
-#define DRM_IOCTL_PSCNV_VM_READ DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_VM_READ, struct drm_pscnv_vm_rw)
-#define DRM_IOCTL_PSCNV_VM_WRITE DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_VM_WRITE, struct drm_pscnv_vm_rw)
+#define DRM_IOCTL_PSCNV_VM_READ DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_VM_READ, struct drm_pscnv_vm_rw)
+#define DRM_IOCTL_PSCNV_VM_WRITE DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_VM_WRITE, struct drm_pscnv_vm_rw)
+#define DRM_IOCTL_PSCNV_VM_MAP DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_VM_MAP, struct drm_pscnv_vm_map)
+#define DRM_IOCTL_PSCNV_VM_UNMAP DRM_IOW(DRM_COMMAND_BASE + DRM_PSCNV_VM_UNMAP, struct drm_pscnv_vm_map)
#endif /* __PSCNV_DRM_H__ */
View
36 driver/pscnv/pscnv_gdev.c
@@ -339,6 +339,7 @@ static inline struct gdev_mem *__gdev_raw_mem_alloc(struct gdev_vas *vas, uint64
fail_ioremap:
GDEV_PRINT("Failed to map PCI BAR1\n");
+ pscnv_vspace_unmap_node(bo->map1);
fail_map_user:
GDEV_PRINT("Failed to map host and device memory\n");
pscnv_vspace_unmap(vspace, mm->start);
@@ -574,3 +575,38 @@ int gdev_raw_write(struct gdev_mem *mem, uint64_t addr, const void *buf, uint32_
return ret;
}
+
+/* map device memory to host DMA memory. */
+void *gdev_raw_mem_map(struct gdev_mem *mem)
+{
+ struct gdev_vas *vas = mem->vas;
+ struct gdev_device *gdev = vas->gdev;
+ struct drm_device *drm = (struct drm_device *) gdev->priv;
+ struct drm_nouveau_private *dev_priv = drm->dev_private;
+ struct pscnv_bo *bo = mem->bo;
+ unsigned long bar1_start = pci_resource_start(drm->pdev, 1);
+ void *map;
+
+ if (dev_priv->vm->map_user(bo))
+ goto fail_map_user;
+ if (!(map = ioremap(bar1_start + bo->map1->start, bo->size)))
+ goto fail_ioremap;
+
+ return map;
+
+fail_ioremap:
+ GDEV_PRINT("Failed to map PCI BAR1\n");
+ pscnv_vspace_unmap_node(bo->map1);
+fail_map_user:
+ GDEV_PRINT("Failed to map host and device memory\n");
+ return NULL;
+}
+
+/* unmap device memory from host DMA memory. */
+void gdev_raw_mem_unmap(struct gdev_mem *mem)
+{
+ struct pscnv_bo *bo = mem->bo;
+
+ pscnv_vspace_unmap_node(bo->map1);
+}
+
View
69 driver/pscnv/pscnv_ioctl.c
@@ -631,6 +631,71 @@ int pscnv_ioctl_vm_write(struct drm_device *dev, void *data, struct drm_file *fi
return ret;
}
+int pscnv_ioctl_vm_map(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_pscnv_vm_map *req = data;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct pscnv_bo *bo;
+ struct pscnv_vspace *vs;
+ int ret;
+
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+ vs = pscnv_get_vspace(dev, file_priv, req->vid);
+ if (!vs)
+ return -ENOENT;
+
+ obj = drm_gem_object_lookup(dev, file_priv, req->handle);
+ if (!obj) {
+ pscnv_vspace_unref(vs);
+ return -EBADF;
+ }
+
+ bo = obj->driver_private;
+
+ /* map the buffer object to BAR1. */
+ ret = dev_priv->vm->map_user(bo);
+
+ pscnv_vspace_unref(vs);
+
+ /* this handle will be used by mmap(). */
+ req->map_handle = (uint64_t)req->handle << 32;
+
+ return ret;
+}
+
+int pscnv_ioctl_vm_unmap(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ struct drm_pscnv_vm_map *req = data;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct pscnv_bo *bo;
+ struct pscnv_vspace *vs;
+
+ NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
+
+ vs = pscnv_get_vspace(dev, file_priv, req->vid);
+ if (!vs)
+ return -ENOENT;
+
+ obj = drm_gem_object_lookup(dev, file_priv, req->handle);
+ if (!obj) {
+ pscnv_vspace_unref(vs);
+ return -EBADF;
+ }
+
+ bo = obj->driver_private;
+
+ if (dev_priv->vm_ok && bo->map1)
+ pscnv_vspace_unmap_node(bo->map1);
+
+ pscnv_vspace_unref(vs);
+
+ return 0;
+}
+
+
#ifdef PSCNV_KAPI_DRM_IOCTL_DEF_DRV
struct drm_ioctl_desc nouveau_ioctls[] = {
DRM_IOCTL_DEF_DRV(PSCNV_GETPARAM, pscnv_ioctl_getparam, DRM_UNLOCKED),
@@ -650,6 +715,8 @@ struct drm_ioctl_desc nouveau_ioctls[] = {
DRM_IOCTL_DEF_DRV(PSCNV_VM_WRITE32, pscnv_ioctl_vm_write32, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(PSCNV_VM_READ, pscnv_ioctl_vm_read, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(PSCNV_VM_WRITE, pscnv_ioctl_vm_write, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(PSCNV_VM_MAP, pscnv_ioctl_vm_map, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(PSCNV_VM_UNMAP, pscnv_ioctl_vm_unmap, DRM_UNLOCKED),
};
#elif defined(PSCNV_KAPI_DRM_IOCTL_DEF)
struct drm_ioctl_desc nouveau_ioctls[] = {
@@ -670,6 +737,8 @@ struct drm_ioctl_desc nouveau_ioctls[] = {
DRM_IOCTL_DEF(DRM_PSCNV_VM_WRITE32, pscnv_ioctl_vm_write32, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_PSCNV_VM_READ, pscnv_ioctl_vm_read, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_PSCNV_VM_WRITE, pscnv_ioctl_vm_write, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_PSCNV_VM_MAP, pscnv_ioctl_vm_map, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_PSCNV_VM_UNMAP, pscnv_ioctl_vm_unmap, DRM_UNLOCKED),
};
#else
#error "Unknown IOCTLDEF method."
View
23 runtime/user/pscnv/libpscnv.c
@@ -312,3 +312,26 @@ int pscnv_vm_write(int fd, uint32_t vid, uint32_t handle, uint64_t addr, const v
return ret;
return 0;
}
+
+int pscnv_vm_map(int fd, uint32_t vid, uint32_t handle, uint64_t *map_handle) {
+ int ret;
+ struct drm_pscnv_vm_map req;
+ req.vid = vid;
+ req.handle = handle;
+ ret = drmCommandWriteRead(fd, DRM_PSCNV_VM_MAP, &req, sizeof(req));
+ if (ret)
+ return ret;
+ *map_handle = req.map_handle;
+ return 0;
+}
+
+int pscnv_vm_unmap(int fd, uint32_t vid, uint32_t handle) {
+ int ret;
+ struct drm_pscnv_vm_map req;
+ req.vid = vid;
+ req.handle = handle;
+ ret = drmCommandWriteRead(fd, DRM_PSCNV_VM_UNMAP, &req, sizeof(req));
+ if (ret)
+ return ret;
+ return 0;
+}
View
2  runtime/user/pscnv/libpscnv.h
@@ -49,6 +49,8 @@ int pscnv_vm_read32(int fd, uint32_t vid, uint32_t handle, uint64_t addr, uint32
int pscnv_vm_write32(int fd, uint32_t vid, uint32_t handle, uint64_t addr, uint32_t val);
int pscnv_vm_read(int fd, uint32_t vid, uint32_t handle, uint64_t addr, void *buf, uint32_t size);
int pscnv_vm_write(int fd, uint32_t vid, uint32_t handle, uint64_t addr, const void *buf, uint32_t size);
+int pscnv_vm_map(int fd, uint32_t vid, uint32_t handle, uint64_t *map_handle);
+int pscnv_vm_unmap(int fd, uint32_t vid, uint32_t handle);
#define pscnv_obj_gr_new pscnv_obj_eng_new
View
8 runtime/user/pscnv/pscnv_drm.h
@@ -156,6 +156,12 @@ struct drm_pscnv_vm_rw {
const void *buf_wr; /* < */
};
+struct drm_pscnv_vm_map {
+ uint32_t vid; /* < */
+ uint32_t handle; /* < */
+ uint64_t map_handle; /* > < */
+};
+
#define DRM_PSCNV_GETPARAM 0x00 /* get some information from the card */
#define DRM_PSCNV_GEM_NEW 0x20 /* create a new BO */
#define DRM_PSCNV_GEM_INFO 0x21 /* get info about a BO */
@@ -174,5 +180,7 @@ struct drm_pscnv_vm_rw {
#define DRM_PSCNV_VM_WRITE32 0x2d /* Write to virtual memory */
#define DRM_PSCNV_VM_READ 0x2e /* Read from virtual memory */
#define DRM_PSCNV_VM_WRITE 0x2f /* Write to virtual memory */
+#define DRM_PSCNV_VM_MAP 0x30 /* Map virtual memory */
+#define DRM_PSCNV_VM_UNMAP 0x31 /* Unmap virtual memory */
#endif /* __PSCNV_DRM_H__ */
View
38 runtime/user/pscnv/pscnv_gdev.c
@@ -390,3 +390,41 @@ int gdev_raw_write(struct gdev_mem *mem, uint64_t addr, const void *buf, uint32_
else
return pscnv_vm_write(fd, vid, handle, addr, buf, size);
}
+
+/* map device memory to host DMA memory. */
+void *gdev_raw_mem_map(struct gdev_mem *mem)
+{
+ struct pscnv_ib_bo *bo = mem->bo;
+ int fd = bo->fd;
+ int vid = bo->vid;
+ uint32_t handle = bo->handle;
+ uint32_t size = bo->size;
+ uint64_t map_handle;
+ void *map;
+
+ pscnv_vm_map(fd, vid, handle, &map_handle);
+
+ map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_handle);
+ if ((void*)map == MAP_FAILED)
+ goto fail;
+
+ return map;
+
+fail:
+ pscnv_vm_unmap(fd, vid, handle);
+ return NULL;
+}
+
+/* unmap device memory from host DMA memory. */
+void gdev_raw_mem_unmap(struct gdev_mem *mem)
+{
+ struct pscnv_ib_bo *bo = mem->bo;
+ int fd = bo->fd;
+ int vid = bo->vid;
+ uint32_t handle = bo->handle;
+ uint32_t size = bo->size;
+
+ munmap(mem->map, size);
+ pscnv_vm_unmap(fd, vid, handle);
+}
+
Please sign in to comment.
Something went wrong with that request. Please try again.