* 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