/* * mmioify turns vbtracetool nvidia io logs into mmiotrace logs: * * Copyright 2007 Stuart Bennett * * This program is released under the terms of the GNU General Public License, version 2 * * output file log-mmt can be parsed with mmio-parse as normal * output file *should not* be run with mmio-replay, as the mappings are made up */ #include #include #include #include #define PCIO0 0x00601000 void cheesy_io_parser(char rw, long lineno, int size, uint16_t port, uint32_t data, FILE *outf) { static uint32_t address = 0; if (address) { if (size == 2) { static int bottom = -1; if (bottom >= 0) { if (port == 0x3d2) { fprintf(outf, "%c 4 %ld 1 0x%08x 0x%08x 0x0 0\n", rw, lineno, address, data << 16 | bottom); address = 0; } bottom = -1; } if (port == 0x3d0) bottom = data; } if (size == 4 && (port == 0x3d0 || port == 0xe80c)) { fprintf(outf, "%c 4 %ld 1 0x%08x 0x%08x 0x0 0\n", rw, lineno, address, data); address = 0; } } if (rw == 'W' && !address) { if (size == 2) { static int top = -1; if (top >= 0) { if (port == 0x3d0) address = top | data; top = -1; } if (port == 0x3d2) top = data << 16; } if (size == 4 && (port == 0x3d0 || port == 0xe808)) address = data; } } int main(int argc, char *argv[]) { FILE *tracef, *outf; long lineno = 0; char outname[1024]; strcpy(outname, argv[1]); strcat(outname, "-mmt"); if (!(tracef = fopen(argv[1], "r"))) { printf("File open failed\n"); exit(EXIT_FAILURE); } if (!(outf = fopen(outname, "w"))) { printf("File open failed\n"); exit(EXIT_FAILURE); } fprintf(outf, "PCIDEV 0000 10de0000 0 00000000 0 0 0 0 0 0 1000000 0 0 0 0 0 0\n"); fprintf(outf, "MAP 0 1 0x00000000 0x00000000 0x1000000 0x0 0\n"); while (!feof(tracef)) { char line[180]; char rw; int size = 0; uint16_t port; uint32_t data; if (!fgets(line, 180, tracef)) break; lineno += 1; if (strncmp(line, "c000", 4)) /* ignore in-built cheesy io parser's output */ continue; rw = line[10]; switch (line[11]) { case '8': size = 1; break; case '1': size = 2; break; case '3': size = 4; break; } port = strtoul(&line[20], NULL, 16); data = strtoul(&line[31], NULL, 16); if (port == 0x3d0 || port == 0x3d2 || port == 0xe808 || port == 0xe80c) { cheesy_io_parser(rw, lineno, size, port, data, outf); continue; } switch (size) { case 1: fprintf(outf, "%c 1 %ld 1 0x%08x 0x%02x 0x0 0\n", rw, lineno, PCIO0 + port, data); break; case 2: fprintf(outf, "%c 1 %ld 1 0x%08x 0x%02x 0x0 0\n", rw, lineno, PCIO0 + port, data & 0xff); fprintf(outf, "%c 1 %ld 1 0x%08x 0x%02x 0x0 0\n", rw, lineno, PCIO0 + port + 1, (data & 0xff00) >> 8); break; case 4: fprintf(outf, "%c 1 %ld 1 0x%08x 0x%02x 0x0 0\n", rw, lineno, PCIO0 + port, data & 0xff); fprintf(outf, "%c 1 %ld 1 0x%08x 0x%02x 0x0 0\n", rw, lineno, PCIO0 + port + 1, (data & 0xff00) >> 8); fprintf(outf, "%c 1 %ld 1 0x%08x 0x%02x 0x0 0\n", rw, lineno, PCIO0 + port + 2, (data & 0xff0000) >> 16); fprintf(outf, "%c 1 %ld 1 0x%08x 0x%02x 0x0 0\n", rw, lineno, PCIO0 + port + 3, (data & 0xff000000) >> 24); break; case 0: printf("size 0!?\n"); return 1; } } fclose(tracef); fclose(outf); return 0; }