From 16fd5a99e1a8c433077e70c1a48e42cc01bf7d29 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 15 Aug 2006 21:02:55 +0000 Subject: 2006-08-15 Kolja Waschk * linkcmds.c, linkcmds.h, memory.c, memory.h, sample.ptf: New files. * bridges.c: corrected detection of bridged connections * clocks.c: removed a printf * linkcmds.[ch] new files, added output of linker script * Makefile.am: added new files * memory.[ch]: new files, detection of memory in SOPC configuration * nios2gen.c: updated command line parsing and output control * output.[ch]: improved output of BSP header file * ptf.[ch]: added ptf_dump_ptf_item and small fixes * sample.ptf: new file, sample configuration for nios2gen * README: updated --- tools/cpu/nios2/nios2gen.c | 399 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 319 insertions(+), 80 deletions(-) (limited to 'tools/cpu/nios2/nios2gen.c') diff --git a/tools/cpu/nios2/nios2gen.c b/tools/cpu/nios2/nios2gen.c index fb271735ca..a62f0e3120 100644 --- a/tools/cpu/nios2/nios2gen.c +++ b/tools/cpu/nios2/nios2gen.c @@ -16,7 +16,14 @@ #include "bridges.h" #include "clocks.h" #include "devices.h" +#include "memory.h" #include "output.h" +#include "linkcmds.h" + +#define NIOS2GEN_PACKAGE PACKAGE +#define NIOS2GEN_VERSION VERSION + +#include "getopt.h" /********************************************************/ @@ -64,29 +71,39 @@ void read_include_file(struct ptf_item *pi, void *arg) p->next = next; } -void usage() -{ -printf( - "Usage: nios2gen [PTFFILE]\n" - "Generate BSP data based upon PTF file from SOPC Builder.\n" - "\n" - "Please specify the name of a nios2gen PTF file that describes where to\n" - "find the system description PTF from SOPC Builder on the command line.\n" -); -} +/********************************************************/ -void version() +void version(FILE *f) { -printf( - "RTEMS/NIOS nios2gen\n" +fprintf(f, + "nios2gen (" __DATE__ ")\n" " Copyright (c) 2006 Kolja Waschk rtemsdev/ixo.de\n" "\n" " The license and distribution terms for this file may be\n" " found in the file LICENSE in this distribution or at\n" " http://www.rtems.com/license/LICENSE.\n" + , VERSION ); } +void usage (FILE *f, char *errmsg) +{ + char *info = "Purpose:\n Create RTEMS nios2 BSP configuration from Altera SOPC description\n"; + if(errmsg) info=errmsg; + version(f); + fprintf(f,"\n%s\nUsage: nios2gen [OPTIONS] [CONFIG PTF] [CONFIG PTF]...\n", info); + fprintf(f," -h --help Print help and exit\n"); + fprintf(f," -V --version Print version and exit\n"); + fprintf(f," -bFILENAME --bspheader=FILENAME Output BSP configuration header file (default='sopc.h')\n"); + fprintf(f," -B --no-bspheader Do not output BSP configuration header file\n"); + fprintf(f," -lFILENAME --linkcmds=FILENAME Output linker script (default='linkcmds')\n"); + fprintf(f," -L --no-linkcmds Do not output linker script\n"); + fprintf(f," -pFILENAME --parsed=FILENAME Output PTF contents as long list (default: don't)\n"); + fprintf(f," -P --no-parsed Do not output PTF contents as long list\n"); + fprintf(f," -q --quiet Do not print progress info to stdout\n\n"); + fprintf(f,"Using \"-\" as the FILENAME means standard output (stdout).\n"); +} + /********************************************************/ int main(int argc, char *argv[]) @@ -96,69 +113,157 @@ int main(int argc, char *argv[]) device_desc *devices; bus_bridge_pair *bridges; clock_desc *clocks; - - if (argc<2) + memory_desc *memory; + + int verbose = 1; + int output_order = 127; + char *parsed_filename = NULL; + int output_parsed = 0; + char *bspheader_filename = "sopc.h"; + int output_bspheader = 1; + char *linkcmds_filename = "linkcmds"; + int output_linkcmds = 2; + + optarg = 0; + optind = 1; + opterr = 1; + optopt = '?'; + + if(argc > 126) { - usage(); - return -1; + usage(stderr,"Too many commandline arguments!\n"); + return -1; }; - if ( !strcmp(argv[1], "--help") || !strcmp(argv[1],"-?") ) { - usage(); + while(1) + { + int c, long_index = 0; + static char *optstring = "hVBb:Ll:Pp:q"; + + static struct option long_options[] = + { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "no-bspheader", 0, NULL, 'B' }, + { "bspheader", 1, NULL, 'b' }, + { "no-linkcmds", 0, NULL, 'L' }, + { "linkcmds", 1, NULL, 'l' }, + { "no-parsed", 0, NULL, 'P' }, + { "parsed", 1, NULL, 'p' }, + { "quiet", 0, NULL, 'q' }, + { NULL, 0, NULL, 0 } + }; + + c = getopt_long (argc, argv, optstring, long_options, &long_index); + + if(c == -1) break; /* Exit from while(1) loop */ + + switch(c) + { + case 'q': /* Be quiet */ + verbose = 0; + break; + + case 'h': /* Print help and exit */ + usage(stdout,NULL); return 0; - }; - if ( !strcmp(argv[1], "--version") ) { - version(); + case 'V': /* Print version and exit */ + version(stdout); return 0; + + case 'B': /* Do not output BSP configuration header file */ + output_bspheader = 0; + break; + + case 'b': /* Output BSP configuration header file */ + bspheader_filename = optarg; + output_bspheader = output_order; + output_order--; + break; + + case 'L': /* Do not output linker script */ + output_linkcmds = 0; + break; + + case 'l': /* Output linker script */ + linkcmds_filename = optarg; + output_linkcmds = output_order; + output_order--; + break; + + case 'P': /* Do not output PTF contents */ + output_parsed = 0; + break; + + case 'p': /* Output PTF contents as long list */ + parsed_filename = optarg; + output_parsed = output_order; + output_order--; + break; + + case 0: + case '?': + return -1; + + default: + fprintf(stderr, "%s: unknown option: %c\n", NIOS2GEN_PACKAGE, c); + }; }; - cfg = ptf_parse_file(argv[1]); - if(cfg == NULL) + if(optind >= argc) { - fprintf(stderr, "Couldn't parse '%s'.\n", argv[1]); + usage(stderr,"No PTF specified!\n"); return -1; }; - printf("Successfully read config PTF file %s.\n", argv[1]); - /********************************************************/ + sopc = ptf_parse_file(argv[optind]); + if(sopc == NULL) { - struct ptf include_item = { item, "INCLUDE", 0, 0, 0 }; - struct ptf_item inc_file_spec = { 1, &include_item }; - ptf_match(cfg, &inc_file_spec, read_include_file, NULL); - } + fprintf(stderr, "Could not parse system description PTF '%s'.\n", argv[optind]); + return -1; + }; + + if(verbose) printf("Successfully read SOPC PTF file %s.\n", argv[optind]); /********************************************************/ - - { - struct ptf *p; - struct ptf sopc_ptf_item = { item, "SOPC_PTF", 0, 0, 0 }; - struct ptf_item sopc_ptf_spec = { 1, &sopc_ptf_item }; - ptf_match(cfg, &sopc_ptf_spec, store_ptf_ptr, &p); - if(p == NULL) - { - fprintf(stderr, "Missing 'SOPC_PTF' filename in %s!\n", argv[1]); - return -1; - }; + cfg = NULL; - sopc = ptf_parse_file(p->value); - if(sopc == NULL) + for(optind++;optindvalue); - return -1; + fprintf(stderr, "Couldn't parse '%s'.\n", argv[optind]); + return -1; }; + + if(verbose) printf("Successfully read config PTF file %s.\n", argv[optind]); - printf("Successfully read SOPC PTF file %s.\n", p->value); + cfg = ptf_concat(cfg, morecfg); }; + /********************************************************/ + /* Pull in include files specified in the configs; */ + /* Only one level is read; included files are not */ + /* checked for further INCLUDEs */ + + { + struct ptf include_item = { item, "INCLUDE", 0, 0, 0 }; + struct ptf_item inc_file_spec = { 1, &include_item }; + ptf_match(cfg, &inc_file_spec, read_include_file, NULL); + } + /********************************************************/ /* Find CPU */ - printf("Looking for usable CPUs...\n"); + if(verbose) printf("Looking for usable CPUs...\n"); + /* Check if a CPU has been specified in the config PTF */ { struct ptf modules = { section, "MODULES", 0, 0, 0 }; struct ptf cpu_def = { item, "CPU", 0, 0, 0 }; @@ -167,6 +272,7 @@ int main(int argc, char *argv[]) ptf_match(cfg, &cpu_spec, store_ptf_ptr, &cpu); }; + /* Look for CPUs in system description PTF */ { int cpu_count; struct ptf system = { section, "SYSTEM", 0, 0, 0 }; @@ -180,73 +286,206 @@ int main(int argc, char *argv[]) if(cpu_count > 1) { - printf("There is more than one CPU. Please specify the one\n"); - printf("you want to use with this BSP in your config file.\n"); - printf("The available CPUs are named as follows:\n"); + fprintf(stderr, "There is more than one CPU. Please specify the one\n"); + fprintf(stderr, "you want to use with this BSP in your config file.\n"); + fprintf(stderr, "The available CPUs are named as follows:\n"); ptf_match(sopc, &class_spec, printf_ptf_value, " %s\n"); return -1; }; if(cpu_count == 0) { - printf("There is no NIOS2 cpu in the system.\n"); + fprintf(stderr, "There is no NIOS2 cpu in the system.\n"); return -1; } }; - printf("Using NIOS II CPU '%s'.\n", cpu->value); - printf("Only modules mastered by this CPU are considered now.\n"); + if(verbose) + { + printf("Using NIOS II CPU '%s'.\n", cpu->value); + printf("Only modules mastered by this CPU are considered now.\n"); + }; /********************************************************/ - /* Find clocks */ + /* Find Bridges */ - printf("Looking for clock definitions...\n"); + if(verbose) printf("Looking for bus bridges...\n"); - clocks = find_clocks(sopc, cfg); + bridges = find_bridges(sopc); - if(clocks) + if(verbose) { - clock_desc *cs; - for(cs = clocks; cs; cs = cs->next) + if(bridges) + { + bus_bridge_pair *bbp; + for(bbp = bridges; bbp; bbp=bbp->next) + { + printf("Found bridge: %s\n", bbp->mastered_by); + printf(" \\_%s\n", bbp->bridges_to); + }; + } + else { - printf("Found clock: %s (%lu Hz)\n", cs->name, cs->freq); + printf("No bridges present.\n"); }; - } - else - { - printf("No clocks present.\n"); }; /********************************************************/ - /* Find Bridges */ + /* Find clocks */ - printf("Looking for bus bridges...\n"); + if(verbose) printf("Looking for clock definitions...\n"); - bridges = find_bridges(sopc); + clocks = find_clocks(sopc, cfg); - if(bridges) + if(verbose) { - bus_bridge_pair *bbp; - for(bbp = bridges; bbp; bbp=bbp->next) + if(clocks) + { + clock_desc *cs; + for(cs = clocks; cs; cs = cs->next) + { + printf("Found clock \"%s\" (%lu Hz), naming it %s\n", cs->name, cs->freq, cs->cfgname); + }; + } + else { - printf("Found bridge: %s\n", bbp->mastered_by); - printf(" \\_%s\n", bbp->bridges_to); + printf("No clocks present.\n"); }; - } - else - { - printf("No bridges present.\n"); }; /********************************************************/ /* Find other devices available to the selected CPU */ + if(verbose) printf("Looking for devices...\n"); + devices = find_devices(sopc, cfg, cpu, bridges); - fwrite_header_file(stdout, cfg, devices, clocks); + if(verbose) + { + if(devices) + { + device_desc *dd; + for(dd = devices; dd; dd=dd->next) + { + printf("Found device \"%s\", naming it %s\n", dd->ptf->value, dd->cfgname); + }; + } + else + { + printf("No devices present.\n"); + }; + }; + + /********************************************************/ + /* Find out which devices are actually memory */ + + if(verbose) printf("Looking for memory...\n"); + + memory = find_memory(devices); + + if(verbose) + { + if(memory) + { + memory_desc *md; + for(md = memory; md; md=md->next) + { + printf("Found memory in \"%s\", base=0x%08X, size=%lu bytes\n", + md->dev->cfgname, + md->base, md->size); + }; + } + else + { + printf("None of the devices seems to provide memory?!\n"); + }; + }; + + + /********************************************************/ + /* Output files in the order they were specified + on the command line */ + + { + int i; + for(i=0;i<3;i++) + { + if(output_bspheader>0 + && output_bspheader>=output_linkcmds + && output_bspheader>=output_parsed) + { + output_bspheader = 0; + if(bspheader_filename == NULL || (bspheader_filename[0]=='-' && bspheader_filename[1]==0)) + { + fwrite_header_file(stdout, cfg, devices, clocks); + } + else + { + FILE *f = fopen(bspheader_filename, "w"); + if(!f) + { + perror(bspheader_filename); + return -1; + } + else + { + fwrite_header_file(f, cfg, devices, clocks); + fclose(f); + } + } + }; + if(output_linkcmds>0 + && output_linkcmds>=output_bspheader + && output_linkcmds>=output_parsed) + { + output_linkcmds = 0; + if(linkcmds_filename == NULL || (linkcmds_filename[0]=='-' && linkcmds_filename[1]==0)) + { + fwrite_linkcmds_file(stdout, cfg, cpu, devices, memory); + } + else + { + FILE *f = fopen(linkcmds_filename, "w"); + if(!f) + { + perror(linkcmds_filename); + return -1; + } + else + { + fwrite_linkcmds_file(f, cfg, cpu, devices, memory); + fclose(f); + } + } + }; + if(output_parsed>0 + && output_parsed>=output_linkcmds + && output_parsed>=output_bspheader) + { + output_parsed = 0; + if(parsed_filename == NULL || (parsed_filename[0]=='-' && parsed_filename[1]==0)) + { + ptf_printf(stdout, sopc, ""); + } + else + { + FILE *f = fopen(parsed_filename, "w"); + if(!f) + { + perror(parsed_filename); + return -1; + } + else + { + ptf_printf(f, sopc, ""); + fclose(f); + } + } + }; + } + }; - // ptf_printf(stdout, ptf, ""); - // ptf_printf(stdout, cfg, ""); + if(verbose) printf("Done.\n"); return 0; } -- cgit v1.2.3