006-mcfv4e_arch_lib_mods.patch 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. From a9faf34ba120d9d39ff0c7656ee3de12a110e22a Mon Sep 17 00:00:00 2001
  2. From: Kurt Mahan <[email protected]>
  3. Date: Wed, 31 Oct 2007 16:57:05 -0600
  4. Subject: [PATCH] Core Coldfire/MCF5445x arch lib changes.
  5. LTIBName: mcfv4e-arch-lib-mods
  6. Signed-off-by: Kurt Mahan <[email protected]>
  7. ---
  8. arch/m68k/lib/checksum.c | 124 +++++++++++++++++++++++
  9. arch/m68k/lib/muldi3.c | 10 ++
  10. arch/m68k/lib/semaphore.S | 25 +++++
  11. arch/m68k/lib/string.c | 64 ++++++++++++
  12. arch/m68k/lib/uaccess.c | 242 +++++++++++++++++++++++++++++++++++++++++++++
  13. 5 files changed, 465 insertions(+), 0 deletions(-)
  14. --- a/arch/m68k/lib/checksum.c
  15. +++ b/arch/m68k/lib/checksum.c
  16. @@ -39,8 +39,131 @@
  17. * computes a partial checksum, e.g. for TCP/UDP fragments
  18. */
  19. +#ifdef CONFIG_COLDFIRE
  20. +
  21. +static inline unsigned short from32to16(unsigned long x)
  22. +{
  23. + /* add up 16-bit and 16-bit for 16+c bit */
  24. + x = (x & 0xffff) + (x >> 16);
  25. + /* add up carry.. */
  26. + x = (x & 0xffff) + (x >> 16);
  27. + return x;
  28. +}
  29. +
  30. +static unsigned long do_csum(const unsigned char *buff, int len)
  31. +{
  32. + int odd, count;
  33. + unsigned long result = 0;
  34. +
  35. + if (len <= 0)
  36. + goto out;
  37. + odd = 1 & (unsigned long) buff;
  38. + if (odd) {
  39. + result = *buff;
  40. + len--;
  41. + buff++;
  42. + }
  43. + count = len >> 1; /* nr of 16-bit words.. */
  44. + if (count) {
  45. + if (2 & (unsigned long) buff) {
  46. + result += *(unsigned short *) buff;
  47. + count--;
  48. + len -= 2;
  49. + buff += 2;
  50. + }
  51. + count >>= 1; /* nr of 32-bit words.. */
  52. + if (count) {
  53. + unsigned long carry = 0;
  54. + do {
  55. + unsigned long w = *(unsigned long *) buff;
  56. + count--;
  57. + buff += 4;
  58. + result += carry;
  59. + result += w;
  60. + carry = (w > result);
  61. + } while (count);
  62. + result += carry;
  63. + result = (result & 0xffff) + (result >> 16);
  64. + }
  65. + if (len & 2) {
  66. + result += *(unsigned short *) buff;
  67. + buff += 2;
  68. + }
  69. + }
  70. + if (len & 1)
  71. + result += (*buff << 8);
  72. + result = from32to16(result);
  73. + if (odd)
  74. + result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
  75. +out:
  76. + return result;
  77. +}
  78. +
  79. +/*
  80. + * This is a version of ip_compute_csum() optimized for IP headers,
  81. + * which always checksum on 4 octet boundaries.
  82. + */
  83. +__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
  84. +{
  85. + return ~do_csum(iph, ihl*4);
  86. +}
  87. +EXPORT_SYMBOL(ip_fast_csum);
  88. +
  89. +/*
  90. + * computes the checksum of a memory block at buff, length len,
  91. + * and adds in "sum" (32-bit)
  92. + *
  93. + * returns a 32-bit number suitable for feeding into itself
  94. + * or csum_tcpudp_magic
  95. + *
  96. + * this function must be called with even lengths, except
  97. + * for the last fragment, which may be odd
  98. + *
  99. + * it's best to have buff aligned on a 32-bit boundary
  100. + */
  101. __wsum csum_partial(const void *buff, int len, __wsum sum)
  102. {
  103. + unsigned int result = do_csum(buff, len);
  104. +
  105. + /* add in old sum, and carry.. */
  106. + result += sum;
  107. + if (sum > result)
  108. + result += 1;
  109. + return result;
  110. +}
  111. +EXPORT_SYMBOL(csum_partial);
  112. +
  113. +/*
  114. + * copy from fs while checksumming, otherwise like csum_partial
  115. + */
  116. +
  117. +__wsum
  118. +csum_partial_copy_from_user(const void __user *src, void *dst, int len,
  119. + __wsum sum, int *csum_err)
  120. +{
  121. + if (csum_err) *csum_err = 0;
  122. + memcpy(dst, src, len);
  123. + return csum_partial(dst, len, sum);
  124. +}
  125. +EXPORT_SYMBOL(csum_partial_copy_from_user);
  126. +
  127. +/*
  128. + * copy from ds while checksumming, otherwise like csum_partial
  129. + */
  130. +
  131. +__wsum
  132. +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
  133. +{
  134. + memcpy(dst, src, len);
  135. + return csum_partial(dst, len, sum);
  136. +}
  137. +EXPORT_SYMBOL(csum_partial_copy_nocheck);
  138. +
  139. +#else /* !CONFIG_COLDFIRE */
  140. +
  141. +unsigned int
  142. +csum_partial(const unsigned char *buff, int len, unsigned int sum)
  143. +{
  144. unsigned long tmp1, tmp2;
  145. /*
  146. * Experiments with ethernet and slip connections show that buff
  147. @@ -423,3 +546,4 @@ csum_partial_copy_nocheck(const void *sr
  148. return(sum);
  149. }
  150. EXPORT_SYMBOL(csum_partial_copy_nocheck);
  151. +#endif /* CONFIG_COLDFIRE */
  152. --- a/arch/m68k/lib/muldi3.c
  153. +++ b/arch/m68k/lib/muldi3.c
  154. @@ -21,12 +21,22 @@ Boston, MA 02111-1307, USA. */
  155. #define BITS_PER_UNIT 8
  156. +#ifdef CONFIG_COLDFIRE
  157. +#define umul_ppmm(w1, w0, u, v) \
  158. + do { \
  159. + unsigned long long x; \
  160. + x = (unsigned long long)u * v; \
  161. + w0 = (unsigned long)(x & 0x00000000ffffffff); \
  162. + w1 = (unsigned long)(x & 0xffffffff00000000) >> 32; \
  163. + } while (0)
  164. +#else /* CONFIG_COLDFIRE */
  165. #define umul_ppmm(w1, w0, u, v) \
  166. __asm__ ("mulu%.l %3,%1:%0" \
  167. : "=d" ((USItype)(w0)), \
  168. "=d" ((USItype)(w1)) \
  169. : "%0" ((USItype)(u)), \
  170. "dmi" ((USItype)(v)))
  171. +#endif /* CONFIG_COLDFIRE */
  172. #define __umulsidi3(u, v) \
  173. ({DIunion __w; \
  174. --- a/arch/m68k/lib/semaphore.S
  175. +++ b/arch/m68k/lib/semaphore.S
  176. @@ -16,11 +16,24 @@
  177. * there is contention on the semaphore.
  178. */
  179. ENTRY(__down_failed)
  180. +#ifndef CONFIG_COLDFIRE
  181. moveml %a0/%d0/%d1,-(%sp)
  182. +#else
  183. + movel %a0,-(%sp)
  184. + movel %d0,-(%sp)
  185. + movel %d1,-(%sp)
  186. +#endif
  187. movel %a1,-(%sp)
  188. jbsr __down
  189. movel (%sp)+,%a1
  190. +#ifndef CONFIG_COLDFIRE
  191. moveml (%sp)+,%a0/%d0/%d1
  192. +#else
  193. + movel (%sp)+,%d1
  194. + movel (%sp)+,%d0
  195. + movel (%sp)+,%a0
  196. +#endif
  197. +
  198. rts
  199. ENTRY(__down_failed_interruptible)
  200. @@ -44,10 +57,22 @@ ENTRY(__down_failed_trylock)
  201. rts
  202. ENTRY(__up_wakeup)
  203. +#ifndef CONFIG_COLDFIRE
  204. moveml %a0/%d0/%d1,-(%sp)
  205. +#else
  206. + movel %a0,-(%sp)
  207. + movel %d0,-(%sp)
  208. + movel %d1,-(%sp)
  209. +#endif
  210. movel %a1,-(%sp)
  211. jbsr __up
  212. movel (%sp)+,%a1
  213. +#ifndef CONFIG_COLDFIRE
  214. moveml (%sp)+,%a0/%d0/%d1
  215. +#else
  216. + movel (%sp)+,%d1
  217. + movel (%sp)+,%d0
  218. + movel (%sp)+,%a0
  219. +#endif
  220. rts
  221. --- a/arch/m68k/lib/string.c
  222. +++ b/arch/m68k/lib/string.c
  223. @@ -15,6 +15,7 @@ char *strcpy(char *dest, const char *src
  224. }
  225. EXPORT_SYMBOL(strcpy);
  226. +#ifndef CONFIG_COLDFIRE
  227. void *memset(void *s, int c, size_t count)
  228. {
  229. void *xs = s;
  230. @@ -143,6 +144,69 @@ void *memcpy(void *to, const void *from,
  231. }
  232. EXPORT_SYMBOL(memcpy);
  233. +#else /* CONFIG_COLDFIRE */
  234. +
  235. +void *memset(void *s, int c, size_t count)
  236. +{
  237. + unsigned long x;
  238. + void *originalTo;
  239. +
  240. + for (x = 0; x < count; x++)
  241. + *(unsigned char *)s++ = (unsigned char)c;
  242. +
  243. + return originalTo;
  244. +}
  245. +EXPORT_SYMBOL(memset);
  246. +
  247. +void *memcpy(void *to, const void *from, size_t n)
  248. +{
  249. + void *xto = to;
  250. + size_t temp;
  251. +
  252. + if (!n)
  253. + return xto;
  254. + if ((long) to & 1) {
  255. + char *cto = to;
  256. + const char *cfrom = from;
  257. + *cto++ = *cfrom++;
  258. + to = cto;
  259. + from = cfrom;
  260. + n--;
  261. + }
  262. + if (n > 2 && (long) to & 2) {
  263. + short *sto = to;
  264. + const short *sfrom = from;
  265. + *sto++ = *sfrom++;
  266. + to = sto;
  267. + from = sfrom;
  268. + n -= 2;
  269. + }
  270. + temp = n >> 2;
  271. + if (temp) {
  272. + long *lto = to;
  273. + const long *lfrom = from;
  274. + for (; temp; temp--)
  275. + *lto++ = *lfrom++;
  276. + to = lto;
  277. + from = lfrom;
  278. + }
  279. + if (n & 2) {
  280. + short *sto = to;
  281. + const short *sfrom = from;
  282. + *sto++ = *sfrom++;
  283. + to = sto;
  284. + from = sfrom;
  285. + }
  286. + if (n & 1) {
  287. + char *cto = to;
  288. + const char *cfrom = from;
  289. + *cto = *cfrom;
  290. + }
  291. + return xto;
  292. +}
  293. +EXPORT_SYMBOL(memcpy);
  294. +#endif /* CONFIG_COLDFIRE */
  295. +
  296. void *memmove(void *dest, const void *src, size_t n)
  297. {
  298. void *xdest = dest;
  299. --- a/arch/m68k/lib/uaccess.c
  300. +++ b/arch/m68k/lib/uaccess.c
  301. @@ -5,6 +5,7 @@
  302. */
  303. #include <linux/module.h>
  304. +#ifndef CONFIG_COLDFIRE
  305. #include <asm/uaccess.h>
  306. unsigned long __generic_copy_from_user(void *to, const void __user *from,
  307. @@ -220,3 +221,244 @@ unsigned long __clear_user(void __user *
  308. return res;
  309. }
  310. EXPORT_SYMBOL(__clear_user);
  311. +
  312. +#else /* CONFIG_COLDFIRE */
  313. +
  314. +#include <asm/cf_uaccess.h>
  315. +
  316. +unsigned long __generic_copy_from_user(void *to, const void *from,
  317. + unsigned long n)
  318. +{
  319. + unsigned long tmp;
  320. + __asm__ __volatile__
  321. + (" tstl %2\n"
  322. + " jeq 2f\n"
  323. + "1: movel (%1)+,%3\n"
  324. + " movel %3,(%0)+\n"
  325. + " subql #1,%2\n"
  326. + " jne 1b\n"
  327. + "2: movel %4,%2\n"
  328. + " bclr #1,%2\n"
  329. + " jeq 4f\n"
  330. + "3: movew (%1)+,%3\n"
  331. + " movew %3,(%0)+\n"
  332. + "4: bclr #0,%2\n"
  333. + " jeq 6f\n"
  334. + "5: moveb (%1)+,%3\n"
  335. + " moveb %3,(%0)+\n"
  336. + "6:\n"
  337. + ".section .fixup,\"ax\"\n"
  338. + " .even\n"
  339. + "7: movel %2,%%d0\n"
  340. + "71:clrl (%0)+\n"
  341. + " subql #1,%%d0\n"
  342. + " jne 71b\n"
  343. + " lsll #2,%2\n"
  344. + " addl %4,%2\n"
  345. + " btst #1,%4\n"
  346. + " jne 81f\n"
  347. + " btst #0,%4\n"
  348. + " jne 91f\n"
  349. + " jra 6b\n"
  350. + "8: addql #2,%2\n"
  351. + "81:clrw (%0)+\n"
  352. + " btst #0,%4\n"
  353. + " jne 91f\n"
  354. + " jra 6b\n"
  355. + "9: addql #1,%2\n"
  356. + "91:clrb (%0)+\n"
  357. + " jra 6b\n"
  358. + ".previous\n"
  359. + ".section __ex_table,\"a\"\n"
  360. + " .align 4\n"
  361. + " .long 1b,7b\n"
  362. + " .long 3b,8b\n"
  363. + " .long 5b,9b\n"
  364. + ".previous"
  365. + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
  366. + : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
  367. + : "d0", "memory");
  368. + return n;
  369. +}
  370. +EXPORT_SYMBOL(__generic_copy_from_user);
  371. +
  372. +
  373. +unsigned long __generic_copy_to_user(void *to, const void *from,
  374. + unsigned long n)
  375. +{
  376. + unsigned long tmp;
  377. + __asm__ __volatile__
  378. + (" tstl %2\n"
  379. + " jeq 3f\n"
  380. + "1: movel (%1)+,%3\n"
  381. + "22:movel %3,(%0)+\n"
  382. + "2: subql #1,%2\n"
  383. + " jne 1b\n"
  384. + "3: movel %4,%2\n"
  385. + " bclr #1,%2\n"
  386. + " jeq 4f\n"
  387. + " movew (%1)+,%3\n"
  388. + "24:movew %3,(%0)+\n"
  389. + "4: bclr #0,%2\n"
  390. + " jeq 5f\n"
  391. + " moveb (%1)+,%3\n"
  392. + "25:moveb %3,(%0)+\n"
  393. + "5:\n"
  394. + ".section .fixup,\"ax\"\n"
  395. + " .even\n"
  396. + "60:addql #1,%2\n"
  397. + "6: lsll #2,%2\n"
  398. + " addl %4,%2\n"
  399. + " jra 5b\n"
  400. + "7: addql #2,%2\n"
  401. + " jra 5b\n"
  402. + "8: addql #1,%2\n"
  403. + " jra 5b\n"
  404. + ".previous\n"
  405. + ".section __ex_table,\"a\"\n"
  406. + " .align 4\n"
  407. + " .long 1b,60b\n"
  408. + " .long 22b,6b\n"
  409. + " .long 2b,6b\n"
  410. + " .long 24b,7b\n"
  411. + " .long 3b,60b\n"
  412. + " .long 4b,7b\n"
  413. + " .long 25b,8b\n"
  414. + " .long 5b,8b\n"
  415. + ".previous"
  416. + : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
  417. + : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
  418. + : "memory");
  419. + return n;
  420. +}
  421. +EXPORT_SYMBOL(__generic_copy_to_user);
  422. +
  423. +/*
  424. + * Copy a null terminated string from userspace.
  425. + */
  426. +
  427. +long strncpy_from_user(char *dst, const char *src, long count)
  428. +{
  429. + long res = -EFAULT;
  430. + if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
  431. + return res;
  432. + if (count == 0) return count;
  433. + __asm__ __volatile__
  434. + ("1: moveb (%2)+,%%d0\n"
  435. + "12:moveb %%d0,(%1)+\n"
  436. + " jeq 2f\n"
  437. + " subql #1,%3\n"
  438. + " jne 1b\n"
  439. + "2: subl %3,%0\n"
  440. + "3:\n"
  441. + ".section .fixup,\"ax\"\n"
  442. + " .even\n"
  443. + "4: movel %4,%0\n"
  444. + " jra 3b\n"
  445. + ".previous\n"
  446. + ".section __ex_table,\"a\"\n"
  447. + " .align 4\n"
  448. + " .long 1b,4b\n"
  449. + " .long 12b,4b\n"
  450. + ".previous"
  451. + : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
  452. + : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
  453. + : "d0", "memory");
  454. + return res;
  455. +}
  456. +EXPORT_SYMBOL(strncpy_from_user);
  457. +
  458. +/*
  459. + * Return the size of a string (including the ending 0)
  460. + *
  461. + * Return 0 on exception, a value greater than N if too long
  462. + */
  463. +long strnlen_user(const char *src, long n)
  464. +{
  465. + long res = -EFAULT;
  466. + if (!(access_ok(VERIFY_READ, src, 1))) /* --tym-- */
  467. + return res;
  468. +
  469. + res = -(long)src;
  470. + __asm__ __volatile__
  471. + ("1:\n"
  472. + " tstl %2\n"
  473. + " jeq 3f\n"
  474. + "2: moveb (%1)+,%%d0\n"
  475. + "22:\n"
  476. + " subql #1,%2\n"
  477. + " tstb %%d0\n"
  478. + " jne 1b\n"
  479. + " jra 4f\n"
  480. + "3:\n"
  481. + " addql #1,%0\n"
  482. + "4:\n"
  483. + " addl %1,%0\n"
  484. + "5:\n"
  485. + ".section .fixup,\"ax\"\n"
  486. + " .even\n"
  487. + "6: moveq %3,%0\n"
  488. + " jra 5b\n"
  489. + ".previous\n"
  490. + ".section __ex_table,\"a\"\n"
  491. + " .align 4\n"
  492. + " .long 2b,6b\n"
  493. + " .long 22b,6b\n"
  494. + ".previous"
  495. + : "=d"(res), "=a"(src), "=d"(n)
  496. + : "i"(0), "0"(res), "1"(src), "2"(n)
  497. + : "d0");
  498. + return res;
  499. +}
  500. +EXPORT_SYMBOL(strnlen_user);
  501. +
  502. +
  503. +/*
  504. + * Zero Userspace
  505. + */
  506. +
  507. +unsigned long __clear_user(void *to, unsigned long n)
  508. +{
  509. + __asm__ __volatile__
  510. + (" tstl %1\n"
  511. + " jeq 3f\n"
  512. + "1: movel %3,(%0)+\n"
  513. + "2: subql #1,%1\n"
  514. + " jne 1b\n"
  515. + "3: movel %2,%1\n"
  516. + " bclr #1,%1\n"
  517. + " jeq 4f\n"
  518. + "24:movew %3,(%0)+\n"
  519. + "4: bclr #0,%1\n"
  520. + " jeq 5f\n"
  521. + "25:moveb %3,(%0)+\n"
  522. + "5:\n"
  523. + ".section .fixup,\"ax\"\n"
  524. + " .even\n"
  525. + "61:addql #1,%1\n"
  526. + "6: lsll #2,%1\n"
  527. + " addl %2,%1\n"
  528. + " jra 5b\n"
  529. + "7: addql #2,%1\n"
  530. + " jra 5b\n"
  531. + "8: addql #1,%1\n"
  532. + " jra 5b\n"
  533. + ".previous\n"
  534. + ".section __ex_table,\"a\"\n"
  535. + " .align 4\n"
  536. + " .long 1b,61b\n"
  537. + " .long 2b,6b\n"
  538. + " .long 3b,61b\n"
  539. + " .long 24b,7b\n"
  540. + " .long 4b,7b\n"
  541. + " .long 25b,8b\n"
  542. + " .long 5b,8b\n"
  543. + ".previous"
  544. + : "=a"(to), "=d"(n)
  545. + : "r"(n & 3), "d"(0), "0"(to), "1"(n/4));
  546. + return n;
  547. +}
  548. +EXPORT_SYMBOL(__clear_user);
  549. +
  550. +#endif /* CONFIG_COLDFIRE */
  551. +