[igt-dev] [PATCH i-g-t] igt/gem_ctx_isolation: Test INSTPM back to gen6
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Tue May 29 14:06:52 UTC 2018
On 29/05/18 12:16, Chris Wilson wrote:
> 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 at chris-wilson.co.uk>
> Cc: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> ---
> tests/gem_ctx_isolation.c | 51 ++++++++++++++++++++++++++++++++-------
> 1 file changed, 42 insertions(+), 9 deletions(-)
>
> diff --git a/tests/gem_ctx_isolation.c b/tests/gem_ctx_isolation.c
> index 4968e3678..fe7d3490c 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);
More information about the igt-dev
mailing list