From 2d5784c8254b4a0e3e04dd0f1e46ab1eb85612dd Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 26 Nov 2014 17:01:59 -0800 Subject: [PATCH] vc4: Add another check for invalid TLB scoreboard handling. This was caught by an assertion in the simulator. --- src/gallium/drivers/vc4/vc4_qpu.c | 23 ++++++++++++++++++++++ src/gallium/drivers/vc4/vc4_qpu.h | 3 +++ src/gallium/drivers/vc4/vc4_qpu_validate.c | 21 ++++++++++++-------- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/vc4/vc4_qpu.c b/src/gallium/drivers/vc4/vc4_qpu.c index a551a0fa187..093ca077e6d 100644 --- a/src/gallium/drivers/vc4/vc4_qpu.c +++ b/src/gallium/drivers/vc4/vc4_qpu.c @@ -244,3 +244,26 @@ qpu_set_cond_mul(uint64_t inst, uint32_t sig) return (inst & ~QPU_COND_MUL_MASK) | QPU_SET_FIELD(sig, QPU_COND_MUL); } +bool +qpu_waddr_is_tlb(uint32_t waddr) +{ + switch (waddr) { + case QPU_W_TLB_COLOR_ALL: + case QPU_W_TLB_COLOR_MS: + case QPU_W_TLB_Z: + return true; + default: + return false; + } +} + +bool +qpu_inst_is_tlb(uint64_t inst) +{ + uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); + + return (qpu_waddr_is_tlb(QPU_GET_FIELD(inst, QPU_WADDR_ADD)) || + qpu_waddr_is_tlb(QPU_GET_FIELD(inst, QPU_WADDR_MUL)) || + sig == QPU_SIG_COLOR_LOAD || + sig == QPU_SIG_WAIT_FOR_SCOREBOARD); +} diff --git a/src/gallium/drivers/vc4/vc4_qpu.h b/src/gallium/drivers/vc4/vc4_qpu.h index 2f371087e64..5f4caab193e 100644 --- a/src/gallium/drivers/vc4/vc4_qpu.h +++ b/src/gallium/drivers/vc4/vc4_qpu.h @@ -133,6 +133,9 @@ uint64_t qpu_set_sig(uint64_t inst, uint32_t sig); uint64_t qpu_set_cond_add(uint64_t inst, uint32_t cond); uint64_t qpu_set_cond_mul(uint64_t inst, uint32_t cond); +bool qpu_waddr_is_tlb(uint32_t waddr); +bool qpu_inst_is_tlb(uint64_t inst); + static inline uint64_t qpu_load_imm_f(struct qpu_reg dst, float val) { diff --git a/src/gallium/drivers/vc4/vc4_qpu_validate.c b/src/gallium/drivers/vc4/vc4_qpu_validate.c index d0437332334..8fe5f41fcf2 100644 --- a/src/gallium/drivers/vc4/vc4_qpu_validate.c +++ b/src/gallium/drivers/vc4/vc4_qpu_validate.c @@ -91,11 +91,17 @@ writes_sfu(uint64_t inst) void vc4_qpu_validate(uint64_t *insts, uint32_t num_inst) { + bool scoreboard_locked = false; + for (int i = 0; i < num_inst; i++) { uint64_t inst = insts[i]; - if (QPU_GET_FIELD(inst, QPU_SIG) != QPU_SIG_PROG_END) + if (QPU_GET_FIELD(inst, QPU_SIG) != QPU_SIG_PROG_END) { + if (qpu_inst_is_tlb(inst)) + scoreboard_locked = true; + continue; + } /* "The Thread End instruction must not write to either physical * regfile A or B." @@ -103,6 +109,11 @@ vc4_qpu_validate(uint64_t *insts, uint32_t num_inst) assert(QPU_GET_FIELD(inst, QPU_WADDR_ADD) >= 32); assert(QPU_GET_FIELD(inst, QPU_WADDR_MUL) >= 32); + /* Can't trigger an implicit wait on scoreboard in the program + * end instruction. + */ + assert(!qpu_inst_is_tlb(inst) || scoreboard_locked); + /* Two delay slots will be executed. */ assert(i + 2 <= num_inst); @@ -141,13 +152,7 @@ vc4_qpu_validate(uint64_t *insts, uint32_t num_inst) for (int i = 0; i < 2; i++) { uint64_t inst = insts[i]; - assert(QPU_GET_FIELD(inst, QPU_SIG) != QPU_SIG_COLOR_LOAD); - assert(QPU_GET_FIELD(inst, QPU_SIG) != - QPU_SIG_WAIT_FOR_SCOREBOARD); - assert(!writes_reg(inst, QPU_W_TLB_COLOR_MS)); - assert(!writes_reg(inst, QPU_W_TLB_COLOR_ALL)); - assert(!writes_reg(inst, QPU_W_TLB_Z)); - + assert(!qpu_inst_is_tlb(inst)); } /* "If TMU_NOSWAP is written, the write must be three instructions -- 2.30.2