lusercopy.S 4.0 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. .text
  33. #include <asm/assembly.h>
  34. #include <asm/errno.h>
  35. #include <linux/linkage.h>
  36. /*
  37. * get_sr gets the appropriate space value into
  38. * sr1 for kernel/user space access, depending
  39. * on the flag stored in the task structure.
  40. */
  41. .macro get_sr
  42. mfctl %cr30,%r1
  43. ldw TI_SEGMENT(%r1),%r22
  44. mfsp %sr3,%r1
  45. or,<> %r22,%r0,%r0
  46. copy %r0,%r1
  47. mtsp %r1,%sr1
  48. .endm
  49. .macro fixup_branch lbl
  50. ldil L%\lbl, %r1
  51. ldo R%\lbl(%r1), %r1
  52. bv %r0(%r1)
  53. .endm
  54. /*
  55. * long lstrncpy_from_user(char *dst, const char *src, long n)
  56. *
  57. * Returns -EFAULT if exception before terminator,
  58. * N if the entire buffer filled,
  59. * otherwise strlen (i.e. excludes zero byte)
  60. */
  61. ENTRY(lstrncpy_from_user)
  62. .proc
  63. .callinfo NO_CALLS
  64. .entry
  65. comib,= 0,%r24,$lsfu_done
  66. copy %r24,%r23
  67. get_sr
  68. 1: ldbs,ma 1(%sr1,%r25),%r1
  69. $lsfu_loop:
  70. stbs,ma %r1,1(%r26)
  71. comib,=,n 0,%r1,$lsfu_done
  72. addib,<>,n -1,%r24,$lsfu_loop
  73. 2: ldbs,ma 1(%sr1,%r25),%r1
  74. $lsfu_done:
  75. sub %r23,%r24,%r28
  76. $lsfu_exit:
  77. bv %r0(%r2)
  78. nop
  79. .exit
  80. ENDPROC(lstrncpy_from_user)
  81. .section .fixup,"ax"
  82. 3: fixup_branch $lsfu_exit
  83. ldi -EFAULT,%r28
  84. .previous
  85. .section __ex_table,"aw"
  86. ASM_ULONG_INSN 1b,3b
  87. ASM_ULONG_INSN 2b,3b
  88. .previous
  89. .procend
  90. /*
  91. * unsigned long lclear_user(void *to, unsigned long n)
  92. *
  93. * Returns 0 for success.
  94. * otherwise, returns number of bytes not transferred.
  95. */
  96. ENTRY(lclear_user)
  97. .proc
  98. .callinfo NO_CALLS
  99. .entry
  100. comib,=,n 0,%r25,$lclu_done
  101. get_sr
  102. $lclu_loop:
  103. addib,<> -1,%r25,$lclu_loop
  104. 1: stbs,ma %r0,1(%sr1,%r26)
  105. $lclu_done:
  106. bv %r0(%r2)
  107. copy %r25,%r28
  108. .exit
  109. ENDPROC(lclear_user)
  110. .section .fixup,"ax"
  111. 2: fixup_branch $lclu_done
  112. ldo 1(%r25),%r25
  113. .previous
  114. .section __ex_table,"aw"
  115. ASM_ULONG_INSN 1b,2b
  116. .previous
  117. .procend
  118. /*
  119. * long lstrnlen_user(char *s, long n)
  120. *
  121. * Returns 0 if exception before zero byte or reaching N,
  122. * N+1 if N would be exceeded,
  123. * else strlen + 1 (i.e. includes zero byte).
  124. */
  125. ENTRY(lstrnlen_user)
  126. .proc
  127. .callinfo NO_CALLS
  128. .entry
  129. comib,= 0,%r25,$lslen_nzero
  130. copy %r26,%r24
  131. get_sr
  132. 1: ldbs,ma 1(%sr1,%r26),%r1
  133. $lslen_loop:
  134. comib,=,n 0,%r1,$lslen_done
  135. addib,<> -1,%r25,$lslen_loop
  136. 2: ldbs,ma 1(%sr1,%r26),%r1
  137. $lslen_done:
  138. bv %r0(%r2)
  139. sub %r26,%r24,%r28
  140. .exit
  141. $lslen_nzero:
  142. b $lslen_done
  143. ldo 1(%r26),%r26 /* special case for N == 0 */
  144. ENDPROC(lstrnlen_user)
  145. .section .fixup,"ax"
  146. 3: fixup_branch $lslen_done
  147. copy %r24,%r26 /* reset r26 so 0 is returned on fault */
  148. .previous
  149. .section __ex_table,"aw"
  150. ASM_ULONG_INSN 1b,3b
  151. ASM_ULONG_INSN 2b,3b
  152. .previous
  153. .procend
  154. .end