1 From a9faf34ba120d9d39ff0c7656ee3de12a110e22a Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Wed, 31 Oct 2007 16:57:05 -0600
4 Subject: [PATCH] Core Coldfire/MCF5445x arch lib changes.
6 LTIBName: mcfv4e-arch-lib-mods
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
9 arch/m68k/lib/checksum.c | 124 +++++++++++++++++++++++
10 arch/m68k/lib/muldi3.c | 10 ++
11 arch/m68k/lib/semaphore.S | 25 +++++
12 arch/m68k/lib/string.c | 64 ++++++++++++
13 arch/m68k/lib/uaccess.c | 242 +++++++++++++++++++++++++++++++++++++++++++++
14 5 files changed, 465 insertions(+), 0 deletions(-)
16 --- a/arch/m68k/lib/checksum.c
17 +++ b/arch/m68k/lib/checksum.c
19 * computes a partial checksum, e.g. for TCP/UDP fragments
22 +#ifdef CONFIG_COLDFIRE
24 +static inline unsigned short from32to16(unsigned long x)
26 + /* add up 16-bit and 16-bit for 16+c bit */
27 + x = (x & 0xffff) + (x >> 16);
28 + /* add up carry.. */
29 + x = (x & 0xffff) + (x >> 16);
33 +static unsigned long do_csum(const unsigned char *buff, int len)
36 + unsigned long result = 0;
40 + odd = 1 & (unsigned long) buff;
46 + count = len >> 1; /* nr of 16-bit words.. */
48 + if (2 & (unsigned long) buff) {
49 + result += *(unsigned short *) buff;
54 + count >>= 1; /* nr of 32-bit words.. */
56 + unsigned long carry = 0;
58 + unsigned long w = *(unsigned long *) buff;
63 + carry = (w > result);
66 + result = (result & 0xffff) + (result >> 16);
69 + result += *(unsigned short *) buff;
74 + result += (*buff << 8);
75 + result = from32to16(result);
77 + result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
83 + * This is a version of ip_compute_csum() optimized for IP headers,
84 + * which always checksum on 4 octet boundaries.
86 +__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
88 + return ~do_csum(iph, ihl*4);
90 +EXPORT_SYMBOL(ip_fast_csum);
93 + * computes the checksum of a memory block at buff, length len,
94 + * and adds in "sum" (32-bit)
96 + * returns a 32-bit number suitable for feeding into itself
97 + * or csum_tcpudp_magic
99 + * this function must be called with even lengths, except
100 + * for the last fragment, which may be odd
102 + * it's best to have buff aligned on a 32-bit boundary
104 __wsum csum_partial(const void *buff, int len, __wsum sum)
106 + unsigned int result = do_csum(buff, len);
108 + /* add in old sum, and carry.. */
114 +EXPORT_SYMBOL(csum_partial);
117 + * copy from fs while checksumming, otherwise like csum_partial
121 +csum_partial_copy_from_user(const void __user *src, void *dst, int len,
122 + __wsum sum, int *csum_err)
124 + if (csum_err) *csum_err = 0;
125 + memcpy(dst, src, len);
126 + return csum_partial(dst, len, sum);
128 +EXPORT_SYMBOL(csum_partial_copy_from_user);
131 + * copy from ds while checksumming, otherwise like csum_partial
135 +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
137 + memcpy(dst, src, len);
138 + return csum_partial(dst, len, sum);
140 +EXPORT_SYMBOL(csum_partial_copy_nocheck);
142 +#else /* !CONFIG_COLDFIRE */
145 +csum_partial(const unsigned char *buff, int len, unsigned int sum)
147 unsigned long tmp1, tmp2;
149 * Experiments with ethernet and slip connections show that buff
150 @@ -423,3 +546,4 @@ csum_partial_copy_nocheck(const void *sr
153 EXPORT_SYMBOL(csum_partial_copy_nocheck);
154 +#endif /* CONFIG_COLDFIRE */
155 --- a/arch/m68k/lib/muldi3.c
156 +++ b/arch/m68k/lib/muldi3.c
157 @@ -21,12 +21,22 @@ Boston, MA 02111-1307, USA. */
159 #define BITS_PER_UNIT 8
161 +#ifdef CONFIG_COLDFIRE
162 +#define umul_ppmm(w1, w0, u, v) \
164 + unsigned long long x; \
165 + x = (unsigned long long)u * v; \
166 + w0 = (unsigned long)(x & 0x00000000ffffffff); \
167 + w1 = (unsigned long)(x & 0xffffffff00000000) >> 32; \
169 +#else /* CONFIG_COLDFIRE */
170 #define umul_ppmm(w1, w0, u, v) \
171 __asm__ ("mulu%.l %3,%1:%0" \
172 : "=d" ((USItype)(w0)), \
173 "=d" ((USItype)(w1)) \
174 : "%0" ((USItype)(u)), \
175 "dmi" ((USItype)(v)))
176 +#endif /* CONFIG_COLDFIRE */
178 #define __umulsidi3(u, v) \
180 --- a/arch/m68k/lib/semaphore.S
181 +++ b/arch/m68k/lib/semaphore.S
183 * there is contention on the semaphore.
186 +#ifndef CONFIG_COLDFIRE
187 moveml %a0/%d0/%d1,-(%sp)
196 +#ifndef CONFIG_COLDFIRE
197 moveml (%sp)+,%a0/%d0/%d1
206 ENTRY(__down_failed_interruptible)
207 @@ -44,10 +57,22 @@ ENTRY(__down_failed_trylock)
211 +#ifndef CONFIG_COLDFIRE
212 moveml %a0/%d0/%d1,-(%sp)
221 +#ifndef CONFIG_COLDFIRE
222 moveml (%sp)+,%a0/%d0/%d1
230 --- a/arch/m68k/lib/string.c
231 +++ b/arch/m68k/lib/string.c
232 @@ -15,6 +15,7 @@ char *strcpy(char *dest, const char *src
234 EXPORT_SYMBOL(strcpy);
236 +#ifndef CONFIG_COLDFIRE
237 void *memset(void *s, int c, size_t count)
240 @@ -143,6 +144,69 @@ void *memcpy(void *to, const void *from,
242 EXPORT_SYMBOL(memcpy);
244 +#else /* CONFIG_COLDFIRE */
246 +void *memset(void *s, int c, size_t count)
251 + for (x = 0; x < count; x++)
252 + *(unsigned char *)s++ = (unsigned char)c;
256 +EXPORT_SYMBOL(memset);
258 +void *memcpy(void *to, const void *from, size_t n)
265 + if ((long) to & 1) {
267 + const char *cfrom = from;
273 + if (n > 2 && (long) to & 2) {
275 + const short *sfrom = from;
284 + const long *lfrom = from;
285 + for (; temp; temp--)
292 + const short *sfrom = from;
299 + const char *cfrom = from;
304 +EXPORT_SYMBOL(memcpy);
305 +#endif /* CONFIG_COLDFIRE */
307 void *memmove(void *dest, const void *src, size_t n)
310 --- a/arch/m68k/lib/uaccess.c
311 +++ b/arch/m68k/lib/uaccess.c
315 #include <linux/module.h>
316 +#ifndef CONFIG_COLDFIRE
317 #include <asm/uaccess.h>
319 unsigned long __generic_copy_from_user(void *to, const void __user *from,
320 @@ -220,3 +221,244 @@ unsigned long __clear_user(void __user *
323 EXPORT_SYMBOL(__clear_user);
325 +#else /* CONFIG_COLDFIRE */
327 +#include <asm/cf_uaccess.h>
329 +unsigned long __generic_copy_from_user(void *to, const void *from,
333 + __asm__ __volatile__
336 + "1: movel (%1)+,%3\n"
337 + " movel %3,(%0)+\n"
343 + "3: movew (%1)+,%3\n"
344 + " movew %3,(%0)+\n"
347 + "5: moveb (%1)+,%3\n"
348 + " moveb %3,(%0)+\n"
350 + ".section .fixup,\"ax\"\n"
352 + "7: movel %2,%%d0\n"
372 + ".section __ex_table,\"a\"\n"
378 + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
379 + : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
383 +EXPORT_SYMBOL(__generic_copy_from_user);
386 +unsigned long __generic_copy_to_user(void *to, const void *from,
390 + __asm__ __volatile__
393 + "1: movel (%1)+,%3\n"
394 + "22:movel %3,(%0)+\n"
400 + " movew (%1)+,%3\n"
401 + "24:movew %3,(%0)+\n"
404 + " moveb (%1)+,%3\n"
405 + "25:moveb %3,(%0)+\n"
407 + ".section .fixup,\"ax\"\n"
418 + ".section __ex_table,\"a\"\n"
429 + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
430 + : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
434 +EXPORT_SYMBOL(__generic_copy_to_user);
437 + * Copy a null terminated string from userspace.
440 +long strncpy_from_user(char *dst, const char *src, long count)
442 + long res = -EFAULT;
443 + if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
445 + if (count == 0) return count;
446 + __asm__ __volatile__
447 + ("1: moveb (%2)+,%%d0\n"
448 + "12:moveb %%d0,(%1)+\n"
454 + ".section .fixup,\"ax\"\n"
459 + ".section __ex_table,\"a\"\n"
464 + : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
465 + : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
469 +EXPORT_SYMBOL(strncpy_from_user);
472 + * Return the size of a string (including the ending 0)
474 + * Return 0 on exception, a value greater than N if too long
476 +long strnlen_user(const char *src, long n)
478 + long res = -EFAULT;
479 + if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
483 + __asm__ __volatile__
487 + "2: moveb (%1)+,%%d0\n"
498 + ".section .fixup,\"ax\"\n"
503 + ".section __ex_table,\"a\"\n"
508 + : "=d"(res), "=a"(src), "=d"(n)
509 + : "i"(0), "0"(res), "1"(src), "2"(n)
513 +EXPORT_SYMBOL(strnlen_user);
520 +unsigned long __clear_user(void *to, unsigned long n)
522 + __asm__ __volatile__
525 + "1: movel %3,(%0)+\n"
531 + "24:movew %3,(%0)+\n"
534 + "25:moveb %3,(%0)+\n"
536 + ".section .fixup,\"ax\"\n"
547 + ".section __ex_table,\"a\"\n"
557 + : "=a"(to), "=d"(n)
558 + : "r"(n & 3), "d"(0), "0"(to), "1"(n/4));
561 +EXPORT_SYMBOL(__clear_user);
563 +#endif /* CONFIG_COLDFIRE */