source: rtems/tools/cpu/nios2/nios2gen.c @ c499856

4.11
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on Mar 20, 2014 at 9:10:47 PM

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 12.9 KB
Line 
1/*
2 *  Copyright (c) 2006 Kolja Waschk rtemsdev/ixo.de
3 *
4 *  The license and distribution terms for this file may be
5 *  found in the file LICENSE in this distribution or at
6 *  http://www.rtems.org/license/LICENSE.
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "ptf.h"
14#include "bridges.h"
15#include "clocks.h"
16#include "devices.h"
17#include "memory.h"
18#include "output.h"
19#include "linkcmds.h"
20
21#define NIOS2GEN_PACKAGE PACKAGE
22#define NIOS2GEN_VERSION VERSION
23
24#include "getopt.h"
25
26/********************************************************/
27
28void store_ptf_parent(struct ptf_item *pi, void *arg)
29{
30  struct ptf *p = pi->item[pi->level-1];
31  *(struct ptf **)arg = p;
32}
33
34/********************************************************/
35
36void store_ptf_ptr(struct ptf_item *pi, void *arg)
37{
38  struct ptf *p = pi->item[pi->level];
39  *(struct ptf **)arg = p;
40}
41
42/********************************************************/
43
44void printf_ptf_value(struct ptf_item *pi, void *arg)
45{
46  struct ptf *p = pi->item[pi->level];
47  printf(*(char **)arg, p->value);
48}
49
50/********************************************************/
51
52void read_include_file(struct ptf_item *pi, void *arg)
53{
54    struct ptf *inc, *next;
55    struct ptf *p = pi->item[pi->level];
56
57    inc = ptf_parse_file(p->value);
58
59    if(inc == NULL)
60    {
61        fprintf(stderr, "Warning: couldn't parse included '%s'.\n", p->value);
62        return;
63    };
64
65    printf("Successfully read included PTF file %s.\n", p->value);
66
67    next = p->next;
68    for(p->next = inc; p->next != NULL; p = p->next);
69    p->next = next;
70}
71
72/********************************************************/
73
74void version(FILE *f)
75{
76fprintf(f,
77  "nios2gen (" __DATE__ ")\n"
78  "  Copyright (c) 2006 Kolja Waschk rtemsdev/ixo.de\n"
79  "\n"
80  "  The license and distribution terms for this file may be\n"
81  "  found in the file LICENSE in this distribution or at\n"
82  "  http://www.rtems.org/license/LICENSE.\n"
83  , VERSION
84);
85}
86
87void usage (FILE *f, char *errmsg)
88{
89  char *info = "Purpose:\n  Create RTEMS nios2 BSP configuration from Altera SOPC description\n";
90  if(errmsg) info=errmsg;
91  version(f);
92  fprintf(f,"\n%s\nUsage: nios2gen [OPTIONS] <SOPC PTF> [CONFIG PTF] [CONFIG PTF]...\n", info);
93  fprintf(f,"   -h         --help               Print help and exit\n");
94  fprintf(f,"   -V         --version            Print version and exit\n");
95  fprintf(f,"   -bFILENAME --bspheader=FILENAME Output BSP configuration header file (default='sopc.h')\n");
96  fprintf(f,"   -B         --no-bspheader       Do not output BSP configuration header file\n");
97  fprintf(f,"   -lFILENAME --linkcmds=FILENAME  Output linker script (default='linkcmds')\n");
98  fprintf(f,"   -L         --no-linkcmds        Do not output linker script\n");
99  fprintf(f,"   -pFILENAME --parsed=FILENAME    Output PTF contents as long list (default: don't)\n");
100  fprintf(f,"   -P         --no-parsed          Do not output PTF contents as long list\n");
101  fprintf(f,"   -q         --quiet              Do not print progress info to stdout\n\n");
102  fprintf(f,"Using \"-\" as the FILENAME means standard output (stdout).\n");
103}
104
105/********************************************************/
106
107int main(int argc, char *argv[])
108{
109    struct ptf *sopc, *cfg, *p, *cpu;
110    struct ptf_item pi;
111    device_desc *devices;
112    bus_bridge_pair *bridges;
113    clock_desc *clocks;
114    memory_desc *memory;
115
116    int verbose = 1;
117    int output_order = 127;
118    char *parsed_filename = NULL;
119    int output_parsed = 0;
120    char *bspheader_filename = "sopc.h";
121    int output_bspheader = 1;
122    char *linkcmds_filename = "linkcmds";
123    int output_linkcmds = 2;
124
125    optarg = 0;
126    optind = 1;
127    opterr = 1;
128    optopt = '?';
129
130    if(argc > 126)
131    {
132      usage(stderr,"Too many commandline arguments!\n");
133      return -1;
134    };
135
136    while(1)
137    {
138      int c, long_index = 0;
139      static char *optstring = "hVBb:Ll:Pp:q";
140
141      static struct option long_options[] =
142      {
143        { "help",           0, NULL, 'h' },
144        { "version",        0, NULL, 'V' },
145        { "no-bspheader",   0, NULL, 'B' },
146        { "bspheader",      1, NULL, 'b' },
147        { "no-linkcmds",    0, NULL, 'L' },
148        { "linkcmds",       1, NULL, 'l' },
149        { "no-parsed",      0, NULL, 'P' },
150        { "parsed",         1, NULL, 'p' },
151        { "quiet",          0, NULL, 'q' },
152        { NULL, 0, NULL, 0 }
153      };
154
155      c = getopt_long (argc, argv, optstring, long_options, &long_index);
156
157      if(c == -1) break; /* Exit from while(1) loop */
158
159      switch(c)
160      {
161      case 'q': /* Be quiet */
162        verbose = 0;
163        break;
164
165      case 'h': /* Print help and exit */
166        usage(stdout,NULL);
167        return 0;
168
169      case 'V': /* Print version and exit */
170        version(stdout);
171        return 0;
172
173      case 'B': /* Do not output BSP configuration header file */
174        output_bspheader = 0;
175        break;
176
177      case 'b': /* Output BSP configuration header file */
178        bspheader_filename = optarg;
179        output_bspheader = output_order;
180        output_order--;
181        break;
182
183      case 'L': /* Do not output linker script */
184        output_linkcmds = 0;
185        break;
186
187      case 'l': /* Output linker script */
188        linkcmds_filename = optarg;
189        output_linkcmds = output_order;
190        output_order--;
191        break;
192
193      case 'P': /* Do not output PTF contents */
194        output_parsed = 0;
195        break;
196
197      case 'p': /* Output PTF contents as long list */
198        parsed_filename = optarg;
199        output_parsed = output_order;
200        output_order--;
201        break;
202
203      case 0:
204      case '?':
205        return -1;
206
207      default:
208        fprintf(stderr, "%s: unknown option: %c\n", NIOS2GEN_PACKAGE, c);
209      };
210    };
211
212    if(optind >= argc)
213    {
214        usage(stderr,"No PTF specified!\n");
215        return -1;
216    };
217
218    /********************************************************/
219
220    sopc = ptf_parse_file(argv[optind]);
221    if(sopc == NULL)
222    {
223        fprintf(stderr, "Could not parse system description PTF '%s'.\n", argv[optind]);
224        return -1;
225    };
226
227    if(verbose) printf("Successfully read SOPC PTF file %s.\n", argv[optind]);
228
229    /********************************************************/
230
231    cfg = NULL;
232
233    for(optind++;optind<argc;optind++)
234    {
235      struct ptf *morecfg = ptf_parse_file(argv[optind]);
236
237      if(morecfg == NULL)
238      {
239        fprintf(stderr, "Couldn't parse '%s'.\n", argv[optind]);
240        return -1;
241      };
242
243      if(verbose) printf("Successfully read config PTF file %s.\n", argv[optind]);
244
245      cfg = ptf_concat(cfg, morecfg);
246    };
247
248    /********************************************************/
249    /* Pull in include files specified in the configs; */
250    /* Only one level is read; included files are not */
251    /* checked for further INCLUDEs */
252
253    {
254      struct ptf include_item = { item, "INCLUDE", 0, 0, 0 };
255      struct ptf_item inc_file_spec = { 1, &include_item };
256      ptf_match(cfg, &inc_file_spec, read_include_file, NULL);
257    }
258
259    /********************************************************/
260    /* Find CPU */
261
262    if(verbose) printf("Looking for usable CPUs...\n");
263
264    /* Check if a CPU has been specified in the config PTF */
265    {
266      struct ptf modules         = { section, "MODULES", 0, 0, 0 };
267      struct ptf cpu_def         = { item, "CPU", 0, 0, 0 };
268      struct ptf_item cpu_spec   = { 2, &modules, &cpu_def };
269
270      ptf_match(cfg, &cpu_spec, store_ptf_ptr, &cpu);
271    };
272
273    /* Look for CPUs in system description PTF */
274    {
275      int cpu_count;
276      struct ptf system          = { section, "SYSTEM", 0, 0, 0 };
277      struct ptf module          = { section, "MODULE", 0, 0, 0 };
278      struct ptf nios2_cpu_class = { item, "class", "altera_nios2", 0, 0 };
279      struct ptf_item class_spec = { 3, &system, &module, &nios2_cpu_class };
280
281      if(cpu) if(cpu->value) class_spec.item[1]->value = cpu->value;
282
283      cpu_count = ptf_match(sopc, &class_spec, store_ptf_parent, &cpu);
284
285      if(cpu_count > 1)
286      {
287        fprintf(stderr, "There is more than one CPU. Please specify the one\n");
288        fprintf(stderr, "you want to use with this BSP in your config file.\n");
289        fprintf(stderr, "The available CPUs are named as follows:\n");
290        ptf_match(sopc, &class_spec, printf_ptf_value, "  %s\n");
291        return -1;
292      };
293
294      if(cpu_count == 0)
295      {
296        fprintf(stderr, "There is no NIOS2 cpu in the system.\n");
297        return -1;
298      }
299    };
300
301    if(verbose)
302    {
303      printf("Using NIOS II CPU '%s'.\n", cpu->value);
304      printf("Only modules mastered by this CPU are considered now.\n");
305    };
306
307    /********************************************************/
308    /* Find Bridges */
309
310    if(verbose) printf("Looking for bus bridges...\n");
311
312    bridges = find_bridges(sopc);
313
314    if(verbose)
315    {
316      if(bridges)
317      {
318        bus_bridge_pair *bbp;
319        for(bbp = bridges; bbp; bbp=bbp->next)
320        {
321          printf("Found bridge: %s\n", bbp->mastered_by);
322          printf("               \\_%s\n", bbp->bridges_to);
323        };
324      }
325      else
326      {
327        printf("No bridges present.\n");
328      };
329    };
330
331    /********************************************************/
332    /* Find clocks */
333
334    if(verbose) printf("Looking for clock definitions...\n");
335
336    clocks = find_clocks(sopc, cfg);
337
338    if(verbose)
339    {
340      if(clocks)
341      {
342        clock_desc *cs;
343        for(cs = clocks; cs; cs = cs->next)
344        {
345          printf("Found clock \"%s\" (%lu Hz), naming it %s\n", cs->name, cs->freq, cs->cfgname);
346        };
347      }
348      else
349      {
350        printf("No clocks present.\n");
351      };
352    };
353
354    /********************************************************/
355    /* Find other devices available to the selected CPU */
356
357    if(verbose) printf("Looking for devices...\n");
358
359    devices = find_devices(sopc, cfg, cpu, bridges);
360
361    if(verbose)
362    {
363      if(devices)
364      {
365        device_desc *dd;
366        for(dd = devices; dd; dd=dd->next)
367        {
368          printf("Found device \"%s\", naming it %s\n", dd->ptf->value, dd->cfgname);
369        };
370      }
371      else
372      {
373        printf("No devices present.\n");
374      };
375    };
376
377    /********************************************************/
378    /* Find out which devices are actually memory */
379
380    if(verbose) printf("Looking for memory...\n");
381
382    memory = find_memory(devices);
383
384    if(verbose)
385    {
386      if(memory)
387      {
388        memory_desc *md;
389        for(md = memory; md; md=md->next)
390        {
391          printf("Found memory in \"%s\", base=0x%08X, size=%lu bytes\n",
392                          md->dev->cfgname,
393                          md->base, md->size);
394        };
395      }
396      else
397      {
398        printf("None of the devices seems to provide memory?!\n");
399      };
400    };
401
402
403    /********************************************************/
404    /* Output files in the order they were specified
405       on the command line */
406
407    {
408      int i;
409      for(i=0;i<3;i++)
410      {
411        if(output_bspheader>0
412           && output_bspheader>=output_linkcmds
413           && output_bspheader>=output_parsed)
414        {
415          output_bspheader = 0;
416          if(bspheader_filename == NULL || (bspheader_filename[0]=='-' && bspheader_filename[1]==0))
417          {
418            fwrite_header_file(stdout, cfg, devices, clocks);
419          }
420          else
421          {
422            FILE *f = fopen(bspheader_filename, "w");
423            if(!f)
424            {
425              perror(bspheader_filename);
426              return -1;
427            }
428            else
429            {
430              fwrite_header_file(f, cfg, devices, clocks);
431              fclose(f);
432            }
433          }
434        };
435        if(output_linkcmds>0
436           && output_linkcmds>=output_bspheader
437           && output_linkcmds>=output_parsed)
438        {
439          output_linkcmds = 0;
440          if(linkcmds_filename == NULL || (linkcmds_filename[0]=='-' && linkcmds_filename[1]==0))
441          {
442            fwrite_linkcmds_file(stdout, cfg, cpu, devices, memory);
443          }
444          else
445          {
446            FILE *f = fopen(linkcmds_filename, "w");
447            if(!f)
448            {
449              perror(linkcmds_filename);
450              return -1;
451            }
452            else
453            {
454              fwrite_linkcmds_file(f, cfg, cpu, devices, memory);
455              fclose(f);
456            }
457          }
458        };
459        if(output_parsed>0
460           && output_parsed>=output_linkcmds
461           && output_parsed>=output_bspheader)
462        {
463          output_parsed = 0;
464          if(parsed_filename == NULL || (parsed_filename[0]=='-' && parsed_filename[1]==0))
465          {
466            ptf_printf(stdout, sopc, "");
467          }
468          else
469          {
470            FILE *f = fopen(parsed_filename, "w");
471            if(!f)
472            {
473              perror(parsed_filename);
474              return -1;
475            }
476            else
477            {
478              ptf_printf(f, sopc, "");
479              fclose(f);
480            }
481          }
482        };
483      }
484    };
485
486    if(verbose) printf("Done.\n");
487
488    return 0;
489}
490
491/* vi:ts=4:
492 */
493
494
Note: See TracBrowser for help on using the repository browser.