diff --git a/sdbfs/userspace/sdb-read.c b/sdbfs/userspace/sdb-read.c index 943ec032927619b81dc0867a392f44a0c8538fd5..37919f29225665f1d6eb92e5f0b79f6ed713d280 100644 --- a/sdbfs/userspace/sdb-read.c +++ b/sdbfs/userspace/sdb-read.c @@ -68,50 +68,142 @@ static int do_read(struct sdbfs *fs, int offset, void *buf, int count) } /* Boring ascii representation of a device */ -static void list_device(struct sdb_device *d, int depth, int base) +static int list_device(struct sdb_device *d, int depth, int base) { struct sdb_product *p; struct sdb_component *c; + struct sdb_synthesis *s; + + unsigned char *data; static int warned; - int i; + char *warn; + int i, ret; c = &d->sdb_component; p = &c->product; + s = (void *)d; - if (!opt_long) { - printf("%.19s\n", p->name); - return; - } - - if (!warned) { + if (!warned && opt_long) { fprintf(stderr, "%s: listing format is to be defined\n", prgname); warned = 1; } - /* hack: show directory level looking at the internals */ - printf("%016llx:%08x @ %08llx-%08llx ", - (long long)ntohll(p->vendor_id), ntohl(p->device_id), - (long long)base + ntohll(c->addr_first), - (long long)base + ntohll(c->addr_last)); - for (i = 0; i < depth; i++) - printf(" "); - printf("%.19s\n", p->name); + /* Different sdb items are listed in different ways */ + switch(p->record_type) { + + /* The following items are components, and are listed as such */ + case sdb_type_interconnect: + case sdb_type_device: + case sdb_type_bridge: + if (!opt_long) { + printf("%.19s\n", p->name); + return 0; + } + + + /* hack: show directory level looking at the internals */ + printf("%016llx:%08x @ %08llx-%08llx ", + (long long)ntohll(p->vendor_id), ntohl(p->device_id), + (long long)base + ntohll(c->addr_first), + (long long)base + ntohll(c->addr_last)); + for (i = 0; i < depth; i++) + printf(" "); + printf("%.19s\n", p->name); + + return 0; + + /* A product, but not a component (no address range) */ + case sdb_type_integration: + if (!opt_long) { + printf("%.19s\n", p->name); + return 0; + } + printf("%016llx:%08x ", + (long long)ntohll(p->vendor_id), ntohl(p->device_id)); + /* like above, show directory level */ + for (i = 0; i < depth; i++) + printf(" "); + printf("%.19s\n", p->name); + return 0; + + /* Just a string */ + case sdb_type_repo_url: + if (opt_long) + printf("repo-url: %.63s\n", + ((struct sdb_repo_url *)d)->repo_url); + return 0; + + /* Some metadata */ + case sdb_type_synthesis: + if (!opt_long) + return 0; + printf("synthesis-name: %.16s\n", s->syn_name); + printf(" commit-id: "); + for (i = 0; i < sizeof(s->commit_id); i++) + printf("%02x", s->commit_id[i]); + printf("\n"); + + /* Some of the following fields are sometimes empty */ + if (s->tool_name[0] && s->tool_name[0] != ' ') + printf(" tool-name: %.8s\n", s->tool_name); + if (s->tool_version) + printf(" tool-version: 0x%08x\n", + ntohl(s->tool_version)); + if (s->date) + printf(" build-date: %08x\n", ntohl(s->date)); + if (s->user_name[0] && s->tool_name[0] != ' ') + printf(" build-user: %.15s\n", s->user_name); + return 0; + + case sdb_type_empty: + return 0; + + default: + break; + } + + /* Unknown record type */ + if (p->record_type & 0x80) { + warn = "Warning"; + ret = 0; + } else { + warn = "Error"; + ret = -1; + } + + fprintf(stderr, "%s: unknown record type 0x%02x\n", warn, + p->record_type); + if (!opt_long) { + printf("Unknown-record\n"); + return ret; + } + /* long listing of unknown record */ + printf("Unknown-record:\n"); + data = (void *)d; + for (i = 0; i < sizeof(struct sdb_empty); i++) + printf("%s%02x%c", + (i & 0xf) == 0 ? " " : "", + data[i], + (i & 0xf) == 0xf ? '\n' : ' '); + return ret; } /* The following three function perform the real work, main() is just glue */ -static void do_list(struct sdbfs *fs) +static int do_list(struct sdbfs *fs) { struct sdb_device *d; int new = 1; + int err = 0; while ( (d = sdbfs_scan(fs, new)) != NULL) { - list_device(d, fs->depth, fs->base[fs->depth]); + err += list_device(d, fs->depth, fs->base[fs->depth]); new = 0; } + return err; } -static void do_cat_name(struct sdbfs *fs, char *name) +static int do_cat_name(struct sdbfs *fs, char *name) { char buf[4096]; int i; @@ -124,9 +216,10 @@ static void do_cat_name(struct sdbfs *fs, char *name) while ( (i = sdbfs_fread(fs, -1, buf, sizeof(buf))) > 0) fwrite(buf, 1, i, stdout); sdbfs_close(fs); + return 0; } -static void do_cat_id(struct sdbfs *fs, uint64_t vendor, uint32_t dev) +static int do_cat_id(struct sdbfs *fs, uint64_t vendor, uint32_t dev) { char buf[4096]; int i; @@ -140,6 +233,7 @@ static void do_cat_id(struct sdbfs *fs, uint64_t vendor, uint32_t dev) while ( (i = sdbfs_fread(fs, -1, buf, sizeof(buf))) > 0) fwrite(buf, 1, i, stdout); sdbfs_close(fs); + return 0; } /* As promised, here's the user-interface glue (and initialization, I admit) */ @@ -244,12 +338,12 @@ int main(int argc, char **argv) } /* Now use the thing: either scan, or look for name, or look for id */ if (!filearg) - do_list(fs); + err = do_list(fs); else if (sscanf(filearg, "%llx:%lx", &int64, &int32) != 2) - do_cat_name(fs, filearg); + err = do_cat_name(fs, filearg); else - do_cat_id(fs, int64, int32); + err = do_cat_id(fs, int64, int32); sdbfs_dev_destroy(fs); - return 0; + return err; }