summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2012-12-20 11:50:56 -0500
committerJerome Glisse <jglisse@redhat.com>2012-12-20 11:50:56 -0500
commite2114e386376b35173424cd6db53f27501a0c095 (patch)
tree6a815bf434d49e2754b80d5e5e375b147a8d9cd5
parented4aec6661009eb800f8a30277fa9d547ae7b28e (diff)
rdb simplify ib make it easier to spot reg value at draw time
-rw-r--r--Makefile8
-rw-r--r--rdb_simplifyib.c290
2 files changed, 297 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 864ca46..21db771 100644
--- a/Makefile
+++ b/Makefile
@@ -43,9 +43,12 @@ ICM_O = $(ICM_C:.c=.o)
ANN4_C = rdb_missingreg.c rdb.c
ANN4_O = $(ANN4_C:.c=.o)
+SIMP_C = rdb_simplifyib.c rdb.c
+SIMP_O = $(SIMP_C:.c=.o)
+
TARGETS = rdb_sanitize rdb_read rdb_preg rdb_build rdb_anotate rdb_build2 \
rdb_update rdb_annotateib rdb_cmpib rdb_annotateib2 rdb_header \
- rdb_missingreg rdb_analyze rdb_queryregname
+ rdb_missingreg rdb_analyze rdb_queryregname rdb_simplifyib
##### RULES #####
.SUFFIXES:
@@ -100,6 +103,9 @@ rdb_missingreg: $(ANN4_O)
rdb_queryregname: $(QUE_O)
$(CC) -o $@ $(QUE_O)
+rdb_simplifyib: $(SIMP_O)
+ $(CC) -o $@ $(SIMP_O)
+
clean:
rm -f $(TARGETS)
rm -f *.o
diff --git a/rdb_simplifyib.c b/rdb_simplifyib.c
new file mode 100644
index 0000000..b9179ef
--- /dev/null
+++ b/rdb_simplifyib.c
@@ -0,0 +1,290 @@
+/*
+ * 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "list.h"
+#include "rdb.h"
+
+union blocku {
+ unsigned reg[2];
+ unsigned pkt[256];
+};
+
+#define TYPE_REG 0
+#define TYPE_PKT 1
+
+struct block {
+ struct list_head list;
+ unsigned type;
+ union blocku u;
+};
+
+struct ctx {
+ struct list_head blocks;
+ struct rdb *rdb;
+};
+
+void ctx_add_reg(struct ctx *ctx, unsigned reg, unsigned v)
+{
+ struct block *b;
+
+ switch (reg) {
+ /* dont unduplicate some of the sync reg */
+ case 0x00008040: // WAIT_UNTIL
+ case 0x000085f0: // CP_COHER_CNTL
+ case 0x000085f4: // CP_COHER_SIZE
+ case 0x000085f8: // CP_COHER_BASE
+ break;
+ default:
+ LIST_FOR_EACH_ENTRY(b, &ctx->blocks, list) {
+ if (b->type == TYPE_REG && b->u.reg[0] == reg) {
+ b->u.reg[1] = v;
+ list_del(&b->list);
+ list_add_tail(&b->list, &ctx->blocks);
+ return;
+ }
+ }
+ break;
+ }
+ b = malloc(sizeof(*b));
+ b->u.reg[0] = reg;
+ b->u.reg[1] = v;
+ b->type = TYPE_REG;
+ list_add_tail(&b->list, &ctx->blocks);
+}
+
+struct block *ctx_add_pkt(struct ctx *ctx, unsigned count)
+{
+ struct block *b;
+
+ b = malloc(sizeof(*b));
+ b->type = TYPE_PKT;
+ b->u.pkt[0] = count + 1;
+ list_add_tail(&b->list, &ctx->blocks);
+ return b;
+}
+
+void ctx_init(struct ctx *ctx, struct rdb *rdb)
+{
+ list_init_head(&ctx->blocks);
+ ctx->rdb = rdb;
+}
+
+void ctx_print(struct ctx *ctx)
+{
+ struct block *b, *tmp;
+
+ LIST_FOR_EACH_ENTRY_SAFE(b, tmp, &ctx->blocks, list) {
+ switch (b->type) {
+ case TYPE_REG:
+ {
+ const struct rdb_reg *reg;
+
+ reg = rdb_find_reg_any_domain(ctx->rdb, b->u.reg[0]);
+ if (reg) {
+ printf("0x%08x 0x%08x %s\n", b->u.reg[0], b->u.reg[1], reg->name);
+ } else {
+ printf("0x%08x 0x%08x ??\n", b->u.reg[0], b->u.reg[1]);
+ }
+ break;
+ }
+ case TYPE_PKT:
+ {
+ unsigned it;
+
+ it = ((b->u.pkt[1] >> 8) & 0xff);
+ switch (it) {
+ case 0x29:
+ case 0x2b:
+ case 0x2d:
+ case 0x2e:
+ case 0x35:
+ printf("0x%08x PKT3 0x%02x DRAW *******************************************\n", b->u.pkt[1], it);
+ break;
+ default:
+ printf("0x%08x PKT3 0x%02x\n", b->u.pkt[1], it);
+ break;
+ }
+ for (unsigned i = 2; i <= b->u.pkt[0]; i++) {
+ printf("0x%08x\n", b->u.pkt[i]);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ list_del_init(&b->list);
+ free(b);
+ }
+}
+
+char *line_skip(char *line, unsigned nspace)
+{
+ do {
+ if (*line == ' ') {
+ nspace--;
+ }
+ line++;
+ } while (nspace);
+ return line;
+}
+
+void annotate(struct ctx *ctx, FILE *file)
+{
+ char line[128], *tmp;
+ unsigned offset, value, ndw = 0, pkt = 0, it, doprint = 0, pktidx = 0;
+ struct block *b;
+
+ 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 {
+ ctx_add_reg(ctx, offset, value);
+ offset += 4;
+ }
+ break;
+ case 0x69:
+ if (!offset) {
+ offset = (value << 2) + 0x28000;
+ } else {
+ ctx_add_reg(ctx, offset, value);
+ offset += 4;
+ }
+ break;
+ default:
+ b->u.pkt[pktidx++] = value;
+ break;
+ }
+ break;
+ case 0:
+ default:
+ ctx_add_reg(ctx, offset, value);
+ offset += 4;
+ break;
+ }
+ ndw--;
+ } else {
+ if (doprint) {
+ doprint = 0;
+ ctx_print(ctx);
+ }
+ 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;
+ pktidx = 1;
+ it = ((value >> 8) & 0xff);
+ switch (it) {
+ case 0x68:
+ case 0x69:
+ break;
+ case 0x29:
+ case 0x2b:
+ case 0x2d:
+ case 0x2e:
+ case 0x35:
+ doprint = 1;
+ /* fallthrough */
+ default:
+ b = ctx_add_pkt(ctx, ndw);
+ b->u.pkt[pktidx++] = value;
+ break;
+ }
+ break;
+ case 1:
+ case 2:
+ default:
+ break;
+ }
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ struct ctx ctx;
+ struct rdb rdb;
+ FILE *file;
+
+ if (argc != 3) {
+ printf("usage %s rdb ibfile\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;
+ }
+ ctx_init(&ctx, &rdb);
+ annotate(&ctx, file);
+ fclose(file);
+}