copy_to_user.S 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * linux/arch/arm/lib/copy_to_user.S
  3. *
  4. * Author: Nicolas Pitre
  5. * Created: Sep 29, 2005
  6. * Copyright: MontaVista Software, Inc.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/linkage.h>
  13. #include <asm/assembler.h>
  14. #include <asm/unwind.h>
  15. #include <asm/export.h>
  16. /*
  17. * Prototype:
  18. *
  19. * size_t arm_copy_to_user(void *to, const void *from, size_t n)
  20. *
  21. * Purpose:
  22. *
  23. * copy a block to user memory from kernel memory
  24. *
  25. * Params:
  26. *
  27. * to = user memory
  28. * from = kernel memory
  29. * n = number of bytes to copy
  30. *
  31. * Return value:
  32. *
  33. * Number of bytes NOT copied.
  34. */
  35. #define LDR1W_SHIFT 0
  36. #ifndef CONFIG_THUMB2_KERNEL
  37. #define STR1W_SHIFT 0
  38. #else
  39. #define STR1W_SHIFT 1
  40. #endif
  41. .macro ldr1w ptr reg abort
  42. W(ldr) \reg, [\ptr], #4
  43. .endm
  44. .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
  45. ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
  46. .endm
  47. .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
  48. ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
  49. .endm
  50. .macro ldr1b ptr reg cond=al abort
  51. ldr\cond\()b \reg, [\ptr], #1
  52. .endm
  53. .macro str1w ptr reg abort
  54. strusr \reg, \ptr, 4, abort=\abort
  55. .endm
  56. .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
  57. str1w \ptr, \reg1, \abort
  58. str1w \ptr, \reg2, \abort
  59. str1w \ptr, \reg3, \abort
  60. str1w \ptr, \reg4, \abort
  61. str1w \ptr, \reg5, \abort
  62. str1w \ptr, \reg6, \abort
  63. str1w \ptr, \reg7, \abort
  64. str1w \ptr, \reg8, \abort
  65. .endm
  66. .macro str1b ptr reg cond=al abort
  67. strusr \reg, \ptr, 1, \cond, abort=\abort
  68. .endm
  69. .macro enter reg1 reg2
  70. mov r3, #0
  71. stmdb sp!, {r0, r2, r3, \reg1, \reg2}
  72. .endm
  73. .macro usave reg1 reg2
  74. UNWIND( .save {r0, r2, r3, \reg1, \reg2} )
  75. .endm
  76. .macro exit reg1 reg2
  77. add sp, sp, #8
  78. ldmfd sp!, {r0, \reg1, \reg2}
  79. .endm
  80. .text
  81. ENTRY(__copy_to_user_std)
  82. WEAK(arm_copy_to_user)
  83. #include "copy_template.S"
  84. ENDPROC(arm_copy_to_user)
  85. ENDPROC(__copy_to_user_std)
  86. #ifndef CONFIG_UACCESS_WITH_MEMCPY
  87. EXPORT_SYMBOL(arm_copy_to_user)
  88. #endif
  89. .pushsection .text.fixup,"ax"
  90. .align 0
  91. copy_abort_preamble
  92. ldmfd sp!, {r1, r2, r3}
  93. sub r0, r0, r1
  94. rsb r0, r0, r2
  95. copy_abort_end
  96. .popsection