summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-11-26 17:01:59 -0800
committerEric Anholt <[email protected]>2014-12-01 11:00:23 -0800
commit2d5784c8254b4a0e3e04dd0f1e46ab1eb85612dd (patch)
treef5d5e1efee525c39ed92c71a216f4d21f1601c46 /src/gallium
parentbb19f2c3c4a47c25c2680ad2d94a10f8ee5e70d7 (diff)
vc4: Add another check for invalid TLB scoreboard handling.
This was caught by an assertion in the simulator.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu.c23
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu.h3
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu_validate.c21
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