From 8a4fee7a5de445c2769e0e8a74f85958e4c87eb2 Mon Sep 17 00:00:00 2001
From: Oliver Ford <oliford@NervousEnergy.(none)>
Date: Thu, 17 Apr 2008 22:18:32 +0100
Subject: [PATCH] Report approximate PC when matching memory polls in IRQ/fault handlers.

---
 include/watch.h |    2 +-
 src/irq.cpp     |   31 ++++++++++++++++++++-----------
 src/watch.cpp   |    8 ++++----
 3 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/include/watch.h b/include/watch.h
index 1a76866..b319647 100644
--- a/include/watch.h
+++ b/include/watch.h
@@ -41,7 +41,7 @@ public:
     void showVar(const char *args);
     void beginWatch(int isStart=1);
     void reportWatch(const char *header, uint32 pos
-                     , uint32 newval, uint32 changed);
+                     , uint32 newval, uint32 changed, uint32 addr);
 };
 #define REG_VAR_WATCHLIST(Pred, Name, Var, Desc)       \
     __REG_VAR(watchListVar, Var, Pred, Name, Desc)
diff --git a/src/irq.cpp b/src/irq.cpp
index 2a5cb83..358ecfd 100644
--- a/src/irq.cpp
+++ b/src/irq.cpp
@@ -84,28 +84,34 @@ static void
 report_memPoll(irqData *data, const char *header, traceitem *item)
 {
     watchListVar *w = (watchListVar*)item->d0;
-    uint32 pos=item->d1, val=item->d2, changed=item->d3;
-    w->reportWatch(header, pos, val, changed);
+    uint32 pos=item->d1, val=item->d2, changed=item->d3, addr=item->d4;
+    w->reportWatch(header, pos, val, changed, addr);
 }
 
+
 // Perform a set of memory polls and add to trace buffer.
 static void __irq
-checkPolls(struct irqData *data, pollinfo *info)
+checkPolls(struct irqData *data, pollinfo *info, uint32 addr)
 {
     for (uint i=0; i<info->count; i++) {
         memcheck *mc = &info->list[i];
         uint32 val, changed;
         int ret = testMem(mc, &val, &changed);
-        if (!ret)
-            continue;
+    if (!ret)
+        continue;        
+    
         ret = add_trace(data, report_memPoll, (uint32)info->cls, i
-                        , val, changed);
+                        , val, changed, addr);
+
         if (ret)
             // Couldn't add trace - reset compare function.
             mc->trySuppress = 0;
     }
+        
+    
 }
 
+
 // Handler for interrupt events.  Note that this is running in
 // "Modified Virtual Address" mode, so avoid reading any global
 // variables or calling any non local functions.
@@ -120,10 +126,11 @@ irq_handler(struct irqData *data, struct irqregs *regs)
         // Separate routine for PXA chips
         PXA_irq_handler(data, regs);
 
+    uint32 faultaddr = MVAddr_irq(regs->old_pc - 4);    
     // Trace time memory polling.
     prePoll(data, isPXA);
-    checkPolls(data, &data->irqpoll);
-    checkPolls(data, &data->tracepoll);
+    checkPolls(data, &data->irqpoll, faultaddr);
+    checkPolls(data, &data->tracepoll, faultaddr);
     postPoll(data, isPXA);
 }
 
@@ -139,9 +146,10 @@ abort_handler(struct irqData *data, struct irqregs *regs)
         // Separate routine for PXA chips
         ret = PXA_abort_handler(data, regs);
 
+    uint32 faultaddr = MVAddr_irq(regs->old_pc - 4);    
     // Trace time memory polling.
     prePoll(data, isPXA);
-    checkPolls(data, &data->tracepoll);
+    checkPolls(data, &data->tracepoll, faultaddr);
     postPoll(data, isPXA);
 
     return ret;
@@ -159,9 +167,10 @@ prefetch_handler(struct irqData *data, struct irqregs *regs)
         // Separate routine for PXA chips
         ret = PXA_prefetch_handler(data, regs);
 
+    uint32 faultaddr = MVAddr_irq(regs->old_pc - 4);    
     // Trace time memory polling.
     prePoll(data, isPXA);
-    checkPolls(data, &data->tracepoll);
+    checkPolls(data, &data->tracepoll, faultaddr);
     postPoll(data, isPXA);
 
     return ret;
@@ -184,7 +193,7 @@ resume_handler(struct irqData *data, struct irqregs *regs)
         PXA_resume_handler(data, regs);
 
     add_trace(data, report_resume);
-    checkPolls(data, &data->resumepoll);
+    checkPolls(data, &data->resumepoll, 0);
 }
 
 
diff --git a/src/watch.cpp b/src/watch.cpp
index 9435292..5753614 100644
--- a/src/watch.cpp
+++ b/src/watch.cpp
@@ -224,16 +224,16 @@ watchListVar::beginWatch(int isStart)
 
 void
 watchListVar::reportWatch(const char *header, uint32 pos
-                          , uint32 newval, uint32 changed)
+                          , uint32 newval, uint32 changed, uint32 addr)
 {
     memcheck *mc = &watchlist[pos];
     const char *atype = "mem";
     if (mc->isInsn)
         atype = "insn";
 
-    Output("%s %s %s(%d) %08x=%08x (%08x)"
+    Output("%s %s %s(%d) %08x=%08x (%08x) @~%08x"
            , header, atype, name, pos
-           , mc->addr, newval, changed);
+           , mc->addr, newval, changed, addr);
 }
 
 static watchListVar *
@@ -333,7 +333,7 @@ cmd_watch(const char *cmd, const char *args)
                 continue;
             char header[64];
             _snprintf(header, sizeof(header), "%06d:", cur_time - start_time);
-            wl->reportWatch(header, i, val, changed);
+            wl->reportWatch(header, i, val, changed, 0);
         }
 
         cur_time = GetTickCount();
-- 
1.5.2.5

