From 78318119eead6aed050d1730a6b72d1c555302d2 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 1 Jul 2020 21:15:30 +0100 Subject: target/m68k: fix physical address translation in m68k_cpu_get_phys_page_debug() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The result of the get_physical_address() function should be combined with the offset of the original page access before being returned. Otherwise the m68k_cpu_get_phys_page_debug() function can round to the wrong page causing incorrect lookups in gdbstub and various "Disassembler disagrees with translator over instruction decoding" warnings to appear at translation time. Fixes: 88b2fef6c3 ("target/m68k: add MC68040 MMU") Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20200701201531.13828-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- target/m68k/helper.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 79b0b10ea9..631eab7774 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -820,10 +820,14 @@ hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) if (env->sr & SR_S) { access_type |= ACCESS_SUPER; } + if (get_physical_address(env, &phys_addr, &prot, addr, access_type, &page_size) != 0) { return -1; } + + addr &= TARGET_PAGE_MASK; + phys_addr += addr & (page_size - 1); return phys_addr; } -- cgit v1.2.3 From 852002b5664bf079da05c5201dbf2345b870e5ed Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 1 Jul 2020 21:15:31 +0100 Subject: target/m68k: consolidate physical translation offset into get_physical_address() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since all callers to get_physical_address() now apply the same page offset to the translation result, move the logic into get_physical_address() itself to avoid duplication. Suggested-by: Philippe Mathieu-Daudé Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier Message-Id: <20200701201531.13828-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- target/m68k/helper.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 631eab7774..3ff5765795 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -643,7 +643,7 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, /* Transparent Translation Register bit */ env->mmu.mmusr = M68K_MMU_T_040 | M68K_MMU_R_040; } - *physical = address & TARGET_PAGE_MASK; + *physical = address; *page_size = TARGET_PAGE_SIZE; return 0; } @@ -771,7 +771,7 @@ static int get_physical_address(CPUM68KState *env, hwaddr *physical, } *page_size = 1 << page_bits; page_mask = ~(*page_size - 1); - *physical = next & page_mask; + *physical = (next & page_mask) + (address & (*page_size - 1)); if (access_type & ACCESS_PTEST) { env->mmu.mmusr |= next & M68K_MMU_SR_MASK_040; @@ -826,8 +826,6 @@ hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) return -1; } - addr &= TARGET_PAGE_MASK; - phys_addr += addr & (page_size - 1); return phys_addr; } @@ -891,10 +889,8 @@ bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size, ret = get_physical_address(&cpu->env, &physical, &prot, address, access_type, &page_size); if (likely(ret == 0)) { - address &= TARGET_PAGE_MASK; - physical += address & (page_size - 1); - tlb_set_page(cs, address, physical, - prot, mmu_idx, TARGET_PAGE_SIZE); + tlb_set_page(cs, address & TARGET_PAGE_MASK, + physical & TARGET_PAGE_MASK, prot, mmu_idx, page_size); return true; } @@ -1383,9 +1379,8 @@ void HELPER(ptest)(CPUM68KState *env, uint32_t addr, uint32_t is_read) ret = get_physical_address(env, &physical, &prot, addr, access_type, &page_size); if (ret == 0) { - addr &= TARGET_PAGE_MASK; - physical += addr & (page_size - 1); - tlb_set_page(env_cpu(env), addr, physical, + tlb_set_page(env_cpu(env), addr & TARGET_PAGE_MASK, + physical & TARGET_PAGE_MASK, prot, access_type & ACCESS_SUPER ? MMU_KERNEL_IDX : MMU_USER_IDX, page_size); } -- cgit v1.2.3 From d159dd058c7dc48a9291fde92eaae52a9f26a4d1 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 12 Jun 2020 16:04:00 +0200 Subject: softfloat,m68k: disable floatx80_invalid_encoding() for m68k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the comment, this definition of invalid encoding is given by intel developer's manual, and doesn't comply with 680x0 FPU. With m68k, the explicit integer bit can be zero in the case of: - zeros (exp == 0, mantissa == 0) - denormalized numbers (exp == 0, mantissa != 0) - unnormalized numbers (exp != 0, exp < 0x7FFF) - infinities (exp == 0x7FFF, mantissa == 0) - not-a-numbers (exp == 0x7FFF, mantissa != 0) For infinities and NaNs, the explicit integer bit can be either one or zero. The IEEE 754 standard does not define a zero integer bit. Such a number is an unnormalized number. Hardware does not directly support denormalized and unnormalized numbers, but implicitly supports them by trapping them as unimplemented data types, allowing efficient conversion in software. See "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL", "1.6 FLOATING-POINT DATA TYPES" We will implement in the m68k TCG emulator the FP_UNIMP exception to trap into the kernel to normalize the number. In case of linux-user, the number will be normalized by QEMU. Signed-off-by: Laurent Vivier Reviewed-by: Alex Bennée Message-Id: <20200612140400.2130118-1-laurent@vivier.eu> --- include/fpu/softfloat.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index ff4e2605b1..f1a19df066 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -794,7 +794,31 @@ static inline bool floatx80_unordered_quiet(floatx80 a, floatx80 b, *----------------------------------------------------------------------------*/ static inline bool floatx80_invalid_encoding(floatx80 a) { +#if defined(TARGET_M68K) + /*------------------------------------------------------------------------- + | With m68k, the explicit integer bit can be zero in the case of: + | - zeros (exp == 0, mantissa == 0) + | - denormalized numbers (exp == 0, mantissa != 0) + | - unnormalized numbers (exp != 0, exp < 0x7FFF) + | - infinities (exp == 0x7FFF, mantissa == 0) + | - not-a-numbers (exp == 0x7FFF, mantissa != 0) + | + | For infinities and NaNs, the explicit integer bit can be either one or + | zero. + | + | The IEEE 754 standard does not define a zero integer bit. Such a number + | is an unnormalized number. Hardware does not directly support + | denormalized and unnormalized numbers, but implicitly supports them by + | trapping them as unimplemented data types, allowing efficient conversion + | in software. + | + | See "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL", + | "1.6 FLOATING-POINT DATA TYPES" + *------------------------------------------------------------------------*/ + return false; +#else return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0; +#endif } #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL) -- cgit v1.2.3