public inbox for linux-m68k@lists.linux-m68k.org
 help / color / mirror / Atom feed
* memcpy on 68000
@ 2011-07-24 13:50 Matthias Reis
  2011-07-24 16:08 ` Andreas Schwab
  2011-07-28  7:49 ` Greg Ungerer
  0 siblings, 2 replies; 6+ messages in thread
From: Matthias Reis @ 2011-07-24 13:50 UTC (permalink / raw)
  To: linux-m68k

Hi all,

I recently did some work to compile a kernel for MMU less Atari STs.
However, I 'm having a problem with the memcpy code as it is compiled by
gcc. When copying from odd addresses, gcc produces memcpy code that tries
to access odd addresses with move.w, which is not possible on the 68000
and therefore produces address error exceptions. Below you can find the
debug output from the hatari emulator and the memcpy version I'm using (I
hope it's the most recent one). Any help would be appreciated.

Best regards,
Matthias

P.S.: I'm using the -m68000 gcc switch

========

memcpy:

1. CPU breakpoint condition(s) matched 2 times.
        pc = $ae57c

CPU=$ae57c, VBL=1057, FrameCycles=10708, HBL=47, LineCycles=180, DSP=N/A
> c
Returning to emulation...
cpu video_cyc= 10708 180@ 47 : $0ae57c : 4e56 0000                        
   link      a6,#0
cpu video_cyc= 10728 200@ 47 : $0ae580 : 48e7 3030                        
   movem.l   d2-d3/a2-a3,-(sp)
cpu video_cyc= 10768  16@ 48 : $0ae584 : 262e 0008                        
   move.l    8(a6),d3
cpu video_cyc= 10784  32@ 48 : $0ae588 : 266e 000c                        
   movea.l   $c(a6),a3
cpu video_cyc= 10800  48@ 48 : $0ae58c : 242e 0010                        
   move.l    $10(a6),d2
cpu video_cyc= 10816  64@ 48 : $0ae590 : 6752                             
   beq.s     $ae5e4
cpu video_cyc= 10824  72@ 48 : $0ae592 : 0803 0000                        
   btst      #0,d3
cpu video_cyc= 10836  84@ 48 : $0ae596 : 6742                             
   beq.s     $ae5da
cpu video_cyc= 10844  92@ 48 : $0ae5da : 2443                             
   movea.l   d3,a2
cpu video_cyc= 10848  96@ 48 : $0ae5dc : 60c0                             
   bra.s     $ae59e
cpu video_cyc= 10860 108@ 48 : $0ae59e : 7002                             
   moveq     #2,d0
cpu video_cyc= 10864 112@ 48 : $0ae5a0 : b082                             
   cmp.l     d2,d0
cpu video_cyc= 10872 120@ 48 : $0ae5a2 : 6408                             
   bcc.s     $ae5ac
cpu video_cyc= 10880 128@ 48 : $0ae5a4 : 200a                             
   move.l    a2,d0
cpu video_cyc= 10884 132@ 48 : $0ae5a6 : 0800 0001                        
   btst      #1,d0
cpu video_cyc= 10896 144@ 48 : $0ae5aa : 6632                             
   bne.s     $ae5de
cpu video_cyc= 10904 152@ 48 : $0ae5de : 34db                             
   move.w    (a3)+,(a2)+
Address Error at address $12513b, PC=$ae5de

CPU=$ae5de, VBL=1057, FrameCycles=10904, HBL=48, LineCycles=152, DSP=N/A
> cpureg
D0: 0016021a D1: 00000400 D2: 00000016 D3: 0016021a
D4: 001d97c8 D5: 0016021a D6: 00000400 D7: 00132ed8
A0: 00132fac A1: 00000400 A2: 0016021a A3: 0012513b
A4: 0012513b A5: 00125151 A6: 00132e8c A7: 00132e6e
USP=000456f6 ISP=00132e6e MSP=00000000 VBR=00000000
T=00 S=1 M=0 X=0 N=0 Z=0 V=0 C=0 IMASK=7
FP0: 0 FP1: 0 FP2: 0 FP3: 0
FP4: 0 FP5: 0 FP6: 0 FP7: 0
N=0 Z=0 I=0 NAN=0
prefetch 34db5582
000ae5de: 34db 5582 60c8 2003 4cdf MOVE.W (A3)+,(A2)+
next PC: 000ae5e0
> m $12513b
12513B: 41 74 61 72 69 20 68 61 72 64 77 61 72 65 20 66   Atari hardware f
12514B: 6f 75 6e 64 3a 20 00 56 49 44 45 4c 20 00 53 54   ound: .VIDEL .ST
12515B: 44 4d 41 2d 53 43 53 49 20 00 54 54 5f 53 48 49   DMA-SCSI .TT_SHI
12516B: 46 54 45 52 20 00 45 58 54 44 5f 53 48 49 46 54   FTER .EXTD_SHIFT
12517B: 45 52 20 00 53 54 4e 44 5f 53 48 49 46 54 45 52   ER .STND_SHIFTER
12518B: 20 00 53 54 5f 4d 46 50 20 00 54 54 5f 4d 46 50    .ST_MFP .TT_MFP
12519B: 20 00 54 54 5f 53 43 53 49 5f 44 4d 41 20 00 45    .TT_SCSI_DMA .E
1251AB: 58 54 44 5f 44 4d 41 20 00 54 54 5f 53 43 53 49   XTD_DMA .TT_SCSI
>


=========

/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 */

#include <linux/module.h>
#include <linux/string.h>

void *memcpy(void *to, const void *from, size_t n)
{
        void *xto = to;
        size_t temp, temp1;

        if (!n)
                return xto;
        if ((long)to & 1) {
                char *cto = to;
                const char *cfrom = from;
                *cto++ = *cfrom++;
                to = cto;
                from = cfrom;
                n--;
        }
        if (n > 2 && (long)to & 2) {
                short *sto = to;
                const short *sfrom = from;
                *sto++ = *sfrom++;
                to = sto;
                from = sfrom;
                n -= 2;
        }
        temp = n >> 2;
        if (temp) {
                long *lto = to;
                const long *lfrom = from;
#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
                for (; temp; temp--)
                        *lto++ = *lfrom++;
#else
                asm volatile (
                        "       movel %2,%3\n"
                        "       andw  #7,%3\n"
                        "       lsrl  #3,%2\n"
                        "       negw  %3\n"
                        "       jmp   %%pc@(1f,%3:w:2)\n"
                        "4:     movel %0@+,%1@+\n"
                        "       movel %0@+,%1@+\n"
                        "       movel %0@+,%1@+\n"
                        "       movel %0@+,%1@+\n"
                        "       movel %0@+,%1@+\n"
                        "       movel %0@+,%1@+\n"
                        "       movel %0@+,%1@+\n"
                        "       movel %0@+,%1@+\n"
                        "1:     dbra  %2,4b\n"
                        "       clrw  %2\n"
                        "       subql #1,%2\n"
                        "       jpl   4b"
                        : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d"
(temp1)
                        : "0" (lfrom), "1" (lto), "2" (temp));
#endif
                to = lto;
                from = lfrom;
        }
        if (n & 2) {
                short *sto = to;
                const short *sfrom = from;
                *sto++ = *sfrom++;
                to = sto;
                from = sfrom;
        }
        if (n & 1) {
                char *cto = to;
                const char *cfrom = from;
                *cto = *cfrom;
        }
        return xto;
}
EXPORT_SYMBOL(memcpy);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: memcpy on 68000
  2011-07-24 13:50 memcpy on 68000 Matthias Reis
@ 2011-07-24 16:08 ` Andreas Schwab
  2011-07-24 17:43   ` Matthias Reis
  2011-07-28  7:49 ` Greg Ungerer
  1 sibling, 1 reply; 6+ messages in thread
From: Andreas Schwab @ 2011-07-24 16:08 UTC (permalink / raw)
  To: Matthias Reis; +Cc: linux-m68k

"Matthias Reis" <matthias.reis@physik.tu-berlin.de> writes:

> I recently did some work to compile a kernel for MMU less Atari STs.
> However, I 'm having a problem with the memcpy code as it is compiled by
> gcc. When copying from odd addresses, gcc produces memcpy code that tries
> to access odd addresses with move.w, which is not possible on the 68000

You need to use a compiler that is targeted to uclinux, not linux (the
latter assumes 68020+, thus disables strict alignment).

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: memcpy on 68000
  2011-07-24 16:08 ` Andreas Schwab
@ 2011-07-24 17:43   ` Matthias Reis
  0 siblings, 0 replies; 6+ messages in thread
From: Matthias Reis @ 2011-07-24 17:43 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linux-m68k

I'm using gcc 4.2.4

$ /usr/local/m68k-uclinux/bin/gcc --version
gcc (GCC) 4.2.4

downloaded from http://www.uclinux.org/pub/uClinux/m68k-elf-tools/tools-20080626/m68k-uclinux-tools-20080626.sh .

This is the gcc command line for memcpy:

  /usr/local/m68k-uclinux/bin/gcc -Wp,-MD,arch/m68k/lib/.memcpy.o.d  -nostdinc -isystem /usr/local/lib/gcc/m68k-uclinux/4.2.4/include -I/home/unsortiert/linux-m68k/arch/m68k/include -Iarch/m68k/include/generated -Iinclude  -include include/generated/autoconf.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -m68000 -mstrict-align -pipe -DUTS_SYSNAME=\"uClinux\" -D__uClinux__ -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow    -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(memcpy)"  -D"KBUILD_MODNAME=KBUILD_STR(memcpy)" -c -o arch/m68k/lib/memcpy.o arch
 /m68k/lib/memcpy.c

As you can see, I tried  -mstrict-align, but I got the same error as previously.

Matthias


On Sun, Jul 24, 2011 at 06:08:11PM +0200, Andreas Schwab wrote:
> "Matthias Reis" <matthias.reis@physik.tu-berlin.de> writes:
> You need to use a compiler that is targeted to uclinux, not linux (the
> latter assumes 68020+, thus disables strict alignment).
> 
> Andreas.
> 
> -- 
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."
> --
> To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: memcpy on 68000
  2011-07-24 13:50 memcpy on 68000 Matthias Reis
  2011-07-24 16:08 ` Andreas Schwab
@ 2011-07-28  7:49 ` Greg Ungerer
  2011-07-28  8:09   ` Andreas Schwab
  2011-07-29 14:01   ` Matthias Reis
  1 sibling, 2 replies; 6+ messages in thread
From: Greg Ungerer @ 2011-07-28  7:49 UTC (permalink / raw)
  To: Matthias Reis; +Cc: linux-m68k

Hi Matthias,

On 07/24/2011 11:50 PM, Matthias Reis wrote:
> I recently did some work to compile a kernel for MMU less Atari STs.
> However, I 'm having a problem with the memcpy code as it is compiled by
> gcc. When copying from odd addresses, gcc produces memcpy code that tries
> to access odd addresses with move.w, which is not possible on the 68000
> and therefore produces address error exceptions. Below you can find the
> debug output from the hatari emulator and the memcpy version I'm using (I
> hope it's the most recent one). Any help would be appreciated.

That looks to be the memcpy.c from linux-3.0, yes?

Looking at the memcpy.c code for m68knommu before merging
and cleanup I can see that it used to do this:

   const char *c_from = from;
   char *c_to = to;
   while (n-- > 0)
     *c_to++ = *c_from++;
   return((void *) to);

for the the M68000 case. (Actually it did that for all
non-ColdFire cases). Which obviously would always work,
but is not particularly efficient.

So, yes, the current code is broken for M68000. It doesn't
check alignment of the source ("from") address.

Heres a first attempt at a fix for this. This is only compile
tested, not run tested... Basically we check that if after
16bit aligning the destination if the source is unaligned
then we resort to a byte wise copy.

Need to check if CPU32 needs this or not too. ColdFire doesn't.


diff --git a/arch/m68k/lib/memcpy.c b/arch/m68k/lib/memcpy.c
index 0648893..10ca051 100644
--- a/arch/m68k/lib/memcpy.c
+++ b/arch/m68k/lib/memcpy.c
@@ -22,6 +22,15 @@ void *memcpy(void *to, const void *from, size_t n)
                 from = cfrom;
                 n--;
         }
+#if defined(CONFIG_M68000)
+       if ((long)from & 1) {
+               char *cto = to;
+               const char *cfrom = from;
+               for (; n; n--)
+                       *cto++ = *cfrom++;
+               return xto;
+       }
+#endif
         if (n > 2 && (long)to & 2) {
                 short *sto = to;
                 const short *sfrom = from;


Regards
Greg


------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close,                            FAX:         +61 7 3891 3630
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: memcpy on 68000
  2011-07-28  7:49 ` Greg Ungerer
@ 2011-07-28  8:09   ` Andreas Schwab
  2011-07-29 14:01   ` Matthias Reis
  1 sibling, 0 replies; 6+ messages in thread
From: Andreas Schwab @ 2011-07-28  8:09 UTC (permalink / raw)
  To: Greg Ungerer; +Cc: Matthias Reis, linux-m68k

Greg Ungerer <gerg@snapgear.com> writes:

> Need to check if CPU32 needs this or not too. ColdFire doesn't.

CPU32 is 68020-based.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: memcpy on 68000
  2011-07-28  7:49 ` Greg Ungerer
  2011-07-28  8:09   ` Andreas Schwab
@ 2011-07-29 14:01   ` Matthias Reis
  1 sibling, 0 replies; 6+ messages in thread
From: Matthias Reis @ 2011-07-29 14:01 UTC (permalink / raw)
  To: Greg Ungerer; +Cc: Matthias Reis, linux-m68k

Hi Greg,

thanks for the fix. I'll test this as soon as I get my own PC back... I
use Geert's master tree as code basis.

Best regards,
Matthias


> That looks to be the memcpy.c from linux-3.0, yes?
>
> Looking at the memcpy.c code for m68knommu before merging
> and cleanup I can see that it used to do this:
>
>    const char *c_from = from;
>    char *c_to = to;
>    while (n-- > 0)
>      *c_to++ = *c_from++;
>    return((void *) to);
>
> for the the M68000 case. (Actually it did that for all
> non-ColdFire cases). Which obviously would always work,
> but is not particularly efficient.
>
> So, yes, the current code is broken for M68000. It doesn't
> check alignment of the source ("from") address.
>
> Heres a first attempt at a fix for this. This is only compile
> tested, not run tested... Basically we check that if after
> 16bit aligning the destination if the source is unaligned
> then we resort to a byte wise copy.
>
> Need to check if CPU32 needs this or not too. ColdFire doesn't.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-07-29 14:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-24 13:50 memcpy on 68000 Matthias Reis
2011-07-24 16:08 ` Andreas Schwab
2011-07-24 17:43   ` Matthias Reis
2011-07-28  7:49 ` Greg Ungerer
2011-07-28  8:09   ` Andreas Schwab
2011-07-29 14:01   ` Matthias Reis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox