| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- From a9faf34ba120d9d39ff0c7656ee3de12a110e22a Mon Sep 17 00:00:00 2001
- From: Kurt Mahan <[email protected]>
- Date: Wed, 31 Oct 2007 16:57:05 -0600
- Subject: [PATCH] Core Coldfire/MCF5445x arch lib changes.
- LTIBName: mcfv4e-arch-lib-mods
- Signed-off-by: Kurt Mahan <[email protected]>
- ---
- arch/m68k/lib/checksum.c | 124 +++++++++++++++++++++++
- arch/m68k/lib/muldi3.c | 10 ++
- arch/m68k/lib/semaphore.S | 25 +++++
- arch/m68k/lib/string.c | 64 ++++++++++++
- arch/m68k/lib/uaccess.c | 242 +++++++++++++++++++++++++++++++++++++++++++++
- 5 files changed, 465 insertions(+), 0 deletions(-)
- --- a/arch/m68k/lib/checksum.c
- +++ b/arch/m68k/lib/checksum.c
- @@ -39,8 +39,131 @@
- * computes a partial checksum, e.g. for TCP/UDP fragments
- */
-
- +#ifdef CONFIG_COLDFIRE
- +
- +static inline unsigned short from32to16(unsigned long x)
- +{
- + /* add up 16-bit and 16-bit for 16+c bit */
- + x = (x & 0xffff) + (x >> 16);
- + /* add up carry.. */
- + x = (x & 0xffff) + (x >> 16);
- + return x;
- +}
- +
- +static unsigned long do_csum(const unsigned char *buff, int len)
- +{
- + int odd, count;
- + unsigned long result = 0;
- +
- + if (len <= 0)
- + goto out;
- + odd = 1 & (unsigned long) buff;
- + if (odd) {
- + result = *buff;
- + len--;
- + buff++;
- + }
- + count = len >> 1; /* nr of 16-bit words.. */
- + if (count) {
- + if (2 & (unsigned long) buff) {
- + result += *(unsigned short *) buff;
- + count--;
- + len -= 2;
- + buff += 2;
- + }
- + count >>= 1; /* nr of 32-bit words.. */
- + if (count) {
- + unsigned long carry = 0;
- + do {
- + unsigned long w = *(unsigned long *) buff;
- + count--;
- + buff += 4;
- + result += carry;
- + result += w;
- + carry = (w > result);
- + } while (count);
- + result += carry;
- + result = (result & 0xffff) + (result >> 16);
- + }
- + if (len & 2) {
- + result += *(unsigned short *) buff;
- + buff += 2;
- + }
- + }
- + if (len & 1)
- + result += (*buff << 8);
- + result = from32to16(result);
- + if (odd)
- + result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
- +out:
- + return result;
- +}
- +
- +/*
- + * This is a version of ip_compute_csum() optimized for IP headers,
- + * which always checksum on 4 octet boundaries.
- + */
- +__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
- +{
- + return ~do_csum(iph, ihl*4);
- +}
- +EXPORT_SYMBOL(ip_fast_csum);
- +
- +/*
- + * computes the checksum of a memory block at buff, length len,
- + * and adds in "sum" (32-bit)
- + *
- + * returns a 32-bit number suitable for feeding into itself
- + * or csum_tcpudp_magic
- + *
- + * this function must be called with even lengths, except
- + * for the last fragment, which may be odd
- + *
- + * it's best to have buff aligned on a 32-bit boundary
- + */
- __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 += 1;
- + return result;
- +}
- +EXPORT_SYMBOL(csum_partial);
- +
- +/*
- + * copy from fs while checksumming, otherwise like csum_partial
- + */
- +
- +__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);
- + return csum_partial(dst, len, sum);
- +}
- +EXPORT_SYMBOL(csum_partial_copy_from_user);
- +
- +/*
- + * copy from ds while checksumming, otherwise like csum_partial
- + */
- +
- +__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);
- +
- +#else /* !CONFIG_COLDFIRE */
- +
- +unsigned int
- +csum_partial(const unsigned char *buff, int len, unsigned int sum)
- +{
- unsigned long tmp1, tmp2;
- /*
- * Experiments with ethernet and slip connections show that buff
- @@ -423,3 +546,4 @@ csum_partial_copy_nocheck(const void *sr
- return(sum);
- }
- EXPORT_SYMBOL(csum_partial_copy_nocheck);
- +#endif /* CONFIG_COLDFIRE */
- --- a/arch/m68k/lib/muldi3.c
- +++ b/arch/m68k/lib/muldi3.c
- @@ -21,12 +21,22 @@ Boston, MA 02111-1307, USA. */
-
- #define BITS_PER_UNIT 8
-
- +#ifdef CONFIG_COLDFIRE
- +#define umul_ppmm(w1, w0, u, v) \
- + do { \
- + unsigned long long x; \
- + x = (unsigned long long)u * v; \
- + w0 = (unsigned long)(x & 0x00000000ffffffff); \
- + w1 = (unsigned long)(x & 0xffffffff00000000) >> 32; \
- + } while (0)
- +#else /* CONFIG_COLDFIRE */
- #define umul_ppmm(w1, w0, u, v) \
- __asm__ ("mulu%.l %3,%1:%0" \
- : "=d" ((USItype)(w0)), \
- "=d" ((USItype)(w1)) \
- : "%0" ((USItype)(u)), \
- "dmi" ((USItype)(v)))
- +#endif /* CONFIG_COLDFIRE */
-
- #define __umulsidi3(u, v) \
- ({DIunion __w; \
- --- a/arch/m68k/lib/semaphore.S
- +++ b/arch/m68k/lib/semaphore.S
- @@ -16,11 +16,24 @@
- * there is contention on the semaphore.
- */
- ENTRY(__down_failed)
- +#ifndef CONFIG_COLDFIRE
- moveml %a0/%d0/%d1,-(%sp)
- +#else
- + movel %a0,-(%sp)
- + movel %d0,-(%sp)
- + movel %d1,-(%sp)
- +#endif
- movel %a1,-(%sp)
- jbsr __down
- movel (%sp)+,%a1
- +#ifndef CONFIG_COLDFIRE
- moveml (%sp)+,%a0/%d0/%d1
- +#else
- + movel (%sp)+,%d1
- + movel (%sp)+,%d0
- + movel (%sp)+,%a0
- +#endif
- +
- rts
-
- ENTRY(__down_failed_interruptible)
- @@ -44,10 +57,22 @@ ENTRY(__down_failed_trylock)
- rts
-
- ENTRY(__up_wakeup)
- +#ifndef CONFIG_COLDFIRE
- moveml %a0/%d0/%d1,-(%sp)
- +#else
- + movel %a0,-(%sp)
- + movel %d0,-(%sp)
- + movel %d1,-(%sp)
- +#endif
- movel %a1,-(%sp)
- jbsr __up
- movel (%sp)+,%a1
- +#ifndef CONFIG_COLDFIRE
- moveml (%sp)+,%a0/%d0/%d1
- +#else
- + movel (%sp)+,%d1
- + movel (%sp)+,%d0
- + movel (%sp)+,%a0
- +#endif
- rts
-
- --- a/arch/m68k/lib/string.c
- +++ b/arch/m68k/lib/string.c
- @@ -15,6 +15,7 @@ char *strcpy(char *dest, const char *src
- }
- EXPORT_SYMBOL(strcpy);
-
- +#ifndef CONFIG_COLDFIRE
- void *memset(void *s, int c, size_t count)
- {
- void *xs = s;
- @@ -143,6 +144,69 @@ void *memcpy(void *to, const void *from,
- }
- EXPORT_SYMBOL(memcpy);
-
- +#else /* CONFIG_COLDFIRE */
- +
- +void *memset(void *s, int c, size_t count)
- +{
- + unsigned long x;
- + void *originalTo;
- +
- + for (x = 0; x < count; x++)
- + *(unsigned char *)s++ = (unsigned char)c;
- +
- + return originalTo;
- +}
- +EXPORT_SYMBOL(memset);
- +
- +void *memcpy(void *to, const void *from, size_t n)
- +{
- + void *xto = to;
- + size_t temp;
- +
- + 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;
- + for (; temp; temp--)
- + *lto++ = *lfrom++;
- + 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);
- +#endif /* CONFIG_COLDFIRE */
- +
- void *memmove(void *dest, const void *src, size_t n)
- {
- void *xdest = dest;
- --- a/arch/m68k/lib/uaccess.c
- +++ b/arch/m68k/lib/uaccess.c
- @@ -5,6 +5,7 @@
- */
-
- #include <linux/module.h>
- +#ifndef CONFIG_COLDFIRE
- #include <asm/uaccess.h>
-
- unsigned long __generic_copy_from_user(void *to, const void __user *from,
- @@ -220,3 +221,244 @@ unsigned long __clear_user(void __user *
- return res;
- }
- EXPORT_SYMBOL(__clear_user);
- +
- +#else /* CONFIG_COLDFIRE */
- +
- +#include <asm/cf_uaccess.h>
- +
- +unsigned long __generic_copy_from_user(void *to, const void *from,
- + unsigned long n)
- +{
- + unsigned long tmp;
- + __asm__ __volatile__
- + (" tstl %2\n"
- + " jeq 2f\n"
- + "1: movel (%1)+,%3\n"
- + " movel %3,(%0)+\n"
- + " subql #1,%2\n"
- + " jne 1b\n"
- + "2: movel %4,%2\n"
- + " bclr #1,%2\n"
- + " jeq 4f\n"
- + "3: movew (%1)+,%3\n"
- + " movew %3,(%0)+\n"
- + "4: bclr #0,%2\n"
- + " jeq 6f\n"
- + "5: moveb (%1)+,%3\n"
- + " moveb %3,(%0)+\n"
- + "6:\n"
- + ".section .fixup,\"ax\"\n"
- + " .even\n"
- + "7: movel %2,%%d0\n"
- + "71:clrl (%0)+\n"
- + " subql #1,%%d0\n"
- + " jne 71b\n"
- + " lsll #2,%2\n"
- + " addl %4,%2\n"
- + " btst #1,%4\n"
- + " jne 81f\n"
- + " btst #0,%4\n"
- + " jne 91f\n"
- + " jra 6b\n"
- + "8: addql #2,%2\n"
- + "81:clrw (%0)+\n"
- + " btst #0,%4\n"
- + " jne 91f\n"
- + " jra 6b\n"
- + "9: addql #1,%2\n"
- + "91:clrb (%0)+\n"
- + " jra 6b\n"
- + ".previous\n"
- + ".section __ex_table,\"a\"\n"
- + " .align 4\n"
- + " .long 1b,7b\n"
- + " .long 3b,8b\n"
- + " .long 5b,9b\n"
- + ".previous"
- + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
- + : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
- + : "d0", "memory");
- + return n;
- +}
- +EXPORT_SYMBOL(__generic_copy_from_user);
- +
- +
- +unsigned long __generic_copy_to_user(void *to, const void *from,
- + unsigned long n)
- +{
- + unsigned long tmp;
- + __asm__ __volatile__
- + (" tstl %2\n"
- + " jeq 3f\n"
- + "1: movel (%1)+,%3\n"
- + "22:movel %3,(%0)+\n"
- + "2: subql #1,%2\n"
- + " jne 1b\n"
- + "3: movel %4,%2\n"
- + " bclr #1,%2\n"
- + " jeq 4f\n"
- + " movew (%1)+,%3\n"
- + "24:movew %3,(%0)+\n"
- + "4: bclr #0,%2\n"
- + " jeq 5f\n"
- + " moveb (%1)+,%3\n"
- + "25:moveb %3,(%0)+\n"
- + "5:\n"
- + ".section .fixup,\"ax\"\n"
- + " .even\n"
- + "60:addql #1,%2\n"
- + "6: lsll #2,%2\n"
- + " addl %4,%2\n"
- + " jra 5b\n"
- + "7: addql #2,%2\n"
- + " jra 5b\n"
- + "8: addql #1,%2\n"
- + " jra 5b\n"
- + ".previous\n"
- + ".section __ex_table,\"a\"\n"
- + " .align 4\n"
- + " .long 1b,60b\n"
- + " .long 22b,6b\n"
- + " .long 2b,6b\n"
- + " .long 24b,7b\n"
- + " .long 3b,60b\n"
- + " .long 4b,7b\n"
- + " .long 25b,8b\n"
- + " .long 5b,8b\n"
- + ".previous"
- + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
- + : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
- + : "memory");
- + return n;
- +}
- +EXPORT_SYMBOL(__generic_copy_to_user);
- +
- +/*
- + * Copy a null terminated string from userspace.
- + */
- +
- +long strncpy_from_user(char *dst, const char *src, long count)
- +{
- + long res = -EFAULT;
- + if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
- + return res;
- + if (count == 0) return count;
- + __asm__ __volatile__
- + ("1: moveb (%2)+,%%d0\n"
- + "12:moveb %%d0,(%1)+\n"
- + " jeq 2f\n"
- + " subql #1,%3\n"
- + " jne 1b\n"
- + "2: subl %3,%0\n"
- + "3:\n"
- + ".section .fixup,\"ax\"\n"
- + " .even\n"
- + "4: movel %4,%0\n"
- + " jra 3b\n"
- + ".previous\n"
- + ".section __ex_table,\"a\"\n"
- + " .align 4\n"
- + " .long 1b,4b\n"
- + " .long 12b,4b\n"
- + ".previous"
- + : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
- + : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
- + : "d0", "memory");
- + return res;
- +}
- +EXPORT_SYMBOL(strncpy_from_user);
- +
- +/*
- + * Return the size of a string (including the ending 0)
- + *
- + * Return 0 on exception, a value greater than N if too long
- + */
- +long strnlen_user(const char *src, long n)
- +{
- + long res = -EFAULT;
- + if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
- + return res;
- +
- + res = -(long)src;
- + __asm__ __volatile__
- + ("1:\n"
- + " tstl %2\n"
- + " jeq 3f\n"
- + "2: moveb (%1)+,%%d0\n"
- + "22:\n"
- + " subql #1,%2\n"
- + " tstb %%d0\n"
- + " jne 1b\n"
- + " jra 4f\n"
- + "3:\n"
- + " addql #1,%0\n"
- + "4:\n"
- + " addl %1,%0\n"
- + "5:\n"
- + ".section .fixup,\"ax\"\n"
- + " .even\n"
- + "6: moveq %3,%0\n"
- + " jra 5b\n"
- + ".previous\n"
- + ".section __ex_table,\"a\"\n"
- + " .align 4\n"
- + " .long 2b,6b\n"
- + " .long 22b,6b\n"
- + ".previous"
- + : "=d"(res), "=a"(src), "=d"(n)
- + : "i"(0), "0"(res), "1"(src), "2"(n)
- + : "d0");
- + return res;
- +}
- +EXPORT_SYMBOL(strnlen_user);
- +
- +
- +/*
- + * Zero Userspace
- + */
- +
- +unsigned long __clear_user(void *to, unsigned long n)
- +{
- + __asm__ __volatile__
- + (" tstl %1\n"
- + " jeq 3f\n"
- + "1: movel %3,(%0)+\n"
- + "2: subql #1,%1\n"
- + " jne 1b\n"
- + "3: movel %2,%1\n"
- + " bclr #1,%1\n"
- + " jeq 4f\n"
- + "24:movew %3,(%0)+\n"
- + "4: bclr #0,%1\n"
- + " jeq 5f\n"
- + "25:moveb %3,(%0)+\n"
- + "5:\n"
- + ".section .fixup,\"ax\"\n"
- + " .even\n"
- + "61:addql #1,%1\n"
- + "6: lsll #2,%1\n"
- + " addl %2,%1\n"
- + " jra 5b\n"
- + "7: addql #2,%1\n"
- + " jra 5b\n"
- + "8: addql #1,%1\n"
- + " jra 5b\n"
- + ".previous\n"
- + ".section __ex_table,\"a\"\n"
- + " .align 4\n"
- + " .long 1b,61b\n"
- + " .long 2b,6b\n"
- + " .long 3b,61b\n"
- + " .long 24b,7b\n"
- + " .long 4b,7b\n"
- + " .long 25b,8b\n"
- + " .long 5b,8b\n"
- + ".previous"
- + : "=a"(to), "=d"(n)
- + : "r"(n & 3), "d"(0), "0"(to), "1"(n/4));
- + return n;
- +}
- +EXPORT_SYMBOL(__clear_user);
- +
- +#endif /* CONFIG_COLDFIRE */
- +
|