/* * 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 char *line_skip(char *line, unsigned nspace) { do { if (*line == ' ') { nspace--; } line++; } while (nspace); return line; } /* register we want to track REG 0x000085f0 0x00000000 0x00000002 32 0 1 0 CP_COHER_CNTL REG 0x000085f4 0x00000103 0x00000000 32 0 1 0 CP_COHER_SIZE REG 0x000085f8 0x00000103 0x00000000 32 0 1 0 CP_COHER_BASE REG 0x0002800c 0x00000000 0x00000003 32 0 1 0 DB_DEPTH_BASE REG 0x00028014 0x00000000 0x00000003 32 0 1 0 DB_HTILE_DATA_BASE REG 0x00028040 0x00000000 0x00000001 32 0 8 4 CB_COLOR_BASE REG 0x000280c0 0x00000000 0x00000001 32 0 8 4 CB_COLOR_TILE REG 0x000280e0 0x00000000 0x00000001 32 0 8 4 CB_COLOR_FRAG REG 0x00028ad8 0x00000000 0x00000010 32 0 1 0 VGT_STRMOUT_BUFFER_BASE_0 REG 0x00028840 0x00000000 0x0000000c 32 0 1 0 SQ_PGM_START_PS REG 0x00028858 0x00000000 0x0000000c 32 0 1 0 SQ_PGM_START_VS HD5xxx REG 0x00028048 0x00000104 0x00000003 32 0 1 0 DB_Z_READ_BASE REG 0x0002804c 0x00000104 0x00000003 32 0 1 0 DB_STENCIL_READ_BASE REG 0x00028050 0x00000104 0x00000003 32 0 1 0 DB_Z_WRITE_BASE REG 0x00028054 0x00000104 0x00000003 32 0 1 0 DB_STENCIL_WRITE_BASE REG 0x00028c60 0x00000104 0x00000001 32 0 8 60 CB_COLOR_BASE REG 0x00028c7c 0x00000104 0x00000001 32 0 8 60 CB_COLOR_CMASK REG 0x00028c84 0x00000104 0x00000001 32 0 8 60 CB_COLOR_FMASK REG 0x0002885c 0x00000104 0x00000000 32 0 1 0 SQ_PGM_START_VS */ struct areg { unsigned offset; unsigned printbit; unsigned hdxxxx; unsigned cvalue; char *name; }; struct areg aregs[] = { {0xf0010000, 0, 3, 0, "EE EVENT_WRITE"}, {0xf0020000, 0, 3, 0, "EE EVENT_WRITE_EOP"}, {0xf0030000, 1, 3, 0, "UP SURFACE_BASE_UPDATE"}, {0x00008040, 1, 3, 0, "WW WAIT_UNTIL"}, {0x000085f0, 1, 3, 0, "SS CP_COHER_CNTL"}, {0x000085f4, 0, 3, 0, "SS CP_COHER_SIZE"}, {0x000085f8, 0, 3, 0, "SS CP_COHER_BASE"}, {0x00028014, 0, 3, 0, "* DB_HTILE_DATA_BASE"}, {0x00028ad8, 0, 3, 0, "* VGT_STRMOUT_BUFFER_BASE_0"}, {0x00028840, 0, 3, 0, "* SQ_PGM_START_PS"}, /* hd2xxx/hd4xxx */ {0x00028d0c, 1, 1, 0, "* DB_RENDER_CONTROL"}, {0x00028d10, 1, 1, 0, "* DB_RENDER_OVERRIDE"}, {0x0002800c, 0, 1, 0, "* DB_DEPTH_BASE"}, {0x00028040, 0, 1, 0, "* CB_COLOR_BASE"}, {0x000280c0, 0, 1, 0, "* CB_COLOR_TILE"}, {0x000280e0, 0, 1, 0, "* CB_COLOR_FRAG"}, {0x00028858, 0, 1, 0, "* SQ_PGM_START_VS"}, /* evergreen */ {0x00028000, 1, 2, 0, "* DB_RENDER_CONTROL"}, {0x0002800c, 1, 2, 0, "* DB_RENDER_OVERRIDE"}, {0x00028048, 0, 2, 0, "* DB_Z_READ_BASE"}, {0x0002804c, 0, 2, 0, "* DB_STENCIL_READ_BASE"}, {0x00028050, 0, 2, 0, "* DB_Z_WRITE_BASE"}, {0x00028054, 0, 2, 0, "* DB_STENCIL_WRITE_BASE"}, {0x00028c60, 0, 2, 0, "* CB_COLOR_BASE"}, {0x00028c7c, 0, 2, 0, "* CB_COLOR_CMASK"}, {0x00028c84, 0, 2, 0, "* CB_COLOR_FMASK"}, {0x0002885c, 0, 2, 0, "* SQ_PGM_START_VS"}, }; void process_areg(unsigned line, unsigned offset, unsigned value, unsigned hdxxxx) { unsigned i, b; for (i = 0; i < sizeof(aregs)/sizeof(aregs[0]); i++) { if (aregs[i].offset == offset && (aregs[i].hdxxxx & hdxxxx)) { if (aregs[i].cvalue != value) { fprintf(stderr, "[%8d] 0x%08x -> 0x%08x %s", line, aregs[i].cvalue, value, aregs[i].name); aregs[i].cvalue = value; if (aregs[i].printbit) { fprintf(stderr, " ["); for (b = 0; b < 32; b++) { if (value & (1 << b)) { fprintf(stderr, " %d", b); } } fprintf(stderr, "]"); } fprintf(stderr, "\n"); } else { fprintf(stderr, "[%8d] 0x%08x SAME %s", line, aregs[i].cvalue, aregs[i].name); if (aregs[i].printbit) { fprintf(stderr, " ["); for (b = 0; b < 32; b++) { if (value & (1 << b)) { fprintf(stderr, " %d", b); } } fprintf(stderr, " ]"); } fprintf(stderr, "\n"); } return; } } } void analyze(FILE *file, unsigned hdxxxx) { char line[128], *tmp; unsigned offset, value, ndw = 0, pkt = 0, it, linec = 0; while (!feof(file)) { if (fgets(line, sizeof(line), file) == NULL) { continue; } linec++; line[strlen(line) - 1] = 0; tmp = strstr(line, "] ["); if (tmp == NULL) { fprintf(stderr, "%s\n", line); continue; } tmp = strchr(tmp + 4, ']'); if (tmp == NULL) { fprintf(stderr, "%s\n", line); continue; } value = strtoul(tmp + 2, &tmp, 0); if (tmp == NULL) { fprintf(stderr, "%s\n", line); continue; } if (ndw) { switch (pkt) { case 3: switch (it) { case 0x68: if (!offset) { offset = (value << 2) + 0x8000; } else { process_areg(linec, offset, value, hdxxxx); offset += 4; } break; case 0x69: if (!offset) { offset = (value << 2) + 0x28000; } else { process_areg(linec, offset, value, hdxxxx); offset += 4; } break; case 0x46: /* event_write */ case 0x47: /* event_write_eop */ case 0x43: /* surface sync == cp_coher* */ case 0x73: /* surface base update */ process_areg(linec, offset, value, hdxxxx); offset += 4; break; default: break; } break; case 0: default: process_areg(linec, offset, value, hdxxxx); 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 0x46: /* event_write */ offset = 0xf0010000; break; case 0x47: /* event_write_eop */ offset = 0xf0020000; break; case 0x43: /* surface sync == cp_coher* */ offset = 0x85f0; break; case 0x73: /* surface base update */ offset = 0xf0030000; break; case 0x29: case 0x2b: case 0x2d: case 0x2e: case 0x35: fprintf(stderr, "[%8d] DRAW_PKT *******************************************************\n", linec); break; default: break; } break; case 1: case 2: default: break; } } } } int main(int argc, char *argv[]) { FILE *file; unsigned hdxxxx = 1; if (argc != 2) { printf("usage %s ibfile\n", argv[0]); return -1; } file = fopen(argv[1], "r"); if (file == NULL) { fprintf(stderr, "failed reading %s\n", argv[1]); return -1; } if (strstr(argv[1], "hd5xxx")) { hdxxxx = 2; } analyze(file, hdxxxx); fclose(file); }