aboutsummaryrefslogtreecommitdiff
path: root/arch/arm26/lib
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/arm26/lib
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/arm26/lib')
-rw-r--r--arch/arm26/lib/Makefile26
-rw-r--r--arch/arm26/lib/ashldi3.c61
-rw-r--r--arch/arm26/lib/ashrdi3.c61
-rw-r--r--arch/arm26/lib/backtrace.S145
-rw-r--r--arch/arm26/lib/changebit.S28
-rw-r--r--arch/arm26/lib/clearbit.S31
-rw-r--r--arch/arm26/lib/copy_page.S62
-rw-r--r--arch/arm26/lib/csumipv6.S32
-rw-r--r--arch/arm26/lib/csumpartial.S130
-rw-r--r--arch/arm26/lib/csumpartialcopy.S52
-rw-r--r--arch/arm26/lib/csumpartialcopygeneric.S352
-rw-r--r--arch/arm26/lib/csumpartialcopyuser.S115
-rw-r--r--arch/arm26/lib/delay.S57
-rw-r--r--arch/arm26/lib/ecard.S41
-rw-r--r--arch/arm26/lib/findbit.S67
-rw-r--r--arch/arm26/lib/floppydma.S32
-rw-r--r--arch/arm26/lib/gcclib.h21
-rw-r--r--arch/arm26/lib/getuser.S112
-rw-r--r--arch/arm26/lib/io-acorn.S71
-rw-r--r--arch/arm26/lib/io-readsb.S116
-rw-r--r--arch/arm26/lib/io-readsl.S78
-rw-r--r--arch/arm26/lib/io-readsw.S107
-rw-r--r--arch/arm26/lib/io-writesb.S122
-rw-r--r--arch/arm26/lib/io-writesl.S56
-rw-r--r--arch/arm26/lib/io-writesw.S127
-rw-r--r--arch/arm26/lib/kbd.c279
-rw-r--r--arch/arm26/lib/lib1funcs.S314
-rw-r--r--arch/arm26/lib/longlong.h184
-rw-r--r--arch/arm26/lib/lshrdi3.c61
-rw-r--r--arch/arm26/lib/memchr.S25
-rw-r--r--arch/arm26/lib/memcpy.S318
-rw-r--r--arch/arm26/lib/memset.S80
-rw-r--r--arch/arm26/lib/memzero.S80
-rw-r--r--arch/arm26/lib/muldi3.c77
-rw-r--r--arch/arm26/lib/putuser.S109
-rw-r--r--arch/arm26/lib/setbit.S29
-rw-r--r--arch/arm26/lib/strchr.S25
-rw-r--r--arch/arm26/lib/strrchr.S25
-rw-r--r--arch/arm26/lib/testchangebit.S29
-rw-r--r--arch/arm26/lib/testclearbit.S29
-rw-r--r--arch/arm26/lib/testsetbit.S29
-rw-r--r--arch/arm26/lib/uaccess-kernel.S173
-rw-r--r--arch/arm26/lib/uaccess-user.S718
-rw-r--r--arch/arm26/lib/ucmpdi2.c51
-rw-r--r--arch/arm26/lib/udivdi3.c242
45 files changed, 4979 insertions, 0 deletions
diff --git a/arch/arm26/lib/Makefile b/arch/arm26/lib/Makefile
new file mode 100644
index 00000000000..6df2b793d36
--- /dev/null
+++ b/arch/arm26/lib/Makefile
@@ -0,0 +1,26 @@
+#
+# linux/arch/arm26/lib/Makefile
+#
+# Copyright (C) 1995-2000 Russell King
+#
+
+lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
+ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
+ copy_page.o delay.o findbit.o memchr.o memcpy.o \
+ memset.o memzero.o setbit.o \
+ strchr.o strrchr.o testchangebit.o \
+ testclearbit.o testsetbit.o getuser.o \
+ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
+ ucmpdi2.o udivdi3.o lib1funcs.o ecard.o io-acorn.o \
+ floppydma.o io-readsb.o io-writesb.o io-writesl.o \
+ uaccess-kernel.o uaccess-user.o io-readsw.o \
+ io-writesw.o io-readsl.o ecard.o io-acorn.o \
+ floppydma.o
+
+lib-n :=
+
+lib-$(CONFIG_VT)+= kbd.o
+
+csumpartialcopy.o: csumpartialcopygeneric.S
+csumpartialcopyuser.o: csumpartialcopygeneric.S
+
diff --git a/arch/arm26/lib/ashldi3.c b/arch/arm26/lib/ashldi3.c
new file mode 100644
index 00000000000..130f5a83966
--- /dev/null
+++ b/arch/arm26/lib/ashldi3.c
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+
+DItype
+__ashldi3 (DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ w.s.low = 0;
+ w.s.high = (USItype)uu.s.low << -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.low >> bm;
+ w.s.low = (USItype)uu.s.low << b;
+ w.s.high = ((USItype)uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
+
diff --git a/arch/arm26/lib/ashrdi3.c b/arch/arm26/lib/ashrdi3.c
new file mode 100644
index 00000000000..71625d218f8
--- /dev/null
+++ b/arch/arm26/lib/ashrdi3.c
@@ -0,0 +1,61 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License.
+ */
+/* support functions required by the kernel. based on code from gcc-2.95.3 */
+/* I Molton 29/07/01 */
+
+#include "gcclib.h"
+
+DItype
+__ashrdi3 (DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+ w.s.low = uu.s.high >> -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.high << bm;
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((USItype)uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/arm26/lib/backtrace.S b/arch/arm26/lib/backtrace.S
new file mode 100644
index 00000000000..d793fe4339f
--- /dev/null
+++ b/arch/arm26/lib/backtrace.S
@@ -0,0 +1,145 @@
+/*
+ * linux/arch/arm26/lib/backtrace.S
+ *
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+@ fp is 0 or stack frame
+
+#define frame r4
+#define next r5
+#define save r6
+#define mask r7
+#define offset r8
+
+ENTRY(__backtrace)
+ mov r1, #0x10
+ mov r0, fp
+
+ENTRY(c_backtrace)
+
+#ifdef CONFIG_NO_FRAME_POINTER
+ mov pc, lr
+#else
+
+ stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...
+ mov mask, #0xfc000003
+ tst mask, r0
+ movne r0, #0
+ movs frame, r0
+1: moveq r0, #-2
+ LOADREGS(eqfd, sp!, {r4 - r8, pc})
+
+2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction
+ ldr r0, [sp], #4
+ adr r1, 2b - 4
+ sub offset, r0, r1
+
+3: tst frame, mask @ Check for address exceptions...
+ bne 1b
+
+1001: ldr next, [frame, #-12] @ get fp
+1002: ldr r2, [frame, #-4] @ get lr
+1003: ldr r3, [frame, #0] @ get pc
+ sub save, r3, offset @ Correct PC for prefetching
+ bic save, save, mask
+1004: ldr r1, [save, #0] @ get instruction at function
+ mov r1, r1, lsr #10
+ ldr r3, .Ldsi+4
+ teq r1, r3
+ subeq save, save, #4
+ adr r0, .Lfe
+ mov r1, save
+ bic r2, r2, mask
+ bl printk @ print pc and link register
+
+ ldr r0, [frame, #-8] @ get sp
+ sub r0, r0, #4
+1005: ldr r1, [save, #4] @ get instruction at function+4
+ mov r3, r1, lsr #10
+ ldr r2, .Ldsi+4
+ teq r3, r2 @ Check for stmia sp!, {args}
+ addeq save, save, #4 @ next instruction
+ bleq .Ldumpstm
+
+ sub r0, frame, #16
+1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
+ mov r3, r1, lsr #10
+ ldr r2, .Ldsi
+ teq r3, r2
+ bleq .Ldumpstm
+
+ teq frame, next
+ movne frame, next
+ teqne frame, #0
+ bne 3b
+ LOADREGS(fd, sp!, {r4 - r8, pc})
+
+/*
+ * Fixup for LDMDB
+ */
+ .section .fixup,"ax"
+ .align 0
+1007: ldr r0, =.Lbad
+ mov r1, frame
+ bl printk
+ LOADREGS(fd, sp!, {r4 - r8, pc})
+ .ltorg
+ .previous
+
+ .section __ex_table,"a"
+ .align 3
+ .long 1001b, 1007b
+ .long 1002b, 1007b
+ .long 1003b, 1007b
+ .long 1004b, 1007b
+ .long 1005b, 1007b
+ .long 1006b, 1007b
+ .previous
+
+#define instr r4
+#define reg r5
+#define stack r6
+
+.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr}
+ mov stack, r0
+ mov instr, r1
+ mov reg, #9
+ mov r7, #0
+1: mov r3, #1
+ tst instr, r3, lsl reg
+ beq 2f
+ add r7, r7, #1
+ teq r7, #4
+ moveq r7, #0
+ moveq r3, #'\n'
+ movne r3, #' '
+ ldr r2, [stack], #-4
+ mov r1, reg
+ adr r0, .Lfp
+ bl printk
+2: subs reg, reg, #1
+ bpl 1b
+ teq r7, #0
+ adrne r0, .Lcr
+ blne printk
+ mov r0, stack
+ LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})
+
+.Lfe: .asciz "Function entered at [<%p>] from [<%p>]\n"
+.Lfp: .asciz " r%d = %08X%c"
+.Lcr: .asciz "\n"
+.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
+ .align
+.Ldsi: .word 0x00e92dd8 >> 2
+ .word 0x00e92d00 >> 2
+
+#endif
diff --git a/arch/arm26/lib/changebit.S b/arch/arm26/lib/changebit.S
new file mode 100644
index 00000000000..1b6a077be5a
--- /dev/null
+++ b/arch/arm26/lib/changebit.S
@@ -0,0 +1,28 @@
+/*
+ * linux/arch/arm26/lib/changebit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+/* Purpose : Function to change a bit
+ * Prototype: int change_bit(int bit, void *addr)
+ */
+ENTRY(_change_bit_be)
+ eor r0, r0, #0x18 @ big endian byte ordering
+ENTRY(_change_bit_le)
+ and r2, r0, #7
+ mov r3, #1
+ mov r3, r3, lsl r2
+ save_and_disable_irqs ip, r2
+ ldrb r2, [r1, r0, lsr #3]
+ eor r2, r2, r3
+ strb r2, [r1, r0, lsr #3]
+ restore_irqs ip
+ RETINSTR(mov,pc,lr)
diff --git a/arch/arm26/lib/clearbit.S b/arch/arm26/lib/clearbit.S
new file mode 100644
index 00000000000..0a895b0c759
--- /dev/null
+++ b/arch/arm26/lib/clearbit.S
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm26/lib/clearbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+/*
+ * Purpose : Function to clear a bit
+ * Prototype: int clear_bit(int bit, void *addr)
+ */
+ENTRY(_clear_bit_be)
+ eor r0, r0, #0x18 @ big endian byte ordering
+ENTRY(_clear_bit_le)
+ and r2, r0, #7
+ mov r3, #1
+ mov r3, r3, lsl r2
+ save_and_disable_irqs ip, r2
+ ldrb r2, [r1, r0, lsr #3]
+ bic r2, r2, r3
+ strb r2, [r1, r0, lsr #3]
+ restore_irqs ip
+ RETINSTR(mov,pc,lr)
+
+
diff --git a/arch/arm26/lib/copy_page.S b/arch/arm26/lib/copy_page.S
new file mode 100644
index 00000000000..2d79ee12ea1
--- /dev/null
+++ b/arch/arm26/lib/copy_page.S
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/arm26/lib/copypage.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/asm_offsets.h>
+
+ .text
+ .align 5
+/*
+ * ARMv3 optimised copy_user_page
+ *
+ * FIXME: rmk do we need to handle cache stuff...
+ * FIXME: im is this right on ARM26?
+ */
+ENTRY(__copy_user_page)
+ stmfd sp!, {r4, lr} @ 2
+ mov r2, #PAGE_SZ/64 @ 1
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+1: stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4
+ subs r2, r2, #1 @ 1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmneia r1!, {r3, r4, ip, lr} @ 4
+ bne 1b @ 1
+ LOADREGS(fd, sp!, {r4, pc}) @ 3
+
+ .align 5
+/*
+ * ARMv3 optimised clear_user_page
+ *
+ * FIXME: rmk do we need to handle cache stuff...
+ */
+ENTRY(__clear_user_page)
+ str lr, [sp, #-4]!
+ mov r1, #PAGE_SZ/64 @ 1
+ mov r2, #0 @ 1
+ mov r3, #0 @ 1
+ mov ip, #0 @ 1
+ mov lr, #0 @ 1
+1: stmia r0!, {r2, r3, ip, lr} @ 4
+ stmia r0!, {r2, r3, ip, lr} @ 4
+ stmia r0!, {r2, r3, ip, lr} @ 4
+ stmia r0!, {r2, r3, ip, lr} @ 4
+ subs r1, r1, #1 @ 1
+ bne 1b @ 1
+ ldr pc, [sp], #4
+
+ .section ".init.text", #alloc, #execinstr
+
diff --git a/arch/arm26/lib/csumipv6.S b/arch/arm26/lib/csumipv6.S
new file mode 100644
index 00000000000..62831155acd
--- /dev/null
+++ b/arch/arm26/lib/csumipv6.S
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/arm26/lib/csumipv6.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+ENTRY(__csum_ipv6_magic)
+ str lr, [sp, #-4]!
+ adds ip, r2, r3
+ ldmia r1, {r1 - r3, lr}
+ adcs ip, ip, r1
+ adcs ip, ip, r2
+ adcs ip, ip, r3
+ adcs ip, ip, lr
+ ldmia r0, {r0 - r3}
+ adcs r0, ip, r0
+ adcs r0, r0, r1
+ adcs r0, r0, r2
+ ldr r2, [sp, #4]
+ adcs r0, r0, r3
+ adcs r0, r0, r2
+ adcs r0, r0, #0
+ LOADREGS(fd, sp!, {pc})
+
diff --git a/arch/arm26/lib/csumpartial.S b/arch/arm26/lib/csumpartial.S
new file mode 100644
index 00000000000..e53e7109e62
--- /dev/null
+++ b/arch/arm26/lib/csumpartial.S
@@ -0,0 +1,130 @@
+/*
+ * linux/arch/arm26/lib/csumpartial.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+/*
+ * Function: __u32 csum_partial(const char *src, int len, __u32 sum)
+ * Params : r0 = buffer, r1 = len, r2 = checksum
+ * Returns : r0 = new checksum
+ */
+
+buf .req r0
+len .req r1
+sum .req r2
+td0 .req r3
+td1 .req r4 @ save before use
+td2 .req r5 @ save before use
+td3 .req lr
+
+.zero: mov r0, sum
+ add sp, sp, #4
+ ldr pc, [sp], #4
+
+ /*
+ * Handle 0 to 7 bytes, with any alignment of source and
+ * destination pointers. Note that when we get here, C = 0
+ */
+.less8: teq len, #0 @ check for zero count
+ beq .zero
+
+ /* we must have at least one byte. */
+ tst buf, #1 @ odd address?
+ ldrneb td0, [buf], #1
+ subne len, len, #1
+ adcnes sum, sum, td0, lsl #byte(1)
+
+.less4: tst len, #6
+ beq .less8_byte
+
+ /* we are now half-word aligned */
+
+.less8_wordlp:
+#if __LINUX_ARM_ARCH__ >= 4
+ ldrh td0, [buf], #2
+ sub len, len, #2
+#else
+ ldrb td0, [buf], #1
+ ldrb td3, [buf], #1
+ sub len, len, #2
+ orr td0, td0, td3, lsl #8
+#endif
+ adcs sum, sum, td0
+ tst len, #6
+ bne .less8_wordlp
+
+.less8_byte: tst len, #1 @ odd number of bytes
+ ldrneb td0, [buf], #1 @ include last byte
+ adcnes sum, sum, td0, lsl #byte(0) @ update checksum
+
+.done: adc r0, sum, #0 @ collect up the last carry
+ ldr td0, [sp], #4
+ tst td0, #1 @ check buffer alignment
+ movne td0, r0, lsl #8 @ rotate checksum by 8 bits
+ orrne r0, td0, r0, lsr #24
+ ldr pc, [sp], #4 @ return
+
+.not_aligned: tst buf, #1 @ odd address
+ ldrneb td0, [buf], #1 @ make even
+ subne len, len, #1
+ adcnes sum, sum, td0, lsl #byte(1) @ update checksum
+
+ tst buf, #2 @ 32-bit aligned?
+#if __LINUX_ARM_ARCH__ >= 4
+ ldrneh td0, [buf], #2 @ make 32-bit aligned
+ subne len, len, #2
+#else
+ ldrneb td0, [buf], #1
+ ldrneb ip, [buf], #1
+ subne len, len, #2
+ orrne td0, td0, ip, lsl #8
+#endif
+ adcnes sum, sum, td0 @ update checksum
+ mov pc, lr
+
+ENTRY(csum_partial)
+ stmfd sp!, {buf, lr}
+ cmp len, #8 @ Ensure that we have at least
+ blo .less8 @ 8 bytes to copy.
+
+ adds sum, sum, #0 @ C = 0
+ tst buf, #3 @ Test destination alignment
+ blne .not_aligned @ aligh destination, return here
+
+1: bics ip, len, #31
+ beq 3f
+
+ stmfd sp!, {r4 - r5}
+2: ldmia buf!, {td0, td1, td2, td3}
+ adcs sum, sum, td0
+ adcs sum, sum, td1
+ adcs sum, sum, td2
+ adcs sum, sum, td3
+ ldmia buf!, {td0, td1, td2, td3}
+ adcs sum, sum, td0
+ adcs sum, sum, td1
+ adcs sum, sum, td2
+ adcs sum, sum, td3
+ sub ip, ip, #32
+ teq ip, #0
+ bne 2b
+ ldmfd sp!, {r4 - r5}
+
+3: tst len, #0x1c @ should not change C
+ beq .less4
+
+4: ldr td0, [buf], #4
+ sub len, len, #4
+ adcs sum, sum, td0
+ tst len, #0x1c
+ bne 4b
+ b .less4
diff --git a/arch/arm26/lib/csumpartialcopy.S b/arch/arm26/lib/csumpartialcopy.S
new file mode 100644
index 00000000000..a1c4b5fdd49
--- /dev/null
+++ b/arch/arm26/lib/csumpartialcopy.S
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/arm26/lib/csumpartialcopy.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len, __u32 sum)
+ * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum
+ * Returns : r0 = new checksum
+ */
+
+ .macro save_regs
+ stmfd sp!, {r1, r4 - r8, fp, ip, lr, pc}
+ .endm
+
+ .macro load_regs,flags
+ LOADREGS(\flags,fp,{r1, r4 - r8, fp, sp, pc})
+ .endm
+
+ .macro load1b, reg1
+ ldrb \reg1, [r0], #1
+ .endm
+
+ .macro load2b, reg1, reg2
+ ldrb \reg1, [r0], #1
+ ldrb \reg2, [r0], #1
+ .endm
+
+ .macro load1l, reg1
+ ldr \reg1, [r0], #4
+ .endm
+
+ .macro load2l, reg1, reg2
+ ldr \reg1, [r0], #4
+ ldr \reg2, [r0], #4
+ .endm
+
+ .macro load4l, reg1, reg2, reg3, reg4
+ ldmia r0!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
+#define FN_ENTRY ENTRY(csum_partial_copy_nocheck)
+
+#include "csumpartialcopygeneric.S"
diff --git a/arch/arm26/lib/csumpartialcopygeneric.S b/arch/arm26/lib/csumpartialcopygeneric.S
new file mode 100644
index 00000000000..5249c3ad11d
--- /dev/null
+++ b/arch/arm26/lib/csumpartialcopygeneric.S
@@ -0,0 +1,352 @@
+/*
+ * linux/arch/arm26/lib/csumpartialcopygeneric.S
+ *
+ * Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * JMA 01/06/03 Commented out some shl0s; probobly irrelevant to arm26
+ *
+ */
+
+/*
+ * unsigned int
+ * csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, )
+ * r0 = src, r1 = dst, r2 = len, r3 = sum
+ * Returns : r0 = checksum
+ *
+ * Note that 'tst' and 'teq' preserve the carry flag.
+ */
+
+/* Quick hack */
+ .macro save_regs
+ stmfd sp!, {r1, r4 - r8, fp, ip, lr, pc}
+ .endm
+
+/* end Quick Hack */
+
+src .req r0
+dst .req r1
+len .req r2
+sum .req r3
+
+.zero: mov r0, sum
+ load_regs ea
+
+ /*
+ * Align an unaligned destination pointer. We know that
+ * we have >= 8 bytes here, so we don't need to check
+ * the length. Note that the source pointer hasn't been
+ * aligned yet.
+ */
+.dst_unaligned: tst dst, #1
+ beq .dst_16bit
+
+ load1b ip
+ sub len, len, #1
+ adcs sum, sum, ip, lsl #byte(1) @ update checksum
+ strb ip, [dst], #1
+ tst dst, #2
+ moveq pc, lr @ dst is now 32bit aligned
+
+.dst_16bit: load2b r8, ip
+ sub len, len, #2
+ adcs sum, sum, r8, lsl #byte(0)
+ strb r8, [dst], #1
+ adcs sum, sum, ip, lsl #byte(1)
+ strb ip, [dst], #1
+ mov pc, lr @ dst is now 32bit aligned
+
+ /*
+ * Handle 0 to 7 bytes, with any alignment of source and
+ * destination pointers. Note that when we get here, C = 0
+ */
+.less8: teq len, #0 @ check for zero count
+ beq .zero
+
+ /* we must have at least one byte. */
+ tst dst, #1 @ dst 16-bit aligned
+ beq .less8_aligned
+
+ /* Align dst */
+ load1b ip
+ sub len, len, #1
+ adcs sum, sum, ip, lsl #byte(1) @ update checksum
+ strb ip, [dst], #1
+ tst len, #6
+ beq .less8_byteonly
+
+1: load2b r8, ip
+ sub len, len, #2
+ adcs sum, sum, r8, lsl #byte(0)
+ strb r8, [dst], #1
+ adcs sum, sum, ip, lsl #byte(1)
+ strb ip, [dst], #1
+.less8_aligned: tst len, #6
+ bne 1b
+.less8_byteonly:
+ tst len, #1
+ beq .done
+ load1b r8
+ adcs sum, sum, r8, lsl #byte(0) @ update checksum
+ strb r8, [dst], #1
+ b .done
+
+FN_ENTRY
+ mov ip, sp
+ save_regs
+ sub fp, ip, #4
+
+ cmp len, #8 @ Ensure that we have at least
+ blo .less8 @ 8 bytes to copy.
+
+ adds sum, sum, #0 @ C = 0
+ tst dst, #3 @ Test destination alignment
+ blne .dst_unaligned @ align destination, return here
+
+ /*
+ * Ok, the dst pointer is now 32bit aligned, and we know
+ * that we must have more than 4 bytes to copy. Note
+ * that C contains the carry from the dst alignment above.
+ */
+
+ tst src, #3 @ Test source alignment
+ bne .src_not_aligned
+
+ /* Routine for src & dst aligned */
+
+ bics ip, len, #15
+ beq 2f
+
+1: load4l r4, r5, r6, r7
+ stmia dst!, {r4, r5, r6, r7}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ adcs sum, sum, r6
+ adcs sum, sum, r7
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+
+2: ands ip, len, #12
+ beq 4f
+ tst ip, #8
+ beq 3f
+ load2l r4, r5
+ stmia dst!, {r4, r5}</