cpcgen.c (c18e9bc3) | cpcgen.c (d0e58ef5) |
---|---|
1/* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12/* 13 * Copyright (c) 2019, Joyent, Inc. 14 */ 15 16/* | 1/* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12/* 13 * Copyright (c) 2019, Joyent, Inc. 14 */ 15 16/* |
17 * This file transforms the perfmon data files into C files and manual pages. | 17 * This program transforms Intel perfmon and AMD PMC data files into C files and 18 * manual pages. |
18 */ 19 20#include <stdio.h> 21#include <stdarg.h> 22#include <unistd.h> 23#include <err.h> 24#include <libgen.h> 25#include <libnvpair.h> 26#include <strings.h> 27#include <errno.h> 28#include <limits.h> 29#include <sys/mman.h> 30#include <sys/param.h> 31#include <assert.h> 32#include <ctype.h> 33#include <sys/types.h> 34#include <sys/stat.h> 35#include <fcntl.h> | 19 */ 20 21#include <stdio.h> 22#include <stdarg.h> 23#include <unistd.h> 24#include <err.h> 25#include <libgen.h> 26#include <libnvpair.h> 27#include <strings.h> 28#include <errno.h> 29#include <limits.h> 30#include <sys/mman.h> 31#include <sys/param.h> 32#include <assert.h> 33#include <ctype.h> 34#include <sys/types.h> 35#include <sys/stat.h> 36#include <fcntl.h> |
37#include <dirent.h> |
|
36 37#include <json_nvlist.h> 38 39#define EXIT_USAGE 2 40#define CPROC_MAX_STEPPINGS 16 41 | 38 39#include <json_nvlist.h> 40 41#define EXIT_USAGE 2 42#define CPROC_MAX_STEPPINGS 16 43 |
44typedef enum { 45 CPCGEN_MODE_UNKNOWN = 0, 46 CPCGEN_MODE_INTEL, 47 CPCGEN_MODE_AMD 48} cpc_mode_t; 49 |
|
42typedef struct cpc_proc { 43 struct cpc_proc *cproc_next; 44 uint_t cproc_family; 45 uint_t cproc_model; 46 uint_t cproc_nsteps; 47 uint_t cproc_steppings[CPROC_MAX_STEPPINGS]; 48} cpc_proc_t; 49 --- 20 unchanged lines hidden (view full) --- 70 uint_t cwhite_mask; 71} cpc_whitelist_t; 72 73/* 74 * List of architectures that we support generating this data for. This is done 75 * so that processors that illumos doesn't support or run on aren't generated 76 * (generally the Xeon Phi). 77 */ | 50typedef struct cpc_proc { 51 struct cpc_proc *cproc_next; 52 uint_t cproc_family; 53 uint_t cproc_model; 54 uint_t cproc_nsteps; 55 uint_t cproc_steppings[CPROC_MAX_STEPPINGS]; 56} cpc_proc_t; 57 --- 20 unchanged lines hidden (view full) --- 78 uint_t cwhite_mask; 79} cpc_whitelist_t; 80 81/* 82 * List of architectures that we support generating this data for. This is done 83 * so that processors that illumos doesn't support or run on aren't generated 84 * (generally the Xeon Phi). 85 */ |
78static cpc_whitelist_t cpcgen_whitelist[] = { | 86static cpc_whitelist_t cpcgen_intel_whitelist[] = { |
79 /* Nehalem */ 80 { "NHM-EP", "nhm_ep", CPC_FILE_CORE }, 81 { "NHM-EX", "nhm_ex", CPC_FILE_CORE }, 82 /* Westmere */ 83 { "WSM-EP-DP", "wsm_ep_dp", CPC_FILE_CORE }, 84 { "WSM-EP-SP", "wsm_ep_sp", CPC_FILE_CORE }, 85 { "WSM-EX", "wsm_ex", CPC_FILE_CORE }, 86 /* Sandy Bridge */ --- 29 unchanged lines hidden (view full) --- 116 117/* 118 * This table maps events with an Intel specific name to the corresponding PAPI 119 * name. There may be multiple Intel events which map to the same PAPI event. 120 * This is usually because different processors have different names for an 121 * event. We use the title as opposed to the event codes because those can 122 * change somewhat arbitrarily between processor generations. 123 */ | 87 /* Nehalem */ 88 { "NHM-EP", "nhm_ep", CPC_FILE_CORE }, 89 { "NHM-EX", "nhm_ex", CPC_FILE_CORE }, 90 /* Westmere */ 91 { "WSM-EP-DP", "wsm_ep_dp", CPC_FILE_CORE }, 92 { "WSM-EP-SP", "wsm_ep_sp", CPC_FILE_CORE }, 93 { "WSM-EX", "wsm_ex", CPC_FILE_CORE }, 94 /* Sandy Bridge */ --- 29 unchanged lines hidden (view full) --- 124 125/* 126 * This table maps events with an Intel specific name to the corresponding PAPI 127 * name. There may be multiple Intel events which map to the same PAPI event. 128 * This is usually because different processors have different names for an 129 * event. We use the title as opposed to the event codes because those can 130 * change somewhat arbitrarily between processor generations. 131 */ |
124static cpc_papi_t cpcgen_papi_map[] = { | 132static cpc_papi_t cpcgen_intel_papi_map[] = { |
125 { "CPU_CLK_UNHALTED.THREAD_P", "PAPI_tot_cyc" }, 126 { "INST_RETIRED.ANY_P", "PAPI_tot_ins" }, 127 { "BR_INST_RETIRED.ALL_BRANCHES", "PAPI_br_ins" }, 128 { "BR_MISP_RETIRED.ALL_BRANCHES", "PAPI_br_msp" }, 129 { "BR_INST_RETIRED.CONDITIONAL", "PAPI_br_cn" }, 130 { "CYCLE_ACTIVITY.CYCLES_L1D_MISS", "PAPI_l1_dcm" }, 131 { "L1I.HITS", "PAPI_l1_ich" }, 132 { "ICACHE.HIT", "PAPI_l1_ich" }, --- 12 unchanged lines hidden (view full) --- 145 { "PAGE_WALKS.WALKS", "PAPI_tlb_tl" }, 146 { "INST_QUEUE_WRITES", "PAPI_tot_iis" }, 147 { "MEM_INST_RETIRED.STORES" "PAPI_sr_ins" }, 148 { "MEM_INST_RETIRED.LOADS" "PAPI_ld_ins" }, 149 { NULL, NULL } 150}; 151 152typedef struct cpcgen_ops { | 133 { "CPU_CLK_UNHALTED.THREAD_P", "PAPI_tot_cyc" }, 134 { "INST_RETIRED.ANY_P", "PAPI_tot_ins" }, 135 { "BR_INST_RETIRED.ALL_BRANCHES", "PAPI_br_ins" }, 136 { "BR_MISP_RETIRED.ALL_BRANCHES", "PAPI_br_msp" }, 137 { "BR_INST_RETIRED.CONDITIONAL", "PAPI_br_cn" }, 138 { "CYCLE_ACTIVITY.CYCLES_L1D_MISS", "PAPI_l1_dcm" }, 139 { "L1I.HITS", "PAPI_l1_ich" }, 140 { "ICACHE.HIT", "PAPI_l1_ich" }, --- 12 unchanged lines hidden (view full) --- 153 { "PAGE_WALKS.WALKS", "PAPI_tlb_tl" }, 154 { "INST_QUEUE_WRITES", "PAPI_tot_iis" }, 155 { "MEM_INST_RETIRED.STORES" "PAPI_sr_ins" }, 156 { "MEM_INST_RETIRED.LOADS" "PAPI_ld_ins" }, 157 { NULL, NULL } 158}; 159 160typedef struct cpcgen_ops { |
161 void (*cgen_op_gather)(const char *, const char *); 162 void (*cgen_op_common)(int); |
|
153 char *(*cgen_op_name)(cpc_map_t *); | 163 char *(*cgen_op_name)(cpc_map_t *); |
164 boolean_t (*cgen_op_skip)(nvlist_t *, const char *, uint_t); |
|
154 boolean_t (*cgen_op_file_before)(FILE *, cpc_map_t *); 155 boolean_t (*cgen_op_file_after)(FILE *, cpc_map_t *); 156 boolean_t (*cgen_op_event)(FILE *, nvlist_t *, const char *, uint32_t); 157} cpcgen_ops_t; 158 159static cpcgen_ops_t cpcgen_ops; | 165 boolean_t (*cgen_op_file_before)(FILE *, cpc_map_t *); 166 boolean_t (*cgen_op_file_after)(FILE *, cpc_map_t *); 167 boolean_t (*cgen_op_event)(FILE *, nvlist_t *, const char *, uint32_t); 168} cpcgen_ops_t; 169 170static cpcgen_ops_t cpcgen_ops; |
160static const char *cpcgen_mapfile = "/mapfile.csv"; | 171static const char *cpcgen_intel_mapfile = "/mapfile.csv"; |
161static const char *cpcgen_progname; 162static cpc_map_t *cpcgen_maps; | 172static const char *cpcgen_progname; 173static cpc_map_t *cpcgen_maps; |
174static cpc_mode_t cpcgen_mode = CPCGEN_MODE_UNKNOWN; |
|
163 164/* 165 * Constants used for generating data. 166 */ 167/* BEGIN CSTYLED */ | 175 176/* 177 * Constants used for generating data. 178 */ 179/* BEGIN CSTYLED */ |
168static const char *cpcgen_cfile_header = "" | 180static const char *cpcgen_cfile_intel_header = "" |
169"/*\n" 170" * Copyright (c) 2018, Intel Corporation\n" 171" * Copyright (c) 2018, Joyent, Inc\n" 172" * All rights reserved.\n" 173" *\n" 174" * Redistribution and use in source and binary forms, with or without\n" 175" * modification, are permitted provided that the following conditions are met:\n" 176" * \n" --- 23 unchanged lines hidden (view full) --- 200" * This file was automatically generated by cpcgen from the data file\n" 201" * data/perfmon%s\n" 202" *\n" 203" * Do not modify this file. Your changes will be lost!\n" 204" */\n" 205"\n"; 206/* END CSTYLED */ 207 | 181"/*\n" 182" * Copyright (c) 2018, Intel Corporation\n" 183" * Copyright (c) 2018, Joyent, Inc\n" 184" * All rights reserved.\n" 185" *\n" 186" * Redistribution and use in source and binary forms, with or without\n" 187" * modification, are permitted provided that the following conditions are met:\n" 188" * \n" --- 23 unchanged lines hidden (view full) --- 212" * This file was automatically generated by cpcgen from the data file\n" 213" * data/perfmon%s\n" 214" *\n" 215" * Do not modify this file. Your changes will be lost!\n" 216" */\n" 217"\n"; 218/* END CSTYLED */ 219 |
208static const char *cpcgen_cfile_table_start = "" | 220static const char *cpcgen_cfile_intel_table_start = "" |
209"#include <core_pcbe_table.h>\n" 210"\n" 211"const struct events_table_t pcbe_core_events_%s[] = {\n"; 212 | 221"#include <core_pcbe_table.h>\n" 222"\n" 223"const struct events_table_t pcbe_core_events_%s[] = {\n"; 224 |
213static const char *cpcgen_cfile_table_end = "" | 225static const char *cpcgen_cfile_intel_table_end = "" |
214"\t{ NT_END, 0, 0, \"\" }\n" 215"};\n"; 216 217/* BEGIN CSTYLED */ | 226"\t{ NT_END, 0, 0, \"\" }\n" 227"};\n"; 228 229/* BEGIN CSTYLED */ |
218static const char *cpcgen_manual_header = "" | 230static const char *cpcgen_manual_intel_intel_header = "" |
219".\\\" Copyright (c) 2018, Intel Corporation \n" 220".\\\" Copyright (c) 2018, Joyent, Inc.\n" 221".\\\" All rights reserved.\n" 222".\\\"\n" 223".\\\" Redistribution and use in source and binary forms, with or without \n" 224".\\\" modification, are permitted provided that the following conditions are met:\n" 225".\\\"\n" 226".\\\" 1. Redistributions of source code must retain the above copyright notice,\n" --- 37 unchanged lines hidden (view full) --- 264"models and is derived from Intel's perfmon data.\n" 265"For more information, please consult the Intel Software Developer's Manual " 266"or Intel's perfmon website.\n" 267".Pp\n" 268"CPU models described by this document:\n" 269".Bl -bullet\n"; 270/* END CSTYLED */ 271 | 231".\\\" Copyright (c) 2018, Intel Corporation \n" 232".\\\" Copyright (c) 2018, Joyent, Inc.\n" 233".\\\" All rights reserved.\n" 234".\\\"\n" 235".\\\" Redistribution and use in source and binary forms, with or without \n" 236".\\\" modification, are permitted provided that the following conditions are met:\n" 237".\\\"\n" 238".\\\" 1. Redistributions of source code must retain the above copyright notice,\n" --- 37 unchanged lines hidden (view full) --- 276"models and is derived from Intel's perfmon data.\n" 277"For more information, please consult the Intel Software Developer's Manual " 278"or Intel's perfmon website.\n" 279".Pp\n" 280"CPU models described by this document:\n" 281".Bl -bullet\n"; 282/* END CSTYLED */ 283 |
272static const char *cpcgen_manual_data = "" | 284static const char *cpcgen_manual_intel_data = "" |
273".El\n" 274".Pp\n" 275"The following events are supported:\n" 276".Bl -tag -width Sy\n"; 277 | 285".El\n" 286".Pp\n" 287"The following events are supported:\n" 288".Bl -tag -width Sy\n"; 289 |
278static const char *cpcgen_manual_trailer = "" | 290static const char *cpcgen_manual_intel_trailer = "" |
279".El\n" 280".Sh SEE ALSO\n" 281".Xr cpc 3CPC\n" 282".Pp\n" 283".Lk https://download.01.org/perfmon/index/"; 284 | 291".El\n" 292".Sh SEE ALSO\n" 293".Xr cpc 3CPC\n" 294".Pp\n" 295".Lk https://download.01.org/perfmon/index/"; 296 |
297static const char *cpcgen_cfile_cddl_header = "" 298"/*\n" 299" * This file and its contents are supplied under the terms of the\n" 300" * Common Development and Distribution License (\"CDDL\"), version 1.0.\n" 301" * You may only use this file in accordance with the terms of version\n" 302" * 1.0 of the CDDL.\n" 303" *\n" 304" * A full copy of the text of the CDDL should have accompanied this\n" 305" * source. A copy of the CDDL is also available via the Internet at\n" 306" * http://www.illumos.org/license/CDDL.\n" 307" */\n" 308"\n" 309"/*\n" 310" * Copyright 2019 Joyent, Inc\n" 311" */\n" 312"\n" 313"/*\n" 314" * This file was automatically generated by cpcgen.\n" 315" */\n" 316"\n" 317"/*\n" 318" * Do not modify this file. Your changes will be lost!\n" 319" */\n" 320"\n"; 321 322static const char *cpcgen_manual_amd_header = "" 323".\\\" This file was automatically generated by cpcgen from the data file\n" 324".\\\" data/amdpmc/%s\n" 325".\\\"\n" 326".\\\" Do not modify this file. Your changes will be lost!\n" 327".\\\"\n" 328".\\\" We would like to thank AMD for providing the PMC data for use in\n" 329".\\\" our manual pages.\n" 330".Dd March 25, 2019\n" 331".Dt AMD_%s_EVENTS 3CPC\n" 332".Os\n" 333".Sh NAME\n" 334".Nm amd_%s_events\n" 335".Nd AMD family %s processor performance monitoring events\n" 336".Sh DESCRIPTION\n" 337"This manual page describes events specfic to AMD family %s processors.\n" 338"For more information, please consult the appropriate AMD BIOS and Kernel\n" 339"Developer's guide or Open-Source Register Reference manual.\n" 340".Pp\n" 341"Each of the events listed below includes the AMD mnemonic which matches\n" 342"the name found in the AMD manual and a brief summary of the event.\n" 343"If available, a more detailed description of the event follows and then\n" 344"any additional unit values that modify the event.\n" 345"Each unit can be combined to create a new event in the system by placing\n" 346"the '.' character between the event name and the unit name.\n" 347".Pp\n" 348"The following events are supported:\n" 349".Bl -tag -width Sy\n"; 350 351static const char *cpcgen_manual_amd_trailer = "" 352".El\n" 353".Sh SEE ALSO\n" 354".Xr cpc 3CPC\n"; 355 356static const char *cpcgen_cfile_amd_header = "" 357"/*\n" 358" * This file was automatically generated by cpcgen from the data file\n" 359" * data/perfmon%s\n" 360" *\n" 361" * Do not modify this file. Your changes will be lost!\n" 362" */\n" 363"\n"; 364 365static const char *cpcgen_cfile_amd_table_start = "" 366"#include <opteron_pcbe_table.h>\n" 367"#include <sys/null.h>\n" 368"\n" 369"const amd_event_t opteron_pcbe_%s_events[] = {\n"; 370 371static const char *cpcgen_cfile_amd_table_end = "" 372"\t{ NULL, 0, 0 }\n" 373"};\n"; 374 |
|
285static cpc_map_t * 286cpcgen_map_lookup(const char *path) 287{ 288 cpc_map_t *m; 289 290 for (m = cpcgen_maps; m != NULL; m = m->cmap_next) { 291 if (strcmp(path, m->cmap_path) == 0) { 292 return (m); --- 198 unchanged lines hidden (view full) --- 491 if ((slash = strchr(path + 1, '/')) == NULL) { 492 errx(EXIT_FAILURE, "invalid path in mapfile: \"%s\": missing " 493 "second '/'", path); 494 } 495 /* Account for the last '/' character. */ 496 len = slash - path - 1; 497 assert(len > 0); 498 | 375static cpc_map_t * 376cpcgen_map_lookup(const char *path) 377{ 378 cpc_map_t *m; 379 380 for (m = cpcgen_maps; m != NULL; m = m->cmap_next) { 381 if (strcmp(path, m->cmap_path) == 0) { 382 return (m); --- 198 unchanged lines hidden (view full) --- 581 if ((slash = strchr(path + 1, '/')) == NULL) { 582 errx(EXIT_FAILURE, "invalid path in mapfile: \"%s\": missing " 583 "second '/'", path); 584 } 585 /* Account for the last '/' character. */ 586 len = slash - path - 1; 587 assert(len > 0); 588 |
499 for (i = 0; cpcgen_whitelist[i].cwhite_short != NULL; i++) { | 589 for (i = 0; cpcgen_intel_whitelist[i].cwhite_short != NULL; i++) { |
500 if (platform != NULL && strcasecmp(platform, | 590 if (platform != NULL && strcasecmp(platform, |
501 cpcgen_whitelist[i].cwhite_short) != 0) | 591 cpcgen_intel_whitelist[i].cwhite_short) != 0) |
502 continue; | 592 continue; |
503 if (strncmp(path + 1, cpcgen_whitelist[i].cwhite_short, | 593 if (strncmp(path + 1, cpcgen_intel_whitelist[i].cwhite_short, |
504 len) == 0 && | 594 len) == 0 && |
505 (cpcgen_whitelist[i].cwhite_mask & type) == type) { 506 return (cpcgen_whitelist[i].cwhite_human); | 595 (cpcgen_intel_whitelist[i].cwhite_mask & type) == type) { 596 return (cpcgen_intel_whitelist[i].cwhite_human); |
507 } 508 } 509 510 return (NULL); 511} 512 513/* | 597 } 598 } 599 600 return (NULL); 601} 602 603/* |
604 * Determine which CPU Vendor we're transmuting data from. 605 */ 606static void 607cpcgen_determine_vendor(const char *datadir) 608{ 609 char *mappath; 610 struct stat st; 611 612 if (asprintf(&mappath, "%s/%s", datadir, cpcgen_intel_mapfile) == -1) { 613 err(EXIT_FAILURE, "failed to construct path to mapfile"); 614 } 615 616 if (stat(mappath, &st) == 0) { 617 cpcgen_mode = CPCGEN_MODE_INTEL; 618 } else { 619 if (errno != ENOENT) { 620 err(EXIT_FAILURE, "stat(2) of %s failed unexpectedly"); 621 } 622 623 cpcgen_mode = CPCGEN_MODE_AMD; 624 } 625 626 free(mappath); 627} 628 629/* 630 * Read in all the data files that exist for AMD. 631 * 632 * Our family names for AMD systems are based on the family and type so a given 633 * name will look like f17h_core.json. 634 */ 635static void 636cpcgen_read_amd(const char *datadir, const char *platform) 637{ 638 DIR *dir; 639 struct dirent *d; 640 const char *suffix = ".json"; 641 const size_t slen = strlen(suffix); 642 643 if ((dir = opendir(datadir)) == NULL) { 644 err(EXIT_FAILURE, "failed to open directory %s", datadir); 645 } 646 647 while ((d = readdir(dir)) != NULL) { 648 char *name, *c; 649 cpc_map_t *map; 650 nvlist_t *parsed; 651 652 if ((name = strdup(d->d_name)) == NULL) { 653 errx(EXIT_FAILURE, "ran out of memory duplicating " 654 "name %s", d->d_name); 655 } 656 c = strstr(name, suffix); 657 658 if (c == NULL) { 659 free(name); 660 continue; 661 } 662 663 if (*(c + slen) != '\0') { 664 free(name); 665 continue; 666 } 667 668 *c = '\0'; 669 c = strchr(name, '_'); 670 if (c == NULL) { 671 free(name); 672 continue; 673 } 674 *c = '\0'; 675 c++; 676 if (strcmp(c, "core") != 0) { 677 errx(EXIT_FAILURE, "unexpected AMD JSON file name: %s", 678 d->d_name); 679 } 680 681 if (platform != NULL && strcmp(platform, name) != 0) { 682 free(name); 683 continue; 684 } 685 686 if ((map = calloc(1, sizeof (cpc_map_t))) == NULL) { 687 err(EXIT_FAILURE, "failed to allocate space for cpc " 688 "file"); 689 } 690 691 parsed = cpcgen_read_datafile(datadir, d->d_name); 692 if ((map->cmap_path = strdup(d->d_name)) == NULL) { 693 err(EXIT_FAILURE, "failed to duplicate path string"); 694 } 695 map->cmap_type = CPC_FILE_CORE; 696 map->cmap_data = parsed; 697 map->cmap_name = name; 698 map->cmap_procs = NULL; 699 700 map->cmap_next = cpcgen_maps; 701 cpcgen_maps = map; 702 } 703} 704 705/* |
|
514 * Read in the mapfile.csv that is used to map between processor families and 515 * parse this. Each line has a comma separated value. 516 */ 517static void | 706 * Read in the mapfile.csv that is used to map between processor families and 707 * parse this. Each line has a comma separated value. 708 */ 709static void |
518cpcgen_read_mapfile(const char *datadir, const char *platform) | 710cpcgen_read_intel(const char *datadir, const char *platform) |
519{ 520 FILE *map; 521 char *mappath, *last; 522 char *data = NULL; 523 size_t datalen = 0; 524 uint_t lineno; 525 | 711{ 712 FILE *map; 713 char *mappath, *last; 714 char *data = NULL; 715 size_t datalen = 0; 716 uint_t lineno; 717 |
526 if (asprintf(&mappath, "%s/%s", datadir, cpcgen_mapfile) == -1) { | 718 if (asprintf(&mappath, "%s/%s", datadir, cpcgen_intel_mapfile) == -1) { |
527 err(EXIT_FAILURE, "failed to construct path to mapfile"); 528 } 529 530 if ((map = fopen(mappath, "r")) == NULL) { 531 err(EXIT_FAILURE, "failed to open data mapfile %s", mappath); 532 } 533 534 lineno = 0; --- 56 unchanged lines hidden (view full) --- 591 592 if ((map->cmap_path = strdup(path)) == NULL) { 593 err(EXIT_FAILURE, "failed to duplicate path " 594 "string"); 595 } 596 597 map->cmap_type = type; 598 map->cmap_data = parsed; | 719 err(EXIT_FAILURE, "failed to construct path to mapfile"); 720 } 721 722 if ((map = fopen(mappath, "r")) == NULL) { 723 err(EXIT_FAILURE, "failed to open data mapfile %s", mappath); 724 } 725 726 lineno = 0; --- 56 unchanged lines hidden (view full) --- 783 784 if ((map->cmap_path = strdup(path)) == NULL) { 785 err(EXIT_FAILURE, "failed to duplicate path " 786 "string"); 787 } 788 789 map->cmap_type = type; 790 map->cmap_data = parsed; |
599 map->cmap_next = cpcgen_maps; | |
600 map->cmap_name = name; 601 map->cmap_procs = NULL; | 791 map->cmap_name = name; 792 map->cmap_procs = NULL; |
793 794 map->cmap_next = cpcgen_maps; |
|
602 cpcgen_maps = map; 603 } 604 605 if ((proc = calloc(1, sizeof (cpc_proc_t))) == NULL) { 606 err(EXIT_FAILURE, "failed to allocate memory for " 607 "family and model tracking"); 608 } 609 --- 15 unchanged lines hidden (view full) --- 625 if (fclose(map) == EOF) { 626 err(EXIT_FAILURE, "failed to close %s", mappath); 627 } 628 free(data); 629 free(mappath); 630} 631 632static char * | 795 cpcgen_maps = map; 796 } 797 798 if ((proc = calloc(1, sizeof (cpc_proc_t))) == NULL) { 799 err(EXIT_FAILURE, "failed to allocate memory for " 800 "family and model tracking"); 801 } 802 --- 15 unchanged lines hidden (view full) --- 818 if (fclose(map) == EOF) { 819 err(EXIT_FAILURE, "failed to close %s", mappath); 820 } 821 free(data); 822 free(mappath); 823} 824 825static char * |
633cpcgen_manual_name(cpc_map_t *map) | 826cpcgen_manual_intel_name(cpc_map_t *map) |
634{ 635 char *name; 636 637 if (asprintf(&name, "%s_events.3cpc", map->cmap_name) == -1) { 638 warn("failed to assemble manual page name for %s", 639 map->cmap_path); 640 return (NULL); 641 } 642 643 return (name); 644} 645 646static boolean_t | 827{ 828 char *name; 829 830 if (asprintf(&name, "%s_events.3cpc", map->cmap_name) == -1) { 831 warn("failed to assemble manual page name for %s", 832 map->cmap_path); 833 return (NULL); 834 } 835 836 return (name); 837} 838 839static boolean_t |
647cpcgen_manual_file_before(FILE *f, cpc_map_t *map) | 840cpcgen_manual_intel_file_before(FILE *f, cpc_map_t *map) |
648{ 649 size_t i; 650 char *upper; 651 cpc_proc_t *proc; 652 653 if ((upper = strdup(map->cmap_name)) == NULL) { 654 warn("failed to duplicate manual name for %s", map->cmap_name); 655 return (B_FALSE); 656 } 657 658 for (i = 0; upper[i] != '\0'; i++) { 659 upper[i] = toupper(upper[i]); 660 } 661 | 841{ 842 size_t i; 843 char *upper; 844 cpc_proc_t *proc; 845 846 if ((upper = strdup(map->cmap_name)) == NULL) { 847 warn("failed to duplicate manual name for %s", map->cmap_name); 848 return (B_FALSE); 849 } 850 851 for (i = 0; upper[i] != '\0'; i++) { 852 upper[i] = toupper(upper[i]); 853 } 854 |
662 if (fprintf(f, cpcgen_manual_header, map->cmap_path, upper, | 855 if (fprintf(f, cpcgen_manual_intel_intel_header, map->cmap_path, upper, |
663 map->cmap_name) == -1) { 664 warn("failed to write out manual header for %s", 665 map->cmap_name); 666 free(upper); 667 return (B_FALSE); 668 } | 856 map->cmap_name) == -1) { 857 warn("failed to write out manual header for %s", 858 map->cmap_name); 859 free(upper); 860 return (B_FALSE); 861 } |
862 free(upper); |
|
669 670 for (proc = map->cmap_procs; proc != NULL; proc = proc->cproc_next) { 671 if (proc->cproc_nsteps > 0) { 672 uint_t step; 673 674 for (step = 0; step < proc->cproc_nsteps; step++) { 675 if (fprintf(f, ".It\n.Sy Family 0x%x, Model " 676 "0x%x, Stepping 0x%x\n", 677 proc->cproc_family, proc->cproc_model, 678 proc->cproc_steppings[step]) == -1) { 679 warn("failed to write out model " 680 "information for %s", 681 map->cmap_name); | 863 864 for (proc = map->cmap_procs; proc != NULL; proc = proc->cproc_next) { 865 if (proc->cproc_nsteps > 0) { 866 uint_t step; 867 868 for (step = 0; step < proc->cproc_nsteps; step++) { 869 if (fprintf(f, ".It\n.Sy Family 0x%x, Model " 870 "0x%x, Stepping 0x%x\n", 871 proc->cproc_family, proc->cproc_model, 872 proc->cproc_steppings[step]) == -1) { 873 warn("failed to write out model " 874 "information for %s", 875 map->cmap_name); |
682 free(upper); | |
683 return (B_FALSE); 684 } 685 } 686 } else { 687 if (fprintf(f, ".It\n.Sy Family 0x%x, Model 0x%x\n", 688 proc->cproc_family, proc->cproc_model) == -1) { 689 warn("failed to write out model information " 690 "for %s", map->cmap_name); | 876 return (B_FALSE); 877 } 878 } 879 } else { 880 if (fprintf(f, ".It\n.Sy Family 0x%x, Model 0x%x\n", 881 proc->cproc_family, proc->cproc_model) == -1) { 882 warn("failed to write out model information " 883 "for %s", map->cmap_name); |
691 free(upper); | |
692 return (B_FALSE); 693 } 694 } 695 } 696 | 884 return (B_FALSE); 885 } 886 } 887 } 888 |
697 if (fprintf(f, cpcgen_manual_data, map->cmap_path, upper, 698 map->cmap_name) == -1) { | 889 if (fprintf(f, cpcgen_manual_intel_data) == -1) { |
699 warn("failed to write out manual header for %s", 700 map->cmap_name); | 890 warn("failed to write out manual header for %s", 891 map->cmap_name); |
701 free(upper); | |
702 return (B_FALSE); 703 } 704 705 free(upper); 706 return (B_TRUE); 707} 708 709static boolean_t | 892 return (B_FALSE); 893 } 894 895 free(upper); 896 return (B_TRUE); 897} 898 899static boolean_t |
710cpcgen_manual_file_after(FILE *f, cpc_map_t *map) | 900cpcgen_manual_intel_file_after(FILE *f, cpc_map_t *map) |
711{ | 901{ |
712 if (fprintf(f, cpcgen_manual_trailer) == -1) { | 902 if (fprintf(f, cpcgen_manual_intel_trailer) == -1) { |
713 warn("failed to write out manual header for %s", 714 map->cmap_name); 715 return (B_FALSE); 716 } 717 718 return (B_TRUE); 719} 720 721static boolean_t | 903 warn("failed to write out manual header for %s", 904 map->cmap_name); 905 return (B_FALSE); 906 } 907 908 return (B_TRUE); 909} 910 911static boolean_t |
722cpcgen_manual_event(FILE *f, nvlist_t *nvl, const char *path, uint32_t ent) | 912cpcgen_manual_intel_event(FILE *f, nvlist_t *nvl, const char *path, 913 uint32_t ent) |
723{ 724 char *event, *lname, *brief = NULL, *public = NULL, *errata = NULL; 725 size_t i; 726 727 if (nvlist_lookup_string(nvl, "EventName", &event) != 0) { 728 warnx("Found event without 'EventName' property " 729 "in %s, entry %u", path, ent); 730 return (B_FALSE); --- 17 unchanged lines hidden (view full) --- 748 (void) nvlist_lookup_string(nvl, "PublicDescription", &public); 749 (void) nvlist_lookup_string(nvl, "Errata", &errata); 750 if (errata != NULL && (strcmp(errata, "0") == 0 || 751 strcmp(errata, "null") == 0)) { 752 errata = NULL; 753 } 754 755 if (fprintf(f, ".It Sy %s\n", lname) == -1) { | 914{ 915 char *event, *lname, *brief = NULL, *public = NULL, *errata = NULL; 916 size_t i; 917 918 if (nvlist_lookup_string(nvl, "EventName", &event) != 0) { 919 warnx("Found event without 'EventName' property " 920 "in %s, entry %u", path, ent); 921 return (B_FALSE); --- 17 unchanged lines hidden (view full) --- 939 (void) nvlist_lookup_string(nvl, "PublicDescription", &public); 940 (void) nvlist_lookup_string(nvl, "Errata", &errata); 941 if (errata != NULL && (strcmp(errata, "0") == 0 || 942 strcmp(errata, "null") == 0)) { 943 errata = NULL; 944 } 945 946 if (fprintf(f, ".It Sy %s\n", lname) == -1) { |
756 warn("failed to write out probe entry %s", event); | 947 warn("failed to write out event entry %s", event); |
757 free(lname); 758 return (B_FALSE); 759 } 760 761 if (public != NULL) { 762 if (fprintf(f, "%s\n", public) == -1) { | 948 free(lname); 949 return (B_FALSE); 950 } 951 952 if (public != NULL) { 953 if (fprintf(f, "%s\n", public) == -1) { |
763 warn("failed to write out probe entry %s", event); | 954 warn("failed to write out event entry %s", event); |
764 free(lname); 765 return (B_FALSE); 766 } 767 } else if (brief != NULL) { 768 if (fprintf(f, "%s\n", brief) == -1) { | 955 free(lname); 956 return (B_FALSE); 957 } 958 } else if (brief != NULL) { 959 if (fprintf(f, "%s\n", brief) == -1) { |
769 warn("failed to write out probe entry %s", event); | 960 warn("failed to write out event entry %s", event); |
770 free(lname); 771 return (B_FALSE); 772 } 773 } 774 775 if (errata != NULL) { 776 if (fprintf(f, ".Pp\nThe following errata may apply to this: " 777 "%s\n", errata) == -1) { 778 | 961 free(lname); 962 return (B_FALSE); 963 } 964 } 965 966 if (errata != NULL) { 967 if (fprintf(f, ".Pp\nThe following errata may apply to this: " 968 "%s\n", errata) == -1) { 969 |
779 warn("failed to write out probe entry %s", event); | 970 warn("failed to write out event entry %s", event); |
780 free(lname); 781 return (B_FALSE); 782 } 783 } 784 785 free(lname); 786 return (B_TRUE); 787} 788 789static char * | 971 free(lname); 972 return (B_FALSE); 973 } 974 } 975 976 free(lname); 977 return (B_TRUE); 978} 979 980static char * |
790cpcgen_cfile_name(cpc_map_t *map) | 981cpcgen_cfile_intel_name(cpc_map_t *map) |
791{ 792 char *name; 793 794 if (asprintf(&name, "core_pcbe_%s.c", map->cmap_name) == -1) { 795 warn("failed to assemble file name for %s", map->cmap_path); 796 return (NULL); 797 } 798 799 return (name); 800} 801 802static boolean_t | 982{ 983 char *name; 984 985 if (asprintf(&name, "core_pcbe_%s.c", map->cmap_name) == -1) { 986 warn("failed to assemble file name for %s", map->cmap_path); 987 return (NULL); 988 } 989 990 return (name); 991} 992 993static boolean_t |
803cpcgen_cfile_file_before(FILE *f, cpc_map_t *map) | 994cpcgen_cfile_intel_before(FILE *f, cpc_map_t *map) |
804{ | 995{ |
805 if (fprintf(f, cpcgen_cfile_header, map->cmap_path) == -1) { | 996 if (fprintf(f, cpcgen_cfile_intel_header, map->cmap_path) == -1) { |
806 warn("failed to write header to temporary file for %s", 807 map->cmap_path); 808 return (B_FALSE); 809 } 810 | 997 warn("failed to write header to temporary file for %s", 998 map->cmap_path); 999 return (B_FALSE); 1000 } 1001 |
811 if (fprintf(f, cpcgen_cfile_table_start, map->cmap_name) == -1) { | 1002 if (fprintf(f, cpcgen_cfile_intel_table_start, map->cmap_name) == -1) { |
812 warn("failed to write header to temporary file for %s", 813 map->cmap_path); 814 return (B_FALSE); 815 } 816 817 return (B_TRUE); 818} 819 820static boolean_t | 1003 warn("failed to write header to temporary file for %s", 1004 map->cmap_path); 1005 return (B_FALSE); 1006 } 1007 1008 return (B_TRUE); 1009} 1010 1011static boolean_t |
821cpcgen_cfile_file_after(FILE *f, cpc_map_t *map) | 1012cpcgen_cfile_intel_after(FILE *f, cpc_map_t *map) |
822{ | 1013{ |
823 if (fprintf(f, cpcgen_cfile_table_end) == -1) { | 1014 if (fprintf(f, cpcgen_cfile_intel_table_end) == -1) { |
824 warn("failed to write footer to temporary file for %s", 825 map->cmap_path); 826 return (B_FALSE); 827 } 828 829 return (B_TRUE); 830} 831 832static boolean_t | 1015 warn("failed to write footer to temporary file for %s", 1016 map->cmap_path); 1017 return (B_FALSE); 1018 } 1019 1020 return (B_TRUE); 1021} 1022 1023static boolean_t |
833cpcgen_cfile_event(FILE *f, nvlist_t *nvl, const char *path, uint_t ent) | 1024cpcgen_cfile_intel_event(FILE *f, nvlist_t *nvl, const char *path, uint_t ent) |
834{ 835 char *ecode, *umask, *name, *counter, *lname, *cmask; 836 size_t i; 837 838 if (nvlist_lookup_string(nvl, "EventName", &name) != 0) { 839 warnx("Found event without 'EventName' property " 840 "in %s, entry %u", path, ent); 841 return (B_FALSE); --- 56 unchanged lines hidden (view full) --- 898 return (B_FALSE); 899 } 900 901 free(lname); 902 903 /* 904 * Check if we have any PAPI aliases. 905 */ | 1025{ 1026 char *ecode, *umask, *name, *counter, *lname, *cmask; 1027 size_t i; 1028 1029 if (nvlist_lookup_string(nvl, "EventName", &name) != 0) { 1030 warnx("Found event without 'EventName' property " 1031 "in %s, entry %u", path, ent); 1032 return (B_FALSE); --- 56 unchanged lines hidden (view full) --- 1089 return (B_FALSE); 1090 } 1091 1092 free(lname); 1093 1094 /* 1095 * Check if we have any PAPI aliases. 1096 */ |
906 for (i = 0; cpcgen_papi_map[i].cpapi_intc != NULL; i++) { 907 if (strcmp(name, cpcgen_papi_map[i].cpapi_intc) != 0) | 1097 for (i = 0; cpcgen_intel_papi_map[i].cpapi_intc != NULL; i++) { 1098 if (strcmp(name, cpcgen_intel_papi_map[i].cpapi_intc) != 0) |
908 continue; 909 910 if (fprintf(f, "\t{ %s, %s, %s, \"%s\" },\n", ecode, umask, | 1099 continue; 1100 1101 if (fprintf(f, "\t{ %s, %s, %s, \"%s\" },\n", ecode, umask, |
911 cmask, cpcgen_papi_map[i].cpapi_papi) == -1) { | 1102 cmask, cpcgen_intel_papi_map[i].cpapi_papi) == -1) { |
912 warn("failed to write out entry %s from %s", name, 913 path); 914 return (B_FALSE); 915 } 916 } 917 918 return (B_TRUE); 919} --- 52 unchanged lines hidden (view full) --- 972 map->cmap_name) == -1) { 973 return (B_FALSE); 974 } 975 976 return (B_TRUE); 977} 978 979/* | 1103 warn("failed to write out entry %s from %s", name, 1104 path); 1105 return (B_FALSE); 1106 } 1107 } 1108 1109 return (B_TRUE); 1110} --- 52 unchanged lines hidden (view full) --- 1163 map->cmap_name) == -1) { 1164 return (B_FALSE); 1165 } 1166 1167 return (B_TRUE); 1168} 1169 1170/* |
1171 * This is a wrapper around unlinkat that makes sure that we don't clobber 1172 * errno, which is used for properly printing out error messages below. 1173 */ 1174static void 1175cpcgen_remove_tmpfile(int dirfd, const char *path) 1176{ 1177 int e = errno; 1178 (void) unlinkat(dirfd, path, 0); 1179 errno = e; 1180} 1181 1182/* |
|
980 * Generate a header file that declares all of these arrays and provide a map 981 * for models to the corresponding table to use. 982 */ 983static void | 1183 * Generate a header file that declares all of these arrays and provide a map 1184 * for models to the corresponding table to use. 1185 */ 1186static void |
984cpcgen_common_files(int dirfd) | 1187cpcgen_common_intel_files(int dirfd) |
985{ 986 const char *fname = "core_pcbe_cpcgen.h"; 987 char *tmpname; 988 int fd; 989 FILE *f; 990 cpc_map_t *map; 991 992 if (asprintf(&tmpname, ".%s.%d", fname, getpid()) == -1) { 993 err(EXIT_FAILURE, "failed to construct temporary file name"); 994 } 995 996 if ((fd = openat(dirfd, tmpname, O_RDWR | O_CREAT, 0644)) < 0) { 997 err(EXIT_FAILURE, "failed to create temporary file %s", 998 tmpname); 999 } 1000 1001 if ((f = fdopen(fd, "w")) == NULL) { | 1188{ 1189 const char *fname = "core_pcbe_cpcgen.h"; 1190 char *tmpname; 1191 int fd; 1192 FILE *f; 1193 cpc_map_t *map; 1194 1195 if (asprintf(&tmpname, ".%s.%d", fname, getpid()) == -1) { 1196 err(EXIT_FAILURE, "failed to construct temporary file name"); 1197 } 1198 1199 if ((fd = openat(dirfd, tmpname, O_RDWR | O_CREAT, 0644)) < 0) { 1200 err(EXIT_FAILURE, "failed to create temporary file %s", 1201 tmpname); 1202 } 1203 1204 if ((f = fdopen(fd, "w")) == NULL) { |
1002 int e = errno; 1003 (void) unlinkat(dirfd, tmpname, 0); 1004 errno = e; | 1205 cpcgen_remove_tmpfile(dirfd, tmpname); |
1005 err(EXIT_FAILURE, "failed to fdopen temporary file"); 1006 } 1007 | 1206 err(EXIT_FAILURE, "failed to fdopen temporary file"); 1207 } 1208 |
1008 if (fprintf(f, cpcgen_cfile_header, cpcgen_mapfile) == -1) { 1009 int e = errno; 1010 (void) unlinkat(dirfd, tmpname, 0); 1011 errno = e; | 1209 if (fprintf(f, cpcgen_cfile_intel_header, cpcgen_intel_mapfile) == -1) { 1210 cpcgen_remove_tmpfile(dirfd, tmpname); |
1012 errx(EXIT_FAILURE, "failed to write header to temporary file " 1013 "for %s", fname); 1014 } 1015 1016 if (fprintf(f, "#ifndef _CORE_PCBE_CPCGEN_H\n" 1017 "#define\t_CORE_PCBE_CPCGEN_H\n" 1018 "\n" 1019 "#ifdef __cplusplus\n" 1020 "extern \"C\" {\n" 1021 "#endif\n" 1022 "\n" 1023 "extern const struct events_table_t *core_cpcgen_table(uint_t, " 1024 "uint_t);\n" 1025 "\n") == -1) { | 1211 errx(EXIT_FAILURE, "failed to write header to temporary file " 1212 "for %s", fname); 1213 } 1214 1215 if (fprintf(f, "#ifndef _CORE_PCBE_CPCGEN_H\n" 1216 "#define\t_CORE_PCBE_CPCGEN_H\n" 1217 "\n" 1218 "#ifdef __cplusplus\n" 1219 "extern \"C\" {\n" 1220 "#endif\n" 1221 "\n" 1222 "extern const struct events_table_t *core_cpcgen_table(uint_t, " 1223 "uint_t);\n" 1224 "\n") == -1) { |
1026 int e = errno; 1027 (void) unlinkat(dirfd, tmpname, 0); 1028 errno = e; | 1225 cpcgen_remove_tmpfile(dirfd, tmpname); |
1029 errx(EXIT_FAILURE, "failed to write header to " 1030 "temporary file for %s", fname); 1031 } 1032 1033 for (map = cpcgen_maps; map != NULL; map = map->cmap_next) { 1034 if (fprintf(f, "extern const struct events_table_t " 1035 "pcbe_core_events_%s[];\n", map->cmap_name) == -1) { | 1226 errx(EXIT_FAILURE, "failed to write header to " 1227 "temporary file for %s", fname); 1228 } 1229 1230 for (map = cpcgen_maps; map != NULL; map = map->cmap_next) { 1231 if (fprintf(f, "extern const struct events_table_t " 1232 "pcbe_core_events_%s[];\n", map->cmap_name) == -1) { |
1036 int e = errno; 1037 (void) unlinkat(dirfd, tmpname, 0); 1038 errno = e; | 1233 cpcgen_remove_tmpfile(dirfd, tmpname); |
1039 errx(EXIT_FAILURE, "failed to write entry to " 1040 "temporary file for %s", fname); 1041 } 1042 } 1043 1044 if (fprintf(f, "\n" 1045 "#ifdef __cplusplus\n" 1046 "}\n" 1047 "#endif\n" 1048 "\n" 1049 "#endif /* _CORE_PCBE_CPCGEN_H */\n") == -1) { | 1234 errx(EXIT_FAILURE, "failed to write entry to " 1235 "temporary file for %s", fname); 1236 } 1237 } 1238 1239 if (fprintf(f, "\n" 1240 "#ifdef __cplusplus\n" 1241 "}\n" 1242 "#endif\n" 1243 "\n" 1244 "#endif /* _CORE_PCBE_CPCGEN_H */\n") == -1) { |
1050 int e = errno; 1051 (void) unlinkat(dirfd, tmpname, 0); 1052 errno = e; | 1245 cpcgen_remove_tmpfile(dirfd, tmpname); |
1053 errx(EXIT_FAILURE, "failed to write header to " 1054 "temporary file for %s", fname); 1055 } 1056 1057 if (fflush(f) != 0 || fclose(f) != 0) { | 1246 errx(EXIT_FAILURE, "failed to write header to " 1247 "temporary file for %s", fname); 1248 } 1249 1250 if (fflush(f) != 0 || fclose(f) != 0) { |
1058 int e = errno; 1059 (void) unlinkat(dirfd, tmpname, 0); 1060 errno = e; | 1251 cpcgen_remove_tmpfile(dirfd, tmpname); |
1061 err(EXIT_FAILURE, "failed to flush and close temporary file"); 1062 } 1063 1064 if (renameat(dirfd, tmpname, dirfd, fname) != 0) { 1065 err(EXIT_FAILURE, "failed to rename temporary file %s", 1066 tmpname); 1067 } 1068 --- 6 unchanged lines hidden (view full) --- 1075 } 1076 1077 if ((fd = openat(dirfd, tmpname, O_RDWR | O_CREAT, 0644)) < 0) { 1078 err(EXIT_FAILURE, "failed to create temporary file %s", 1079 tmpname); 1080 } 1081 1082 if ((f = fdopen(fd, "w")) == NULL) { | 1252 err(EXIT_FAILURE, "failed to flush and close temporary file"); 1253 } 1254 1255 if (renameat(dirfd, tmpname, dirfd, fname) != 0) { 1256 err(EXIT_FAILURE, "failed to rename temporary file %s", 1257 tmpname); 1258 } 1259 --- 6 unchanged lines hidden (view full) --- 1266 } 1267 1268 if ((fd = openat(dirfd, tmpname, O_RDWR | O_CREAT, 0644)) < 0) { 1269 err(EXIT_FAILURE, "failed to create temporary file %s", 1270 tmpname); 1271 } 1272 1273 if ((f = fdopen(fd, "w")) == NULL) { |
1083 int e = errno; 1084 (void) unlinkat(dirfd, tmpname, 0); 1085 errno = e; | 1274 cpcgen_remove_tmpfile(dirfd, tmpname); |
1086 err(EXIT_FAILURE, "failed to fdopen temporary file"); 1087 } 1088 | 1275 err(EXIT_FAILURE, "failed to fdopen temporary file"); 1276 } 1277 |
1089 if (fprintf(f, cpcgen_cfile_header, cpcgen_mapfile) == -1) { 1090 int e = errno; 1091 (void) unlinkat(dirfd, tmpname, 0); 1092 errno = e; | 1278 if (fprintf(f, cpcgen_cfile_intel_header, cpcgen_intel_mapfile) == -1) { 1279 cpcgen_remove_tmpfile(dirfd, tmpname); |
1093 errx(EXIT_FAILURE, "failed to write header to temporary file " 1094 "for %s", fname); 1095 } 1096 1097 if (fprintf(f, "#include <core_pcbe_table.h>\n" 1098 "#include <sys/null.h>\n" 1099 "#include \"core_pcbe_cpcgen.h\"\n" 1100 "\n" 1101 "const struct events_table_t *\n" 1102 "core_cpcgen_table(uint_t model, uint_t stepping)\n" 1103 "{\n") == -1) { | 1280 errx(EXIT_FAILURE, "failed to write header to temporary file " 1281 "for %s", fname); 1282 } 1283 1284 if (fprintf(f, "#include <core_pcbe_table.h>\n" 1285 "#include <sys/null.h>\n" 1286 "#include \"core_pcbe_cpcgen.h\"\n" 1287 "\n" 1288 "const struct events_table_t *\n" 1289 "core_cpcgen_table(uint_t model, uint_t stepping)\n" 1290 "{\n") == -1) { |
1104 int e = errno; 1105 (void) unlinkat(dirfd, tmpname, 0); 1106 errno = e; | 1291 cpcgen_remove_tmpfile(dirfd, tmpname); |
1107 errx(EXIT_FAILURE, "failed to write header to " 1108 "temporary file for %s", fname); 1109 } 1110 1111 for (map = cpcgen_maps; map != NULL; map = map->cmap_next) { 1112 if (!cpcgen_generate_map(f, map, map == cpcgen_maps)) { | 1292 errx(EXIT_FAILURE, "failed to write header to " 1293 "temporary file for %s", fname); 1294 } 1295 1296 for (map = cpcgen_maps; map != NULL; map = map->cmap_next) { 1297 if (!cpcgen_generate_map(f, map, map == cpcgen_maps)) { |
1113 int e = errno; 1114 (void) unlinkat(dirfd, tmpname, 0); 1115 errno = e; | 1298 cpcgen_remove_tmpfile(dirfd, tmpname); |
1116 errx(EXIT_FAILURE, "failed to write to temporary " 1117 "file for %s", fname); 1118 } 1119 } 1120 1121 if (fprintf(f, "\t} else {\n" 1122 "\t\t\treturn (NULL);\n" 1123 "\t}\n" 1124 "}\n") == -1) { | 1299 errx(EXIT_FAILURE, "failed to write to temporary " 1300 "file for %s", fname); 1301 } 1302 } 1303 1304 if (fprintf(f, "\t} else {\n" 1305 "\t\t\treturn (NULL);\n" 1306 "\t}\n" 1307 "}\n") == -1) { |
1125 int e = errno; 1126 (void) unlinkat(dirfd, tmpname, 0); 1127 errno = e; | 1308 cpcgen_remove_tmpfile(dirfd, tmpname); |
1128 errx(EXIT_FAILURE, "failed to write header to " 1129 "temporary file for %s", fname); 1130 } 1131 1132 if (fflush(f) != 0 || fclose(f) != 0) { | 1309 errx(EXIT_FAILURE, "failed to write header to " 1310 "temporary file for %s", fname); 1311 } 1312 1313 if (fflush(f) != 0 || fclose(f) != 0) { |
1133 int e = errno; 1134 (void) unlinkat(dirfd, tmpname, 0); 1135 errno = e; | 1314 cpcgen_remove_tmpfile(dirfd, tmpname); |
1136 err(EXIT_FAILURE, "failed to flush and close temporary file"); 1137 } 1138 1139 if (renameat(dirfd, tmpname, dirfd, fname) != 0) { 1140 err(EXIT_FAILURE, "failed to rename temporary file %s", 1141 tmpname); 1142 } 1143 --- 12 unchanged lines hidden (view full) --- 1156 * - TakenAlone is non-zero, which means that it cannot run at the same time as 1157 * another field. 1158 * - Offcore is one, indicating that it is off the core and we need to figure 1159 * out if we can support this. 1160 * - If the counter is fixed, don't use it for now. 1161 * - If more than one value is specified in the EventCode or UMask values 1162 */ 1163static boolean_t | 1315 err(EXIT_FAILURE, "failed to flush and close temporary file"); 1316 } 1317 1318 if (renameat(dirfd, tmpname, dirfd, fname) != 0) { 1319 err(EXIT_FAILURE, "failed to rename temporary file %s", 1320 tmpname); 1321 } 1322 --- 12 unchanged lines hidden (view full) --- 1335 * - TakenAlone is non-zero, which means that it cannot run at the same time as 1336 * another field. 1337 * - Offcore is one, indicating that it is off the core and we need to figure 1338 * out if we can support this. 1339 * - If the counter is fixed, don't use it for now. 1340 * - If more than one value is specified in the EventCode or UMask values 1341 */ 1342static boolean_t |
1164cpcgen_skip_entry(nvlist_t *nvl, const char *path, uint_t ent) | 1343cpcgen_skip_intel_entry(nvlist_t *nvl, const char *path, uint_t ent) |
1165{ 1166 char *event, *msridx, *msrval, *taken, *offcore, *counter; 1167 char *ecode, *umask; 1168 1169 /* 1170 * Require EventName, it's kind of useless without that. 1171 */ 1172 if (nvlist_lookup_string(nvl, "EventName", &event) != 0) { --- 35 unchanged lines hidden (view full) --- 1208 } 1209 1210 1211 if (strncasecmp(counter, "fixed", strlen("fixed")) == 0) 1212 return (B_TRUE); 1213 1214 return (B_FALSE); 1215} | 1344{ 1345 char *event, *msridx, *msrval, *taken, *offcore, *counter; 1346 char *ecode, *umask; 1347 1348 /* 1349 * Require EventName, it's kind of useless without that. 1350 */ 1351 if (nvlist_lookup_string(nvl, "EventName", &event) != 0) { --- 35 unchanged lines hidden (view full) --- 1387 } 1388 1389 1390 if (strncasecmp(counter, "fixed", strlen("fixed")) == 0) 1391 return (B_TRUE); 1392 1393 return (B_FALSE); 1394} |
1395static char * 1396cpcgen_manual_amd_name(cpc_map_t *map) 1397{ 1398 char *name; |
|
1216 | 1399 |
1400 if (asprintf(&name, "amd_%s_events.3cpc", map->cmap_name) == -1) { 1401 warn("failed to assemble file name for %s", map->cmap_path); 1402 return (NULL); 1403 } 1404 1405 return (name); 1406} 1407 1408static boolean_t 1409cpcgen_manual_amd_file_before(FILE *f, cpc_map_t *map) 1410{ 1411 size_t i; 1412 char *upper; 1413 const char *family; 1414 1415 if ((upper = strdup(map->cmap_name)) == NULL) { 1416 warn("failed to duplicate manual name for %s", map->cmap_name); 1417 return (B_FALSE); 1418 } 1419 1420 for (i = 0; upper[i] != '\0'; i++) { 1421 upper[i] = toupper(upper[i]); 1422 } 1423 1424 family = map->cmap_name + 1; 1425 1426 if (fprintf(f, cpcgen_manual_amd_header, map->cmap_path, upper, 1427 family, family, family) == -1) { 1428 warn("failed to write out manual header for %s", 1429 map->cmap_name); 1430 free(upper); 1431 return (B_FALSE); 1432 } 1433 1434 free(upper); 1435 return (B_TRUE); 1436} 1437 1438static boolean_t 1439cpcgen_manual_amd_file_after(FILE *f, cpc_map_t *map) 1440{ 1441 if (fprintf(f, cpcgen_manual_amd_trailer) == -1) { 1442 warn("failed to write out manual header for %s", 1443 map->cmap_name); 1444 return (B_FALSE); 1445 } 1446 1447 return (B_TRUE); 1448} 1449 1450static boolean_t 1451cpcgen_manual_amd_event(FILE *f, nvlist_t *nvl, const char *path, uint32_t ent) 1452{ 1453 char *name, *mnemonic = NULL, *summary = NULL, *desc = NULL; 1454 char *umode; 1455 nvlist_t *units = NULL; 1456 uint32_t i, length; 1457 1458 if (nvlist_lookup_string(nvl, "name", &name) != 0) { 1459 warnx("Found event without 'name' property in %s, entry %u", 1460 path, ent); 1461 return (B_FALSE); 1462 } 1463 1464 if (nvlist_lookup_string(nvl, "mnemonic", &mnemonic) != 0 || 1465 nvlist_lookup_string(nvl, "summary", &summary) != 0) { 1466 warnx("event %s in %s, entry %u, missing required fields", 1467 name, path, ent); 1468 return (B_FALSE); 1469 } 1470 1471 /* 1472 * Allow the other fields to be missing. 1473 */ 1474 (void) nvlist_lookup_string(nvl, "description", &desc); 1475 (void) nvlist_lookup_nvlist(nvl, "units", &units); 1476 1477 if (fprintf(f, ".It Sy %s\n", name) == -1) { 1478 warn("failed to write out event entry %s", name); 1479 } 1480 1481 if (fprintf(f, ".Sy %s -\n" 1482 "%s\n", mnemonic, summary) == -1) { 1483 warn("failed to write out event entry %s", name); 1484 return (B_FALSE); 1485 } 1486 1487 if (desc != NULL) { 1488 if (fprintf(f, ".Pp\n%s\n", desc) == -1) { 1489 warn("failed to write out event entry %s", name); 1490 return (B_FALSE); 1491 } 1492 } 1493 1494 if (units == NULL) 1495 return (B_TRUE); 1496 1497 /* 1498 * Skip units we don't know how to handle. 1499 */ 1500 if (nvlist_lookup_string(nvl, "unit_mode", &umode) == 0) { 1501 return (B_TRUE); 1502 } 1503 1504 if (fprintf(f, ".Pp\n" 1505 "This event has the following units which may be used\n" 1506 "to modify the behavior of the event:\n" 1507 ".Bl -tag -width Sy\n") == -1) { 1508 warn("failed to write out event entry %s", name); 1509 return (B_FALSE); 1510 } 1511 1512 if (nvlist_lookup_uint32(units, "length", &length) != 0) { 1513 warnx("found units array, but could not look up length " 1514 "property for events %s (index %u) in file %s", 1515 name, ent, path); 1516 return (B_FALSE); 1517 } 1518 1519 for (i = 0; i < length; i++) { 1520 nvlist_t *uvl; 1521 char num[64]; 1522 char *uname, *udesc = NULL; 1523 1524 (void) snprintf(num, sizeof (num), "%u", i); 1525 if (nvlist_lookup_nvlist(units, num, &uvl) != 0) { 1526 warnx("failed to look up unit %u for event %s (index " 1527 "%u) in file %s", i, name, ent, path); 1528 return (B_FALSE); 1529 } 1530 1531 if (nvlist_lookup_string(uvl, "name", &uname) != 0) { 1532 warnx("failed to find required members for unit array " 1533 "entry %u of event %s (index %u) from file %s", 1534 i, name, ent, path); 1535 return (B_FALSE); 1536 } 1537 (void) nvlist_lookup_string(uvl, "description", &udesc); 1538 if (fprintf(f, ".It Sy %s\n", uname) == -1) { 1539 warn("failed to write out event entry %s", name); 1540 return (B_FALSE); 1541 } 1542 1543 if (udesc != NULL) { 1544 if (fprintf(f, "%s\n", udesc) == -1) { 1545 warn("failed to write out event entry %s", 1546 name); 1547 return (B_FALSE); 1548 } 1549 } 1550 } 1551 1552 if (fprintf(f, ".El\n") == -1) { 1553 warn("failed to write out event entry %s", 1554 name); 1555 return (B_FALSE); 1556 } 1557 1558 return (B_TRUE); 1559} 1560 1561static char * 1562cpcgen_cfile_amd_name(cpc_map_t *map) 1563{ 1564 char *name; 1565 1566 if (asprintf(&name, "opteron_pcbe_%s.c", map->cmap_name) == -1) { 1567 warn("failed to assemble file name for %s", map->cmap_path); 1568 return (NULL); 1569 } 1570 1571 return (name); 1572} 1573 |
|
1217/* | 1574/* |
1575 * Generate a header file that can be used to synthesize the data events we care 1576 * about. 1577 */ 1578static void 1579cpcgen_common_amd_files(int dirfd) 1580{ 1581 const char *fname = "opteron_pcbe_cpcgen.h"; 1582 char *tmpname; 1583 int fd; 1584 FILE *f; 1585 cpc_map_t *map; 1586 1587 if (asprintf(&tmpname, ".%s.%d", fname, getpid()) == -1) { 1588 err(EXIT_FAILURE, "failed to construct temporary file name"); 1589 } 1590 1591 if ((fd = openat(dirfd, tmpname, O_RDWR | O_CREAT, 0644)) < 0) { 1592 err(EXIT_FAILURE, "failed to create temporary file %s", 1593 tmpname); 1594 } 1595 1596 if ((f = fdopen(fd, "w")) == NULL) { 1597 cpcgen_remove_tmpfile(dirfd, tmpname); 1598 err(EXIT_FAILURE, "failed to fdopen temporary file"); 1599 } 1600 1601 if (fprintf(f, cpcgen_cfile_cddl_header) == -1) { 1602 cpcgen_remove_tmpfile(dirfd, tmpname); 1603 err(EXIT_FAILURE, "failed to write header to " 1604 "temporary file for %s", fname); 1605 } 1606 1607 if (fprintf(f, "#ifndef _OPTERON_PCBE_CPCGEN_H\n" 1608 "#define\t_OPTERON_PCBE_CPCGEN_H\n" 1609 "\n" 1610 "#ifdef __cplusplus\n" 1611 "extern \"C\" {\n" 1612 "#endif\n" 1613 "\n") == -1) { 1614 cpcgen_remove_tmpfile(dirfd, tmpname); 1615 err(EXIT_FAILURE, "failed to write header to " 1616 "temporary file for %s", fname); 1617 } 1618 1619 for (map = cpcgen_maps; map != NULL; map = map->cmap_next) { 1620 if (fprintf(f, "extern const amd_event_t " 1621 "opteron_pcbe_%s_events[];\n", map->cmap_name) == -1) { 1622 cpcgen_remove_tmpfile(dirfd, tmpname); 1623 err(EXIT_FAILURE, "failed to write header to " 1624 "temporary file for %s", fname); 1625 } 1626 } 1627 1628 if (fprintf(f, "\n" 1629 "#ifdef __cplusplus\n" 1630 "}\n" 1631 "#endif\n" 1632 "\n" 1633 "#endif /* _OPTERON_PCBE_CPCGEN_H */\n") == -1) { 1634 cpcgen_remove_tmpfile(dirfd, tmpname); 1635 err(EXIT_FAILURE, "failed to write header to " 1636 "temporary file for %s", fname); 1637 } 1638 1639 1640 1641 if (fflush(f) != 0 || fclose(f) != 0) { 1642 cpcgen_remove_tmpfile(dirfd, tmpname); 1643 err(EXIT_FAILURE, "failed to flush and close temporary file"); 1644 } 1645 1646 if (renameat(dirfd, tmpname, dirfd, fname) != 0) { 1647 err(EXIT_FAILURE, "failed to rename temporary file %s", 1648 tmpname); 1649 } 1650 1651 free(tmpname); 1652} 1653 1654static boolean_t 1655cpcgen_cfile_amd_before(FILE *f, cpc_map_t *map) 1656{ 1657 if (fprintf(f, cpcgen_cfile_amd_header, map->cmap_name) == -1) { 1658 warn("failed to write header to temporary file for %s", 1659 map->cmap_path); 1660 return (B_FALSE); 1661 } 1662 1663 if (fprintf(f, cpcgen_cfile_amd_table_start, map->cmap_name) == -1) { 1664 warn("failed to write header to temporary file for %s", 1665 map->cmap_path); 1666 return (B_FALSE); 1667 } 1668 1669 1670 return (B_TRUE); 1671} 1672 1673static boolean_t 1674cpcgen_cfile_amd_after(FILE *f, cpc_map_t *map) 1675{ 1676 if (fprintf(f, cpcgen_cfile_amd_table_end) == -1) { 1677 warn("failed to write footer to temporary file for %s", 1678 map->cmap_path); 1679 return (B_FALSE); 1680 } 1681 1682 return (B_TRUE); 1683} 1684 1685static boolean_t 1686cpcgen_cfile_amd_event(FILE *f, nvlist_t *nvl, const char *path, uint_t ent) 1687{ 1688 char *name, *code, *umode; 1689 uint32_t i, length; 1690 nvlist_t *units; 1691 1692 if (nvlist_lookup_string(nvl, "name", &name) != 0) { 1693 warnx("Found event without 'name' property in %s, entry %u", 1694 path, ent); 1695 return (B_FALSE); 1696 } 1697 1698 if (nvlist_lookup_string(nvl, "code", &code) != 0) { 1699 warnx("event %s (index %u) from %s missing required properties " 1700 "for C translation", name, path, ent); 1701 return (B_FALSE); 1702 } 1703 1704 if (fprintf(f, "\t{ \"%s\", %s, 0 },\n", name, code) == -1) { 1705 warn("failed to write out entry %s from %s", name, path); 1706 return (B_FALSE); 1707 } 1708 1709 /* 1710 * The 'units' array is optional. If the rule has a specific 'unit_mode' 1711 * indicating how the units should be combined, skip that. We don't know 1712 * how to properly process that right now. 1713 */ 1714 if (nvlist_lookup_nvlist(nvl, "units", &units) != 0) { 1715 return (B_TRUE); 1716 } 1717 1718 if (nvlist_lookup_string(nvl, "unit_mode", &umode) == 0) { 1719 return (B_TRUE); 1720 } 1721 1722 if (nvlist_lookup_uint32(units, "length", &length) != 0) { 1723 warnx("found units array, but could not look up length " 1724 "property for events %s (index %u) in file %s", 1725 name, ent, path); 1726 return (B_FALSE); 1727 } 1728 1729 for (i = 0; i < length; i++) { 1730 nvlist_t *uvl; 1731 char num[64]; 1732 char *uname, *urw; 1733 int32_t bit; 1734 1735 (void) snprintf(num, sizeof (num), "%u", i); 1736 if (nvlist_lookup_nvlist(units, num, &uvl) != 0) { 1737 warnx("failed to look up unit %u for event %s (index " 1738 "%u) in file %s", i, name, ent, path); 1739 return (B_FALSE); 1740 } 1741 1742 if (nvlist_lookup_string(uvl, "name", &uname) != 0 || 1743 nvlist_lookup_string(uvl, "rw", &urw) != 0 || 1744 nvlist_lookup_int32(uvl, "bit", &bit) != 0) { 1745 warnx("failed to find required members for unit array " 1746 "entry %u of event %s (index %u) from file %s", 1747 i, name, ent, path); 1748 dump_nvlist(uvl, 0); 1749 return (B_FALSE); 1750 } 1751 1752 if (bit < 0 || bit > 31) { 1753 warnx("event %s (index %u) from file %s has invalid " 1754 "bit value: %d; skipping", name, ent, path, bit); 1755 continue; 1756 } 1757 1758 if (strcasecmp(urw, "Read-write") != 0) 1759 continue; 1760 1761 if (fprintf(f, "\t{ \"%s.%s\", %s, 0x%x },\n", name, uname, 1762 code, 1U << bit) == -1) { 1763 warn("failed to write out entry %s from %s", name, 1764 path); 1765 return (B_FALSE); 1766 } 1767 } 1768 1769 return (B_TRUE); 1770} 1771 1772/* |
|
1218 * For each processor family, generate a data file that contains all of the 1219 * events that we support. Also generate a header that can be included that 1220 * declares all of the tables. 1221 */ 1222static void 1223cpcgen_gen(int dirfd) 1224{ 1225 cpc_map_t *map = cpcgen_maps; --- 18 unchanged lines hidden (view full) --- 1244 } 1245 1246 if ((fd = openat(dirfd, tmpname, O_RDWR | O_CREAT, 0444)) < 0) { 1247 err(EXIT_FAILURE, "failed to create temporary file %s", 1248 tmpname); 1249 } 1250 1251 if ((f = fdopen(fd, "w")) == NULL) { | 1773 * For each processor family, generate a data file that contains all of the 1774 * events that we support. Also generate a header that can be included that 1775 * declares all of the tables. 1776 */ 1777static void 1778cpcgen_gen(int dirfd) 1779{ 1780 cpc_map_t *map = cpcgen_maps; --- 18 unchanged lines hidden (view full) --- 1799 } 1800 1801 if ((fd = openat(dirfd, tmpname, O_RDWR | O_CREAT, 0444)) < 0) { 1802 err(EXIT_FAILURE, "failed to create temporary file %s", 1803 tmpname); 1804 } 1805 1806 if ((f = fdopen(fd, "w")) == NULL) { |
1252 int e = errno; 1253 (void) unlinkat(dirfd, tmpname, 0); 1254 errno = e; | 1807 cpcgen_remove_tmpfile(dirfd, tmpname); |
1255 err(EXIT_FAILURE, "failed to fdopen temporary file"); 1256 } 1257 1258 if (!cpcgen_ops.cgen_op_file_before(f, map)) { | 1808 err(EXIT_FAILURE, "failed to fdopen temporary file"); 1809 } 1810 1811 if (!cpcgen_ops.cgen_op_file_before(f, map)) { |
1259 (void) unlinkat(dirfd, tmpname, 0); | 1812 cpcgen_remove_tmpfile(dirfd, tmpname); |
1260 exit(EXIT_FAILURE); 1261 } 1262 1263 /* 1264 * Iterate over array contents. 1265 */ 1266 if ((ret = nvlist_lookup_uint32(map->cmap_data, "length", 1267 &length)) != 0) { --- 4 unchanged lines hidden (view full) --- 1272 1273 for (i = 0; i < length; i++) { 1274 nvlist_t *nvl; 1275 char num[64]; 1276 1277 (void) snprintf(num, sizeof (num), "%u", i); 1278 if ((ret = nvlist_lookup_nvlist(map->cmap_data, 1279 num, &nvl)) != 0) { | 1813 exit(EXIT_FAILURE); 1814 } 1815 1816 /* 1817 * Iterate over array contents. 1818 */ 1819 if ((ret = nvlist_lookup_uint32(map->cmap_data, "length", 1820 &length)) != 0) { --- 4 unchanged lines hidden (view full) --- 1825 1826 for (i = 0; i < length; i++) { 1827 nvlist_t *nvl; 1828 char num[64]; 1829 1830 (void) snprintf(num, sizeof (num), "%u", i); 1831 if ((ret = nvlist_lookup_nvlist(map->cmap_data, 1832 num, &nvl)) != 0) { |
1833 cpcgen_remove_tmpfile(dirfd, tmpname); |
|
1280 errx(EXIT_FAILURE, "failed to look up array " 1281 "entry %u in parsed data for %s: %s", i, 1282 map->cmap_path, strerror(ret)); 1283 } 1284 | 1834 errx(EXIT_FAILURE, "failed to look up array " 1835 "entry %u in parsed data for %s: %s", i, 1836 map->cmap_path, strerror(ret)); 1837 } 1838 |
1285 if (cpcgen_skip_entry(nvl, map->cmap_path, i)) | 1839 if (cpcgen_ops.cgen_op_skip != NULL && 1840 cpcgen_ops.cgen_op_skip(nvl, map->cmap_path, i)) { |
1286 continue; | 1841 continue; |
1842 } |
|
1287 1288 if (!cpcgen_ops.cgen_op_event(f, nvl, map->cmap_path, 1289 i)) { | 1843 1844 if (!cpcgen_ops.cgen_op_event(f, nvl, map->cmap_path, 1845 i)) { |
1290 (void) unlinkat(dirfd, tmpname, 0); | 1846 cpcgen_remove_tmpfile(dirfd, tmpname); |
1291 exit(EXIT_FAILURE); 1292 } 1293 } 1294 1295 if (!cpcgen_ops.cgen_op_file_after(f, map)) { | 1847 exit(EXIT_FAILURE); 1848 } 1849 } 1850 1851 if (!cpcgen_ops.cgen_op_file_after(f, map)) { |
1296 (void) unlinkat(dirfd, tmpname, 0); | 1852 cpcgen_remove_tmpfile(dirfd, tmpname); |
1297 exit(EXIT_FAILURE); 1298 } 1299 1300 if (fflush(f) != 0 || fclose(f) != 0) { | 1853 exit(EXIT_FAILURE); 1854 } 1855 1856 if (fflush(f) != 0 || fclose(f) != 0) { |
1301 int e = errno; 1302 (void) unlinkat(dirfd, tmpname, 0); 1303 errno = e; | 1857 cpcgen_remove_tmpfile(dirfd, tmpname); |
1304 err(EXIT_FAILURE, "failed to flush and close " 1305 "temporary file"); 1306 } 1307 1308 if (renameat(dirfd, tmpname, dirfd, name) != 0) { 1309 err(EXIT_FAILURE, "failed to rename temporary file %s", 1310 tmpname); 1311 } --- 16 unchanged lines hidden (view full) --- 1328 } 1329 1330 (void) fprintf(stderr, "Usage: %s -a|-p platform -c|-H|-m -d datadir " 1331 "-o outdir\n" 1332 "\n" 1333 "\t-a generate data for all platforms\n" 1334 "\t-c generate C file for CPC\n" 1335 "\t-d specify the directory containt perfmon data\n" | 1858 err(EXIT_FAILURE, "failed to flush and close " 1859 "temporary file"); 1860 } 1861 1862 if (renameat(dirfd, tmpname, dirfd, name) != 0) { 1863 err(EXIT_FAILURE, "failed to rename temporary file %s", 1864 tmpname); 1865 } --- 16 unchanged lines hidden (view full) --- 1882 } 1883 1884 (void) fprintf(stderr, "Usage: %s -a|-p platform -c|-H|-m -d datadir " 1885 "-o outdir\n" 1886 "\n" 1887 "\t-a generate data for all platforms\n" 1888 "\t-c generate C file for CPC\n" 1889 "\t-d specify the directory containt perfmon data\n" |
1336 "\t-h generate header file and common files\n" | 1890 "\t-H generate header file and common files\n" |
1337 "\t-m generate manual pages for CPC data\n" | 1891 "\t-m generate manual pages for CPC data\n" |
1338 "\t-o outut files in directory outdir\n" | 1892 "\t-o output files in directory outdir\n" |
1339 "\t-p generate data for a specified platform\n", 1340 cpcgen_progname); 1341} 1342 1343int 1344main(int argc, char *argv[]) 1345{ 1346 int c, outdirfd; --- 64 unchanged lines hidden (view full) --- 1411 if (count > 1) { 1412 cpcgen_usage("Only one of -a and -p may be specified\n"); 1413 return (2); 1414 } else if (count == 0) { 1415 cpcgen_usage("One of -a and -p is required\n"); 1416 return (2); 1417 } 1418 | 1893 "\t-p generate data for a specified platform\n", 1894 cpcgen_progname); 1895} 1896 1897int 1898main(int argc, char *argv[]) 1899{ 1900 int c, outdirfd; --- 64 unchanged lines hidden (view full) --- 1965 if (count > 1) { 1966 cpcgen_usage("Only one of -a and -p may be specified\n"); 1967 return (2); 1968 } else if (count == 0) { 1969 cpcgen_usage("One of -a and -p is required\n"); 1970 return (2); 1971 } 1972 |
1419 | |
1420 if (outdir == NULL) { 1421 cpcgen_usage("Missing required output directory (-o)\n"); 1422 return (2); 1423 } 1424 1425 if ((outdirfd = open(outdir, O_RDONLY)) < 0) { 1426 err(EXIT_FAILURE, "failed to open output directory %s", outdir); 1427 } 1428 1429 if (datadir == NULL) { 1430 cpcgen_usage("Missing required data directory (-d)\n"); 1431 return (2); 1432 } 1433 | 1973 if (outdir == NULL) { 1974 cpcgen_usage("Missing required output directory (-o)\n"); 1975 return (2); 1976 } 1977 1978 if ((outdirfd = open(outdir, O_RDONLY)) < 0) { 1979 err(EXIT_FAILURE, "failed to open output directory %s", outdir); 1980 } 1981 1982 if (datadir == NULL) { 1983 cpcgen_usage("Missing required data directory (-d)\n"); 1984 return (2); 1985 } 1986 |
1434 cpcgen_read_mapfile(datadir, platform); | 1987 cpcgen_determine_vendor(datadir); |
1435 | 1988 |
1436 if (do_header) { 1437 cpcgen_common_files(outdirfd); 1438 return (0); 1439 } | 1989 switch (cpcgen_mode) { 1990 case CPCGEN_MODE_INTEL: 1991 cpcgen_ops.cgen_op_gather = cpcgen_read_intel; 1992 cpcgen_ops.cgen_op_common = cpcgen_common_intel_files; 1993 cpcgen_ops.cgen_op_skip = cpcgen_skip_intel_entry; 1994 if (do_mpage) { 1995 cpcgen_ops.cgen_op_name = cpcgen_manual_intel_name; 1996 cpcgen_ops.cgen_op_file_before = 1997 cpcgen_manual_intel_file_before; 1998 cpcgen_ops.cgen_op_file_after = 1999 cpcgen_manual_intel_file_after; 2000 cpcgen_ops.cgen_op_event = cpcgen_manual_intel_event; 2001 } else { 2002 cpcgen_ops.cgen_op_name = cpcgen_cfile_intel_name; 2003 cpcgen_ops.cgen_op_file_before = 2004 cpcgen_cfile_intel_before; 2005 cpcgen_ops.cgen_op_file_after = 2006 cpcgen_cfile_intel_after; 2007 cpcgen_ops.cgen_op_event = cpcgen_cfile_intel_event; 2008 } 2009 break; 2010 case CPCGEN_MODE_AMD: 2011 cpcgen_ops.cgen_op_gather = cpcgen_read_amd; 2012 cpcgen_ops.cgen_op_common = cpcgen_common_amd_files; 2013 cpcgen_ops.cgen_op_skip = NULL; 2014 if (do_mpage) { 2015 cpcgen_ops.cgen_op_name = cpcgen_manual_amd_name; 2016 cpcgen_ops.cgen_op_file_before = 2017 cpcgen_manual_amd_file_before; 2018 cpcgen_ops.cgen_op_file_after = 2019 cpcgen_manual_amd_file_after; 2020 cpcgen_ops.cgen_op_event = cpcgen_manual_amd_event; 2021 } else { 2022 cpcgen_ops.cgen_op_name = cpcgen_cfile_amd_name; 2023 cpcgen_ops.cgen_op_file_before = 2024 cpcgen_cfile_amd_before; 2025 cpcgen_ops.cgen_op_file_after = cpcgen_cfile_amd_after; 2026 cpcgen_ops.cgen_op_event = cpcgen_cfile_amd_event; |
1440 | 2027 |
1441 if (do_mpage) { 1442 cpcgen_ops.cgen_op_name = cpcgen_manual_name; 1443 cpcgen_ops.cgen_op_file_before = cpcgen_manual_file_before; 1444 cpcgen_ops.cgen_op_file_after = cpcgen_manual_file_after; 1445 cpcgen_ops.cgen_op_event = cpcgen_manual_event; | 2028 } 2029 break; 2030 default: 2031 errx(EXIT_FAILURE, "failed to determine if operating on AMD or " 2032 "Intel"); 2033 break; |
1446 } 1447 | 2034 } 2035 |
1448 if (do_cfile) { 1449 cpcgen_ops.cgen_op_name = cpcgen_cfile_name; 1450 cpcgen_ops.cgen_op_file_before = cpcgen_cfile_file_before; 1451 cpcgen_ops.cgen_op_file_after = cpcgen_cfile_file_after; 1452 cpcgen_ops.cgen_op_event = cpcgen_cfile_event; | 2036 cpcgen_ops.cgen_op_gather(datadir, platform); 2037 2038 if (do_header) { 2039 cpcgen_ops.cgen_op_common(outdirfd); 2040 return (0); |
1453 } 1454 | 2041 } 2042 |
1455 | |
1456 cpcgen_gen(outdirfd); 1457 1458 return (0); 1459} | 2043 cpcgen_gen(outdirfd); 2044 2045 return (0); 2046} |