diff options
Diffstat (limited to 'src/plugins/perfmon/mapfile_tool.c')
-rw-r--r-- | src/plugins/perfmon/mapfile_tool.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/src/plugins/perfmon/mapfile_tool.c b/src/plugins/perfmon/mapfile_tool.c new file mode 100644 index 00000000000..750e12b4970 --- /dev/null +++ b/src/plugins/perfmon/mapfile_tool.c @@ -0,0 +1,241 @@ +/* + * mapfile_tool.c - skeleton vpp engine plug-in + * + * Copyright (c) 2018 Cisco Systems and/or affiliates + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdio.h> +#include <vppinfra/format.h> +#include <vppinfra/error.h> +#include <vppinfra/unix.h> + +typedef struct +{ + u8 *ifile; + u8 *ofile; + u8 *mapfile; + u8 *table; + FILE *ofp; +} mapfile_tool_main_t; + +mapfile_tool_main_t mapfile_tool_main; + +static char *top_boilerplate = + "typedef struct {\n" + " u8 model;\n" + " u8 stepping;\n" + " u8 has_stepping;\n" + " char *filename;\n" + "} file_by_model_and_stepping_t;\n\n" + "static const file_by_model_and_stepping_t fms_table [] =\n" + "{\n" " /* model, stepping, stepping valid, file */\n"; + +static char *bottom_boilerplate = "};\n"; + +static void +print_chunk (mapfile_tool_main_t * mtm, char *chunk) +{ + fformat (mtm->ofp, "%s", chunk); +} + +static int +parse_mapfile (mapfile_tool_main_t * mtm) +{ + u8 *cp = mtm->mapfile; + int i; + char model[3]; + u8 *stepping = 0; + u8 *filename = 0; + int has_stepping; + + /* Skip header line */ + while (*cp && *cp != '\n') + cp++; + + if (*cp == 0) + { + fformat (stderr, "mapfile broken or empty\n"); + return 1; + } + /* skip newline */ + cp++; + + /* GenuineIntel-6-55-[01234],V1.12,/SKX/skylakex_uncore_v1.12.json,uncore */ + /* skip 15 ^ */ + + /* Across payload lines... */ + while (1) + { + if (*cp == 0) + return 0; + + for (i = 0; i < 15; i++) + { + if (*cp == 0) + { + bad: + fformat (stderr, "mapfile broken\n"); + return 1; + } + cp++; + } + /* should point at model */ + model[0] = *cp++; + model[1] = *cp++; + model[2] = 0; + vec_reset_length (stepping); + /* Stepping significant? */ + if (*cp == '-') + { + cp += 2; + while (*cp != ']') + { + vec_add1 (stepping, *cp); + cp++; + } + cp++; + } + /* Skip dirname */ + while (*cp != '/') + cp++; + cp++; + while (*cp != '/') + *cp++; + cp++; + vec_reset_length (filename); + while (*cp != ',') + { + vec_add1 (filename, *cp); + cp++; + } + + cp++; + /* We only want ",core" entries */ + if (memcmp (cp, "core", 4)) + { + while (*cp && *cp != '\n') + cp++; + if (*cp) + cp++; + continue; + } + + /* Skip to start of next line */ + while (*cp && *cp != '\n') + cp++; + if (*cp) + cp++; + + has_stepping = 1; + + if (vec_len (stepping) == 0) + { + vec_add1 (stepping, '0'); + has_stepping = 0; + } + + for (i = 0; i < vec_len (stepping); i++) + { + mtm->table = + format (mtm->table, " { 0x%s, 0x%c, %d, \"%v\" },\n", + model, stepping[i], has_stepping, filename); + } + } + + /* NOTREACHED */ + return -11; +} + +static int +mapfile_main (unformat_input_t * input, mapfile_tool_main_t * mtm) +{ + u8 *mapfile; + int rv; + clib_error_t *error; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "in %s", &mtm->ifile)) + ; + else if (unformat (input, "out %s", &mtm->ofile)) + ; + else + { + fformat (stderr, "unknown input '%U'\n", format_unformat_error, + input); + usage: + fformat (stderr, "usage: mapfile_tool in <ifile> out <ofile>\n"); + return 1; + } + } + + if (mtm->ifile == 0) + { + fformat (stderr, "input file not specified\n"); + goto usage; + } + + if (mtm->ofile == 0) + mtm->ofile = format (0, "perfmon_version.c%c", 0); + + mtm->ofp = fopen ((char *) mtm->ofile, "w"); + if (mtm->ofp == NULL) + { + fformat (stderr, "Couldn't create '%s'\n", mtm->ofile); + return 1; + } + + error = unix_proc_file_contents ((char *) mtm->ifile, &mapfile); + + if (error) + { + clib_error_free (error); + fformat (stderr, "Failed to read mapfile from %s", mtm->ifile); + return 1; + } + + mtm->mapfile = mapfile; + + rv = parse_mapfile (mtm); + if (rv) + return rv; + + print_chunk (mtm, top_boilerplate); + print_chunk (mtm, (char *) mtm->table); + print_chunk (mtm, bottom_boilerplate); + return 0; +} + +int +main (int argc, char *argv[]) +{ + unformat_input_t input; + mapfile_tool_main_t *mtm = &mapfile_tool_main; + int r; + + clib_mem_init (0, 128 << 20); + + unformat_init_command_line (&input, argv); + r = mapfile_main (&input, mtm); + unformat_free (&input); + return r; +} + + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |