Re: [hatari-devel] MEMWATCH freezes Hatari

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Le 12/10/2018 à 20:44, Nicolas Pomarède a écrit :
I will try to provide an updated patch for Hatari later this evening.

Here's the corresponding patch for Hatari ; I didn't test it as I don't know which program Uwe used to trigger the bug

Nicolas
diff -r e87617b4fe45 src/cpu/cpummu030.c
--- a/src/cpu/cpummu030.c	Thu Oct 11 18:30:37 2018 +0200
+++ b/src/cpu/cpummu030.c	Fri Oct 12 23:18:49 2018 +0200
@@ -69,6 +69,7 @@
 
 int mmu030_fake_prefetch;
 uaecptr mmu030_fake_prefetch_addr;
+int mmu030_df_fc;
 
 uae_u16 mmu030_state[3];
 uae_u32 mmu030_data_buffer;
@@ -2510,6 +2511,7 @@
         mmusr_030 = 0;
         mmu030_flush_atc_all();
 	}
+	mmu030_df_fc = -1;
 	mmu030_set_funcs();
 }
 
@@ -2538,6 +2540,14 @@
 	}
 }
 
+static bool fccanuse(uae_u16 opcode)
+{
+	// MOVES: don't set mmu030_df_fc.
+	if ((opcode & 0xff00) == 0x0e00)
+		return false;
+	return true;
+}
+
 void m68k_do_rte_mmu030 (uaecptr a7)
 {
 	// Restore access error exception state
@@ -2610,6 +2620,14 @@
 				write_log (_T("Software fixed stage B! opcode = %04X, opword = %04x\n"), mmu030_opcode, stageb);
 			}
 		}
+
+		if ((ssw & MMU030_SSW_DF) && fccanuse(mmu030_opcode)) {
+			// If Data Fault: data fetch is retried using SSW FC mode.
+			mmu030_df_fc = ssw & 7;
+		} else {
+			mmu030_df_fc = -1;
+		}
+
 		m68k_areg (regs, 7) += 92;
 	} else {
 		m68k_areg (regs, 7) += 32;
@@ -2658,6 +2676,7 @@
 	uae_s32 regd = regs.regs[reg];
 	if ((dp & 0x800) == 0)
 		regd = (uae_s32)(uae_s16)regd;
+
 	regd <<= (dp >> 9) & 3;
 	if (dp & 0x100) {
 		uae_s32 outer = 0;
@@ -2906,6 +2925,13 @@
 			}
 		}
 
+		if ((ssw & MMU030_SSW_DF) && fccanuse(mmu030_opcode)) {
+			// If Data Fault: data fetch is retried using SSW FC mode.
+			mmu030_df_fc = ssw & 7;
+		} else {
+			mmu030_df_fc = -1;
+		}
+
 	} else {
 		m68k_areg (regs, 7) += 32;
 	}
diff -r e87617b4fe45 src/cpu/cpummu030.h
--- a/src/cpu/cpummu030.h	Thu Oct 11 18:30:37 2018 +0200
+++ b/src/cpu/cpummu030.h	Fri Oct 12 23:18:49 2018 +0200
@@ -18,6 +18,7 @@
 extern bool mmu030_retry;
 extern int mmu030_opcode, mmu030_opcode_stageb;
 extern int mmu030_fake_prefetch;
+extern int mmu030_df_fc;
 extern uaecptr mmu030_fake_prefetch_addr;
 extern uae_u16 mmu030_state[3];
 extern uae_u32 mmu030_data_buffer;
@@ -82,9 +83,26 @@
 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;
 
+static ALWAYS_INLINE uae_u32 uae_mmu030_get_fc_code(void)
+{
+	return (regs.s ? 4 : 0) | 2;
+}
+
+static ALWAYS_INLINE uae_u32 uae_mmu030_get_fc_data(void)
+{
+	uae_u32 fc;
+	if (mmu030_df_fc < 0) {
+		fc = (regs.s ? 4 : 0) | 1;
+	} else {
+		fc = mmu030_df_fc;
+		mmu030_df_fc = -1;
+	}
+	return fc;
+}
+
 static ALWAYS_INLINE uae_u32 uae_mmu030_get_ilong(uaecptr addr)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 2;
+	uae_u32 fc = uae_mmu030_get_fc_code();
 
 	if (unlikely(is_unaligned(addr, 4)))
 		return mmu030_get_ilong_unaligned(addr, fc, 0);
@@ -92,18 +110,20 @@
 }
 static ALWAYS_INLINE uae_u16 uae_mmu030_get_iword(uaecptr addr)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 2;
+	uae_u32 fc = uae_mmu030_get_fc_code();
+
 	return mmu030_get_iword(addr, fc);
 }
 static ALWAYS_INLINE uae_u16 uae_mmu030_get_ibyte(uaecptr addr)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 2;
+	uae_u32 fc = uae_mmu030_get_fc_code();
 
 	return mmu030_get_byte(addr, fc);
 }
+
 static ALWAYS_INLINE uae_u32 uae_mmu030_get_long(uaecptr addr)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 1;
+	uae_u32 fc = uae_mmu030_get_fc_data();
 
 	if (unlikely(is_unaligned(addr, 4)))
 		return mmu030_get_long_unaligned(addr, fc, 0);
@@ -111,7 +131,7 @@
 }
 static ALWAYS_INLINE uae_u32 uae_mmu030_get_word(uaecptr addr)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 1;
+	uae_u32 fc = uae_mmu030_get_fc_data();
 
 	if (unlikely(is_unaligned(addr, 2)))
 		return mmu030_get_word_unaligned(addr, fc, 0);
@@ -119,14 +139,15 @@
 }
 static ALWAYS_INLINE uae_u32 uae_mmu030_get_byte(uaecptr addr)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 1;
+	uae_u32 fc = uae_mmu030_get_fc_data();
 
 	return mmu030_get_byte(addr, fc);
 }
+
 static ALWAYS_INLINE void uae_mmu030_put_long(uaecptr addr, uae_u32 val)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 1;
-    
+	uae_u32 fc = uae_mmu030_get_fc_data();
+
 	if (unlikely(is_unaligned(addr, 4)))
 		mmu030_put_long_unaligned(addr, val, fc, 0);
 	else
@@ -134,7 +155,7 @@
 }
 static ALWAYS_INLINE void uae_mmu030_put_word(uaecptr addr, uae_u32 val)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 1;
+	uae_u32 fc = uae_mmu030_get_fc_data();
 
 	if (unlikely(is_unaligned(addr, 2)))
 		mmu030_put_word_unaligned(addr, val, fc, 0);
@@ -143,7 +164,7 @@
 }
 static ALWAYS_INLINE void uae_mmu030_put_byte(uaecptr addr, uae_u32 val)
 {
-    uae_u32 fc = (regs.s ? 4 : 0) | 1;
+	uae_u32 fc = uae_mmu030_get_fc_data();
 
 	mmu030_put_byte(addr, val, fc);
 }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/