summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-05-29 12:07:09 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2018-05-29 16:58:12 +0100
commit43f7a746ac092e41d4745ed190d4268ef1f82c55 (patch)
tree49c5eb7fd7ea5cf366064b168ef2811eadb0a7b4 /tests
parentf560ae5a464331f03f0a669ed46b8c9e56526187 (diff)
igt/gem_ctx_isolation: Test INSTPM back to gen6
Lionel pointed out that INSTPM was context saved, at least from gen6, not from gen9. The only caveat is that INSTPM is a masked register (the upper 16bits are a write-enable mask, the lower 16bits the value to change) and also contains a read-only counter bit (which counts flushes, and so flip flops between batches). Being a non-privileged register that userspace wants to manipulate, it is writable and readable from a userspace batch, so we can test whether or not a write from one context is visible from a second. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/gem_ctx_isolation.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
index 4968e367..fe7d3490 100644
--- a/tests/gem_ctx_isolation.c
+++ b/tests/gem_ctx_isolation.c
@@ -63,10 +63,12 @@ static const struct named_register {
unsigned int engine_mask;
uint32_t offset;
uint32_t count;
+ uint32_t ignore_bits;
+ bool masked;
} nonpriv_registers[] = {
{ "NOPID", NOCTX, RCS0, 0x2094 },
{ "MI_PREDICATE_RESULT_2", NOCTX, RCS0, 0x23bc },
- { "INSTPM", GEN9, RCS0, 0x20c0 },
+ { "INSTPM", GEN6, RCS0, 0x20c0, 1, BIT(8) /* ro counter */, true },
{ "IA_VERTICES_COUNT", GEN4, RCS0, 0x2310, 2 },
{ "IA_PRIMITIVES_COUNT", GEN4, RCS0, 0x2318, 2 },
{ "VS_INVOCATION_COUNT", GEN4, RCS0, 0x2320, 2 },
@@ -167,6 +169,17 @@ static const char *register_name(uint32_t offset, char *buf, size_t len)
return "unknown";
}
+static const struct named_register *lookup_register(uint32_t offset)
+{
+ for (const struct named_register *r = nonpriv_registers; r->name; r++) {
+ unsigned int width = r->count ? 4*r->count : 4;
+ if (offset >= r->offset && offset < r->offset + width)
+ return r;
+ }
+
+ return NULL;
+}
+
static bool ignore_register(uint32_t offset)
{
for (const struct named_register *r = ignore_registers; r->name; r++) {
@@ -283,7 +296,10 @@ static void write_regs(int fd,
count--; offset += 4) {
*b++ = 0x22 << 23 | 1; /* LRI */
*b++ = offset;
- *b++ = value;
+ if (r->masked)
+ *b++ = value | 0xffffu << 16;
+ else
+ *b++ = value;
}
}
*b++ = MI_BATCH_BUFFER_END;
@@ -424,14 +440,31 @@ static void compare_regs(int fd, uint32_t A, uint32_t B, const char *who)
num_errors = 0;
for (unsigned int n = 0; n < NUM_REGS; n++) {
+ const struct named_register *r;
uint32_t offset = n * sizeof(uint32_t);
- if (a[n] != b[n] && !ignore_register(offset)) {
- igt_warn("Register 0x%04x (%s): A=%08x B=%08x\n",
- offset,
- register_name(offset, buf, sizeof(buf)),
- a[n], b[n]);
- num_errors++;
- }
+ uint32_t mask;
+
+ if (a[n] == b[n])
+ continue;
+
+ if (ignore_register(offset))
+ continue;
+
+ mask = ~0u;
+ r = lookup_register(offset);
+ if (r && r->masked)
+ mask >>= 16;
+ if (r && r->ignore_bits)
+ mask &= ~r->ignore_bits;
+
+ if ((a[n] & mask) == (b[n] & mask))
+ continue;
+
+ igt_warn("Register 0x%04x (%s): A=%08x B=%08x\n",
+ offset,
+ register_name(offset, buf, sizeof(buf)),
+ a[n] & mask, b[n] & mask);
+ num_errors++;
}
munmap(b, regs_size);
munmap(a, regs_size);