diff options
Diffstat (limited to 'src/app/scan_log.c')
-rw-r--r-- | src/app/scan_log.c | 93 |
1 files changed, 66 insertions, 27 deletions
diff --git a/src/app/scan_log.c b/src/app/scan_log.c index 3401be9..3610ac6 100644 --- a/src/app/scan_log.c +++ b/src/app/scan_log.c @@ -24,12 +24,46 @@ */ #include "umrapp.h" +#define LIST_SIZE (1UL << 18) + +int umr_create_mmio_accel(struct umr_asic *asic) +{ + int i, j; + + // create flat array of registers + asic->mmio_accel.reglist = calloc(LIST_SIZE, sizeof *asic->mmio_accel.reglist); + asic->mmio_accel.iplist = calloc(LIST_SIZE, sizeof *asic->mmio_accel.iplist); + if (!asic->mmio_accel.reglist || !asic->mmio_accel.iplist) { + free(asic->mmio_accel.iplist); + free(asic->mmio_accel.reglist); + asic->mmio_accel.iplist = NULL; + asic->mmio_accel.reglist = NULL; + return -1; + } + + for (i = 0; i < asic->no_blocks; i++) { + for (j = 0; j < asic->blocks[i]->no_regs; j++) { + if (asic->blocks[i]->regs[j].type == REG_MMIO) { + if (asic->blocks[i]->regs[j].addr >= LIST_SIZE) { + fprintf(stderr, "[BUG] Register address width too large for scan_log\n"); + continue; + } + asic->mmio_accel.reglist[asic->blocks[i]->regs[j].addr] = &asic->blocks[i]->regs[j]; + asic->mmio_accel.iplist[asic->blocks[i]->regs[j].addr] = asic->blocks[i]; + } + } + } + return 0; +} + void umr_scan_log(struct umr_asic *asic) { char line[256], *chr; FILE *f; - int i, j, k, found; + int k, found; unsigned long delta, did, regno, value, write; + struct umr_reg **reglist; + struct umr_ip_block **iplist; f = fopen("/sys/kernel/debug/tracing/trace", "r"); if (!f) { @@ -37,6 +71,15 @@ void umr_scan_log(struct umr_asic *asic) return; } + if (!asic->mmio_accel.reglist) { + if (umr_create_mmio_accel(asic)) { + return; + } + } + + reglist = asic->mmio_accel.reglist; + iplist = asic->mmio_accel.iplist; + while (fgets(line, sizeof(line), f)) { found = 0; delta = 0; @@ -54,32 +97,28 @@ void umr_scan_log(struct umr_asic *asic) if (did == asic->did) { do { - // try to find reg in asic profile - for (i = 0; i < asic->no_blocks; i++) - for (j = 0; j < asic->blocks[i]->no_regs; j++) - if (asic->blocks[i]->regs[j].type == REG_MMIO && - asic->blocks[i]->regs[j].addr == regno) { - // bingo - if (write) - printf("%s.%s.%s +0x%04lx <= 0x%08lx\n", - asic->asicname, asic->blocks[i]->ipname, asic->blocks[i]->regs[j].regname, - (unsigned long)delta, - (unsigned long)value); - else - printf("%s.%s.%s +0x%04lx => 0x%08lx\n", - asic->asicname, asic->blocks[i]->ipname, asic->blocks[i]->regs[j].regname, - (unsigned long)delta, - (unsigned long)value); - if (options.bitfields) - for (k = 0; k < asic->blocks[i]->regs[j].no_bits; k++) { - uint32_t v; - v = (1UL << (asic->blocks[i]->regs[j].bits[k].stop + 1 - asic->blocks[i]->regs[j].bits[k].start)) - 1; - v &= (value >> asic->blocks[i]->regs[j].bits[k].start); - asic->blocks[i]->regs[j].bits[k].bitfield_print(asic, asic->asicname, asic->blocks[i]->ipname, asic->blocks[i]->regs[j].regname, asic->blocks[i]->regs[j].bits[k].regname, asic->blocks[i]->regs[j].bits[k].start, asic->blocks[i]->regs[j].bits[k].stop, v); - } - found = 1; - goto out; - } + if (reglist[regno] != NULL) { + // bingo + if (write) + printf("%s.%s.%s +0x%04lx <= 0x%08lx\n", + asic->asicname, iplist[regno]->ipname, reglist[regno]->regname, + (unsigned long)delta, + (unsigned long)value); + else + printf("%s.%s.%s +0x%04lx => 0x%08lx\n", + asic->asicname, iplist[regno]->ipname, reglist[regno]->regname, + (unsigned long)delta, + (unsigned long)value); + if (options.bitfields) + for (k = 0; k < reglist[regno]->no_bits; k++) { + uint32_t v; + v = (1UL << (reglist[regno]->bits[k].stop + 1 - reglist[regno]->bits[k].start)) - 1; + v &= (value >> reglist[regno]->bits[k].start); + reglist[regno]->bits[k].bitfield_print(asic, asic->asicname, iplist[regno]->ipname, reglist[regno]->regname, reglist[regno]->bits[k].regname, reglist[regno]->bits[k].start, reglist[regno]->bits[k].stop, v); + } + found = 1; + goto out; + } out: regno -= 1; delta += 1; |