vc4: Move the mirrored kernel code to a kernel/ directory.

Now this whole setup matches the kernel's file layout much more closely.
This commit is contained in:
Eric Anholt 2014-09-30 16:25:48 -07:00
parent ef9914aa74
commit 0b96a086cb
12 changed files with 383 additions and 258 deletions

View File

@ -2163,6 +2163,7 @@ AC_CONFIG_FILES([Makefile
src/gallium/drivers/svga/Makefile
src/gallium/drivers/trace/Makefile
src/gallium/drivers/vc4/Makefile
src/gallium/drivers/vc4/kernel/Makefile
src/gallium/state_trackers/clover/Makefile
src/gallium/state_trackers/dri/Makefile
src/gallium/state_trackers/egl/Makefile

View File

@ -19,6 +19,8 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
SUBDIRS = kernel
include Makefile.sources
include $(top_srcdir)/src/gallium/Automake.inc
@ -37,5 +39,5 @@ AM_CFLAGS = \
noinst_LTLIBRARIES = libvc4.la
libvc4_la_SOURCES = $(C_SOURCES)
libvc4_la_LIBADD = $(SIM_LIB)
libvc4_la_LIBADD = $(SIM_LIB) kernel/libvc4_kernel.la
libvc4_la_LDFLAGS = $(SIM_LDFLAGS)

View File

@ -32,10 +32,11 @@ C_SOURCES := \
vc4_screen.c \
vc4_screen.h \
vc4_simulator.c \
vc4_simulator_validate.c \
vc4_simulator_validate.h \
vc4_simulator_validate_shaders.c \
vc4_state.c \
vc4_tiling.c \
vc4_tiling.h \
kernel/vc4_gem.c \
kernel/vc4_validate.c \
kernel/vc4_validate_shaders.c \
$()

View File

@ -0,0 +1,40 @@
# 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.
include Makefile.sources
include $(top_srcdir)/src/gallium/Automake.inc
if USE_VC4_SIMULATOR
SIM_CFLAGS = -DUSE_VC4_SIMULATOR=1
endif
AM_CFLAGS = \
$(LIBDRM_CFLAGS) \
$(GALLIUM_DRIVER_CFLAGS) \
$(SIM_CFLAGS) \
-I$(top_srcdir)/src/mesa/ \
-I$(srcdir)/../ \
$()
noinst_LTLIBRARIES = libvc4_kernel.la
libvc4_kernel_la_SOURCES = $(C_SOURCES)
libvc4_kernel_la_LDFLAGS = $(SIM_LDFLAGS)

View File

@ -0,0 +1,5 @@
C_SOURCES := \
vc4_gem.c \
vc4_validate.c \
vc4_validate_shaders.c \
$()

View File

@ -0,0 +1,6 @@
This is a mirror of the kernel validation code into the userspace GL library.
It is only built when USE_VC4_SIMULATOR is defined, for compiling the driver
on an x86 system with the simpenrose simulator. It allows testing of changes
across the kernel and userspace with exposure to most of the software stack,
on a higher-performance and more-debuggable environment than the native
hardware.

View File

@ -0,0 +1,168 @@
/*
* 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.
*/
#ifndef VC4_DRV_H
#define VC4_DRV_H
#include "vc4_simulator_validate.h"
enum vc4_bo_mode {
VC4_MODE_UNDECIDED,
VC4_MODE_TILE_ALLOC,
VC4_MODE_TSDA,
VC4_MODE_RENDER,
VC4_MODE_SHADER,
};
struct vc4_bo_exec_state {
struct drm_gem_cma_object *bo;
enum vc4_bo_mode mode;
};
struct exec_info {
/* Kernel-space copy of the ioctl arguments */
struct drm_vc4_submit_cl *args;
/* This is the array of BOs that were looked up at the start of exec.
* Command validation will use indices into this array.
*/
struct vc4_bo_exec_state *bo;
uint32_t bo_count;
/* Current unvalidated indices into @bo loaded by the non-hardware
* VC4_PACKET_GEM_HANDLES.
*/
uint32_t bo_index[2];
/* This is the BO where we store the validated command lists, shader
* records, and uniforms.
*/
struct drm_gem_cma_object *exec_bo;
/**
* This tracks the per-shader-record state (packet 64) that
* determines the length of the shader record and the offset
* it's expected to be found at. It gets read in from the
* command lists.
*/
struct vc4_shader_state {
uint8_t packet;
uint32_t addr;
/* Maximum vertex index referenced by any primitive using this
* shader state.
*/
uint32_t max_index;
} *shader_state;
/** How many shader states the user declared they were using. */
uint32_t shader_state_size;
/** How many shader state records the validator has seen. */
uint32_t shader_state_count;
bool found_tile_binning_mode_config_packet;
bool found_tile_rendering_mode_config_packet;
bool found_start_tile_binning_packet;
uint8_t bin_tiles_x, bin_tiles_y;
uint32_t fb_width, fb_height;
uint32_t tile_alloc_init_block_size;
struct drm_gem_cma_object *tile_alloc_bo;
/**
* Computed addresses pointing into exec_bo where we start the
* bin thread (ct0) and render thread (ct1).
*/
uint32_t ct0ca, ct0ea;
uint32_t ct1ca, ct1ea;
/* Pointers to the shader recs. These paddr gets incremented as CL
* packets are relocated in validate_gl_shader_state, and the vaddrs
* (u and v) get incremented and size decremented as the shader recs
* themselves are validated.
*/
void *shader_rec_u;
void *shader_rec_v;
uint32_t shader_rec_p;
uint32_t shader_rec_size;
/* Pointers to the uniform data. These pointers are incremented, and
* size decremented, as each batch of uniforms is uploaded.
*/
void *uniforms_u;
void *uniforms_v;
uint32_t uniforms_p;
uint32_t uniforms_size;
};
/**
* struct vc4_texture_sample_info - saves the offsets into the UBO for texture
* setup parameters.
*
* This will be used at draw time to relocate the reference to the texture
* contents in p0, and validate that the offset combined with
* width/height/stride/etc. from p1 and p2/p3 doesn't sample outside the BO.
* Note that the hardware treats unprovided config parameters as 0, so not all
* of them need to be set up for every texure sample, and we'll store ~0 as
* the offset to mark the unused ones.
*
* See the VC4 3D architecture guide page 41 ("Texture and Memory Lookup Unit
* Setup") for definitions of the texture parameters.
*/
struct vc4_texture_sample_info {
uint32_t p_offset[4];
};
/**
* struct vc4_validated_shader_info - information about validated shaders that
* needs to be used from command list validation.
*
* For a given shader, each time a shader state record references it, we need
* to verify that the shader doesn't read more uniforms than the shader state
* record's uniform BO pointer can provide, and we need to apply relocations
* and validate the shader state record's uniforms that define the texture
* samples.
*/
struct vc4_validated_shader_info
{
uint32_t uniforms_size;
uint32_t uniforms_src_size;
uint32_t num_texture_samples;
struct vc4_texture_sample_info *texture_samples;
};
/* vc4_validate.c */
int
vc4_validate_cl(struct drm_device *dev,
void *validated,
void *unvalidated,
uint32_t len,
bool is_bin,
struct exec_info *exec);
int
vc4_validate_shader_recs(struct drm_device *dev, struct exec_info *exec);
struct vc4_validated_shader_info *
vc4_validate_shader(struct drm_gem_cma_object *shader_obj,
uint32_t start_offset);
#endif /* VC4_DRV_H */

View File

@ -0,0 +1,147 @@
/*
* 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 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, 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, 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, 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, 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,
exec);
if (ret)
goto fail;
ret = vc4_validate_cl(dev,
exec->exec_bo->vaddr + render_offset,
render,
args->render_cl_size,
false,
exec);
if (ret)
goto fail;
ret = vc4_validate_shader_recs(dev, exec);
fail:
kfree(temp);
return ret;
}
#endif /* USE_VC4_SIMULATOR */

View File

@ -39,7 +39,7 @@
* is where GEM relocation processing happens.
*/
#include "vc4_simulator_validate.h"
#include "vc4_drv.h"
#include "vc4_packet.h"
#define VALIDATE_ARGS \

View File

@ -44,7 +44,7 @@
* never actually modified, this shouldn't be a problem.
*/
#include "vc4_simulator_validate.h"
#include "vc4_drv.h"
#include "vc4_qpu.h"
#include "vc4_qpu_defines.h"

View File

@ -27,6 +27,7 @@
#include "vc4_screen.h"
#include "vc4_context.h"
#include "kernel/vc4_drv.h"
#include "vc4_simulator_validate.h"
#include "simpenrose/simpenrose.h"
@ -52,7 +53,7 @@ vc4_wrap_bo_with_cma(struct drm_device *dev, struct vc4_bo *bo)
return obj;
}
static struct drm_gem_cma_object *
struct drm_gem_cma_object *
drm_gem_cma_create(struct drm_device *dev, size_t size)
{
struct vc4_context *vc4 = dev->vc4;
@ -104,125 +105,6 @@ vc4_simulator_unpin_bos(struct exec_info *exec)
return 0;
}
static int
vc4_cl_validate(struct drm_device *dev, struct 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, 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, 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, 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, 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,
exec);
if (ret)
goto fail;
ret = vc4_validate_cl(dev,
exec->exec_bo->vaddr + render_offset,
render,
args->render_cl_size,
false,
exec);
if (ret)
goto fail;
ret = vc4_validate_shader_recs(dev, exec);
fail:
kfree(temp);
return ret;
}
int
vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args)
{

View File

@ -34,6 +34,8 @@
#include "vc4_context.h"
#include "vc4_qpu_defines.h"
struct exec_info;
#define DRM_INFO(...) fprintf(stderr, __VA_ARGS__)
#define DRM_ERROR(...) fprintf(stderr, __VA_ARGS__)
#define kmalloc(size, arg) malloc(size)
@ -71,140 +73,11 @@ struct drm_gem_cma_object {
void *vaddr;
};
enum vc4_bo_mode {
VC4_MODE_UNDECIDED,
VC4_MODE_TILE_ALLOC,
VC4_MODE_TSDA,
VC4_MODE_RENDER,
VC4_MODE_SHADER,
};
struct vc4_bo_exec_state {
struct drm_gem_cma_object *bo;
enum vc4_bo_mode mode;
};
struct drm_gem_cma_object *
drm_gem_cma_create(struct drm_device *dev, size_t size);
struct exec_info {
/* Kernel-space copy of the ioctl arguments */
struct drm_vc4_submit_cl *args;
/* This is the array of BOs that were looked up at the start of exec.
* Command validation will use indices into this array.
*/
struct vc4_bo_exec_state *bo;
uint32_t bo_count;
/* Current unvalidated indices into @bo loaded by the non-hardware
* VC4_PACKET_GEM_HANDLES.
*/
uint32_t bo_index[2];
/* This is the BO where we store the validated command lists, shader
* records, and uniforms.
*/
struct drm_gem_cma_object *exec_bo;
/**
* This tracks the per-shader-record state (packet 64) that
* determines the length of the shader record and the offset
* it's expected to be found at. It gets read in from the
* command lists.
*/
struct vc4_shader_state {
uint8_t packet;
uint32_t addr;
/* Maximum vertex index referenced by any primitive using this
* shader state.
*/
uint32_t max_index;
} *shader_state;
/** How many shader states the user declared they were using. */
uint32_t shader_state_size;
/** How many shader state records the validator has seen. */
uint32_t shader_state_count;
bool found_tile_binning_mode_config_packet;
bool found_tile_rendering_mode_config_packet;
bool found_start_tile_binning_packet;
uint8_t bin_tiles_x, bin_tiles_y;
uint32_t fb_width, fb_height;
uint32_t tile_alloc_init_block_size;
struct drm_gem_cma_object *tile_alloc_bo;
/**
* Computed addresses pointing into exec_bo where we start the
* bin thread (ct0) and render thread (ct1).
*/
uint32_t ct0ca, ct0ea;
uint32_t ct1ca, ct1ea;
/* Pointers to the shader recs. These paddr gets incremented as CL
* packets are relocated in validate_gl_shader_state, and the vaddrs
* (u and v) get incremented and size decremented as the shader recs
* themselves are validated.
*/
void *shader_rec_u;
void *shader_rec_v;
uint32_t shader_rec_p;
uint32_t shader_rec_size;
/* Pointers to the uniform data. These pointers are incremented, and
* size decremented, as each batch of uniforms is uploaded.
*/
void *uniforms_u;
void *uniforms_v;
uint32_t uniforms_p;
uint32_t uniforms_size;
};
/**
* struct vc4_texture_sample_info - saves the offsets into the UBO for texture
* setup parameters.
*
* This will be used at draw time to relocate the reference to the texture
* contents in p0, and validate that the offset combined with
* width/height/stride/etc. from p1 and p2/p3 doesn't sample outside the BO.
* Note that the hardware treats unprovided config parameters as 0, so not all
* of them need to be set up for every texure sample, and we'll store ~0 as
* the offset to mark the unused ones.
*
* See the VC4 3D architecture guide page 41 ("Texture and Memory Lookup Unit
* Setup") for definitions of the texture parameters.
*/
struct vc4_texture_sample_info {
uint32_t p_offset[4];
};
/**
* struct vc4_validated_shader_info - information about validated shaders that
* needs to be used from command list validation.
*
* For a given shader, each time a shader state record references it, we need
* to verify that the shader doesn't read more uniforms than the shader state
* record's uniform BO pointer can provide, and we need to apply relocations
* and validate the shader state record's uniforms that define the texture
* samples.
*/
struct vc4_validated_shader_info
{
uint32_t uniforms_size;
uint32_t uniforms_src_size;
uint32_t num_texture_samples;
struct vc4_texture_sample_info *texture_samples;
};
int vc4_validate_cl(struct drm_device *dev,
void *validated,
void *unvalidated,
uint32_t len,
bool is_bin,
struct exec_info *exec);
int vc4_validate_shader_recs(struct drm_device *dev, struct exec_info *exec);
struct vc4_validated_shader_info *
vc4_validate_shader(struct drm_gem_cma_object *shader_obj,
uint32_t start_offset);
int
vc4_cl_validate(struct drm_device *dev, struct exec_info *exec);
#endif /* VC4_SIMULATOR_VALIDATE_H */