aboutsummaryrefslogtreecommitdiff
path: root/arch/frv/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv/lib')
-rw-r--r--arch/frv/lib/Makefile4
-rw-r--r--arch/frv/lib/__ucmpdi2.S45
-rw-r--r--arch/frv/lib/atomic-ops.S97
-rw-r--r--arch/frv/lib/atomic64-ops.S162
-rw-r--r--arch/frv/lib/cache.S2
-rw-r--r--arch/frv/lib/checksum.c48
6 files changed, 245 insertions, 113 deletions
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
index 19be2626d5e..4ff2fb1e6b1 100644
--- a/arch/frv/lib/Makefile
+++ b/arch/frv/lib/Makefile
@@ -3,6 +3,6 @@
#
lib-y := \
- __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \
- checksum.o memcpy.o memset.o atomic-ops.o \
+ __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \
+ checksum.o memcpy.o memset.o atomic-ops.o atomic64-ops.o \
outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o
diff --git a/arch/frv/lib/__ucmpdi2.S b/arch/frv/lib/__ucmpdi2.S
new file mode 100644
index 00000000000..d892f16ffaa
--- /dev/null
+++ b/arch/frv/lib/__ucmpdi2.S
@@ -0,0 +1,45 @@
+/* __ucmpdi2.S: 64-bit unsigned compare
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program 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 of the License, or (at your option) any later version.
+ */
+
+
+ .text
+ .p2align 4
+
+###############################################################################
+#
+# int __ucmpdi2(unsigned long long a [GR8:GR9],
+# unsigned long long b [GR10:GR11])
+#
+# - returns 0, 1, or 2 as a <, =, > b respectively.
+#
+###############################################################################
+ .globl __ucmpdi2
+ .type __ucmpdi2,@function
+__ucmpdi2:
+ or.p gr8,gr0,gr4
+ subcc gr8,gr10,gr0,icc0
+ setlos.p #0,gr8
+ bclr icc0,#2 ; a.msw < b.msw
+
+ setlos.p #2,gr8
+ bhilr icc0,#0 ; a.msw > b.msw
+
+ subcc.p gr9,gr11,gr0,icc1
+ setlos #0,gr8
+ setlos.p #2,gr9
+ setlos #1,gr7
+ cknc icc1,cc6
+ cor.p gr9,gr0,gr8, cc6,#1
+ cckls icc1,cc4, cc6,#1
+ andcr cc6,cc4,cc4
+ cor gr7,gr0,gr8, cc4,#1
+ bralr
+ .size __ucmpdi2, .-__ucmpdi2
diff --git a/arch/frv/lib/atomic-ops.S b/arch/frv/lib/atomic-ops.S
index b03d510a89e..5e9e6ab5dd0 100644
--- a/arch/frv/lib/atomic-ops.S
+++ b/arch/frv/lib/atomic-ops.S
@@ -1,7 +1,7 @@
/* atomic-ops.S: kernel atomic operations
*
* For an explanation of how atomic ops work in this arch, see:
- * Documentation/fujitsu/frv/atomic-ops.txt
+ * Documentation/frv/atomic-ops.txt
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
@@ -129,48 +129,6 @@ atomic_sub_return:
###############################################################################
#
-# uint8_t __xchg_8(uint8_t i, uint8_t *v)
-#
-###############################################################################
- .globl __xchg_8
- .type __xchg_8,@function
-__xchg_8:
- or.p gr8,gr8,gr10
-0:
- orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
- ckeq icc3,cc7
- ldub.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
- orcr cc7,cc7,cc3 /* set CC3 to true */
- cstb.p gr10,@(gr9,gr0) ,cc3,#1
- corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
- beq icc3,#0,0b
- bralr
-
- .size __xchg_8, .-__xchg_8
-
-###############################################################################
-#
-# uint16_t __xchg_16(uint16_t i, uint16_t *v)
-#
-###############################################################################
- .globl __xchg_16
- .type __xchg_16,@function
-__xchg_16:
- or.p gr8,gr8,gr10
-0:
- orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
- ckeq icc3,cc7
- lduh.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */
- orcr cc7,cc7,cc3 /* set CC3 to true */
- csth.p gr10,@(gr9,gr0) ,cc3,#1
- corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
- beq icc3,#0,0b
- bralr
-
- .size __xchg_16, .-__xchg_16
-
-###############################################################################
-#
# uint32_t __xchg_32(uint32_t i, uint32_t *v)
#
###############################################################################
@@ -192,56 +150,6 @@ __xchg_32:
###############################################################################
#
-# uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new)
-#
-###############################################################################
- .globl __cmpxchg_8
- .type __cmpxchg_8,@function
-__cmpxchg_8:
- or.p gr8,gr8,gr11
-0:
- orcc gr0,gr0,gr0,icc3
- ckeq icc3,cc7
- ldub.p @(gr11,gr0),gr8
- orcr cc7,cc7,cc3
- sub gr8,gr9,gr7
- sllicc gr7,#24,gr0,icc0
- bne icc0,#0,1f
- cstb.p gr10,@(gr11,gr0) ,cc3,#1
- corcc gr29,gr29,gr0 ,cc3,#1
- beq icc3,#0,0b
-1:
- bralr
-
- .size __cmpxchg_8, .-__cmpxchg_8
-
-###############################################################################
-#
-# uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new)
-#
-###############################################################################
- .globl __cmpxchg_16
- .type __cmpxchg_16,@function
-__cmpxchg_16:
- or.p gr8,gr8,gr11
-0:
- orcc gr0,gr0,gr0,icc3
- ckeq icc3,cc7
- lduh.p @(gr11,gr0),gr8
- orcr cc7,cc7,cc3
- sub gr8,gr9,gr7
- sllicc gr7,#16,gr0,icc0
- bne icc0,#0,1f
- csth.p gr10,@(gr11,gr0) ,cc3,#1
- corcc gr29,gr29,gr0 ,cc3,#1
- beq icc3,#0,0b
-1:
- bralr
-
- .size __cmpxchg_16, .-__cmpxchg_16
-
-###############################################################################
-#
# uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new)
#
###############################################################################
@@ -255,11 +163,10 @@ __cmpxchg_32:
ld.p @(gr11,gr0),gr8
orcr cc7,cc7,cc3
subcc gr8,gr9,gr7,icc0
- bne icc0,#0,1f
+ bnelr icc0,#0
cst.p gr10,@(gr11,gr0) ,cc3,#1
corcc gr29,gr29,gr0 ,cc3,#1
beq icc3,#0,0b
-1:
bralr
.size __cmpxchg_32, .-__cmpxchg_32
diff --git a/arch/frv/lib/atomic64-ops.S b/arch/frv/lib/atomic64-ops.S
new file mode 100644
index 00000000000..b6194eeac12
--- /dev/null
+++ b/arch/frv/lib/atomic64-ops.S
@@ -0,0 +1,162 @@
+/* kernel atomic64 operations
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ * Documentation/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program 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 of the License, or (at your option) any later version.
+ */
+
+#include <asm/spr-regs.h>
+
+ .text
+ .balign 4
+
+
+###############################################################################
+#
+# long long atomic64_inc_return(atomic64_t *v)
+#
+###############################################################################
+ .globl atomic64_inc_return
+ .type atomic64_inc_return,@function
+atomic64_inc_return:
+ or.p gr8,gr8,gr10
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ addicc gr9,#1,gr9,icc0
+ addxi gr8,#0,gr8,icc0
+ cstd.p gr8,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size atomic64_inc_return, .-atomic64_inc_return
+
+###############################################################################
+#
+# long long atomic64_dec_return(atomic64_t *v)
+#
+###############################################################################
+ .globl atomic64_dec_return
+ .type atomic64_dec_return,@function
+atomic64_dec_return:
+ or.p gr8,gr8,gr10
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ subicc gr9,#1,gr9,icc0
+ subxi gr8,#0,gr8,icc0
+ cstd.p gr8,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size atomic64_dec_return, .-atomic64_dec_return
+
+###############################################################################
+#
+# long long atomic64_add_return(long long i, atomic64_t *v)
+#
+###############################################################################
+ .globl atomic64_add_return
+ .type atomic64_add_return,@function
+atomic64_add_return:
+ or.p gr8,gr8,gr4
+ or gr9,gr9,gr5
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ addcc gr9,gr5,gr9,icc0
+ addx gr8,gr4,gr8,icc0
+ cstd.p gr8,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size atomic64_add_return, .-atomic64_add_return
+
+###############################################################################
+#
+# long long atomic64_sub_return(long long i, atomic64_t *v)
+#
+###############################################################################
+ .globl atomic64_sub_return
+ .type atomic64_sub_return,@function
+atomic64_sub_return:
+ or.p gr8,gr8,gr4
+ or gr9,gr9,gr5
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ subcc gr9,gr5,gr9,icc0
+ subx gr8,gr4,gr8,icc0
+ cstd.p gr8,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size atomic64_sub_return, .-atomic64_sub_return
+
+###############################################################################
+#
+# uint64_t __xchg_64(uint64_t i, uint64_t *v)
+#
+###############################################################################
+ .globl __xchg_64
+ .type __xchg_64,@function
+__xchg_64:
+ or.p gr8,gr8,gr4
+ or gr9,gr9,gr5
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ cstd.p gr4,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size __xchg_64, .-__xchg_64
+
+###############################################################################
+#
+# uint64_t __cmpxchg_64(uint64_t test, uint64_t new, uint64_t *v)
+#
+###############################################################################
+ .globl __cmpxchg_64
+ .type __cmpxchg_64,@function
+__cmpxchg_64:
+ or.p gr8,gr8,gr4
+ or gr9,gr9,gr5
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr12,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3
+ subcc gr8,gr4,gr0,icc0
+ subcc.p gr9,gr5,gr0,icc1
+ bnelr icc0,#0
+ bnelr icc1,#0
+ cstd.p gr10,@(gr12,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size __cmpxchg_64, .-__cmpxchg_64
+
diff --git a/arch/frv/lib/cache.S b/arch/frv/lib/cache.S
index 0e10ad8dc46..0c4fb204911 100644
--- a/arch/frv/lib/cache.S
+++ b/arch/frv/lib/cache.S
@@ -1,4 +1,4 @@
-/* cache.S: cache managment routines
+/* cache.S: cache management routines
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c
index 7bf5bd6cac8..44e16d59bc1 100644
--- a/arch/frv/lib/checksum.c
+++ b/arch/frv/lib/checksum.c
@@ -32,7 +32,7 @@
of the assembly has to go. */
#include <net/checksum.h>
-#include <asm/checksum.h>
+#include <linux/module.h>
static inline unsigned short from32to16(unsigned long x)
{
@@ -104,45 +104,63 @@ out:
*
* it's best to have buff aligned on a 32-bit boundary
*/
-unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+__wsum csum_partial(const void *buff, int len, __wsum sum)
{
unsigned int result = do_csum(buff, len);
/* add in old sum, and carry.. */
- result += sum;
- if (sum > result)
+ result += (__force u32)sum;
+ if ((__force u32)sum > result)
result += 1;
- return result;
+ return (__force __wsum)result;
}
+EXPORT_SYMBOL(csum_partial);
+
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
-unsigned short 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);
+
/*
* copy from fs while checksumming, otherwise like csum_partial
*/
-
-unsigned int
-csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+__wsum
+csum_partial_copy_from_user(const void __user *src, void *dst,
+ int len, __wsum sum, int *csum_err)
{
- if (csum_err) *csum_err = 0;
- memcpy(dst, src, len);
+ int rem;
+
+ if (csum_err)
+ *csum_err = 0;
+
+ rem = copy_from_user(dst, src, len);
+ if (rem != 0) {
+ if (csum_err)
+ *csum_err = -EFAULT;
+ memset(dst + len - rem, 0, rem);
+ len = rem;
+ }
+
return csum_partial(dst, len, sum);
}
+EXPORT_SYMBOL(csum_partial_copy_from_user);
+
/*
* copy from ds while checksumming, otherwise like csum_partial
*/
-
-unsigned int
-csum_partial_copy(const char *src, char *dst, int len, int sum)
+__wsum
+csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
{
memcpy(dst, src, len);
return csum_partial(dst, len, sum);
}
+
+EXPORT_SYMBOL(csum_partial_copy_nocheck);