blob: 750e12b497095afb720d49642d485c8764867da5 [file] [log] [blame]
Dave Barachbef36192018-12-17 15:55:52 -05001/*
2 * mapfile_tool.c - skeleton vpp engine plug-in
3 *
4 * Copyright (c) 2018 Cisco Systems and/or affiliates
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#include <stdio.h>
18#include <vppinfra/format.h>
19#include <vppinfra/error.h>
20#include <vppinfra/unix.h>
21
22typedef struct
23{
24 u8 *ifile;
25 u8 *ofile;
26 u8 *mapfile;
27 u8 *table;
28 FILE *ofp;
29} mapfile_tool_main_t;
30
31mapfile_tool_main_t mapfile_tool_main;
32
33static char *top_boilerplate =
34 "typedef struct {\n"
35 " u8 model;\n"
36 " u8 stepping;\n"
37 " u8 has_stepping;\n"
38 " char *filename;\n"
39 "} file_by_model_and_stepping_t;\n\n"
40 "static const file_by_model_and_stepping_t fms_table [] =\n"
41 "{\n" " /* model, stepping, stepping valid, file */\n";
42
43static char *bottom_boilerplate = "};\n";
44
45static void
46print_chunk (mapfile_tool_main_t * mtm, char *chunk)
47{
48 fformat (mtm->ofp, "%s", chunk);
49}
50
51static int
52parse_mapfile (mapfile_tool_main_t * mtm)
53{
54 u8 *cp = mtm->mapfile;
55 int i;
56 char model[3];
57 u8 *stepping = 0;
58 u8 *filename = 0;
59 int has_stepping;
60
61 /* Skip header line */
62 while (*cp && *cp != '\n')
63 cp++;
64
65 if (*cp == 0)
66 {
67 fformat (stderr, "mapfile broken or empty\n");
68 return 1;
69 }
70 /* skip newline */
71 cp++;
72
73 /* GenuineIntel-6-55-[01234],V1.12,/SKX/skylakex_uncore_v1.12.json,uncore */
74 /* skip 15 ^ */
75
76 /* Across payload lines... */
77 while (1)
78 {
79 if (*cp == 0)
80 return 0;
81
82 for (i = 0; i < 15; i++)
83 {
84 if (*cp == 0)
85 {
86 bad:
87 fformat (stderr, "mapfile broken\n");
88 return 1;
89 }
90 cp++;
91 }
92 /* should point at model */
93 model[0] = *cp++;
94 model[1] = *cp++;
95 model[2] = 0;
96 vec_reset_length (stepping);
97 /* Stepping significant? */
98 if (*cp == '-')
99 {
100 cp += 2;
101 while (*cp != ']')
102 {
103 vec_add1 (stepping, *cp);
104 cp++;
105 }
106 cp++;
107 }
108 /* Skip dirname */
109 while (*cp != '/')
110 cp++;
111 cp++;
112 while (*cp != '/')
113 *cp++;
114 cp++;
115 vec_reset_length (filename);
116 while (*cp != ',')
117 {
118 vec_add1 (filename, *cp);
119 cp++;
120 }
121
122 cp++;
123 /* We only want ",core" entries */
124 if (memcmp (cp, "core", 4))
125 {
126 while (*cp && *cp != '\n')
127 cp++;
128 if (*cp)
129 cp++;
130 continue;
131 }
132
133 /* Skip to start of next line */
134 while (*cp && *cp != '\n')
135 cp++;
136 if (*cp)
137 cp++;
138
139 has_stepping = 1;
140
141 if (vec_len (stepping) == 0)
142 {
143 vec_add1 (stepping, '0');
144 has_stepping = 0;
145 }
146
147 for (i = 0; i < vec_len (stepping); i++)
148 {
149 mtm->table =
150 format (mtm->table, " { 0x%s, 0x%c, %d, \"%v\" },\n",
151 model, stepping[i], has_stepping, filename);
152 }
153 }
154
155 /* NOTREACHED */
156 return -11;
157}
158
159static int
160mapfile_main (unformat_input_t * input, mapfile_tool_main_t * mtm)
161{
162 u8 *mapfile;
163 int rv;
164 clib_error_t *error;
165
166 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
167 {
168 if (unformat (input, "in %s", &mtm->ifile))
169 ;
170 else if (unformat (input, "out %s", &mtm->ofile))
171 ;
172 else
173 {
174 fformat (stderr, "unknown input '%U'\n", format_unformat_error,
175 input);
176 usage:
177 fformat (stderr, "usage: mapfile_tool in <ifile> out <ofile>\n");
178 return 1;
179 }
180 }
181
182 if (mtm->ifile == 0)
183 {
184 fformat (stderr, "input file not specified\n");
185 goto usage;
186 }
187
188 if (mtm->ofile == 0)
189 mtm->ofile = format (0, "perfmon_version.c%c", 0);
190
191 mtm->ofp = fopen ((char *) mtm->ofile, "w");
192 if (mtm->ofp == NULL)
193 {
194 fformat (stderr, "Couldn't create '%s'\n", mtm->ofile);
195 return 1;
196 }
197
198 error = unix_proc_file_contents ((char *) mtm->ifile, &mapfile);
199
200 if (error)
201 {
202 clib_error_free (error);
203 fformat (stderr, "Failed to read mapfile from %s", mtm->ifile);
204 return 1;
205 }
206
207 mtm->mapfile = mapfile;
208
209 rv = parse_mapfile (mtm);
210 if (rv)
211 return rv;
212
213 print_chunk (mtm, top_boilerplate);
214 print_chunk (mtm, (char *) mtm->table);
215 print_chunk (mtm, bottom_boilerplate);
216 return 0;
217}
218
219int
220main (int argc, char *argv[])
221{
222 unformat_input_t input;
223 mapfile_tool_main_t *mtm = &mapfile_tool_main;
224 int r;
225
226 clib_mem_init (0, 128 << 20);
227
228 unformat_init_command_line (&input, argv);
229 r = mapfile_main (&input, mtm);
230 unformat_free (&input);
231 return r;
232}
233
234
235/*
236 * fd.io coding-style-patch-verification: ON
237 *
238 * Local Variables:
239 * eval: (c-set-style "gnu")
240 * End:
241 */