]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
debugmem cpu cache checks.
authorToni Wilen <twilen@winuae.net>
Fri, 12 Jul 2019 16:40:02 +0000 (19:40 +0300)
committerToni Wilen <twilen@winuae.net>
Fri, 12 Jul 2019 16:40:02 +0000 (19:40 +0300)
debug.cpp
debugmem.cpp
include/debugmem.h
newcpu.cpp

index e36b0e06b7bec6049f4cb1c0a5ef9811c73c5fbf..338220623dab743c2ef0adf195dc359ddcf3f36b 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -3181,6 +3181,7 @@ static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp, uae_u3
                mwhit.reg = reg;
                if (mwhit.rwi & 2)
                        mwhit.val = val;
+               mwhit.pc = M68K_GETPC;
                memwatch_triggered = i + 1;
                if (m->reportonly) {
                        memwatch_hit_msg(memwatch_triggered - 1);
@@ -7205,7 +7206,6 @@ void debug_init_trainer(const TCHAR *file)
 
        }
 
-end:
        if (tpptrcnt > 0)
                debug_opcode_watch = true;
 
index 70a4af3fcb980c34920dc65cc85b4de649005b52..c7fbbe0798e87da658a4c1df7f35994cdaa7ac23 100644 (file)
@@ -216,6 +216,7 @@ static int alloccnt;
 #define DEBUGMEM_INUSE 0x80
 #define DEBUGMEM_PARTIAL 0x100
 #define DEBUGMEM_NOSTACKCHECK 0x200
+#define DEBUGMEM_WRITE_NOCACHEFLUSH 0x400
 #define DEBUGMEM_STACK 0x1000
 
 struct debugmemdata
@@ -348,7 +349,7 @@ static void debugreport(struct debugmemdata *dm, uaecptr addr, int rwi, int size
                addr_start, addr_start + PAGE_SIZE - 1,
                !(state & (DEBUGMEM_ALLOCATED | DEBUGMEM_INUSE)) ? 'I' : (state & DEBUGMEM_WRITE) ? 'W' : 'R',
                (state & DEBUGMEM_WRITE) ? '*' : (state & DEBUGMEM_INITIALIZED) ? '+' : '-',
-               dm->unused_start, PAGE_SIZE - dm->unused_end);
+               dm->unused_start, PAGE_SIZE - dm->unused_end - 1);
        debugmem_break(1);
 }
 
@@ -551,6 +552,38 @@ bool debugmem_break_stack_push(void)
        return true;
 }
 
+void debugmem_flushcache(uaecptr addr, int size)
+{
+       if (!debugmem_initialized)
+               return;
+       if (size < 0) {
+               for (int i = 0; i < totalmemdata; i++) {
+                       struct debugmemdata* dm = dmd[i];
+                       if (dm->flags & DEBUGMEM_WRITE_NOCACHEFLUSH) {
+                               for (int j = 0; j < PAGE_SIZE; j++) {
+                                       dm->state[j] &= ~DEBUGMEM_WRITE_NOCACHEFLUSH;
+                               }
+                               dm->flags &= ~DEBUGMEM_WRITE_NOCACHEFLUSH;
+                       }
+               }
+               return;
+       }
+       if (addr + size < debugmem_bank.start || addr >= debugmem_bank.start + debugmem_bank.allocated_size)
+               return;
+       for (int i = 0; i < (PAGE_SIZE + size - 1) / PAGE_SIZE; i++) {
+               uaecptr a = (addr & ~PAGE_SIZE) + i * PAGE_SIZE;
+               if (a < debugmem_bank.start || a >= debugmem_bank.start + debugmem_bank.allocated_size)
+                       continue;
+               struct debugmemdata* dm = dmd[(a - debugmem_bank.start) / PAGE_SIZE];
+               for (int j = 0; j < PAGE_SIZE; j++) {
+                       uaecptr aa = a + j;
+                       if (aa < addr || aa >= addr + size)
+                               continue;
+                       dm->state[j] &= ~DEBUGMEM_WRITE_NOCACHEFLUSH;
+               }
+       }
+}
+
 static bool debugmem_func(uaecptr addr, int rwi, int size, uae_u32 val)
 {
        bool ret = true;
@@ -585,13 +618,16 @@ static bool debugmem_func(uaecptr addr, int rwi, int size, uae_u32 val)
                }
 
                if (!(rwi & DEBUGMEM_NOSTACKCHECK) || ((rwi & DEBUGMEM_NOSTACKCHECK) && !(dm->flags & DEBUGMEM_STACK))) {
-                       if ((rwi & DEBUGMEM_FETCH) && !(state & DEBUGMEM_INITIALIZED)) {
+                       if ((rwi & DEBUGMEM_FETCH) && !(state & DEBUGMEM_INITIALIZED) && !(state & DEBUGMEM_WRITE)) {
                                debugreport(dm, oaddr, rwi, size, _T("Instruction fetch from uninitialized memory"));
                                return false;
                        }
-
-                       if ((rwi & DEBUGMEM_FETCH) && (state & DEBUGMEM_WRITE) && !(state & DEBUGMEM_FETCH)) {
-                               debugreport(dm, oaddr, rwi, size, _T("Instruction fetch from memory that was modified"));
+                       if ((rwi & DEBUGMEM_FETCH) && (state & DEBUGMEM_WRITE_NOCACHEFLUSH)) {
+                               debugreport(dm, oaddr, rwi, size, _T("Instruction fetch from memory that was modified without flushing caches"));
+                               return false;
+                       }
+                       if ((rwi & DEBUGMEM_FETCH) && (state & DEBUGMEM_WRITE) && (state & DEBUGMEM_FETCH)) {
+                               debugreport(dm, oaddr, rwi, size, _T("Instruction fetch from memory that was modified after being executed at least once"));
                                return false;
                        }
                }
@@ -611,6 +647,12 @@ static bool debugmem_func(uaecptr addr, int rwi, int size, uae_u32 val)
                                return false;
                        }
                }
+               if (rwi & DEBUGMEM_WRITE) {
+                       rwi |= DEBUGMEM_WRITE_NOCACHEFLUSH;
+                       dm->flags |= DEBUGMEM_WRITE_NOCACHEFLUSH;
+               }
+               if ((rwi & DEBUGMEM_FETCH) && (state & DEBUGMEM_WRITE))
+                       state &= ~(DEBUGMEM_WRITE | DEBUGMEM_WRITE_NOCACHEFLUSH);
                if ((state | rwi) != state) {
                        //console_out_f(_T("addr %08x %d/%d (%02x -> %02x) PC=%08x\n"), addr, i, size, state, rwi, M68K_GETPC);
                        dm->state[offset] |= rwi;
index dc1d1c0d4f161d966e78ba351ea70827a33c2f9d..c8aec21e8510926d711dbbbac52a911055f9b352 100644 (file)
@@ -26,6 +26,7 @@ bool debugmem_break_stack_pop(void);
 bool debugmem_break_stack_push(void);
 bool debugmem_enable_stackframe(bool enable);
 bool debugmem_illg(uae_u16);
+void debugmem_flushcache(uaecptr, int);
 
 extern uae_u32 debugmem_chiplimit;
 extern uae_u32 debugmem_chiphit(uaecptr addr, uae_u32 v, int size);
index 6c4315476d64dc43ccd39b4a087e719c14145efc..8a6d497dc17f21764528a273b78790e7e626320e 100644 (file)
@@ -1471,10 +1471,12 @@ void flush_cpu_caches(bool force)
                        for (int i = 0; i < CACHELINES020; i++)
                                caches020[i].valid = 0;
                        regs.cacr &= ~0x08;
+                       debugmem_flushcache(0, -1);
                }
                if (regs.cacr & 0x04) { // clear entry in instr cache
                        caches020[(regs.caar >> 2) & (CACHELINES020 - 1)].valid = 0;
                        regs.cacr &= ~0x04;
+                       debugmem_flushcache(regs.caar, CACHELINES020);
                }
        } else if (currprefs.cpu_model == 68030) {
                if ((regs.cacr & 0x08) || force) { // clear instr cache
@@ -1487,10 +1489,12 @@ void flush_cpu_caches(bool force)
                                }
                        }
                        regs.cacr &= ~0x08;
+                       debugmem_flushcache(0, -1);
                }
                if (regs.cacr & 0x04) { // clear entry in instr cache
                        icaches030[(regs.caar >> 4) & (CACHELINES030 - 1)].valid[(regs.caar >> 2) & 3] = 0;
                        regs.cacr &= ~0x04;
+                       debugmem_flushcache(regs.caar, CACHELINES030);
                }
                if ((regs.cacr & 0x800) || force) { // clear data cache
                        if (doflush) {
@@ -1517,6 +1521,7 @@ void flush_cpu_caches(bool force)
                                        icaches040[i].valid[j] = false;
                                }
                        }
+                       debugmem_flushcache(0, -1);
                }
        }
 }
@@ -1623,6 +1628,7 @@ static void flush_cpu_caches_040_2(int cache, int scope, uaecptr addr, bool push
                                                tagmask = cacheitag04060mask;
                                                index = (addr >> 4) & cacheisets04060mask;
                                                c = &icaches040[index];
+                                               debugmem_flushcache(addr, 16);
                                        } else {
                                                tagmask = cachedtag04060mask;
                                                index = (addr >> 4) & cachedsets04060mask;