0,0 → 1,155 |
/* |
* Copyright © 2014 Broadcom |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
|
#ifdef USE_VC4_SIMULATOR |
|
#include "vc4_drv.h" |
|
int |
vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec) |
{ |
struct drm_vc4_submit_cl *args = exec->args; |
void *temp = NULL; |
void *bin, *render; |
int ret = 0; |
uint32_t bin_offset = 0; |
uint32_t render_offset = bin_offset + args->bin_cl_size; |
uint32_t shader_rec_offset = roundup(render_offset + |
args->render_cl_size, 16); |
uint32_t uniforms_offset = shader_rec_offset + args->shader_rec_size; |
uint32_t exec_size = uniforms_offset + args->uniforms_size; |
uint32_t temp_size = exec_size + (sizeof(struct vc4_shader_state) * |
args->shader_rec_count); |
|
if (shader_rec_offset < render_offset || |
uniforms_offset < shader_rec_offset || |
exec_size < uniforms_offset || |
args->shader_rec_count >= (UINT_MAX / |
sizeof(struct vc4_shader_state)) || |
temp_size < exec_size) { |
DRM_ERROR("overflow in exec arguments\n"); |
goto fail; |
} |
|
/* Allocate space where we'll store the copied in user command lists |
* and shader records. |
* |
* We don't just copy directly into the BOs because we need to |
* read the contents back for validation, and I think the |
* bo->vaddr is uncached access. |
*/ |
temp = kmalloc(temp_size, GFP_KERNEL); |
if (!temp) { |
DRM_ERROR("Failed to allocate storage for copying " |
"in bin/render CLs.\n"); |
ret = -ENOMEM; |
goto fail; |
} |
bin = temp + bin_offset; |
render = temp + render_offset; |
exec->shader_rec_u = temp + shader_rec_offset; |
exec->uniforms_u = temp + uniforms_offset; |
exec->shader_state = temp + exec_size; |
exec->shader_state_size = args->shader_rec_count; |
|
ret = copy_from_user(bin, |
(void __user *)(uintptr_t)args->bin_cl, |
args->bin_cl_size); |
if (ret) { |
DRM_ERROR("Failed to copy in bin cl\n"); |
goto fail; |
} |
|
ret = copy_from_user(render, |
(void __user *)(uintptr_t)args->render_cl, |
args->render_cl_size); |
if (ret) { |
DRM_ERROR("Failed to copy in render cl\n"); |
goto fail; |
} |
|
ret = copy_from_user(exec->shader_rec_u, |
(void __user *)(uintptr_t)args->shader_rec, |
args->shader_rec_size); |
if (ret) { |
DRM_ERROR("Failed to copy in shader recs\n"); |
goto fail; |
} |
|
ret = copy_from_user(exec->uniforms_u, |
(void __user *)(uintptr_t)args->uniforms, |
args->uniforms_size); |
if (ret) { |
DRM_ERROR("Failed to copy in uniforms cl\n"); |
goto fail; |
} |
|
exec->exec_bo = drm_gem_cma_create(dev, exec_size); |
#if 0 |
if (IS_ERR(exec->exec_bo)) { |
DRM_ERROR("Couldn't allocate BO for exec\n"); |
ret = PTR_ERR(exec->exec_bo); |
exec->exec_bo = NULL; |
goto fail; |
} |
#endif |
|
exec->ct0ca = exec->exec_bo->paddr + bin_offset; |
exec->ct1ca = exec->exec_bo->paddr + render_offset; |
|
exec->shader_rec_v = exec->exec_bo->vaddr + shader_rec_offset; |
exec->shader_rec_p = exec->exec_bo->paddr + shader_rec_offset; |
exec->shader_rec_size = args->shader_rec_size; |
|
exec->uniforms_v = exec->exec_bo->vaddr + uniforms_offset; |
exec->uniforms_p = exec->exec_bo->paddr + uniforms_offset; |
exec->uniforms_size = args->uniforms_size; |
|
ret = vc4_validate_cl(dev, |
exec->exec_bo->vaddr + bin_offset, |
bin, |
args->bin_cl_size, |
true, |
args->bin_cl_size != 0, |
exec); |
if (ret) |
goto fail; |
|
ret = vc4_validate_cl(dev, |
exec->exec_bo->vaddr + render_offset, |
render, |
args->render_cl_size, |
false, |
args->bin_cl_size != 0, |
exec); |
if (ret) |
goto fail; |
|
ret = vc4_validate_shader_recs(dev, exec); |
|
fail: |
kfree(temp); |
return ret; |
} |
|
#endif /* USE_VC4_SIMULATOR */ |