intel: aubinator: enable loading xml files from a given directory
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Wed, 5 Oct 2016 22:52:51 +0000 (23:52 +0100)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Sat, 8 Oct 2016 01:17:35 +0000 (02:17 +0100)
This might be useful for people who debug with out of tree descriptions.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Sirisha Gandikota <Sirisha.Gandikota@intel.com>
src/intel/tools/aubinator.c
src/intel/tools/decoder.c
src/intel/tools/decoder.h

index 8be7580c2b1dac0842aa00766b386c7285a2a62e..7f6655acbbecb7b27e5d94600245ce8f8b609e8e 100644 (file)
@@ -1037,7 +1037,8 @@ print_help(const char *progname, FILE *file)
            "      --color[=WHEN]  colorize the output; WHEN can be 'auto' (default\n"
            "                        if omitted), 'always', or 'never'\n"
            "      --no-pager      don't launch pager\n"
-           "      --no-offsets    don't print instruction offsets\n",
+           "      --no-offsets    don't print instruction offsets\n"
+           "      --xml=DIR       load hardware xml description from directory DIR\n",
            progname);
 }
 
@@ -1047,7 +1048,7 @@ int main(int argc, char *argv[])
    struct aub_file *file;
    int c, i;
    bool help = false, pager = true;
-   const char *input_file = NULL;
+   char *input_file = NULL, *xml_path = NULL;
    char gen_val[24];
    const struct {
       const char *name;
@@ -1069,6 +1070,7 @@ int main(int argc, char *argv[])
       { "gen",        required_argument, NULL,                          'g' },
       { "headers",    no_argument,       (int *) &option_full_decode,   false },
       { "color",      required_argument, NULL,                          'c' },
+      { "xml",        required_argument, NULL,                          'x' },
       { NULL,         0,                 NULL,                          0 }
    };
    struct gen_device_info devinfo;
@@ -1091,6 +1093,9 @@ int main(int argc, char *argv[])
             exit(EXIT_FAILURE);
          }
          break;
+      case 'x':
+         xml_path = strdup(optarg);
+         break;
       default:
          break;
       }
@@ -1131,9 +1136,15 @@ int main(int argc, char *argv[])
    if (isatty(1) && pager)
       setup_pager();
 
-   spec = gen_spec_load(&devinfo);
+   if (xml_path == NULL)
+      spec = gen_spec_load(&devinfo);
+   else
+      spec = gen_spec_load_from_path(&devinfo, xml_path);
    disasm = gen_disasm_create(gen->pci_id);
 
+   if (spec == NULL || disasm == NULL)
+      exit(EXIT_FAILURE);
+
    if (input_file == NULL) {
        print_help(input_file, stderr);
        exit(EXIT_FAILURE);
@@ -1147,6 +1158,7 @@ int main(int argc, char *argv[])
    fflush(stdout);
    /* close the stdout which is opened to write the output */
    close(1);
+   free(xml_path);
 
    wait(NULL);
 
index 778cd5bd9b545b4f80a42cd89bf1ebac5be608a3..267b821404c59732a35d8989b6926b33096417d0 100644 (file)
@@ -482,6 +482,70 @@ gen_spec_load(const struct gen_device_info *devinfo)
    return ctx.spec;
 }
 
+struct gen_spec *
+gen_spec_load_from_path(const struct gen_device_info *devinfo,
+                        const char *path)
+{
+   struct parser_context ctx;
+   size_t len, filename_len = strlen(path) + 20;
+   char *filename = malloc(filename_len);
+   void *buf;
+   FILE *input;
+
+   len = snprintf(filename, filename_len, "%s/gen%i.xml",
+                  path, devinfo_to_gen(devinfo));
+   assert(len < filename_len);
+
+   input = fopen(filename, "r");
+   if (input == NULL) {
+      fprintf(stderr, "failed to open xml description\n");
+      free(filename);
+      return NULL;
+   }
+
+   memset(&ctx, 0, sizeof ctx);
+   ctx.parser = XML_ParserCreate(NULL);
+   XML_SetUserData(ctx.parser, &ctx);
+   if (ctx.parser == NULL) {
+      fprintf(stderr, "failed to create parser\n");
+      free(filename);
+      return NULL;
+   }
+
+   XML_SetElementHandler(ctx.parser, start_element, end_element);
+   XML_SetCharacterDataHandler(ctx.parser, character_data);
+   ctx.loc.filename = filename;
+   ctx.spec = xzalloc(sizeof(*ctx.spec));
+
+   do {
+      buf = XML_GetBuffer(ctx.parser, XML_BUFFER_SIZE);
+      len = fread(buf, 1, XML_BUFFER_SIZE, input);
+      if (len < 0) {
+         fprintf(stderr, "fread: %m\n");
+         fclose(input);
+         free(filename);
+         return NULL;
+      }
+      if (XML_ParseBuffer(ctx.parser, len, len == 0) == 0) {
+         fprintf(stderr,
+                 "Error parsing XML at line %ld col %ld: %s\n",
+                 XML_GetCurrentLineNumber(ctx.parser),
+                 XML_GetCurrentColumnNumber(ctx.parser),
+                 XML_ErrorString(XML_GetErrorCode(ctx.parser)));
+         fclose(input);
+         free(filename);
+         return NULL;
+      }
+   } while (len > 0);
+
+   XML_ParserFree(ctx.parser);
+
+   fclose(input);
+   free(filename);
+
+   return ctx.spec;
+}
+
 struct gen_group *
 gen_spec_find_instruction(struct gen_spec *spec, const uint32_t *p)
 {
index 5bea9b957f67e470d6ac300829097f2c46e4971c..739f194e3bd79cb8a7e8bb458ba7ace11415a393 100644 (file)
@@ -39,6 +39,8 @@ static inline uint32_t gen_make_gen(uint32_t major, uint32_t minor)
 
 struct gen_group *gen_spec_find_struct(struct gen_spec *spec, const char *name);
 struct gen_spec *gen_spec_load(const struct gen_device_info *devinfo);
+struct gen_spec *gen_spec_load_from_path(const struct gen_device_info *devinfo,
+                                         const char *path);
 uint32_t gen_spec_get_gen(struct gen_spec *spec);
 struct gen_group *gen_spec_find_instruction(struct gen_spec *spec, const uint32_t *p);
 struct gen_group *gen_spec_find_register(struct gen_spec *spec, uint32_t offset);