/* * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * author: Jerome Glisse */ #include #include #include #include #include "rdb.h" static struct list_head regs; struct reg { struct list_head list; unsigned offset; unsigned v; }; struct reg *find_reg(unsigned offset) { struct reg *reg; LIST_FOR_EACH_ENTRY(reg, ®s, list) { if (reg->offset == offset) { return reg; } } return NULL; } void add_reg(unsigned offset, unsigned v, unsigned diff) { struct reg *reg; reg = find_reg(offset); if (reg) { if (diff) { list_del(®->list); free(reg); return; } reg->v = v; return; } if (diff) { return; } reg = malloc(sizeof(*reg)); if (reg == NULL) { exit(-1); } reg->offset = offset; reg->v = v; list_add(®->list, ®s); } char *line_skip(char *line, unsigned nspace) { do { if (*line == ' ') { nspace--; } line++; } while (nspace); return line; } void annotate(struct rdb *rdb, FILE *file, unsigned diff) { char line[128], *tmp; unsigned offset, value, ndw = 0, pkt = 0, it; while (!feof(file)) { if (fgets(line, sizeof(line), file) == NULL) { continue; } line[strlen(line) - 1] = 0; tmp = strstr(line, "] ["); if (tmp == NULL) { printf("%s\n", line); continue; } tmp = strchr(tmp + 4, ']'); if (tmp == NULL) { printf("%s\n", line); continue; } value = strtoul(tmp + 2, &tmp, 0); if (tmp == NULL) { printf("%s\n", line); continue; } if (ndw) { switch (pkt) { case 3: switch (it) { case 0x68: if (!offset) { offset = (value << 2) + 0x8000; } else { add_reg(offset, value, diff); offset += 4; } break; case 0x69: if (!offset) { offset = (value << 2) + 0x28000; } else { add_reg(offset, value, diff); offset += 4; } break; default: break; } break; case 0: default: add_reg(offset, value, diff); offset += 4; break; } ndw--; } else { pkt = (value >> 30) & 3; switch (pkt) { case 0: offset = (value & 0xffff) << 2; ndw = ((value >> 16) & 0x3fff) + 1; break; case 3: offset = 0; ndw = ((value >> 16) & 0x3fff) + 1; it = ((value >> 8) & 0xff); switch (it) { case 0x29: case 0x2b: case 0x2d: case 0x2e: case 0x35: break; default: break; } break; case 1: case 2: default: break; } } } } int main(int argc, char *argv[]) { struct rdb rdb; struct reg *reg; const struct rdb_reg *rreg; FILE *file; list_init_head(®s); if (argc != 4) { printf("usage %s rdb ibfile1 ibfile2\n", argv[0]); return -1; } file = fopen(argv[1], "r"); if (file == NULL) { fprintf(stderr, "failed reading %s\n", argv[1]); return -1; } rdb_init(&rdb); if (rdb_read(&rdb, file)) { fprintf(stderr, "failed reading %s\n", argv[1]); return -1; } fclose(file); file = fopen(argv[2], "r"); if (file == NULL) { fprintf(stderr, "failed reading %s\n", argv[2]); return -1; } annotate(&rdb, file, 0); fclose(file); file = fopen(argv[3], "r"); if (file == NULL) { fprintf(stderr, "failed reading %s\n", argv[3]); return -1; } annotate(&rdb, file, 1); fclose(file); LIST_FOR_EACH_ENTRY(reg, ®s, list) { rreg = rdb_find_reg(&rdb, 0, reg->offset); if (rreg) { printf("notreset 0x%08x 0x%08x %s\n", reg->offset, reg->v, rreg->name); } else { printf("notreset 0x%08x 0x%08x ??\n", reg->offset, reg->v); } } }