From 987a169b75e9af25f7a8ef3a08bca173cda241be Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sat, 29 Sep 2012 18:42:17 +0200 Subject: [PATCH] fexc: add `uboot` output --- Makefile | 1 + fexc.c | 38 +++++++++++------ fexc.h | 1 + script_uboot.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ script_uboot.h | 22 ++++++++++ 5 files changed, 157 insertions(+), 13 deletions(-) create mode 100644 script_uboot.c create mode 100644 script_uboot.h diff --git a/Makefile b/Makefile index 433f6f5..49a0660 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ fex2bin bin2fex: fexc ln -s $< $@ fexc: fexc.h script.h script.c \ + script_uboot.h script_uboot.c \ script_bin.h script_bin.c \ script_fex.h script_fex.c diff --git a/fexc.c b/fexc.c index 3306cd0..c325735 100644 --- a/fexc.c +++ b/fexc.c @@ -32,6 +32,7 @@ enum script_format { FEX_SCRIPT_FORMAT, BIN_SCRIPT_FORMAT, + UBOOT_HEADER_FORMAT, }; /* @@ -145,6 +146,8 @@ static inline int script_parse(enum script_format format, bin_close: close(in); }; break; + case UBOOT_HEADER_FORMAT: /* not valid input */ + ; } return ret; } @@ -153,21 +156,24 @@ static inline int script_generate(enum script_format format, struct script *script) { int ret = 0; - switch (format) { - case FEX_SCRIPT_FORMAT: { + static int (*text_gen[3]) (FILE *, const char *, struct script *) = { + [FEX_SCRIPT_FORMAT] = script_generate_fex, + [UBOOT_HEADER_FORMAT] = script_generate_uboot, + }; + + if (text_gen[format]) { FILE *out = stdout; if (!filename) filename = ""; else if ((out = fopen(filename, "w")) == NULL) { pr_err("%s: %s\n", filename, strerror(errno)); - break; + goto done; } - ret = script_generate_fex(out, filename, script); + ret = text_gen[format](out, filename, script); fclose(out); - }; break; - case BIN_SCRIPT_FORMAT: { + } else { int out = 1; /* stdout */ size_t sections, entries, bin_size; void *bin; @@ -176,7 +182,7 @@ static inline int script_generate(enum script_format format, filename = ""; else if ((out = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { pr_err("%s: %s\n", filename, strerror(errno)); - break; + goto done; } bin_size = script_bin_size(script, §ions, &entries); @@ -201,8 +207,8 @@ static inline int script_generate(enum script_format format, } free(bin); close(out); - }; break; } +done: return ret; } @@ -215,7 +221,7 @@ static inline void app_usage(const char *arg0, int mode) if (mode == 0) fputs("\ninfmt: fex, bin (default:fex)" - "\noutfmt: fex, bin (default:bin)\n", + "\noutfmt: fex, bin, uboot (default:bin)\n", stderr); } @@ -234,7 +240,7 @@ static inline int app_choose_mode(char *arg0) */ int main(int argc, char *argv[]) { - static const char *formats[] = { "fex", "bin", NULL }; + static const char *formats[] = { "fex", "bin", "uboot", NULL }; enum script_format infmt=FEX_SCRIPT_FORMAT; enum script_format outfmt=BIN_SCRIPT_FORMAT; const char *filename[] = { NULL /*stdin*/, NULL /*stdout*/}; @@ -246,8 +252,10 @@ int main(int argc, char *argv[]) int opt, ret = 1; int verbose = 0; - if (app_mode == 2) /* bin2fex */ - infmt = 1, outfmt = 0; + if (app_mode == 2) { /* bin2fex */ + infmt = BIN_SCRIPT_FORMAT; + outfmt = FEX_SCRIPT_FORMAT; + } while ((opt = getopt(argc, argv, opt_string)) != -1) { switch (opt) { @@ -257,7 +265,11 @@ int main(int argc, char *argv[]) if (strcmp(*f, optarg) == 0) break; } - if (!formats[infmt]) { + switch (infmt) { + case FEX_SCRIPT_FORMAT: + case BIN_SCRIPT_FORMAT: + break; + default: errf("%s: invalid format -- \"%s\"\n", argv[0], optarg); goto show_usage; diff --git a/fexc.h b/fexc.h index 2b33395..c5b32a9 100644 --- a/fexc.h +++ b/fexc.h @@ -25,5 +25,6 @@ #include "script.h" #include "script_bin.h" #include "script_fex.h" +#include "script_uboot.h" #endif diff --git a/script_uboot.c b/script_uboot.c new file mode 100644 index 0000000..dee697a --- /dev/null +++ b/script_uboot.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2012 Alejandro Mery + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "common.h" + +#include +#include +#include + +#include "script.h" +#include "script_uboot.h" + +#define pr_info(...) errf("fexc-uboot: " __VA_ARGS__) +#define pr_err(...) errf("E: fexc-uboot: " __VA_ARGS__) + +#ifdef DEBUG +#define pr_debug(...) errf("D: fexc-uboot: " __VA_ARGS__) +#else +#define pr_debug(...) +#endif + +static inline void out_dram_member(FILE *out, const char *key, uint32_t val) +{ + const char *fmt; + if (strncmp(key, "tpr", 3) == 0 || + strncmp(key, "emr", 3) == 0) + fmt = "\t.%s = %#x,\n"; + else + fmt = "\t.%s = %u,\n"; + + fprintf(out, fmt, key, val); +} + +static int generate_dram_struct(FILE *out, struct script_section *sp) +{ + struct list_entry *le; + struct script_entry *ep; + struct script_single_entry *val; + const char *key; + int ret = 1; + + fprintf(out, "struct dram_para para = {\n"); + for (le = list_first(&sp->entries); le; + le = list_next(&sp->entries, le)) { + ep = container_of(le, struct script_entry, entries); + + if (strncmp(ep->name, "dram_", 5) != 0) + goto invalid_field; + + key = ep->name + 5; + if (strcmp(key, "") == 0) + goto invalid_field; + else if (strcmp(key, "baseaddr") == 0) + continue; /* skip */ + else if (strcmp(key, "clk") == 0) + key = "clock"; + + switch (ep->type) { + case SCRIPT_VALUE_TYPE_SINGLE_WORD: + val = container_of(ep, struct script_single_entry, entry); + if (val->value > 0) + out_dram_member(out, key, val->value); + /* pass through */ + case SCRIPT_VALUE_TYPE_NULL: + continue; + default: +invalid_field: + pr_err("dram_para: %s: invalid field\n", ep->name); + ret = 0; + } + + } + fprintf(out, "};\n"); + return ret; +} + +int script_generate_uboot(FILE *out, const char *UNUSED(filename), + struct script *script) +{ + struct script_section *section; + const char *section_name; + + fprintf(out, "/* this file is generated, don't edit it yourself */\n\n"); + + section_name = "dram_para"; + section = script_find_section(script, section_name); + if (!section) + goto missing_section; + generate_dram_struct(out, section); + + return 1; +missing_section: + pr_err("%s: critical section missing", section_name); + return 0; +} diff --git a/script_uboot.h b/script_uboot.h new file mode 100644 index 0000000..abfca14 --- /dev/null +++ b/script_uboot.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2012 Alejandro Mery + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef _SUBXI_TOOLS_SCRIPT_UBOOT_H +#define _SUBXI_TOOLS_SCRIPT_UBOOT_H + +int script_generate_uboot(FILE *out, const char *filename, struct script *script); + +#endif