Re: [hatari-devel] MEMWATCH freezes Hatari

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


Hi Toni,

Thank you, I'm afraid I cannot easily apply these patches, because they
do not match the code Hatari uses.

@Nicolas, what's the usual procedure in this case?

Best regards

Uwe

> Here is simple and quick but not optimal (extra check needed in common
> path) patch that should implement missing handling of modified SSW FC
> bits when data fault is retried.
> 
> Please confirm. Obviously I don't have any tests cases :)
> 

> diff --git a/include/cpummu030.h b/include/cpummu030.h
> index e321c9d0..221ceaa0 100644
> --- a/include/cpummu030.h
> +++ b/include/cpummu030.h
> @@ -18,6 +18,7 @@ extern int mmu030_idx;
>  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 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;
>  
> +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_u32 uae_mmu030_get_ilong(uaecptr addr)
>  }
>  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_long(uaecptr addr)
>  }
>  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_word(uaecptr addr)
>  }
>  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_long(uaecptr addr, uae_u32 val)
>  }
>  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_word(uaecptr addr, uae_u32 val)
>  }
>  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);
>  }

> diff --git a/cpummu30.cpp b/cpummu30.cpp
> index fd2493a3..36930b1a 100644
> --- a/cpummu30.cpp
> +++ b/cpummu30.cpp
> @@ -64,6 +64,7 @@ int mmu030_opcode_stageb;
>  
>  int mmu030_fake_prefetch;
>  uaecptr mmu030_fake_prefetch_addr;
> +int mmu030_df_fc;
>  
>  uae_u16 mmu030_state[3];
>  uae_u32 mmu030_data_buffer;
> @@ -2492,6 +2493,7 @@ void mmu030_reset(int hardreset)
>          mmusr_030 = 0;
>          mmu030_flush_atc_all();
>  	}
> +	mmu030_df_fc = -1;
>  	mmu030_set_funcs();
>  }
>  
> @@ -2520,6 +2522,14 @@ void mmu030_set_funcs(void)
>  	}
>  }
>  
> +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
> @@ -2592,6 +2602,14 @@ void m68k_do_rte_mmu030 (uaecptr a7)
>  				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;
> @@ -2888,6 +2906,13 @@ void m68k_do_rte_mmu030c (uaecptr a7)
>  			}
>  		}
>  
> +		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;
>  	}




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