Add option to specify engine for register read/write operation. If engine is specified, use MI_LOAD_REGISTER_IMM and MI_STORE_REGISTER_IMM to write and read register using a batch targeted at that engine. v2: no MI_NOOP after BBE (Chris) v3: use modern engine names (Chris), use global fd Cc: Jani Nikula <jani.nikula@xxxxxxxxx> Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> CC: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Signed-off-by: Mika Kuoppala <mika.kuoppala@xxxxxxxxxxxxxxx> --- tools/intel_reg.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 2 deletions(-) diff --git a/tools/intel_reg.c b/tools/intel_reg.c index 00d2a4a1..7f3494ef 100644 --- a/tools/intel_reg.c +++ b/tools/intel_reg.c @@ -33,6 +33,7 @@ #include <unistd.h> #include "igt.h" +#include "igt_gt.h" #include "intel_io.h" #include "intel_chipset.h" @@ -73,6 +74,11 @@ struct config { /* register spec */ char *specfile; + + /* engine to use for lri (write) and srm (read) */ + char *engine; + int fd; + struct reg *regs; ssize_t regcount; @@ -236,13 +242,140 @@ static void dump_decode(struct config *config, struct reg *reg, uint32_t val) } } +static const struct intel_execution_engine2 *find_engine(const char *name, + bool *secure) +{ + const struct intel_execution_engine2 *e; + + if (strlen(name) < 2) + goto out; + + if (name[0] == '-') { + *secure = false; + name++; + } else { + *secure = true; + } + + for (e = intel_execution_engines2; e->name; e++) { + if (!strcmp(e->name, name)) + return e; + } + +out: + fprintf(stderr, "no such engine as '%s'\n", name); + + fprintf(stderr, "valid engines:"); + for (e = intel_execution_engines2; e->name; e++) + fprintf(stderr, " %s", e->name); + + fprintf(stderr, "\n"); + + exit(EXIT_FAILURE); +} + +static int register_srm(struct config *config, struct reg *reg, + uint32_t *val_in) +{ + const int gen = intel_gen(config->devid); + const bool r64b = gen >= 8; + const uint32_t ctx = 0; + struct drm_i915_gem_exec_object2 obj[2]; + struct drm_i915_gem_relocation_entry reloc[1]; + struct drm_i915_gem_execbuffer2 execbuf; + uint32_t *batch, *r; + const struct intel_execution_engine2 *engine; + bool secure; + int fd, i; + uint32_t val; + + if (config->fd == -1) { + config->fd = __drm_open_driver(DRIVER_INTEL); + if (config->fd == -1) { + fprintf(stderr, "Error opening driver: %s", + strerror(errno)); + exit(EXIT_FAILURE); + } + } + + fd = config->fd; + engine = find_engine(config->engine, &secure); + + memset(obj, 0, sizeof(obj)); + obj[0].handle = gem_create(fd, 4096); + obj[1].handle = gem_create(fd, 4096); + obj[1].relocs_ptr = to_user_pointer(reloc); + obj[1].relocation_count = 1; + + batch = gem_mmap__cpu(fd, obj[1].handle, 0, 4096, PROT_WRITE); + gem_set_domain(fd, obj[1].handle, + I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU); + + i = 0; + if (val_in) { + batch[i++] = MI_NOOP; + batch[i++] = MI_NOOP; + + batch[i++] = MI_LOAD_REGISTER_IMM; + batch[i++] = reg->addr; + batch[i++] = *val_in; + batch[i++] = MI_NOOP; + } + + batch[i++] = 0x24 << 23 | (1 + r64b); /* SRM */ + batch[i++] = reg->addr; + reloc[0].target_handle = obj[0].handle; + reloc[0].presumed_offset = obj[0].offset; + reloc[0].offset = i * sizeof(uint32_t); + reloc[0].delta = 0; + reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; + reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; + batch[i++] = reloc[0].delta; + if (r64b) + batch[i++] = 0; + + batch[i++] = MI_BATCH_BUFFER_END; + munmap(batch, 4096); + + memset(&execbuf, 0, sizeof(execbuf)); + execbuf.buffers_ptr = to_user_pointer(obj); + execbuf.buffer_count = 2; + execbuf.flags = gem_class_instance_to_eb_flags(fd, + engine->class, + engine->instance); + if (secure) + execbuf.flags |= I915_EXEC_SECURE; + + if (config->verbosity > 0) + printf("%s: using %sprivileged batch\n", + engine->name, + secure ? "" : "non-"); + + execbuf.rsvd1 = ctx; + gem_execbuf(fd, &execbuf); + gem_close(fd, obj[1].handle); + + r = gem_mmap__cpu(fd, obj[0].handle, 0, 4096, PROT_READ); + gem_set_domain(fd, obj[0].handle, I915_GEM_DOMAIN_CPU, 0); + + val = r[0]; + munmap(r, 4096); + + gem_close(fd, obj[0].handle); + + return val; +} + static int read_register(struct config *config, struct reg *reg, uint32_t *valp) { uint32_t val = 0; switch (reg->port_desc.port) { case PORT_MMIO: - val = INREG(reg->mmio_offset + reg->addr); + if (config->engine) + val = register_srm(config, reg, NULL); + else + val = INREG(reg->mmio_offset + reg->addr); break; case PORT_PORTIO_VGA: iopl(3); @@ -299,7 +432,11 @@ static int write_register(struct config *config, struct reg *reg, uint32_t val) switch (reg->port_desc.port) { case PORT_MMIO: - OUTREG(reg->mmio_offset + reg->addr, val); + if (config->engine) { + register_srm(config, reg, &val); + } else { + OUTREG(reg->mmio_offset + reg->addr, val); + } break; case PORT_PORTIO_VGA: if (val > 0xff) { @@ -641,6 +778,7 @@ static int intel_reg_help(struct config *config, int argc, char *argv[]) printf(" --spec=PATH Read register spec from directory or file\n"); printf(" --mmio=FILE Use an MMIO snapshot\n"); printf(" --devid=DEVID Specify PCI device ID for --mmio=FILE\n"); + printf(" --engine=[-]ENGINE Use a specific engine to read/write\n"); printf(" --all Decode registers for all known platforms\n"); printf(" --binary Binary dump registers\n"); printf(" --verbose Increase verbosity\n"); @@ -758,6 +896,7 @@ enum opt { OPT_ALL, OPT_BINARY, OPT_SPEC, + OPT_ENGINE, OPT_VERBOSE, OPT_QUIET, OPT_HELP, @@ -771,11 +910,13 @@ int main(int argc, char *argv[]) const struct command *command = NULL; struct config config = { .count = 1, + .fd = -1, }; bool help = false; static struct option options[] = { /* global options */ + { "engine", required_argument, NULL, OPT_ENGINE }, { "spec", required_argument, NULL, OPT_SPEC }, { "verbose", no_argument, NULL, OPT_VERBOSE }, { "quiet", no_argument, NULL, OPT_QUIET }, @@ -830,6 +971,14 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } break; + case OPT_ENGINE: + config.engine = strdup(optarg); + if (!config.engine) { + fprintf(stderr, "strdup: %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + break; case OPT_ALL: config.all_platforms = true; break; @@ -898,5 +1047,8 @@ int main(int argc, char *argv[]) free(config.mmiofile); + if (config.fd >= 0) + close(config.fd); + return ret; } -- 2.14.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx