]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
More information added to U MMU translation debug command.
authorToni Wilen <twilen@winuae.net>
Tue, 16 Sep 2025 15:59:18 +0000 (18:59 +0300)
committerToni Wilen <twilen@winuae.net>
Tue, 16 Sep 2025 15:59:18 +0000 (18:59 +0300)
cpummu.cpp
cpummu30.cpp
debug.cpp
include/cpummu.h
include/cpummu030.h
include/mmu_common.h

index b5ca9a3e982e21143965a73ecb831622200c68ac..20e8db4f5b71454c650a6ae8b10b92a5229fd0e5 100644 (file)
@@ -43,6 +43,7 @@
 
 #ifdef FULLMMU
 
+bool mmu_debugger;
 uae_u32 mmu_is_super;
 uae_u32 mmu_tagmask, mmu_pagemask, mmu_pagemaski;
 struct mmu_atc_line mmu_atc_array[ATC_TYPE][ATC_SLOTS][ATC_WAYS];
@@ -65,6 +66,8 @@ int mmu040_movem;
 uaecptr mmu040_movem_ea;
 uae_u32 mmu040_move16[4];
 
+static struct mmu_debug_data *mddm;
+
 #if MMU_ICACHE
 struct mmu_icache mmu_icache_data[MMU_ICACHE_SZ];
 #endif
@@ -638,7 +641,7 @@ static uae_u32 desc_get_long(uaecptr addr)
        mmu_cache_state = ce_cachable[addr >>16] | CACHE_DISABLE_ALLOCATE;
        return x_phys_get_long(addr);
 }
-// Write accesses probably are always pushed to memomory
+// Write accesses probably are always pushed to memory
 static void desc_put_long(uaecptr addr, uae_u32 v)
 {
        mmu_cache_state = CACHE_DISABLE_MMU;
@@ -653,6 +656,7 @@ static void desc_put_long(uaecptr addr, uae_u32 v)
 static uae_u32 mmu_fill_atc(uaecptr addr, bool super, uae_u32 tag, bool write, struct mmu_atc_line *l, uae_u32 *status060)
 {
     uae_u32 desc, desc_addr, wp;
+    uae_u32 desca = 0, descb = 0, descc = 0;
     uae_u32 status = 0;
     int i;
        int old_s;
@@ -670,6 +674,7 @@ static uae_u32 mmu_fill_atc(uaecptr addr, bool super, uae_u32 tag, bool write, s
     
     SAVE_EXCEPTION;
     TRY(prb) {
+        desca = desc_addr;
         desc = desc_get_long(desc_addr);
         if ((desc & 2) == 0) {
 #if MMUDEBUG > 1
@@ -681,13 +686,14 @@ static uae_u32 mmu_fill_atc(uaecptr addr, bool super, uae_u32 tag, bool write, s
         }
         
         wp |= desc;
-        if ((desc & MMU_DES_USED) == 0) {
+        if ((desc & MMU_DES_USED) == 0 && !mmu_debugger) {
             desc_put_long(desc_addr, desc | MMU_DES_USED);
                }
         
         /* fetch pointer table descriptor */
         i = (addr >> 16) & 0x1fc;
         desc_addr = (desc & MMU_ROOT_PTR_ADDR_MASK) | i;
+        descb = desc_addr;
         desc = desc_get_long(desc_addr);
         if ((desc & 2) == 0) {
 #if MMUDEBUG > 1
@@ -698,8 +704,9 @@ static uae_u32 mmu_fill_atc(uaecptr addr, bool super, uae_u32 tag, bool write, s
             goto fail;
         }
         wp |= desc;
-        if ((desc & MMU_DES_USED) == 0)
+        if ((desc & MMU_DES_USED) == 0 && !mmu_debugger) {
             desc_put_long(desc_addr, desc | MMU_DES_USED);
+        }
         
         /* fetch page table descriptor */
         if (mmu_pagesize_8k) {
@@ -711,6 +718,7 @@ static uae_u32 mmu_fill_atc(uaecptr addr, bool super, uae_u32 tag, bool write, s
         }
         
         desc = desc_get_long(desc_addr);
+        descc = desc_addr;
         if ((desc & 3) == 2) {
             /* indirect */
             desc_addr = desc & MMU_PAGE_INDIRECT_MASK;
@@ -720,19 +728,23 @@ static uae_u32 mmu_fill_atc(uaecptr addr, bool super, uae_u32 tag, bool write, s
             wp |= desc;
             if (write) {
                 if ((wp & MMU_DES_WP) || ((desc & MMU_DES_SUPER) && !super)) {
-                    if ((desc & MMU_DES_USED) == 0) {
+                    if ((desc & MMU_DES_USED) == 0 && !mmu_debugger) {
                         desc |= MMU_DES_USED;
                         desc_put_long(desc_addr, desc);
                     }
                 } else if ((desc & (MMU_DES_USED|MMU_DES_MODIFIED)) !=
                            (MMU_DES_USED|MMU_DES_MODIFIED)) {
-                    desc |= MMU_DES_USED|MMU_DES_MODIFIED;
-                    desc_put_long(desc_addr, desc);
+                                       desc |= MMU_DES_USED|MMU_DES_MODIFIED;
+                                       if (!mmu_debugger) {
+                                               desc_put_long(desc_addr, desc);
+                                       }
                 }
             } else {
                 if ((desc & MMU_DES_USED) == 0) {
-                    desc |= MMU_DES_USED;
-                    desc_put_long(desc_addr, desc);
+                                       desc |= MMU_DES_USED;
+                                       if (!mmu_debugger) {
+                                               desc_put_long(desc_addr, desc);
+                                       }
                 }
             }
             desc |= wp & MMU_DES_WP;
@@ -769,6 +781,12 @@ fail:
                        status = l->phys | l->status;
                }
 
+               if (mmu_debugger) {
+                       mddm->descriptor[0] = desca;
+                       mddm->descriptor[1] = descb;
+                       mddm->descriptor[2] = descc;
+               }
+
                RESTORE_EXCEPTION;
     } CATCH(prb) {
         RESTORE_EXCEPTION;
@@ -783,6 +801,10 @@ fail:
         status = MMU_MMUSR_B;
                *status060 |= MMU_FSLW_LK | MMU_FSLW_TWE;
 
+               if (mmu_debugger) {
+                       mddm->desc_fault = true;
+               }
+
 #if MMUDEBUG > 0
         write_log(_T("MMU: bus error during table search.\n"));
 #endif
@@ -832,6 +854,52 @@ static void mmu_add_cache(uaecptr addr, uaecptr phys, bool super, bool data, boo
        }
 }
 
+uaecptr debug_mmu_translate(uaecptr addr, uae_u32 val, bool super, bool data, bool write, int size, struct mmu_debug_data *mdd)
+{
+       memset(mdd, 0, sizeof(struct mmu_debug_data));
+       mddm = mdd;
+       for (int i = 0; i < MAX_MMU_DEBUG_DESCRIPTOR_LEVEL; i++) {
+               mdd->descriptor[i] = 0xffffffff;
+       }
+       mmu_debugger = true;
+       mmu_flush_atc_all(true);
+       if (!data) {
+               int res = mmu_do_match_ttr(regs.itt0, addr, super);
+               if (res == TTR_OK_MATCH) {
+                       mdd->tt = 1;
+                       mdd->ttdata = regs.itt0;
+                       return addr;
+               }
+               res = mmu_do_match_ttr(regs.itt1, addr, super);
+               if (res == TTR_OK_MATCH) {
+                       mdd->tt = 2;
+                       mdd->ttdata = regs.itt1;
+                       return addr;
+               }
+       } else {
+               int res = mmu_do_match_ttr(regs.dtt0, addr, super);
+               if (res == TTR_OK_MATCH) {
+                       mdd->tt = 1;
+                       mdd->ttdata = regs.dtt0;
+                       return addr;
+               }
+               res = mmu_do_match_ttr(regs.dtt1, addr, super);
+               if (res == TTR_OK_MATCH) {
+                       mdd->tt = 2;
+                       mdd->ttdata = regs.dtt1;
+                       return addr;
+               }
+       }
+       uaecptr v = mmu_translate(addr, val, super, data, write, size);
+       return v;
+}
+
+void debug_mmu_translate_end(void)
+{
+       mmu_debugger = false;
+       mddm = NULL;
+}
+
 uaecptr mmu_translate(uaecptr addr, uae_u32 val, bool super, bool data, bool write, int size)
 {
        int way, i, index, way_invalid;
index 941f0acd410217d73c19f7aa841dcb209101e2dd..a1f80ec08d6a1197c490efe07b2fc396bac6f10d 100644 (file)
@@ -80,6 +80,8 @@ uae_u8 mmu030_cache_state;
 struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS + 1];
 bool ismoves030, islrmw030;
 
+static struct mmu_debug_data *mddm;
+
 static void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write);
 static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level);
 static TT_info mmu030_decode_tt(uae_u32 TT);
@@ -1366,7 +1368,9 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
                 /* Set the updated bit */
                 if (!level && !(descr[0]&DESCR_U) && !super_violation) {
                     descr[0] |= DESCR_U;
-                    desc_put_long(descr_addr[descr_num], descr[0]);
+                    if (!mmu_debugger) {
+                           desc_put_long(descr_addr[descr_num], descr[0]);
+                     }
                 }
                 
                 /* Update status bits */
@@ -1515,7 +1519,9 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
                 }
                 /* write modified descriptor if necessary */
                 if (descr_modified) {
-                    desc_put_long(descr_addr[descr_num], descr[0]);
+                    if (!mmu_debugger) {
+                                               desc_put_long(descr_addr[descr_num], descr[0]);
+                    }
                 }
             }
             
@@ -1587,9 +1593,23 @@ static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int lev
         mmu030.status |= (MMUSR_BUS_ERROR|MMUSR_INVALID);
         write_log(_T("MMU: Bus error while %s descriptor!\n"),
                   bBusErrorReadWrite?_T("reading"):_T("writing"));
+
+               if (mmu_debugger) {
+            mddm->desc_fault = true;
+        }
+
     } ENDTRY;
 
-    // Restore original supervisor state
+    if (mmu_debugger) {
+        for (int i = 1; i <= descr_num; i++) {
+            mddm->descriptor[i - 1] = descr_addr[i];
+        }
+        if (descr_size > 4) {
+            mddm->descriptor8 = true;
+        }
+    }
+
+       // Restore original supervisor state
     regs.s = old_s;
 
     /* check if we have to handle ptest */
@@ -1818,18 +1838,26 @@ void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc)
                regs.mmu_ssw = MMU030_SSW_DF | (MMU030_SSW_DF << 1);
                if (!(mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE)) {
                        regs.wb2_status = mmu030fixupreg(0);
-                       mmu030fixupmod(regs.wb2_status, 0, 0);
+                       if (!mmu_debugger) {
+                               mmu030fixupmod(regs.wb2_status, 0, 0);
+                       }
                        regs.wb3_status = mmu030fixupreg(1);
-                       mmu030fixupmod(regs.wb3_status, 0, 1);
+                       if (!mmu_debugger) {
+                               mmu030fixupmod(regs.wb3_status, 0, 1);
+                       }
                }
        } else {
                // only used by data fault but word sounds nice
                flags = MMU030_SSW_SIZE_W;
                if (currprefs.cpu_compatible) {
                        regs.wb2_status = mmu030fixupreg(0);
-                       mmu030fixupmod(regs.wb2_status, 0, 0);
+                       if (!mmu_debugger) {
+                               mmu030fixupmod(regs.wb2_status, 0, 0);
+                       }
                        regs.wb3_status = mmu030fixupreg(1);
-                       mmu030fixupmod(regs.wb3_status, 0, 1);
+                       if (!mmu_debugger) {
+                               mmu030fixupmod(regs.wb3_status, 0, 1);
+                       }
                        regs.mmu_ssw = MMU030_SSW_FB | MMU030_SSW_RB;
                } else {
                        regs.mmu_ssw = MMU030_SSW_FB | MMU030_SSW_RB;
@@ -2615,6 +2643,43 @@ static uaecptr mmu030_get_addr_atc(uaecptr addr, int l, uae_u32 fc, bool write)
 
     return physical_addr;
 }
+
+void debug_mmu030_translate_end(void)
+{
+       mmu_debugger = false;
+       mddm = NULL;
+}
+
+uaecptr debug_mmu030_translate(uaecptr addr, int fc, bool write, struct mmu_debug_data *mdd)
+{
+       memset(mdd, 0, sizeof(struct mmu_debug_data));
+       mddm = mdd;
+       for (int i = 0; i < MAX_MMU_DEBUG_DESCRIPTOR_LEVEL; i++) {
+               mdd->descriptor[i] = 0xffffffff;
+       }
+       mmu_debugger = true;
+       mmu030_flush_atc_all();
+       if ((fc == 7) || (mmu030_match_ttr(addr, fc, write) & TT_OK_MATCH) || (!mmu030.enabled)) {
+               if (mmu030_do_match_ttr(tt0_030, mmu030.transparent.tt0, addr, fc, write) & TT_OK_MATCH) {
+                       mdd->ttdata = tt0_030;
+                       mdd->tt = 1;
+               }
+               if (mmu030_do_match_ttr(tt1_030, mmu030.transparent.tt1, addr, fc, write) & TT_OK_MATCH) {
+                       mdd->ttdata = tt1_030;
+                       mdd->tt = 2;
+               }
+               return addr;
+       }
+       int atc_line_num = mmu030_logical_is_in_atc(addr, fc, write);
+
+       if (atc_line_num >= 0) {
+               return mmu030_get_addr_atc(addr, atc_line_num, fc, write);
+       } else {
+               mmu030_table_search(addr, fc, false, 0);
+               return mmu030_get_addr_atc(addr, mmu030_logical_is_in_atc(addr, fc, write), fc, write);
+       }
+}
+
 uaecptr mmu030_translate(uaecptr addr, bool super, bool data, bool write)
 {
        int fc = (super ? 4 : 0) | (data ? 1 : 2);
index 7804961684b2afbbeffa6a6d5ffaad0e6e907c1e..b8e5b7ec2a62a8e4790c17c6de75cd39d062ab4f 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -6535,6 +6535,73 @@ static void find_ea (TCHAR **inptr)
        }
 }
 
+static void debug_do_mmu_translate(uaecptr addrl)
+{
+       struct mmu_debug_data mdd, mdd2;
+       uaecptr addrp;
+
+       console_out_f(_T("%08x translates to:\n"), addrl);
+       for (int fc = 0; fc < 7; fc++) {
+               bool super = (fc & 4) != 0;
+               bool data = (fc & 1) != 0;
+               bool ins = (fc & 2) != 0;
+               if (currprefs.mmu_model >= 68040 && fc != 5 && fc != 6 && fc != 1 && fc != 2) {
+                       continue;
+               }
+               console_out_f(_T("FC%d %s: "), fc, fc == 6 ? _T("SI") : (fc == 5 ? _T("SD") : (fc == 2 ? _T("UI") : (fc == 1 ? _T("UD") : _T("--")))));
+               TRY(prb) {
+                       if (currprefs.mmu_model >= 68040) {
+                               addrp = debug_mmu_translate(addrl, 0, super, data, false, sz_long, &mdd);
+                       } else {
+                               addrp = debug_mmu030_translate(addrl, fc, false, &mdd);
+                       }
+                       console_out_f(_T("PHYS: %08x"), addrp);
+                       TRY(prb2) {
+                               if (currprefs.mmu_model >= 68040) {
+                                       addrp = debug_mmu_translate(addrl, 0, super, data, true, sz_long, &mdd2);
+                               } else {
+                                       addrp = debug_mmu030_translate(addrl, fc, true, &mdd2);
+                               }
+                               console_out_f(_T(" RW"));
+                       } CATCH(prb2) {
+                               console_out_f(_T(" RO"));
+                       } ENDTRY;
+               } CATCH(prb) {
+                       console_out_f(_T("PHYS: ********"));
+               } ENDTRY;
+               if (mdd.tt) {
+                       console_out_f(_T(" TT%d: %08x"), mdd.tt - 1, mdd.ttdata);
+               } else if (mdd.descriptor[0] != 0xffffffff) {
+                       console_out_f(_T(" DESCR:"));
+                       for (int i = 0; i < MAX_MMU_DEBUG_DESCRIPTOR_LEVEL; i++) {
+                               uaecptr desc = mdd.descriptor[i];
+                               if (desc == 0xffffffff) {
+                                       break;
+                               }
+                               if (mdd.descriptor8) {
+                                       uae_u32 descdata1 = get_long_debug(desc);
+                                       uae_u32 descdata2 = get_long_debug(desc + 4);
+                                       console_out_f(_T(" %08x (%08x.%08x)"), desc, descdata1, descdata2);
+                               } else {
+                                       uae_u32 descdata = get_long_debug(desc);
+                                       console_out_f(_T(" %08x (%08x)"), desc, descdata);
+                               }
+                       }
+               } else {
+                       console_out_f(_T(" DESCR: ********"));
+               }
+               if (mdd.desc_fault) {
+                       console_out_f(_T(" FAULT"));
+               }
+               console_out_f(_T("\n"));
+               if (currprefs.mmu_model >= 68040) {
+                       debug_mmu_translate_end();
+               } else {
+                       debug_mmu030_translate_end();
+               }
+       }
+}
+
 static void m68k_modify (TCHAR **inptr)
 {
        uae_u32 v;
@@ -7294,35 +7361,8 @@ static bool debug_line (TCHAR *input)
                        break;
                case 'U':
                        if (currprefs.mmu_model && more_params (&inptr)) {
-                               int i;
                                uaecptr addrl = readhex(&inptr, NULL);
-                               uaecptr addrp;
-                               console_out_f (_T("%08X translates to:\n"), addrl);
-                               for (i = 0; i < 4; i++) {
-                                       bool super = (i & 2) != 0;
-                                       bool data = (i & 1) != 0;
-                                       console_out_f (_T("S%dD%d="), super, data);
-                                       TRY(prb) {
-                                               if (currprefs.mmu_model >= 68040)
-                                                       addrp = mmu_translate (addrl, 0, super, data, false, sz_long);
-                                               else
-                                                       addrp = mmu030_translate (addrl, super, data, false);
-                                               console_out_f (_T("%08X"), addrp);
-                                               TRY(prb2) {
-                                                       if (currprefs.mmu_model >= 68040)
-                                                               addrp = mmu_translate (addrl, 0, super, data, true, sz_long);
-                                                       else
-                                                               addrp = mmu030_translate (addrl, super, data, true);
-                                                       console_out_f (_T(" RW"));
-                                               } CATCH(prb2) {
-                                                       console_out_f (_T(" RO"));
-                                               } ENDTRY
-                                       } CATCH(prb) {
-                                               console_out_f (_T("***********"));
-                                       } ENDTRY
-                                       console_out_f (_T(" "));
-                               }
-                               console_out_f (_T("\n"));
+                               debug_do_mmu_translate(addrl);
                        }
                        break;
                case 'h':
index 67b1edc4e55f97348b015ed8f425bad1da996af9..9428d4dfc41faa0dc677e747ac02d30e22c541dd 100644 (file)
@@ -234,6 +234,9 @@ static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_l
 extern void mmu_get_move16(uaecptr addr, uae_u32 *v, bool data, int size);
 extern void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, int size);
 
+extern uaecptr debug_mmu_translate(uaecptr addr, uae_u32 val, bool super, bool data, bool write, int size, struct mmu_debug_data *mdd);
+extern void debug_mmu_translate_end(void);
+
 #if MMU_IPAGECACHE
 extern uae_u32 atc_last_ins_laddr, atc_last_ins_paddr;
 extern uae_u8 atc_last_ins_cache;
index baf6de9d54e80c56fde391075686f0a34c3e57ae..39790e3e5ff15279df0b4a49f6a8b32e2f150c67 100644 (file)
@@ -97,6 +97,9 @@ extern uae_u32 REGPARAM3 mmu030_get_lrmw_long_unaligned(uaecptr addr, uae_u32 fc
 extern void REGPARAM3 mmu030_put_word_unaligned(uaecptr addr, uae_u16 val, uae_u32 fc, int flags) REGPARAM;
 extern void REGPARAM3 mmu030_put_long_unaligned(uaecptr addr, uae_u32 val, uae_u32 fc, int flags) REGPARAM;
 
+extern uaecptr debug_mmu030_translate(uaecptr addr, int fc, bool write, struct mmu_debug_data *mdd);
+extern void debug_mmu030_translate_end(void);
+
 static ALWAYS_INLINE uae_u32 uae_mmu030_get_fc_code(void)
 {
        return (regs.s ? 4 : 0) | 2;
index 1fed705543aa87584b7c73f75420d34b20447838..5a46e81f0d009d6b4b1acca8f2028675806a08a2 100644 (file)
@@ -44,6 +44,8 @@ typedef int m68k_exception;
 
 #endif
 
+extern bool mmu_debugger;
+
 /* special status word (access error stack frame) */
 /* 68060 */
 #define MMU_FSLW_MA            0x08000000
@@ -152,4 +154,14 @@ extern void(*x_phys_put_byte)(uaecptr, uae_u32);
 extern void(*x_phys_put_word)(uaecptr, uae_u32);
 extern void(*x_phys_put_long)(uaecptr, uae_u32);
 
+#define MAX_MMU_DEBUG_DESCRIPTOR_LEVEL 8
+struct mmu_debug_data
+{
+    uaecptr descriptor[MAX_MMU_DEBUG_DESCRIPTOR_LEVEL];
+    bool descriptor8;
+    bool desc_fault;
+    int tt;
+    uae_u32 ttdata;
+};
+
 #endif /* UAE_MMU_COMMON_H */