lusercopy.S 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. * unsigned long lclear_user(void *to, unsigned long n)
  56. *
  57. * Returns 0 for success.
  58. * otherwise, returns number of bytes not transferred.
  59. */
  60. ENTRY(lclear_user)
  61. .proc
  62. .callinfo NO_CALLS
  63. .entry
  64. comib,=,n 0,%r25,$lclu_done
  65. get_sr
  66. $lclu_loop:
  67. addib,<> -1,%r25,$lclu_loop
  68. 1: stbs,ma %r0,1(%sr1,%r26)
  69. $lclu_done:
  70. bv %r0(%r2)
  71. copy %r25,%r28
  72. .exit
  73. ENDPROC(lclear_user)
  74. .section .fixup,"ax"
  75. 2: fixup_branch $lclu_done
  76. ldo 1(%r25),%r25
  77. .previous
  78. .section __ex_table,"aw"
  79. ASM_ULONG_INSN 1b,2b
  80. .previous
  81. .procend
  82. /*
  83. * long lstrnlen_user(char *s, long n)
  84. *
  85. * Returns 0 if exception before zero byte or reaching N,
  86. * N+1 if N would be exceeded,
  87. * else strlen + 1 (i.e. includes zero byte).
  88. */
  89. ENTRY(lstrnlen_user)
  90. .proc
  91. .callinfo NO_CALLS
  92. .entry
  93. comib,= 0,%r25,$lslen_nzero
  94. copy %r26,%r24
  95. get_sr
  96. 1: ldbs,ma 1(%sr1,%r26),%r1
  97. $lslen_loop:
  98. comib,=,n 0,%r1,$lslen_done
  99. addib,<> -1,%r25,$lslen_loop
  100. 2: ldbs,ma 1(%sr1,%r26),%r1
  101. $lslen_done:
  102. bv %r0(%r2)
  103. sub %r26,%r24,%r28
  104. .exit
  105. $lslen_nzero:
  106. b $lslen_done
  107. ldo 1(%r26),%r26 /* special case for N == 0 */
  108. ENDPROC(lstrnlen_user)
  109. .section .fixup,"ax"
  110. 3: fixup_branch $lslen_done
  111. copy %r24,%r26 /* reset r26 so 0 is returned on fault */
  112. .previous
  113. .section __ex_table,"aw"
  114. ASM_ULONG_INSN 1b,3b
  115. ASM_ULONG_INSN 2b,3b
  116. .previous
  117. .procend
  118. .end