Commit d0566c2a authored by Eric Anholt's avatar Eric Anholt

drm/vc4: Move validation's current/max ip into the validation struct.

Reduces the argument count for some of the functions, and will be used
more with the upcoming looping support.
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent af713795
...@@ -40,6 +40,14 @@ ...@@ -40,6 +40,14 @@
#include "vc4_qpu_defines.h" #include "vc4_qpu_defines.h"
struct vc4_shader_validation_state { struct vc4_shader_validation_state {
/* Current IP being validated. */
uint32_t ip;
/* IP at the end of the BO, do not read shader[max_ip] */
uint32_t max_ip;
uint64_t *shader;
struct vc4_texture_sample_info tmu_setup[2]; struct vc4_texture_sample_info tmu_setup[2];
int tmu_write_count[2]; int tmu_write_count[2];
...@@ -129,11 +137,11 @@ record_texture_sample(struct vc4_validated_shader_info *validated_shader, ...@@ -129,11 +137,11 @@ record_texture_sample(struct vc4_validated_shader_info *validated_shader,
} }
static bool static bool
check_tmu_write(uint64_t inst, check_tmu_write(struct vc4_validated_shader_info *validated_shader,
struct vc4_validated_shader_info *validated_shader,
struct vc4_shader_validation_state *validation_state, struct vc4_shader_validation_state *validation_state,
bool is_mul) bool is_mul)
{ {
uint64_t inst = validation_state->shader[validation_state->ip];
uint32_t waddr = (is_mul ? uint32_t waddr = (is_mul ?
QPU_GET_FIELD(inst, QPU_WADDR_MUL) : QPU_GET_FIELD(inst, QPU_WADDR_MUL) :
QPU_GET_FIELD(inst, QPU_WADDR_ADD)); QPU_GET_FIELD(inst, QPU_WADDR_ADD));
...@@ -228,11 +236,11 @@ check_tmu_write(uint64_t inst, ...@@ -228,11 +236,11 @@ check_tmu_write(uint64_t inst,
} }
static bool static bool
check_reg_write(uint64_t inst, check_reg_write(struct vc4_validated_shader_info *validated_shader,
struct vc4_validated_shader_info *validated_shader,
struct vc4_shader_validation_state *validation_state, struct vc4_shader_validation_state *validation_state,
bool is_mul) bool is_mul)
{ {
uint64_t inst = validation_state->shader[validation_state->ip];
uint32_t waddr = (is_mul ? uint32_t waddr = (is_mul ?
QPU_GET_FIELD(inst, QPU_WADDR_MUL) : QPU_GET_FIELD(inst, QPU_WADDR_MUL) :
QPU_GET_FIELD(inst, QPU_WADDR_ADD)); QPU_GET_FIELD(inst, QPU_WADDR_ADD));
...@@ -261,7 +269,7 @@ check_reg_write(uint64_t inst, ...@@ -261,7 +269,7 @@ check_reg_write(uint64_t inst,
case QPU_W_TMU1_T: case QPU_W_TMU1_T:
case QPU_W_TMU1_R: case QPU_W_TMU1_R:
case QPU_W_TMU1_B: case QPU_W_TMU1_B:
return check_tmu_write(inst, validated_shader, validation_state, return check_tmu_write(validated_shader, validation_state,
is_mul); is_mul);
case QPU_W_HOST_INT: case QPU_W_HOST_INT:
...@@ -294,10 +302,10 @@ check_reg_write(uint64_t inst, ...@@ -294,10 +302,10 @@ check_reg_write(uint64_t inst,
} }
static void static void
track_live_clamps(uint64_t inst, track_live_clamps(struct vc4_validated_shader_info *validated_shader,
struct vc4_validated_shader_info *validated_shader,
struct vc4_shader_validation_state *validation_state) struct vc4_shader_validation_state *validation_state)
{ {
uint64_t inst = validation_state->shader[validation_state->ip];
uint32_t op_add = QPU_GET_FIELD(inst, QPU_OP_ADD); uint32_t op_add = QPU_GET_FIELD(inst, QPU_OP_ADD);
uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD);
uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL);
...@@ -369,10 +377,10 @@ track_live_clamps(uint64_t inst, ...@@ -369,10 +377,10 @@ track_live_clamps(uint64_t inst,
} }
static bool static bool
check_instruction_writes(uint64_t inst, check_instruction_writes(struct vc4_validated_shader_info *validated_shader,
struct vc4_validated_shader_info *validated_shader,
struct vc4_shader_validation_state *validation_state) struct vc4_shader_validation_state *validation_state)
{ {
uint64_t inst = validation_state->shader[validation_state->ip];
uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD);
uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL);
bool ok; bool ok;
...@@ -382,12 +390,10 @@ check_instruction_writes(uint64_t inst, ...@@ -382,12 +390,10 @@ check_instruction_writes(uint64_t inst,
return false; return false;
} }
ok = (check_reg_write(inst, validated_shader, validation_state, ok = (check_reg_write(validated_shader, validation_state, false) &&
false) && check_reg_write(validated_shader, validation_state, true));
check_reg_write(inst, validated_shader, validation_state,
true));
track_live_clamps(inst, validated_shader, validation_state); track_live_clamps(validated_shader, validation_state);
return ok; return ok;
} }
...@@ -417,30 +423,30 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) ...@@ -417,30 +423,30 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
{ {
bool found_shader_end = false; bool found_shader_end = false;
int shader_end_ip = 0; int shader_end_ip = 0;
uint32_t ip, max_ip; uint32_t ip;
uint64_t *shader;
struct vc4_validated_shader_info *validated_shader; struct vc4_validated_shader_info *validated_shader;
struct vc4_shader_validation_state validation_state; struct vc4_shader_validation_state validation_state;
int i; int i;
memset(&validation_state, 0, sizeof(validation_state)); memset(&validation_state, 0, sizeof(validation_state));
validation_state.shader = shader_obj->vaddr;
validation_state.max_ip = shader_obj->base.size / sizeof(uint64_t);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
validation_state.tmu_setup[i / 4].p_offset[i % 4] = ~0; validation_state.tmu_setup[i / 4].p_offset[i % 4] = ~0;
for (i = 0; i < ARRAY_SIZE(validation_state.live_min_clamp_offsets); i++) for (i = 0; i < ARRAY_SIZE(validation_state.live_min_clamp_offsets); i++)
validation_state.live_min_clamp_offsets[i] = ~0; validation_state.live_min_clamp_offsets[i] = ~0;
shader = shader_obj->vaddr;
max_ip = shader_obj->base.size / sizeof(uint64_t);
validated_shader = kcalloc(1, sizeof(*validated_shader), GFP_KERNEL); validated_shader = kcalloc(1, sizeof(*validated_shader), GFP_KERNEL);
if (!validated_shader) if (!validated_shader)
return NULL; return NULL;
for (ip = 0; ip < max_ip; ip++) { for (ip = 0; ip < validation_state.max_ip; ip++) {
uint64_t inst = shader[ip]; uint64_t inst = validation_state.shader[ip];
uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG);
validation_state.ip = ip;
switch (sig) { switch (sig) {
case QPU_SIG_NONE: case QPU_SIG_NONE:
case QPU_SIG_WAIT_FOR_SCOREBOARD: case QPU_SIG_WAIT_FOR_SCOREBOARD:
...@@ -450,7 +456,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) ...@@ -450,7 +456,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
case QPU_SIG_LOAD_TMU1: case QPU_SIG_LOAD_TMU1:
case QPU_SIG_PROG_END: case QPU_SIG_PROG_END:
case QPU_SIG_SMALL_IMM: case QPU_SIG_SMALL_IMM:
if (!check_instruction_writes(inst, validated_shader, if (!check_instruction_writes(validated_shader,
&validation_state)) { &validation_state)) {
DRM_ERROR("Bad write at ip %d\n", ip); DRM_ERROR("Bad write at ip %d\n", ip);
goto fail; goto fail;
...@@ -467,7 +473,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) ...@@ -467,7 +473,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
break; break;
case QPU_SIG_LOAD_IMM: case QPU_SIG_LOAD_IMM:
if (!check_instruction_writes(inst, validated_shader, if (!check_instruction_writes(validated_shader,
&validation_state)) { &validation_state)) {
DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip); DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip);
goto fail; goto fail;
...@@ -487,7 +493,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) ...@@ -487,7 +493,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
break; break;
} }
if (ip == max_ip) { if (ip == validation_state.max_ip) {
DRM_ERROR("shader failed to terminate before " DRM_ERROR("shader failed to terminate before "
"shader BO end at %zd\n", "shader BO end at %zd\n",
shader_obj->base.size); shader_obj->base.size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment