lusercopy.S 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * User Space Access Routines
  3. *
  4. * Copyright (C) 2000-2002 Hewlett-Packard (John Marvin)
  5. * Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org>
  6. * Copyright (C) 2001 Matthieu Delahaye <delahaym at esiee.fr>
  7. * Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org>
  8. *
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2, or (at your option)
  13. * any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. /*
  25. * These routines still have plenty of room for optimization
  26. * (word & doubleword load/store, dual issue, store hints, etc.).
  27. */
  28. /*
  29. * The following routines assume that space register 3 (sr3) contains
  30. * the space id associated with the current users address space.
  31. */
  32. #include <asm/assembly.h>
  33. #include <asm/errno.h>
  34. #include <linux/linkage.h>
  35. #include <linux/init.h>
  36. __HEAD
  37. /*
  38. * get_sr gets the appropriate space value into
  39. * sr1 for kernel/user space access, depending
  40. * on the flag stored in the task structure.
  41. */
  42. .macro get_sr
  43. mfctl %cr30,%r1
  44. ldw TI_SEGMENT(%r1),%r22
  45. mfsp %sr3,%r1
  46. or,<> %r22,%r0,%r0
  47. copy %r0,%r1
  48. mtsp %r1,%sr1
  49. .endm
  50. .macro fixup_branch lbl
  51. ldil L%\lbl, %r1
  52. ldo R%\lbl(%r1), %r1
  53. bv %r0(%r1)
  54. .endm
  55. /*
  56. * long lstrncpy_from_user(char *dst, const char *src, long n)
  57. *
  58. * Returns -EFAULT if exception before terminator,
  59. * N if the entire buffer filled,
  60. * otherwise strlen (i.e. excludes zero byte)
  61. */
  62. ENTRY(lstrncpy_from_user)
  63. .proc
  64. .callinfo NO_CALLS
  65. .entry
  66. comib,= 0,%r24,$lsfu_done
  67. copy %r24,%r23
  68. get_sr
  69. 1: ldbs,ma 1(%sr1,%r25),%r1
  70. $lsfu_loop:
  71. stbs,ma %r1,1(%r26)
  72. comib,=,n 0,%r1,$lsfu_done
  73. addib,<>,n -1,%r24,$lsfu_loop
  74. 2: ldbs,ma 1(%sr1,%r25),%r1
  75. $lsfu_done:
  76. sub %r23,%r24,%r28
  77. $lsfu_exit:
  78. bv %r0(%r2)
  79. nop
  80. .exit
  81. ENDPROC(lstrncpy_from_user)
  82. .section .fixup,"ax"
  83. 3: fixup_branch $lsfu_exit
  84. ldi -EFAULT,%r28
  85. .previous
  86. .section __ex_table,"aw"
  87. ASM_ULONG_INSN 1b,3b
  88. ASM_ULONG_INSN 2b,3b
  89. .previous
  90. .procend
  91. /*
  92. * unsigned long lclear_user(void *to, unsigned long n)
  93. *
  94. * Returns 0 for success.
  95. * otherwise, returns number of bytes not transferred.
  96. */
  97. ENTRY(lclear_user)
  98. .proc
  99. .callinfo NO_CALLS
  100. .entry
  101. comib,=,n 0,%r25,$lclu_done
  102. get_sr
  103. $lclu_loop:
  104. addib,<> -1,%r25,$lclu_loop
  105. 1: stbs,ma %r0,1(%sr1,%r26)
  106. $lclu_done:
  107. bv %r0(%r2)
  108. copy %r25,%r28
  109. .exit
  110. ENDPROC(lclear_user)
  111. .section .fixup,"ax"
  112. 2: fixup_branch $lclu_done
  113. ldo 1(%r25),%r25
  114. .previous
  115. .section __ex_table,"aw"
  116. ASM_ULONG_INSN 1b,2b
  117. .previous
  118. .procend
  119. /*
  120. * long lstrnlen_user(char *s, long n)
  121. *
  122. * Returns 0 if exception before zero byte or reaching N,
  123. * N+1 if N would be exceeded,
  124. * else strlen + 1 (i.e. includes zero byte).
  125. */
  126. ENTRY(lstrnlen_user)
  127. .proc
  128. .callinfo NO_CALLS
  129. .entry
  130. comib,= 0,%r25,$lslen_nzero
  131. copy %r26,%r24
  132. get_sr
  133. 1: ldbs,ma 1(%sr1,%r26),%r1
  134. $lslen_loop:
  135. comib,=,n 0,%r1,$lslen_done
  136. addib,<> -1,%r25,$lslen_loop
  137. 2: ldbs,ma 1(%sr1,%r26),%r1
  138. $lslen_done:
  139. bv %r0(%r2)
  140. sub %r26,%r24,%r28
  141. .exit
  142. $lslen_nzero:
  143. b $lslen_done
  144. ldo 1(%r26),%r26 /* special case for N == 0 */
  145. ENDPROC(lstrnlen_user)
  146. .section .fixup,"ax"
  147. 3: fixup_branch $lslen_done
  148. copy %r24,%r26 /* reset r26 so 0 is returned on fault */
  149. .previous
  150. .section __ex_table,"aw"
  151. ASM_ULONG_INSN 1b,3b
  152. ASM_ULONG_INSN 2b,3b
  153. .previous
  154. .procend
  155. .end