diff options
Diffstat (limited to 'arch/microblaze/lib')
-rw-r--r-- | arch/microblaze/lib/Makefile | 3 | ||||
-rw-r--r-- | arch/microblaze/lib/checksum.c | 31 | ||||
-rw-r--r-- | arch/microblaze/lib/memcpy.c | 5 | ||||
-rw-r--r-- | arch/microblaze/lib/uaccess_old.S | 135 |
4 files changed, 157 insertions, 17 deletions
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index d27126bf306a..71c8cb6c9e43 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -10,4 +10,5 @@ else lib-y += memcpy.o memmove.o endif -lib-y += uaccess.o +lib-$(CONFIG_NO_MMU) += uaccess.o +lib-$(CONFIG_MMU) += uaccess_old.o diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c index 809340070a13..f08e74591418 100644 --- a/arch/microblaze/lib/checksum.c +++ b/arch/microblaze/lib/checksum.c @@ -32,9 +32,10 @@ /* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most of the assembly has to go. */ -#include <net/checksum.h> -#include <asm/checksum.h> #include <linux/module.h> +#include <net/checksum.h> + +#include <asm/byteorder.h> static inline unsigned short from32to16(unsigned long x) { @@ -102,6 +103,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { return (__force __sum16)~do_csum(iph, ihl*4); } +EXPORT_SYMBOL(ip_fast_csum); /* * computes the checksum of a memory block at buff, length len, @@ -115,15 +117,16 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) * * it's best to have buff aligned on a 32-bit boundary */ -__wsum csum_partial(const void *buff, int len, __wsum sum) +__wsum csum_partial(const void *buff, int len, __wsum wsum) { + unsigned int sum = (__force unsigned int)wsum; unsigned int result = do_csum(buff, len); /* add in old sum, and carry.. */ result += sum; if (sum > result) result += 1; - return result; + return (__force __wsum)result; } EXPORT_SYMBOL(csum_partial); @@ -131,9 +134,9 @@ EXPORT_SYMBOL(csum_partial); * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -__sum16 ip_compute_csum(const unsigned char *buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { - return ~do_csum(buff, len); + return (__force __sum16)~do_csum(buff, len); } EXPORT_SYMBOL(ip_compute_csum); @@ -141,12 +144,18 @@ EXPORT_SYMBOL(ip_compute_csum); * copy from fs while checksumming, otherwise like csum_partial */ __wsum -csum_partial_copy_from_user(const char __user *src, char *dst, int len, - int sum, int *csum_err) +csum_partial_copy_from_user(const void __user *src, void *dst, int len, + __wsum sum, int *csum_err) { - if (csum_err) + int missing; + + missing = __copy_from_user(dst, src, len); + if (missing) { + memset(dst + len - missing, 0, missing); + *csum_err = -EFAULT; + } else *csum_err = 0; - memcpy(dst, src, len); + return csum_partial(dst, len, sum); } EXPORT_SYMBOL(csum_partial_copy_from_user); @@ -155,7 +164,7 @@ EXPORT_SYMBOL(csum_partial_copy_from_user); * copy from ds while checksumming, otherwise like csum_partial */ __wsum -csum_partial_copy(const char *src, char *dst, int len, int sum) +csum_partial_copy(const void *src, void *dst, int len, __wsum sum) { memcpy(dst, src, len); return csum_partial(dst, len, sum); diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c index 5880119c4487..6a907c58a4bc 100644 --- a/arch/microblaze/lib/memcpy.c +++ b/arch/microblaze/lib/memcpy.c @@ -154,8 +154,3 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) } EXPORT_SYMBOL(memcpy); #endif /* __HAVE_ARCH_MEMCPY */ - -void *cacheable_memcpy(void *d, const void *s, __kernel_size_t c) -{ - return memcpy(d, s, c); -} diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S new file mode 100644 index 000000000000..67f991c14b8a --- /dev/null +++ b/arch/microblaze/lib/uaccess_old.S @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2009 PetaLogix + * Copyright (C) 2007 LynuxWorks, Inc. + * + * 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/errno.h> +#include <linux/linkage.h> + +/* + * int __strncpy_user(char *to, char *from, int len); + * + * Returns: + * -EFAULT for an exception + * len if we hit the buffer limit + * bytes copied + */ + + .text +.globl __strncpy_user; +.align 4; +__strncpy_user: + + /* + * r5 - to + * r6 - from + * r7 - len + * r3 - temp count + * r4 - temp val + */ + addik r3,r7,0 /* temp_count = len */ + beqi r3,3f +1: + lbu r4,r6,r0 + sb r4,r5,r0 + + addik r3,r3,-1 + beqi r3,2f /* break on len */ + + addik r5,r5,1 + bneid r4,1b + addik r6,r6,1 /* delay slot */ + addik r3,r3,1 /* undo "temp_count--" */ +2: + rsubk r3,r3,r7 /* temp_count = len - temp_count */ +3: + rtsd r15,8 + nop + + + .section .fixup, "ax" + .align 2 +4: + brid 3b + addik r3,r0, -EFAULT + + .section __ex_table, "a" + .word 1b,4b + +/* + * int __strnlen_user(char __user *str, int maxlen); + * + * Returns: + * 0 on error + * maxlen + 1 if no NUL byte found within maxlen bytes + * size of the string (including NUL byte) + */ + + .text +.globl __strnlen_user; +.align 4; +__strnlen_user: + addik r3,r6,0 + beqi r3,3f +1: + lbu r4,r5,r0 + beqid r4,2f /* break on NUL */ + addik r3,r3,-1 /* delay slot */ + + bneid r3,1b + addik r5,r5,1 /* delay slot */ + + addik r3,r3,-1 /* for break on len */ +2: + rsubk r3,r3,r6 +3: + rtsd r15,8 + nop + + + .section .fixup,"ax" +4: + brid 3b + addk r3,r0,r0 + + .section __ex_table,"a" + .word 1b,4b + +/* + * int __copy_tofrom_user(char *to, char *from, int len) + * Return: + * 0 on success + * number of not copied bytes on error + */ + .text +.globl __copy_tofrom_user; +.align 4; +__copy_tofrom_user: + /* + * r5 - to + * r6 - from + * r7, r3 - count + * r4 - tempval + */ + addik r3,r7,0 + beqi r3,3f +1: + lbu r4,r6,r0 + addik r6,r6,1 +2: + sb r4,r5,r0 + addik r3,r3,-1 + bneid r3,1b + addik r5,r5,1 /* delay slot */ +3: + rtsd r15,8 + nop + + + .section __ex_table,"a" + .word 1b,3b,2b,3b |