nat: use correct data types for memory sizes
[vpp.git] / src / plugins / perfmon / mapfile_tool.c
1 /*
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
22 typedef struct
23 {
24   u8 *ifile;
25   u8 *ofile;
26   u8 *mapfile;
27   u8 *table;
28   FILE *ofp;
29 } mapfile_tool_main_t;
30
31 mapfile_tool_main_t mapfile_tool_main;
32
33 static 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
43 static char *bottom_boilerplate = "};\n";
44
45 static void
46 print_chunk (mapfile_tool_main_t * mtm, char *chunk)
47 {
48   fformat (mtm->ofp, "%s", chunk);
49 }
50
51 static int
52 parse_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
159 static int
160 mapfile_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
219 int
220 main (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  */