uaccess_old.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
  3. * Copyright (C) 2009 PetaLogix
  4. * Copyright (C) 2007 LynuxWorks, Inc.
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file "COPYING" in the main directory of this archive
  8. * for more details.
  9. */
  10. #include <linux/errno.h>
  11. #include <linux/linkage.h>
  12. /*
  13. * int __strncpy_user(char *to, char *from, int len);
  14. *
  15. * Returns:
  16. * -EFAULT for an exception
  17. * len if we hit the buffer limit
  18. * bytes copied
  19. */
  20. .text
  21. .globl __strncpy_user;
  22. .type __strncpy_user, @function
  23. .align 4;
  24. __strncpy_user:
  25. /*
  26. * r5 - to
  27. * r6 - from
  28. * r7 - len
  29. * r3 - temp count
  30. * r4 - temp val
  31. */
  32. addik r3,r7,0 /* temp_count = len */
  33. beqi r3,3f
  34. 1:
  35. lbu r4,r6,r0
  36. sb r4,r5,r0
  37. addik r3,r3,-1
  38. beqi r3,2f /* break on len */
  39. addik r5,r5,1
  40. bneid r4,1b
  41. addik r6,r6,1 /* delay slot */
  42. addik r3,r3,1 /* undo "temp_count--" */
  43. 2:
  44. rsubk r3,r3,r7 /* temp_count = len - temp_count */
  45. 3:
  46. rtsd r15,8
  47. nop
  48. .size __strncpy_user, . - __strncpy_user
  49. .section .fixup, "ax"
  50. .align 2
  51. 4:
  52. brid 3b
  53. addik r3,r0, -EFAULT
  54. .section __ex_table, "a"
  55. .word 1b,4b
  56. /*
  57. * int __strnlen_user(char __user *str, int maxlen);
  58. *
  59. * Returns:
  60. * 0 on error
  61. * maxlen + 1 if no NUL byte found within maxlen bytes
  62. * size of the string (including NUL byte)
  63. */
  64. .text
  65. .globl __strnlen_user;
  66. .type __strnlen_user, @function
  67. .align 4;
  68. __strnlen_user:
  69. addik r3,r6,0
  70. beqi r3,3f
  71. 1:
  72. lbu r4,r5,r0
  73. beqid r4,2f /* break on NUL */
  74. addik r3,r3,-1 /* delay slot */
  75. bneid r3,1b
  76. addik r5,r5,1 /* delay slot */
  77. addik r3,r3,-1 /* for break on len */
  78. 2:
  79. rsubk r3,r3,r6
  80. 3:
  81. rtsd r15,8
  82. nop
  83. .size __strnlen_user, . - __strnlen_user
  84. .section .fixup,"ax"
  85. 4:
  86. brid 3b
  87. addk r3,r0,r0
  88. .section __ex_table,"a"
  89. .word 1b,4b
  90. /*
  91. * int __copy_tofrom_user(char *to, char *from, int len)
  92. * Return:
  93. * 0 on success
  94. * number of not copied bytes on error
  95. */
  96. .text
  97. .globl __copy_tofrom_user;
  98. .type __copy_tofrom_user, @function
  99. .align 4;
  100. __copy_tofrom_user:
  101. /*
  102. * r5 - to
  103. * r6 - from
  104. * r7, r3 - count
  105. * r4 - tempval
  106. */
  107. beqid r7, 3f /* zero size is not likely */
  108. andi r3, r7, 0x3 /* filter add count */
  109. bneid r3, 4f /* if is odd value then byte copying */
  110. or r3, r5, r6 /* find if is any to/from unaligned */
  111. andi r3, r3, 0x3 /* mask unaligned */
  112. bneid r3, 1f /* it is unaligned -> then jump */
  113. or r3, r0, r0
  114. /* at least one 4 byte copy */
  115. 5: lw r4, r6, r3
  116. 6: sw r4, r5, r3
  117. addik r7, r7, -4
  118. bneid r7, 5b
  119. addik r3, r3, 4
  120. addik r3, r7, 0
  121. rtsd r15, 8
  122. nop
  123. 4: or r3, r0, r0
  124. 1: lbu r4,r6,r3
  125. 2: sb r4,r5,r3
  126. addik r7,r7,-1
  127. bneid r7,1b
  128. addik r3,r3,1 /* delay slot */
  129. 3:
  130. addik r3,r7,0
  131. rtsd r15,8
  132. nop
  133. .size __copy_tofrom_user, . - __copy_tofrom_user
  134. .section __ex_table,"a"
  135. .word 1b,3b,2b,3b,5b,3b,6b,3b