uaccess.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef __PARISC_UACCESS_H
  2. #define __PARISC_UACCESS_H
  3. /*
  4.  * User space memory access functions
  5.  */
  6. #include <linux/sched.h>
  7. #include <asm/page.h>
  8. #include <asm/system.h>
  9. #include <asm/cache.h>
  10. #define VERIFY_READ 0
  11. #define VERIFY_WRITE 1
  12. #define KERNEL_DS ((mm_segment_t){0})
  13. #define USER_DS  ((mm_segment_t){1})
  14. #define segment_eq(a,b) ((a).seg == (b).seg)
  15. #define get_ds() (KERNEL_DS)
  16. #define get_fs() (current->addr_limit)
  17. #define set_fs(x) (current->addr_limit = (x))
  18. /*
  19.  * Note that since kernel addresses are in a separate address space on
  20.  * parisc, we don't need to do anything for access_ok() or verify_area().
  21.  * We just let the page fault handler do the right thing. This also means
  22.  * that put_user is the same as __put_user, etc.
  23.  */
  24. #define access_ok(type,addr,size)   (1)
  25. #define verify_area(type,addr,size) (0)
  26. #define put_user __put_user
  27. #define get_user __get_user
  28. /*
  29.  * The exception table contains two values: the first is an address
  30.  * for an instruction that is allowed to fault, and the second is
  31.  * the number of bytes to skip if a fault occurs. We also support in
  32.  * two bit flags: 0x2 tells the exception handler to clear register
  33.  * r9 and 0x1 tells the exception handler to put -EFAULT in r8.
  34.  * This allows us to handle the simple cases for put_user and
  35.  * get_user without having to have .fixup sections.
  36.  */
  37. struct exception_table_entry {
  38. unsigned long addr;  /* address of insn that is allowed to fault.   */
  39. int skip;            /* pcoq skip | r9 clear flag | r8 -EFAULT flag */
  40. };
  41. extern const struct exception_table_entry 
  42.     *search_exception_table(unsigned long addr);
  43. #define __get_user(x,ptr)                               
  44. ({                                                      
  45. register long __gu_err __asm__ ("r8") = 0;      
  46. register long __gu_val __asm__ ("r9") = 0;      
  47. if (segment_eq(get_fs(),KERNEL_DS)) {           
  48.     switch (sizeof(*(ptr))) {                   
  49.     case 1: __get_kernel_asm("ldb",ptr); break; 
  50.     case 2: __get_kernel_asm("ldh",ptr); break; 
  51.     case 4: __get_kernel_asm("ldw",ptr); break; 
  52.     case 8: __get_kernel_asm("ldd",ptr); break; 
  53.     default: BUG(); break;                      
  54.     }                                           
  55. }                                               
  56. else {                                          
  57.     switch (sizeof(*(ptr))) {                   
  58.     case 1: __get_user_asm("ldb",ptr); break;   
  59.     case 2: __get_user_asm("ldh",ptr); break;   
  60.     case 4: __get_user_asm("ldw",ptr); break;   
  61.     case 8: __get_user_asm("ldd",ptr); break;   
  62.     default: BUG(); break;                      
  63.     }                                           
  64. }                                               
  65. (x) = (__typeof__(*(ptr))) __gu_val;            
  66. __gu_err;                                       
  67. })
  68. #define __get_kernel_asm(ldx,ptr)                       
  69. __asm__("n1:t" ldx "t0(%2),%0n"             
  70. "2:n"
  71. "t.section __ex_table,"a"n"         
  72.  "t.wordt1bn"                        
  73.  "t.wordt(2b-1b)+3n"                 
  74.  "t.previous"                          
  75. : "=r"(__gu_val), "=r"(__gu_err)        
  76. : "r"(ptr), "1"(__gu_err));
  77. #define __get_user_asm(ldx,ptr)                         
  78. __asm__("n1:t" ldx "t0(%%sr3,%2),%0n"       
  79. "2:n"
  80. "t.section __ex_table,"a"n"         
  81.  "t.wordt1bn"                        
  82.  "t.wordt(2b-1b)+3n"                 
  83.  "t.previous"                          
  84. : "=r"(__gu_val), "=r"(__gu_err)        
  85. : "r"(ptr), "1"(__gu_err));
  86. #define __put_user(x,ptr)                                       
  87. ({
  88. register long __pu_err __asm__ ("r8") = 0;
  89. if (segment_eq(get_fs(),KERNEL_DS)) {                   
  90.     switch (sizeof(*(ptr))) {                           
  91.     case 1: __put_kernel_asm("stb",x,ptr); break;       
  92.     case 2: __put_kernel_asm("sth",x,ptr); break;       
  93.     case 4: __put_kernel_asm("stw",x,ptr); break;       
  94.     case 8: __put_kernel_asm("std",x,ptr); break;       
  95.     default: BUG(); break;                              
  96.     }                                                   
  97. }                                                       
  98. else {                                                  
  99.     switch (sizeof(*(ptr))) {                           
  100.     case 1: __put_user_asm("stb",x,ptr); break;         
  101.     case 2: __put_user_asm("sth",x,ptr); break;         
  102.     case 4: __put_user_asm("stw",x,ptr); break;         
  103.     case 8: __put_user_asm("std",x,ptr); break;         
  104.     default: BUG(); break;                              
  105.     }                                                   
  106. }                                                       
  107. __pu_err;
  108. })
  109. /*
  110.  * The "__put_user/kernel_asm()" macros tell gcc they read from memory
  111.  * instead of writing. This is because they do not write to any memory
  112.  * gcc knows about, so there are no aliasing issues.
  113.  */
  114. #define __put_kernel_asm(stx,x,ptr)                         
  115. __asm__ __volatile__ (                              
  116. "n1:t" stx "t%2,0(%1)n"                 
  117. "2:n"     
  118. "t.section __ex_table,"a"n"             
  119.  "t.wordt1bn"                            
  120.  "t.wordt(2b-1b)+1n"                     
  121.  "t.previous"                              
  122. : "=r"(__pu_err)                            
  123. : "r"(ptr), "r"(x), "0"(__pu_err))
  124. #define __put_user_asm(stx,x,ptr)                           
  125. __asm__ __volatile__ (                              
  126. "n1:t" stx "t%2,0(%%sr3,%1)n"           
  127. "2:n"     
  128. "t.section __ex_table,"a"n"             
  129.  "t.wordt1bn"                            
  130.  "t.wordt(2b-1b)+1n"                     
  131.  "t.previous"                              
  132. : "=r"(__pu_err)                            
  133. : "r"(ptr), "r"(x), "0"(__pu_err))
  134. /*
  135.  * Complex access routines -- external declarations
  136.  */
  137. extern unsigned long lcopy_to_user(void *, const void *, unsigned long);
  138. extern unsigned long lcopy_from_user(void *, const void *, unsigned long);
  139. extern long lstrncpy_from_user(char *, const char *, long);
  140. extern unsigned lclear_user(void *,unsigned long);
  141. extern long lstrnlen_user(const char *,long);
  142. /*
  143.  * Complex access routines -- macros
  144.  */
  145. #define strncpy_from_user lstrncpy_from_user
  146. #define strnlen_user lstrnlen_user
  147. #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL)
  148. #define clear_user lclear_user
  149. #define copy_from_user lcopy_from_user
  150. #define __copy_from_user lcopy_from_user
  151. #define copy_to_user lcopy_to_user
  152. #define __copy_to_user lcopy_to_user
  153. #define copy_to_user_ret(to,from,n,retval) 
  154.     ({ if (lcopy_to_user(to,from,n)) return retval; })
  155. #define copy_from_user_ret(to,from,n,retval) 
  156.     ({ if (lcopy_from_user(to,from,n)) return retval; })
  157. #endif /* __PARISC_UACCESS_H */