/* * 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 #include #include #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 bspsect = { section, "BSPHEADER", 0, 0, 0 }; struct ptf leadtext = { item, "LEADTEXT", 0, 0, 0 }; struct ptf_item matchleadtext = { 2, &bspsect, &leadtext }; struct ptf epilog = { item, "EPILOG", 0, 0, 0 }; struct ptf_item matchepilog = { 2, &bspsect, &epilog }; out_desc dinfo; dinfo.file = file; dinfo.clocks = clocks; dinfo.devices = devices; ptf_match(cfg, &matchleadtext, 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#define SOPC_HAS_%s 1\n", dinfo.dev->cfgname); */ 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); }