vcsm: Add dmabuf import function.
authorDave Stevenson <dave.stevenson@raspberrypi.org>
Fri, 8 Sep 2017 17:27:14 +0000 (18:27 +0100)
committerpopcornmix <popcornmix@gmail.com>
Fri, 8 Sep 2017 17:29:52 +0000 (18:29 +0100)
host_applications/linux/kernel_headers/vmcs_sm_ioctl.h
host_applications/linux/libs/sm/user-vcsm.c
host_applications/linux/libs/sm/user-vcsm.h
vcfw/rtos/common/rtos_common_mem.h

index c7dda8a378df8953be0b71bc512cba30b94bba3f..7cd8c2bec236236b9a16d0eb0b29cea4dc79e947 100644 (file)
@@ -76,6 +76,8 @@ enum vmcs_sm_cmd_e {
        VMCS_SM_CMD_CLEAN_INVALID,
        VMCS_SM_CMD_CLEAN_INVALID2,
 
+       VMCS_SM_CMD_IMPORT_DMABUF,
+
        VMCS_SM_CMD_LAST        /* Do no delete */
 };
 
@@ -200,6 +202,16 @@ struct vmcs_sm_ioctl_clean_invalid2 {
        } s[0];
 };
 
+struct vmcs_sm_ioctl_import_dmabuf {
+       /* user -> kernel */
+       int dmabuf_fd;
+       enum vmcs_sm_cache_e cached;
+       char name[VMCS_SM_RESOURCE_NAME];
+
+       /* kernel -> user */
+       unsigned int handle;
+};
+
 /* IOCTL numbers */
 #define VMCS_SM_IOCTL_MEM_ALLOC\
        _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_ALLOC,\
@@ -269,6 +281,10 @@ struct vmcs_sm_ioctl_clean_invalid2 {
        _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_HOST_WALK_PID_MAP,\
         struct vmcs_sm_ioctl_walk)
 
+#define VMCS_SM_IOCTL_MEM_IMPORT_DMABUF\
+       _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_IMPORT_DMABUF,\
+        struct vmcs_sm_ioctl_import_dmabuf)
+
 /* ---- Variable Externs ------------------------------------------------- */
 
 /* ---- Function Prototypes ---------------------------------------------- */
index 48f45cae7f1d1551b6d7152d7f5653375abbdd3f..391fd451fe237aa5ab9449ae0456716945aee250 100644 (file)
@@ -1629,3 +1629,72 @@ int vcsm_clean_invalid2( struct vcsm_user_clean_invalid2_s *s )
 out:
    return rc;
 }
+
+/* Imports a dmabuf, and binds it to a VCSM handle and MEM_HANDLE_T
+**
+** Returns:        0 on error
+**                 a non-zero opaque handle on success.
+**
+** On success, the user must invoke vcsm_lock with the returned opaque
+** handle to gain access to the memory associated with the opaque handle.
+** When finished using the memory, the user calls vcsm_unlock_xx (see those
+** function definition for more details on the one that can be used).
+** Use vcsm_release to detach from the dmabuf (VideoCore may still hold
+** a reference to the buffer until it has finished with the buffer).
+**
+*/
+unsigned int vcsm_import_dmabuf( int dmabuf, char *name )
+{
+   struct vmcs_sm_ioctl_import_dmabuf import;
+   int rc;
+
+   if ( vcsm_handle == VCSM_INVALID_HANDLE )
+   {
+      vcos_log_error( "[%s]: [%d]: invalid device or invalid handle!",
+                      __func__,
+                      getpid() );
+
+      rc = -1;
+      goto error;
+   }
+
+   memset( &import, 0, sizeof(import) );
+
+   /* Map the buffer on videocore via the VCSM (Videocore Shared Memory) interface. */
+   import.dmabuf_fd = dmabuf;
+   import.cached = VMCS_SM_CACHE_NONE; //Support no caching for now - makes it easier for cache management
+   if ( name != NULL )
+   {
+      memcpy ( import.name, name, 32 );
+   }
+   rc = ioctl( vcsm_handle,
+               VMCS_SM_IOCTL_MEM_IMPORT_DMABUF,
+               &import );
+
+   if ( rc < 0 || import.handle == 0 )
+   {
+      vcos_log_error( "[%s]: [%d] [%s]: ioctl mem-import-dmabuf FAILED [%d] (hdl: %x)",
+                      __func__,
+                      getpid(),
+                      import.name,
+                      rc,
+                      import.handle );
+      goto error;
+   }
+
+   vcos_log_trace( "[%s]: [%d] [%s]: ioctl mem-import-dmabuf %d (hdl: %x)",
+                   __func__,
+                   getpid(),
+                   import.name,
+                   rc,
+                   import.handle );
+
+   return import.handle;
+
+error:
+   if ( import.handle )
+   {
+      vcsm_free( import.handle );
+   }
+   return 0;
+}
index ecd705970ec26e2b54532c17641cb51c5667e019..f3afaf8a623661234b77106538685fc4198e3bd6 100644 (file)
@@ -453,6 +453,8 @@ struct vcsm_user_clean_invalid2_s {
 
 int vcsm_clean_invalid2( struct vcsm_user_clean_invalid2_s *s );
 
+unsigned int vcsm_import_dmabuf( int dmabuf, char *name );
+
 #ifdef __cplusplus
 }
 #endif
index 7e5b76df6f2b30efc7795e8583bc13f5146993f6..33ea2a7fd7d2fb8120f86b91942f823c5ffbdf6a 100644 (file)
@@ -343,6 +343,19 @@ extern MEM_HANDLE_T mem_alloc_ex(
 
 #ifdef MEM_WRAP_HACK
 extern MEM_HANDLE_T mem_wrap(void *p, uint32_t size, uint32_t align, MEM_FLAG_T flags, const char *desc);
+
+typedef void (*MEM_WRAP_TERM_T)(void */*priv*/, MEM_HANDLE_T /*term_handle*/, void */*p*/, int /*size*/);
+
+/*
+   int mem_wrap_set_on_term(MEM_HANDLE_T handle, MEM_WRAP_TERM_T term_cb, void *cb_priv);
+
+   Adds an additional release callback for wrapped MEM_HANDLE_T.
+   This allows the underlying allocator to release the wrapped memory.
+   The MEM_HANDLE_T must NOT be accessed with mem_lock/mem_acquire etc
+   from the callback context as the handle is already partially released.
+*/
+extern int mem_wrap_set_on_term(MEM_HANDLE_T handle, MEM_WRAP_TERM_T term_cb, void *cb_priv);
+
 #endif
 
 /*