summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/regtools/headergen.cpp227
1 files changed, 214 insertions, 13 deletions
diff --git a/utils/regtools/headergen.cpp b/utils/regtools/headergen.cpp
index fc1ce6fba6..0a65388686 100644
--- a/utils/regtools/headergen.cpp
+++ b/utils/regtools/headergen.cpp
@@ -26,11 +26,16 @@
26#include <sstream> 26#include <sstream>
27#include <sys/stat.h> 27#include <sys/stat.h>
28#include <sys/types.h> 28#include <sys/types.h>
29#include <getopt.h>
29 30
30#define HEADERGEN_VERSION "2.1.7" 31#define HEADERGEN_VERSION "2.1.7"
31 32
32#define error(...) do{ fprintf(stderr, __VA_ARGS__); exit(1); } while(0) 33#define error(...) do{ fprintf(stderr, __VA_ARGS__); exit(1); } while(0)
33 34
35bool g_gen_selector = false;
36
37std::string g_macro_filename;
38
34std::string g_soc_name; 39std::string g_soc_name;
35std::string g_soc_dev; 40std::string g_soc_dev;
36std::string g_soc_reg; 41std::string g_soc_reg;
@@ -86,8 +91,10 @@ void fprint_copyright(FILE *f, const std::vector< xml_ver_t >& versions)
86 * Firmware |____|_ /\\____/ \\___ >__|_ \\|___ /\\____/__/\\_ \\\n\ 91 * Firmware |____|_ /\\____/ \\___ >__|_ \\|___ /\\____/__/\\_ \\\n\
87 * \\/ \\/ \\/ \\/ \\/\n\ 92 * \\/ \\/ \\/ \\/ \\/\n\
88 * This file was automatically generated by headergen, DO NOT EDIT it.\n\ 93 * This file was automatically generated by headergen, DO NOT EDIT it.\n\
89 * headergen version: " HEADERGEN_VERSION "\n\ 94 * headergen version: " HEADERGEN_VERSION "\n");
90 * XML versions:%s\n\ 95 if(versions.size() > 0)
96 fprintf(f, " * XML versions:%s\n", ver.str().c_str());
97 fprintf(f,"\
91 *\n\ 98 *\n\
92 * Copyright (C) 2013 by Amaury Pouly\n\ 99 * Copyright (C) 2013 by Amaury Pouly\n\
93 *\n\ 100 *\n\
@@ -99,8 +106,7 @@ void fprint_copyright(FILE *f, const std::vector< xml_ver_t >& versions)
99 * This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY\n\ 106 * This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY\n\
100 * KIND, either express or implied.\n\ 107 * KIND, either express or implied.\n\
101 *\n\ 108 *\n\
102 ****************************************************************************/\n", 109 ****************************************************************************/\n");
103ver.str().c_str());
104} 110}
105 111
106void fprint_copyright(FILE *f, const xml_ver_t& version) 112void fprint_copyright(FILE *f, const xml_ver_t& version)
@@ -108,6 +114,11 @@ void fprint_copyright(FILE *f, const xml_ver_t& version)
108 fprint_copyright(f, std::vector< xml_ver_t >(1, version)); 114 fprint_copyright(f, std::vector< xml_ver_t >(1, version));
109} 115}
110 116
117void fprint_copyright(FILE *f)
118{
119 fprint_copyright(f, std::vector< xml_ver_t >());
120}
121
111void fprint_include_guard_ex(FILE *f, bool begin, const std::string& name) 122void fprint_include_guard_ex(FILE *f, bool begin, const std::string& name)
112{ 123{
113 if(begin) 124 if(begin)
@@ -262,6 +273,8 @@ void gen_soc_dev_header(const std::string& filename, const xml_ver_t& ver, const
262 } 273 }
263 fprint_copyright(f, ver); 274 fprint_copyright(f, ver);
264 fprint_include_guard(f, true); 275 fprint_include_guard(f, true);
276 if(g_macro_filename.size() > 0)
277 fprintf(f, "#include \"%s\"\n", g_macro_filename.c_str());
265 278
266 /* print base */ 279 /* print base */
267 fprintf(f, "\n"); 280 fprintf(f, "\n");
@@ -311,7 +324,10 @@ void gen_headers(const std::string& prefix, const std::vector< soc_t >& socs)
311 for(size_t i = 0; i < socs.size(); i++) 324 for(size_t i = 0; i < socs.size(); i++)
312 { 325 {
313 g_soc_name = socs[i].name; 326 g_soc_name = socs[i].name;
314 gen_soc_headers(prefix + "/" + socs[i].name, socs[i]); 327 std::string dir = prefix;
328 if(g_gen_selector)
329 dir += "/" + socs[i].name;
330 gen_soc_headers(dir, socs[i]);
315 } 331 }
316} 332}
317 333
@@ -330,16 +346,14 @@ general_dev_list_t build_general_dev_list(const std::vector< soc_t >& socs)
330void gen_select_header(const std::string& filename, const std::string& dev, 346void gen_select_header(const std::string& filename, const std::string& dev,
331 const std::vector< std::string >& socs, const std::vector< xml_ver_t >& ver) 347 const std::vector< std::string >& socs, const std::vector< xml_ver_t >& ver)
332{ 348{
333 /*
334 printf("Generate select header for device %s: write to %s\n", dev.c_str(),
335 filename.c_str());
336 */
337 std::string guard = "__SELECT__" + toupper(dev) + "__H__"; 349 std::string guard = "__SELECT__" + toupper(dev) + "__H__";
338 FILE *f = fopen(filename.c_str(), "w"); 350 FILE *f = fopen(filename.c_str(), "w");
339 if(f == NULL) 351 if(f == NULL)
340 error("Cannot open file %s\n", filename.c_str()); 352 error("Cannot open file %s\n", filename.c_str());
341 fprint_copyright(f, ver); 353 fprint_copyright(f, ver);
342 fprint_include_guard_ex(f, true, guard); 354 fprint_include_guard_ex(f, true, guard);
355 if(g_macro_filename.size() > 0)
356 fprintf(f, "#include \"%s\"\n", g_macro_filename.c_str());
343 fprintf(f, "\n"); 357 fprintf(f, "\n");
344 358
345 for(size_t i = 0; i < socs.size(); i++) 359 for(size_t i = 0; i < socs.size(); i++)
@@ -360,6 +374,7 @@ void gen_select_header(const std::string& filename, const std::string& dev,
360 374
361void gen_selectors(const std::string& prefix, const std::vector< soc_t >& socs) 375void gen_selectors(const std::string& prefix, const std::vector< soc_t >& socs)
362{ 376{
377 printf("Generate select headers: use directory %s\n", prefix.c_str());
363 general_dev_list_t map = build_general_dev_list(socs); 378 general_dev_list_t map = build_general_dev_list(socs);
364 for(general_dev_list_t::iterator it = map.begin(); it != map.end(); ++it) 379 for(general_dev_list_t::iterator it = map.begin(); it != map.end(); ++it)
365 { 380 {
@@ -376,24 +391,210 @@ void gen_selectors(const std::string& prefix, const std::vector< soc_t >& socs)
376 } 391 }
377} 392}
378 393
394void gen_macro_list(FILE *f, const std::string& prefix, int count, int nr_digits,
395 const std::string& sep, int max_per_line = 1000, const std::string& align = "")
396{
397 for(int i = 1; i <= count;)
398 {
399 for(int j = i; j <= std::min(count, i + max_per_line - 1); j++)
400 {
401 fprintf(f, "%s%0*d", prefix.c_str(), nr_digits, j);
402 if(j < count)
403 fprintf(f, "%s", sep.c_str());
404 }
405 i += max_per_line;
406 if(i <= count)
407 fprintf(f, "\\\n%s", align.c_str());
408 }
409}
410
411void gen_macro(const std::string& filename, bool variadic)
412{
413 printf("Generate %smacro header: use %s\n", variadic ? "": "non-variadic ",
414 filename.c_str());
415 std::string guard = "__REGS__MACRO__H__";
416 FILE *f = fopen(filename.c_str(), "w");
417 if(f == NULL)
418 error("Cannot open file %s\n", filename.c_str());
419 fprint_copyright(f);
420 fprint_include_guard_ex(f, true, guard);
421 fprintf(f, "\n");
422
423#define REG_WRITE "REG_WRITE"
424 fprintf(f, "#ifndef %s\n", REG_WRITE);
425 fprintf(f, "#define %s(var,value) ((var) = (value))\n", REG_WRITE);
426 fprintf(f, "#endif /* %s */\n", REG_WRITE);
427 fprintf(f, "\n");
428
429#define REG_READ "REG_READ"
430 fprintf(f, "#ifndef %s\n", REG_READ);
431 fprintf(f, "#define %s(var) (var)\n", REG_READ);
432 fprintf(f, "#endif /* %s */\n", REG_READ);
433 fprintf(f, "\n");
434
435 const int MAX_NARGS = 32;
436
437 fprintf(f, "\
438#define BF_SET(reg, field) "REG_WRITE"(HW_##reg##_SET, BM_##reg##_##field)\n\
439#define BF_CLR(reg, field) "REG_WRITE"(HW_##reg##_CLR, BM_##reg##_##field)\n\
440#define BF_TOG(reg, field) "REG_WRITE"(HW_##reg##_TOG, BM_##reg##_##field)\n\
441\n\
442#define BF_SETV(reg, field, v) "REG_WRITE"(HW_##reg##_SET, BF_##reg##_##field(v))\n\
443#define BF_CLRV(reg, field, v) "REG_WRITE"(HW_##reg##_CLR, BF_##reg##_##field(v))\n\
444#define BF_TOGV(reg, field, v) "REG_WRITE"(HW_##reg##_TOG, BF_##reg##_##field(v))\n\
445\n\
446#define BF_RDX(val, reg, field) (("REG_READ"(val) & BM_##reg##_##field) >> BP_##reg##_##field)\n\
447#define BF_RD(reg, field) BF_RDX("REG_READ"(HW_##reg), reg, field)\n\
448#define BF_WRX(val, reg, field, v) "REG_WRITE"(val, ("REG_READ"(val) & ~BM_##reg##_##field) | (((v) << BP_##reg##_##field) & BM_##reg##_##field))\n\
449#define BF_WR(reg, field, v) BF_WRX(HW_##reg, reg, field, v)\n\
450#define BF_WR_V(reg, field, sy) BF_WR(reg, field, BV_##reg##_##field##__##sy)\n\
451#define BF_WR_VX(val, reg, field, sy) BF_WRX(val, reg, field, BV_##reg##_##field##__##sy)\n\
452\n\
453#define BF_SETn(reg, n, field) "REG_WRITE"(HW_##reg##_SET(n), BM_##reg##_##field)\n\
454#define BF_CLRn(reg, n, field) "REG_WRITE"(HW_##reg##_CLR(n), BM_##reg##_##field)\n\
455#define BF_TOGn(reg, n, field) "REG_WRITE"(HW_##reg##_TOG(n), BM_##reg##_##field)\n\
456\n\
457#define BF_SETVn(reg, n, field, v) "REG_WRITE"(HW_##reg##_SET(n), BF_##reg##_##field(v))\n\
458#define BF_CLRVn(reg, n, field, v) "REG_WRITE"(HW_##reg##_CLR(n), BF_##reg##_##field(v))\n\
459#define BF_TOGVn(reg, n, field, v) "REG_WRITE"(HW_##reg##_TOG(n), BF_##reg##_##field(v))\n\
460\n\
461#define BF_RDn(reg, n, field) BF_RDX(HW_##reg(n), reg, field)\n\
462#define BF_WRn(reg, n, field, v) BF_WRX(HW_##reg(n), reg, field, v)\n\
463#define BF_WRn_V(reg, n, field, sy) BF_WRn(reg, n, field, BV_##reg##_##field##__##sy)\n\
464\n");
465
466 for(int nargs = 1; nargs <= MAX_NARGS; nargs++)
467 {
468 fprintf(f, "#define BM_OR%d(reg, ", nargs);
469 gen_macro_list(f, "f", nargs, 2, ", ", 10, " ");
470 fprintf(f, ") \\\n (");
471 gen_macro_list(f, "BM_##reg##_##f", nargs, 2, " | ", 4, " ");
472 fprintf(f, ")\n");
473 }
474 fprintf(f, "\n");
475
476 for(int nargs = 1; nargs <= MAX_NARGS; nargs++)
477 {
478 fprintf(f, "#define BF_OR%d(reg, ", nargs);
479 gen_macro_list(f, "f", nargs, 2, ", ", 10, " ");
480 fprintf(f, ") \\\n (");
481 gen_macro_list(f, "BF_##reg##_##f", nargs, 2, " | ", 4, " ");
482 fprintf(f, ")\n");
483 }
484 fprintf(f, "\n");
485
486 if(variadic)
487 {
488 fprintf(f, "#define REG_NARG(...) REG_NARGS_(__VA_ARGS__");
489 for(int i = MAX_NARGS; i >= 1; i--)
490 fprintf(f, ", %d", i);
491 fprintf(f, ")\n");
492 fprintf(f, "#define REG_NARGS_(");
493 gen_macro_list(f, "_", MAX_NARGS, 1, ", ");
494 fprintf(f, ", N, ...) N\n\n");
495
496 fprintf(f, "#define REG_VARIADIC(macro, reg, ...) REG_VARIADIC_(macro, NARG(__VA_ARGS__), reg, __VA_ARGS__)\n");
497 fprintf(f, "#define REG_VARIADIC_(macro, cnt, reg, ...) REG_VARIADIC__(macro, cnt, reg, __VA_ARGS__)\n");
498 fprintf(f, "#define REG_VARIADIC__(macro, cnt, reg, ...) REG_VARIADIC___(macro##cnt, reg, ...)\n");
499 fprintf(f, "#define REG_VARIADIC___(macro, reg, ...) macro(reg, __VA_ARGS__)\n\n");
500
501 fprintf(f, "#define BM_OR(reg, ...) REG_VARIADIC(BM_OR, reg, __VA_ARGS__)\n");
502 fprintf(f, "#define BF_OR(reg, ...) REG_VARIADIC(BF_OR, reg, __VA_ARGS__)\n");
503 }
504
505 fprint_include_guard_ex(f, false, guard);
506 fclose(f);
507}
508
379void usage() 509void usage()
380{ 510{
381 printf("usage: headergen <desc files...> <output directory>\n"); 511 printf("usage: headergen [options] <desc files...> <output directory>\n");
512 printf("options:\n");
513 printf(" -?/--help Dispaly this help\n");
514 printf(" -s/--selector Always produce selector files\n");
515 printf(" -m/--no-macro Do not generate a macro file with helpers\n");
516 printf(" -i/--no-include Do not include the macro file in the headers\n");
517 printf(" -v/--no-variadic Do not generate variadic macros\n");
518 printf("Default option is to generate a macro file with variadic macros.\n");
519 printf("Default option is to include the macro file in the headers.\n");
520 printf("Default option is to generate selector files only for two or more socs.\n");
521 printf("Default option is to create one subdirectory per soc, except if no\n");
522 printf("selector files are needed. The subdirectories will be created if\n");
523 printf("necessary.\n");
382 exit(1); 524 exit(1);
383} 525}
384 526
385int main(int argc, char **argv) 527int main(int argc, char **argv)
386{ 528{
387 if(argc < 3) 529 bool force_selector = false;
530 bool no_variadic = false;
531 bool no_macro = false;
532 bool no_include = false;
533 if(argc <= 1)
388 usage(); 534 usage();
535
536 while(1)
537 {
538 static struct option long_options[] =
539 {
540 {"help", no_argument, 0, '?'},
541 {"selector", no_argument, 0, 's'},
542 {"no-macro", no_argument, 0, 'm'},
543 {"no-include", no_argument, 0, 'i'},
544 {"no-variadic", no_argument, 0, 'v'},
545 {0, 0, 0, 0}
546 };
547
548 int c = getopt_long(argc, argv, "?smiv", long_options, NULL);
549 if(c == -1)
550 break;
551 switch(c)
552 {
553 case -1:
554 break;
555 case '?':
556 usage();
557 break;
558 case 's':
559 force_selector = true;
560 break;
561 case 'm':
562 no_macro = true;
563 break;
564 case 'i':
565 no_include = true;
566 break;
567 case 'v':
568 no_variadic = true;
569 break;
570 default:
571 abort();
572 }
573 }
574
389 std::vector< soc_t > socs; 575 std::vector< soc_t > socs;
390 for(int i = 1; i < argc - 1; i++) 576 for(int i = optind; i < argc - 1; i++)
391 if(!soc_desc_parse_xml(argv[i], socs)) 577 if(!soc_desc_parse_xml(argv[i], socs))
392 { 578 {
393 printf("Cannot parse %s\n", argv[i]); 579 printf("Cannot parse %s\n", argv[i]);
394 return 1; 580 return 1;
395 } 581 }
582
583 g_gen_selector = force_selector || socs.size() > 1;
584
585 if(!no_macro)
586 {
587 g_macro_filename = std::string(argv[argc - 1]) + "/regs-macro.h";
588 gen_macro(g_macro_filename, !no_variadic);
589 g_macro_filename = "regs-macro.h";
590 if(no_include)
591 g_macro_filename.clear();
592 }
593 if(g_gen_selector)
594 {
595 gen_selectors(argv[argc - 1], socs);
596 g_macro_filename.clear();
597 }
396 gen_headers(argv[argc - 1], socs); 598 gen_headers(argv[argc - 1], socs);
397 gen_selectors(argv[argc - 1], socs);
398 return 0; 599 return 0;
399} \ No newline at end of file 600} \ No newline at end of file