uaccess-asm.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * linux/include/asm-arm/proc-armo/uaccess.h
  3. *
  4. * Copyright (C) 1996 Russell King
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. /*
  11. * The fs functions are implemented on the ARM2 and ARM3 architectures
  12. * manually.
  13. * Use *_user functions to access user memory with faulting behaving
  14. * as though the user is accessing the memory.
  15. * Use set_fs(get_ds()) and then the *_user functions to allow them to
  16. * access kernel memory.
  17. */
  18. /*
  19. * These are the values used to represent the user `fs' and the kernel `ds'
  20. * FIXME - the KERNEL_DS should end at 0x03000000 but we want to access ROM at
  21. * 0x03400000. ideally we want to forbid access to the IO space inbetween.
  22. */
  23. #define KERNEL_DS 0x03FFFFFF
  24. #define USER_DS 0x02000000
  25. extern uaccess_t uaccess_user, uaccess_kernel;
  26. static inline void set_fs (mm_segment_t fs)
  27. {
  28. current_thread_info()->addr_limit = fs;
  29. current->thread.uaccess = (fs == USER_DS ? &uaccess_user : &uaccess_kernel);
  30. }
  31. #define __range_ok(addr,size) ({ \
  32. unsigned long flag, sum; \
  33. __asm__ __volatile__("subs %1, %0, %3; cmpcs %1, %2; movcs %0, #0" \
  34. : "=&r" (flag), "=&r" (sum) \
  35. : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
  36. : "cc"); \
  37. flag; })
  38. #define __addr_ok(addr) ({ \
  39. unsigned long flag; \
  40. __asm__ __volatile__("cmp %2, %0; movlo %0, #0" \
  41. : "=&r" (flag) \
  42. : "0" (current_thread_info()->addr_limit), "r" (addr) \
  43. : "cc"); \
  44. (flag == 0); })
  45. #define __put_user_asm_byte(x,addr,err) \
  46. __asm__ __volatile__( \
  47. " mov r0, %1\n" \
  48. " mov r1, %2\n" \
  49. " mov r2, %0\n" \
  50. " mov lr, pc\n" \
  51. " mov pc, %3\n" \
  52. " mov %0, r2\n" \
  53. : "=r" (err) \
  54. : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_byte), \
  55. "0" (err) \
  56. : "r0", "r1", "r2", "lr")
  57. #define __put_user_asm_half(x,addr,err) \
  58. __asm__ __volatile__( \
  59. " mov r0, %1\n" \
  60. " mov r1, %2\n" \
  61. " mov r2, %0\n" \
  62. " mov lr, pc\n" \
  63. " mov pc, %3\n" \
  64. " mov %0, r2\n" \
  65. : "=r" (err) \
  66. : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_half), \
  67. "0" (err) \
  68. : "r0", "r1", "r2", "lr")
  69. #define __put_user_asm_word(x,addr,err) \
  70. __asm__ __volatile__( \
  71. " mov r0, %1\n" \
  72. " mov r1, %2\n" \
  73. " mov r2, %0\n" \
  74. " mov lr, pc\n" \
  75. " mov pc, %3\n" \
  76. " mov %0, r2\n" \
  77. : "=r" (err) \
  78. : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_word), \
  79. "0" (err) \
  80. : "r0", "r1", "r2", "lr")
  81. #define __put_user_asm_dword(x,addr,err) \
  82. __asm__ __volatile__( \
  83. " mov r0, %1\n" \
  84. " mov r1, %2\n" \
  85. " mov r2, %0\n" \
  86. " mov lr, pc\n" \
  87. " mov pc, %3\n" \
  88. " mov %0, r2\n" \
  89. : "=r" (err) \
  90. : "r" (x), "r" (addr), "r" (current->thread.uaccess->put_dword), \
  91. "0" (err) \
  92. : "r0", "r1", "r2", "lr")
  93. #define __get_user_asm_byte(x,addr,err) \
  94. __asm__ __volatile__( \
  95. " mov r0, %2\n" \
  96. " mov r1, %0\n" \
  97. " mov lr, pc\n" \
  98. " mov pc, %3\n" \
  99. " mov %0, r1\n" \
  100. " mov %1, r0\n" \
  101. : "=r" (err), "=r" (x) \
  102. : "r" (addr), "r" (current->thread.uaccess->get_byte), "0" (err) \
  103. : "r0", "r1", "r2", "lr")
  104. #define __get_user_asm_half(x,addr,err) \
  105. __asm__ __volatile__( \
  106. " mov r0, %2\n" \
  107. " mov r1, %0\n" \
  108. " mov lr, pc\n" \
  109. " mov pc, %3\n" \
  110. " mov %0, r1\n" \
  111. " mov %1, r0\n" \
  112. : "=r" (err), "=r" (x) \
  113. : "r" (addr), "r" (current->thread.uaccess->get_half), "0" (err) \
  114. : "r0", "r1", "r2", "lr")
  115. #define __get_user_asm_word(x,addr,err) \
  116. __asm__ __volatile__( \
  117. " mov r0, %2\n" \
  118. " mov r1, %0\n" \
  119. " mov lr, pc\n" \
  120. " mov pc, %3\n" \
  121. " mov %0, r1\n" \
  122. " mov %1, r0\n" \
  123. : "=r" (err), "=r" (x) \
  124. : "r" (addr), "r" (current->thread.uaccess->get_word), "0" (err) \
  125. : "r0", "r1", "r2", "lr")
  126. #define __do_copy_from_user(to,from,n) \
  127. (n) = current->thread.uaccess->copy_from_user((to),(from),(n))
  128. #define __do_copy_to_user(to,from,n) \
  129. (n) = current->thread.uaccess->copy_to_user((to),(from),(n))
  130. #define __do_clear_user(addr,sz) \
  131. (sz) = current->thread.uaccess->clear_user((addr),(sz))
  132. #define __do_strncpy_from_user(dst,src,count,res) \
  133. (res) = current->thread.uaccess->strncpy_from_user(dst,src,count)
  134. #define __do_strnlen_user(s,n,res) \
  135. (res) = current->thread.uaccess->strnlen_user(s,n)