summaryrefslogtreecommitdiffstats
path: root/tools/cpu/nios2/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cpu/nios2/output.c')
-rw-r--r--tools/cpu/nios2/output.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/tools/cpu/nios2/output.c b/tools/cpu/nios2/output.c
new file mode 100644
index 0000000000..e957e430a7
--- /dev/null
+++ b/tools/cpu/nios2/output.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2006 Kolja Waschk rtemsdev/ixo.de
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ptf.h"
+#include "devices.h"
+#include "output.h"
+
+typedef struct
+{
+ FILE *file;
+ device_desc *dev;
+ char *def_name;
+ char *orig_value;
+ clock_desc *clocks;
+ device_desc *devices;
+}
+out_desc;
+
+int is_not_connected(struct ptf_item *pi)
+{
+ if(pi->item[0] == NULL) return 0;
+ if(pi->item[0]->name == NULL) return 0;
+
+ if(strcmp(pi->item[0]->name, "SLAVE") == 0)
+ {
+ struct ptf *t;
+ struct ptf_item ti;
+ t = ptf_find(pi->item[0]->sub, &ti, item, "N2G_Selected", "1");
+
+ if(t == NULL) return 1;
+ };
+
+ return 0;
+}
+
+void fwrite_devhead_def(struct ptf_item *pi, void *arg)
+{
+ out_desc *dinfo = arg;
+
+ if(pi != NULL) if(is_not_connected(pi)) return;
+
+ fprintf(dinfo->file, "#define %s_%s %s\n",
+ dinfo->dev->cfgname, dinfo->def_name, dinfo->orig_value);
+}
+
+void fwrite_devhead_line(struct ptf_item *pi, void *arg)
+{
+ out_desc *dinfo = arg;
+
+ if(is_not_connected(pi)) return;
+
+ if(strncmp(dinfo->orig_value, "N2G_", 4)==0)
+ {
+ if(strncmp(dinfo->orig_value, "N2G_CLOCKREF_", 13)==0)
+ {
+ clock_desc *c;
+ for(c = dinfo->clocks; c; c=c->next)
+ {
+ if(strcmp(c->name, pi->item[pi->level]->value) == 0)
+ {
+ fprintf(dinfo->file, "#define %s_%s %s\n",
+ dinfo->dev->cfgname, dinfo->orig_value + 13, c->cfgname);
+ break;
+ };
+ };
+ }
+ else if(strncmp(dinfo->orig_value, "N2G_DEVICEREF_", 14)==0)
+ {
+ device_desc *d;
+ for(d = dinfo->devices; d; d=d->next)
+ {
+ if(strcmp(d->ptf->value, pi->item[pi->level]->value) == 0)
+ {
+ fprintf(dinfo->file, "#define %s_%s %s\n",
+ dinfo->dev->cfgname, dinfo->orig_value + 14, d->cfgname);
+ break;
+ };
+ };
+ }
+ }
+ else
+ {
+ fprintf(dinfo->file, "#define %s_%s %s\n",
+ dinfo->dev->cfgname, dinfo->orig_value,
+ pi->item[pi->level]->value);
+ };
+}
+
+void fwrite_device_header(struct ptf_item *pi, void *arg)
+{
+ struct ptf *f;
+ struct ptf_item fi;
+ out_desc *dinfo = arg;
+
+ /* This is called for every matching CLASS section in the
+ configuration. The following loop iterates through all
+ items in the CLASS section regardless of their nesting level */
+
+ f = ptf_find(pi->item[pi->level]->sub, &fi, item, 0, 0);
+
+ while(f != NULL)
+ {
+ dinfo->orig_value = f->value;
+ if(f->name && strncmp(f->name, "N2G_DEFINE_", 11)==0)
+ {
+ dinfo->def_name = f->name + 11;
+ if(fi.level >= 2)
+ {
+ fi.level--; /* match only the enclosing section */
+ ptf_match(dinfo->dev->ptf->sub, &fi, fwrite_devhead_def, dinfo);
+ fi.level++;
+ }
+ else
+ {
+ fwrite_devhead_def( 0, dinfo );
+ };
+ }
+ else
+ {
+ f->value = 0; /* Match ANY value */
+ ptf_match(dinfo->dev->ptf->sub, &fi, fwrite_devhead_line, dinfo);
+ f->value = dinfo->orig_value;
+ };
+ f = ptf_next(&fi, item, 0, 0);
+ };
+}
+
+void fwrite_value(struct ptf_item *pi, void *arg)
+{
+ FILE *file = arg;
+ fputs(pi->item[pi->level]->value, file);
+}
+
+void fwrite_header_file( FILE *file, struct ptf *cfg, device_desc *devices, clock_desc *clocks)
+{
+ struct ptf *p;
+ struct ptf_item pi;
+
+ struct ptf aclass = { section, "CLASS", 0, 0, 0 };
+ struct ptf_item matchaclass = { 1, &aclass };
+
+ struct ptf header = { item, "HEADER", 0, 0, 0 };
+ struct ptf_item matchheader = { 1, &header };
+
+ struct ptf epilog = { item, "EPILOG", 0, 0, 0 };
+ struct ptf_item matchepilog = { 1, &epilog };
+
+ out_desc dinfo;
+
+ dinfo.file = file;
+ dinfo.clocks = clocks;
+ dinfo.devices = devices;
+
+ ptf_match(cfg, &matchheader, fwrite_value, file);
+
+ if(clocks)
+ {
+ clock_desc *cs;
+ for(cs = clocks; cs; cs = cs->next)
+ {
+ fprintf(file, "#define %s_FREQ %luu\n", cs->cfgname, cs->freq);
+ };
+ };
+
+ if(devices)
+ {
+ for(dinfo.dev = devices; dinfo.dev; dinfo.dev=dinfo.dev->next)
+ {
+ fprintf(file, "\n");
+
+ p = ptf_find(dinfo.dev->ptf, &pi, item, "class", 0);
+ if(p)
+ {
+ aclass.value = p->value;
+ ptf_match(cfg, &matchaclass, fwrite_device_header, &dinfo);
+ };
+ };
+ };
+
+ ptf_match(cfg, &matchepilog, fwrite_value, file);
+}
+
+
+