summaryrefslogtreecommitdiff
path: root/src/app/scan_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/scan_log.c')
-rw-r--r--src/app/scan_log.c93
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;