From 472d9025e57a3afcd8af547df218db134253a56f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Mon, 5 Dec 2011 20:33:55 +0200 Subject: [PATCH] Sconfig: parse Kconfig options from devicetree.cb MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Mainboard and chip Kconfig files have several build options that are redundant with information in devicetree.cb. This patch enables sconfig to auto-generate equivalent configuration. sconfig -s Generates mainboard's static.c file, as before. sconfig -b This operation creates mainboard's bootblock init code. By default, for every chip listed in mainboard/devicetree.cb, if there is a chip/bootblock.c file, the init function is called. A mainboard/bootblock.c file can be added to override default behaviour. sconfig -k This operation generates select -options for component paths. Change-Id: I808d44af552dbc5e0565d6a0f4f72c7be9f5740e Signed-off-by: Kyösti Mälkki Reviewed-on: http://review.coreboot.org/472 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/sconfig/main.c | 173 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 136 insertions(+), 37 deletions(-) diff --git a/util/sconfig/main.c b/util/sconfig/main.c index dab04db32..181be387a 100644 --- a/util/sconfig/main.c +++ b/util/sconfig/main.c @@ -29,6 +29,14 @@ struct header headers; static int devcount = 0; +typedef enum { + STATIC_MODE, + BOOTBLOCK_MODE, + KCONFIG_MODE +} scan_t; + +static scan_t scan_mode = STATIC_MODE; + static struct device root; static struct device mainboard = { .name = "mainboard", @@ -116,21 +124,28 @@ void postprocess_devtree(void) { } } +void translate_name(char *str, int uppercase) +{ + char *c; + for (c = str; *c; c++) { + if (*c == '/') *c = '_'; + if (*c == '-') *c = '_'; + if (uppercase) + *c = toupper(*c); + } +} + struct device *new_chip(struct device *parent, struct device *bus, char *path) { struct device *new_chip = new_dev(parent, bus); new_chip->chiph_exists = 1; new_chip->name = path; new_chip->name_underscore = strdup(new_chip->name); - char *c; - for (c = new_chip->name_underscore; *c; c++) { - if (*c == '/') *c = '_'; - if (*c == '-') *c = '_'; - } + translate_name(new_chip->name_underscore, 0); new_chip->type = chip; new_chip->chip = new_chip; struct stat st; - char *chip_h = malloc(strlen(path)+12); + char *chip_h = malloc(strlen(path)+18); sprintf(chip_h, "src/%s", path); if ((stat(chip_h, &st) == -1) && (errno == ENOENT)) { fprintf(stderr, "ERROR: Chip component %s does not exist.\n", @@ -138,9 +153,15 @@ struct device *new_chip(struct device *parent, struct device *bus, char *path) { exit(1); } - sprintf(chip_h, "src/%s/chip.h", path); - if ((stat(chip_h, &st) == -1) && (errno == ENOENT)) - new_chip->chiph_exists = 0; + if (scan_mode == STATIC_MODE) + sprintf(chip_h, "src/%s/chip.h", path); + else if (scan_mode == BOOTBLOCK_MODE) + sprintf(chip_h, "src/%s/bootblock.c", path); + + if ((scan_mode == STATIC_MODE) || (scan_mode == BOOTBLOCK_MODE)) { + if ((stat(chip_h, &st) == -1) && (errno == ENOENT)) + new_chip->chiph_exists = 0; + } if (parent->latestchild) { parent->latestchild->next_sibling = new_chip; @@ -153,7 +174,7 @@ struct device *new_chip(struct device *parent, struct device *bus, char *path) { } void add_header(struct device *dev) { - if (dev->chiph_exists) { + if ((dev->chiph_exists) || (scan_mode == KCONFIG_MODE)){ int include_exists = 0; struct header *h = &headers; while (h->next) { @@ -399,7 +420,8 @@ static void pass1(FILE *fil, struct device *ptr) { } if ((ptr->type == chip) && (ptr->chiph_exists)) { if (ptr->reg) { - fprintf(fil, "struct %s_config %s_info_%d\t= {\n", ptr->name_underscore, ptr->name_underscore, ptr->id); + fprintf(fil, "struct %s_config %s_info_%d\t= {\n", + ptr->name_underscore, ptr->name_underscore, ptr->id); struct reg *r = ptr->reg; while (r) { fprintf(fil, "\t.%s = %s,\n", r->key, r->value); @@ -407,7 +429,8 @@ static void pass1(FILE *fil, struct device *ptr) { } fprintf(fil, "};\n\n"); } else { - fprintf(fil, "struct %s_config %s_info_%d;\n", ptr->name_underscore, ptr->name_underscore, ptr->id); + fprintf(fil, "struct %s_config %s_info_%d;\n", + ptr->name_underscore, ptr->name_underscore, ptr->id); } } } @@ -441,22 +464,60 @@ static void inherit_subsystem_ids(FILE *file, struct device *dev) } } +static void usage(void) +{ + printf("usage: sconfig vendor/mainboard outputdir [-{s|b|k} outputfile]\n"); + printf("\t-s file\tcreate ramstage static device map\n"); + printf("\t-b file\tcreate bootblock init_mainboard()\n"); + printf("\t-k file\tcreate Kconfig devicetree section\n"); + printf("Defaults to \"-s static.c\" if no {s|b|k} specified.\n"); + exit (1); +} + + int main(int argc, char** argv) { - if (argc != 3) { - printf("usage: sconfig vendor/mainboard outputdir\n"); - return 1; - } + if (argc < 3) + usage(); + char *mainboard=argv[1]; char *outputdir=argv[2]; char *devtree=malloc(strlen(mainboard)+30); - char *outputc=malloc(strlen(outputdir)+10); sprintf(devtree, "src/mainboard/%s/devicetree.cb", mainboard); - sprintf(outputc, "%s/static.c", outputdir); + char *outputc; - headers.next = malloc(sizeof(struct header)); - headers.next->name = malloc(strlen(mainboard)+12); - headers.next->next = 0; - sprintf(headers.next->name, "mainboard/%s", mainboard); + if (argc == 3) { + scan_mode = STATIC_MODE; + outputc=malloc(strlen(outputdir)+20); + sprintf(outputc, "%s/static.c", outputdir); + } else if ((argc == 5) && (argv[3][0] == '-') && (argv[3][2] == 0)) { + + switch (argv[3][1]) { + case 's': + scan_mode = STATIC_MODE; + break; + case 'b': + scan_mode = BOOTBLOCK_MODE; + break; + case 'k': + scan_mode = KCONFIG_MODE; + break; + default: + usage(); + break; + } + char *outputfile=argv[4]; + + outputc=malloc(strlen(outputdir)+strlen(outputfile)+2); + sprintf(outputc, "%s/%s", outputdir, outputfile); + } + + headers.next = 0; + if (scan_mode == STATIC_MODE) { + headers.next = malloc(sizeof(struct header)); + headers.next->name = malloc(strlen(mainboard)+12); + headers.next->next = 0; + sprintf(headers.next->name, "mainboard/%s", mainboard); + } FILE *filec = fopen(devtree, "r"); if (!filec) { @@ -479,29 +540,67 @@ int main(int argc, char** argv) { while (head->next != tmp) head = head->next; } - FILE *staticc = fopen(outputc, "w"); - if (!staticc) { + FILE *autogen = fopen(outputc, "w"); + if (!autogen) { fprintf(stderr, "Could not open file '%s' for writing: ", outputc); perror(NULL); exit(1); } - fprintf(staticc, "#include \n"); - fprintf(staticc, "#include \n"); - struct header *h = &headers; - while (h->next) { - h = h->next; - fprintf(staticc, "#include \"%s/chip.h\"\n", h->name); - } + struct header *h; + if (scan_mode == STATIC_MODE) { - walk_device_tree(staticc, &root, inherit_subsystem_ids, NULL); + fprintf(autogen, "#include \n"); + fprintf(autogen, "#include \n"); + h = &headers; + while (h->next) { + h = h->next; + fprintf(autogen, "#include \"%s/chip.h\"\n", h->name); + } - fprintf(staticc, "\n/* pass 0 */\n"); - walk_device_tree(staticc, &root, pass0, NULL); - fprintf(staticc, "\n/* pass 1 */\nstruct mainboard_config mainboard_info_0;\nstruct device *last_dev = &%s;\n", lastdev->name); - walk_device_tree(staticc, &root, pass1, NULL); + walk_device_tree(autogen, &root, inherit_subsystem_ids, NULL); + fprintf(autogen, "\n/* pass 0 */\n"); + walk_device_tree(autogen, &root, pass0, NULL); + fprintf(autogen, "\n/* pass 1 */\nstruct mainboard_config mainboard_info_0;\n" + "struct device *last_dev = &%s;\n", lastdev->name); + walk_device_tree(autogen, &root, pass1, NULL); + + } else if (scan_mode == BOOTBLOCK_MODE) { + h = &headers; + while (h->next) { + h = h->next; + fprintf(autogen, "#include \"%s/bootblock.c\"\n", h->name); + } + + fprintf(autogen, "\n#if CONFIG_HAS_MAINBOARD_BOOTBLOCK\n"); + fprintf(autogen, "#include \"mainboard/%s/bootblock.c\"\n", mainboard); + fprintf(autogen, "#else\n"); + fprintf(autogen, "static unsigned long init_mainboard(int bsp_cpu)\n{\n"); + fprintf(autogen, "\tif (! bsp_cpu) return 0;\n"); + h = &headers; + while (h->next) { + h = h->next; + translate_name(h->name, 0); + fprintf(autogen, "\tinit_%s();\n", h->name); + } + + fprintf(autogen, "\treturn 0;\n}\n"); + fprintf(autogen, "#endif\n"); + + } else if (scan_mode == KCONFIG_MODE) { + fprintf(autogen, "\nconfig MAINBOARD_DIR\n\tstring\n"); + fprintf(autogen, "\tdefault %s\n", mainboard); + + fprintf(autogen, "\nconfig MAINBOARD_DEVTREE\n\tdef_bool y\n"); + h = &headers; + while (h->next) { + h = h->next; + translate_name(h->name, 1); + fprintf(autogen, "\tselect %s\n", h->name); + } + } - fclose(staticc); + fclose(autogen); return 0; } -- 2.25.1