home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / asm-m68k / uaccess.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  9.8 KB  |  375 lines

  1. #ifndef __M68K_UACCESS_H
  2. #define __M68K_UACCESS_H
  3.  
  4. /*
  5.  * User space memory access functions
  6.  */
  7. #include <linux/compiler.h>
  8. #include <linux/errno.h>
  9. #include <linux/types.h>
  10. #include <linux/sched.h>
  11. #include <asm/segment.h>
  12.  
  13. #define VERIFY_READ    0
  14. #define VERIFY_WRITE    1
  15.  
  16. /* We let the MMU do all checking */
  17. static inline int access_ok(int type, const void __user *addr,
  18.                 unsigned long size)
  19. {
  20.     return 1;
  21. }
  22.  
  23. /*
  24.  * The exception table consists of pairs of addresses: the first is the
  25.  * address of an instruction that is allowed to fault, and the second is
  26.  * the address at which the program should continue.  No registers are
  27.  * modified, so it is entirely up to the continuation code to figure out
  28.  * what to do.
  29.  *
  30.  * All the routines below use bits of fixup code that are out of line
  31.  * with the main instruction path.  This means when everything is well,
  32.  * we don't even have to jump over them.  Further, they do not intrude
  33.  * on our cache or tlb entries.
  34.  */
  35.  
  36. struct exception_table_entry
  37. {
  38.     unsigned long insn, fixup;
  39. };
  40.  
  41. extern int __put_user_bad(void);
  42. extern int __get_user_bad(void);
  43.  
  44. #define __put_user_asm(res, x, ptr, bwl, reg, err)    \
  45. asm volatile ("\n"                    \
  46.     "1:    moves."#bwl"    %2,%1\n"        \
  47.     "2:\n"                        \
  48.     "    .section .fixup,\"ax\"\n"        \
  49.     "    .even\n"                \
  50.     "10:    moveq.l    %3,%0\n"            \
  51.     "    jra 2b\n"                \
  52.     "    .previous\n"                \
  53.     "\n"                        \
  54.     "    .section __ex_table,\"a\"\n"        \
  55.     "    .align    4\n"                \
  56.     "    .long    1b,10b\n"            \
  57.     "    .long    2b,10b\n"            \
  58.     "    .previous"                \
  59.     : "+d" (res), "=m" (*(ptr))            \
  60.     : #reg (x), "i" (err))
  61.  
  62. /*
  63.  * These are the main single-value transfer routines.  They automatically
  64.  * use the right size if we just have the right pointer type.
  65.  */
  66.  
  67. #define __put_user(x, ptr)                        \
  68. ({                                    \
  69.     typeof(*(ptr)) __pu_val = (x);                    \
  70.     int __pu_err = 0;                        \
  71.     __chk_user_ptr(ptr);                        \
  72.     switch (sizeof (*(ptr))) {                    \
  73.     case 1:                                \
  74.         __put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT);    \
  75.         break;                            \
  76.     case 2:                                \
  77.         __put_user_asm(__pu_err, __pu_val, ptr, w, d, -EFAULT);    \
  78.         break;                            \
  79.     case 4:                                \
  80.         __put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT);    \
  81.         break;                            \
  82.     case 8:                                \
  83.          {                                \
  84.          const void __user *__pu_ptr = (ptr);            \
  85.         asm volatile ("\n"                    \
  86.             "1:    moves.l    %2,(%1)+\n"            \
  87.             "2:    moves.l    %R2,(%1)\n"            \
  88.             "3:\n"                        \
  89.             "    .section .fixup,\"ax\"\n"        \
  90.             "    .even\n"                \
  91.             "10:    movel %3,%0\n"                \
  92.             "    jra 3b\n"                \
  93.             "    .previous\n"                \
  94.             "\n"                        \
  95.             "    .section __ex_table,\"a\"\n"        \
  96.             "    .align 4\n"                \
  97.             "    .long 1b,10b\n"                \
  98.             "    .long 2b,10b\n"                \
  99.             "    .long 3b,10b\n"                \
  100.             "    .previous"                \
  101.             : "+d" (__pu_err), "+a" (__pu_ptr)        \
  102.             : "r" (__pu_val), "i" (-EFAULT)            \
  103.             : "memory");                    \
  104.         break;                            \
  105.         }                                \
  106.     default:                            \
  107.         __pu_err = __put_user_bad();                \
  108.         break;                            \
  109.     }                                \
  110.     __pu_err;                            \
  111. })
  112. #define put_user(x, ptr)    __put_user(x, ptr)
  113.  
  114.  
  115. #define __get_user_asm(res, x, ptr, type, bwl, reg, err) ({    \
  116.     type __gu_val;                        \
  117.     asm volatile ("\n"                    \
  118.         "1:    moves."#bwl"    %2,%1\n"        \
  119.         "2:\n"                        \
  120.         "    .section .fixup,\"ax\"\n"        \
  121.         "    .even\n"                \
  122.         "10:    move.l    %3,%0\n"            \
  123.         "    sub."#bwl"    %1,%1\n"        \
  124.         "    jra    2b\n"                \
  125.         "    .previous\n"                \
  126.         "\n"                        \
  127.         "    .section __ex_table,\"a\"\n"        \
  128.         "    .align    4\n"                \
  129.         "    .long    1b,10b\n"            \
  130.         "    .previous"                \
  131.         : "+d" (res), "=&" #reg (__gu_val)        \
  132.         : "m" (*(ptr)), "i" (err));            \
  133.     (x) = (typeof(*(ptr)))(unsigned long)__gu_val;        \
  134. })
  135.  
  136. #define __get_user(x, ptr)                        \
  137. ({                                    \
  138.     int __gu_err = 0;                        \
  139.     __chk_user_ptr(ptr);                        \
  140.     switch (sizeof(*(ptr))) {                    \
  141.     case 1:                                \
  142.         __get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT);    \
  143.         break;                            \
  144.     case 2:                                \
  145.         __get_user_asm(__gu_err, x, ptr, u16, w, d, -EFAULT);    \
  146.         break;                            \
  147.     case 4:                                \
  148.         __get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT);    \
  149.         break;                            \
  150. /*    case 8:    disabled because gcc-4.1 has a broken typeof        \
  151.          {                                \
  152.          const void *__gu_ptr = (ptr);                \
  153.          u64 __gu_val;                        \
  154.         asm volatile ("\n"                    \
  155.             "1:    moves.l    (%2)+,%1\n"            \
  156.             "2:    moves.l    (%2),%R1\n"            \
  157.             "3:\n"                        \
  158.             "    .section .fixup,\"ax\"\n"        \
  159.             "    .even\n"                \
  160.             "10:    move.l    %3,%0\n"            \
  161.             "    sub.l    %1,%1\n"            \
  162.             "    sub.l    %R1,%R1\n"            \
  163.             "    jra    3b\n"                \
  164.             "    .previous\n"                \
  165.             "\n"                        \
  166.             "    .section __ex_table,\"a\"\n"        \
  167.             "    .align    4\n"                \
  168.             "    .long    1b,10b\n"            \
  169.             "    .long    2b,10b\n"            \
  170.             "    .previous"                \
  171.             : "+d" (__gu_err), "=&r" (__gu_val),        \
  172.               "+a" (__gu_ptr)                \
  173.             : "i" (-EFAULT)                    \
  174.             : "memory");                    \
  175.         (x) = (typeof(*(ptr)))__gu_val;                \
  176.         break;                            \
  177.         }    */                            \
  178.     default:                            \
  179.         __gu_err = __get_user_bad();                \
  180.         break;                            \
  181.     }                                \
  182.     __gu_err;                            \
  183. })
  184. #define get_user(x, ptr) __get_user(x, ptr)
  185.  
  186. unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n);
  187. unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n);
  188.  
  189. #define __constant_copy_from_user_asm(res, to, from, tmp, n, s1, s2, s3)\
  190.     asm volatile ("\n"                        \
  191.         "1:    moves."#s1"    (%2)+,%3\n"            \
  192.         "    move."#s1"    %3,(%1)+\n"            \
  193.         "2:    moves."#s2"    (%2)+,%3\n"            \
  194.         "    move."#s2"    %3,(%1)+\n"            \
  195.         "    .ifnc    \""#s3"\",\"\"\n"            \
  196.         "3:    moves."#s3"    (%2)+,%3\n"            \
  197.         "    move."#s3"    %3,(%1)+\n"            \
  198.         "    .endif\n"                    \
  199.         "4:\n"                            \
  200.         "    .section __ex_table,\"a\"\n"            \
  201.         "    .align    4\n"                    \
  202.         "    .long    1b,10f\n"                \
  203.         "    .long    2b,20f\n"                \
  204.         "    .ifnc    \""#s3"\",\"\"\n"            \
  205.         "    .long    3b,30f\n"                \
  206.         "    .endif\n"                    \
  207.         "    .previous\n"                    \
  208.         "\n"                            \
  209.         "    .section .fixup,\"ax\"\n"            \
  210.         "    .even\n"                    \
  211.         "10:    clr."#s1"    (%1)+\n"            \
  212.         "20:    clr."#s2"    (%1)+\n"            \
  213.         "    .ifnc    \""#s3"\",\"\"\n"            \
  214.         "30:    clr."#s3"    (%1)+\n"            \
  215.         "    .endif\n"                    \
  216.         "    moveq.l    #"#n",%0\n"                \
  217.         "    jra    4b\n"                    \
  218.         "    .previous\n"                    \
  219.         : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp)    \
  220.         : : "memory")
  221.  
  222. static __always_inline unsigned long
  223. __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
  224. {
  225.     unsigned long res = 0, tmp;
  226.  
  227.     switch (n) {
  228.     case 1:
  229.         __get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1);
  230.         break;
  231.     case 2:
  232.         __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, d, 2);
  233.         break;
  234.     case 3:
  235.         __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,);
  236.         break;
  237.     case 4:
  238.         __get_user_asm(res, *(u32 *)to, (u32 __user *)from, u32, l, r, 4);
  239.         break;
  240.     case 5:
  241.         __constant_copy_from_user_asm(res, to, from, tmp, 5, l, b,);
  242.         break;
  243.     case 6:
  244.         __constant_copy_from_user_asm(res, to, from, tmp, 6, l, w,);
  245.         break;
  246.     case 7:
  247.         __constant_copy_from_user_asm(res, to, from, tmp, 7, l, w, b);
  248.         break;
  249.     case 8:
  250.         __constant_copy_from_user_asm(res, to, from, tmp, 8, l, l,);
  251.         break;
  252.     case 9:
  253.         __constant_copy_from_user_asm(res, to, from, tmp, 9, l, l, b);
  254.         break;
  255.     case 10:
  256.         __constant_copy_from_user_asm(res, to, from, tmp, 10, l, l, w);
  257.         break;
  258.     case 12:
  259.         __constant_copy_from_user_asm(res, to, from, tmp, 12, l, l, l);
  260.         break;
  261.     default:
  262.         /* we limit the inlined version to 3 moves */
  263.         return __generic_copy_from_user(to, from, n);
  264.     }
  265.  
  266.     return res;
  267. }
  268.  
  269. #define __constant_copy_to_user_asm(res, to, from, tmp, n, s1, s2, s3)    \
  270.     asm volatile ("\n"                        \
  271.         "    move."#s1"    (%2)+,%3\n"            \
  272.         "11:    moves."#s1"    %3,(%1)+\n"            \
  273.         "12:    move."#s2"    (%2)+,%3\n"            \
  274.         "21:    moves."#s2"    %3,(%1)+\n"            \
  275.         "22:\n"                            \
  276.         "    .ifnc    \""#s3"\",\"\"\n"            \
  277.         "    move."#s3"    (%2)+,%3\n"            \
  278.         "31:    moves."#s3"    %3,(%1)+\n"            \
  279.         "32:\n"                            \
  280.         "    .endif\n"                    \
  281.         "4:\n"                            \
  282.         "\n"                            \
  283.         "    .section __ex_table,\"a\"\n"            \
  284.         "    .align    4\n"                    \
  285.         "    .long    11b,5f\n"                \
  286.         "    .long    12b,5f\n"                \
  287.         "    .long    21b,5f\n"                \
  288.         "    .long    22b,5f\n"                \
  289.         "    .ifnc    \""#s3"\",\"\"\n"            \
  290.         "    .long    31b,5f\n"                \
  291.         "    .long    32b,5f\n"                \
  292.         "    .endif\n"                    \
  293.         "    .previous\n"                    \
  294.         "\n"                            \
  295.         "    .section .fixup,\"ax\"\n"            \
  296.         "    .even\n"                    \
  297.         "5:    moveq.l    #"#n",%0\n"                \
  298.         "    jra    4b\n"                    \
  299.         "    .previous\n"                    \
  300.         : "+d" (res), "+a" (to), "+a" (from), "=&d" (tmp)    \
  301.         : : "memory")
  302.  
  303. static __always_inline unsigned long
  304. __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
  305. {
  306.     unsigned long res = 0, tmp;
  307.  
  308.     switch (n) {
  309.     case 1:
  310.         __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1);
  311.         break;
  312.     case 2:
  313.         __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, d, 2);
  314.         break;
  315.     case 3:
  316.         __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
  317.         break;
  318.     case 4:
  319.         __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4);
  320.         break;
  321.     case 5:
  322.         __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,);
  323.         break;
  324.     case 6:
  325.         __constant_copy_to_user_asm(res, to, from, tmp, 6, l, w,);
  326.         break;
  327.     case 7:
  328.         __constant_copy_to_user_asm(res, to, from, tmp, 7, l, w, b);
  329.         break;
  330.     case 8:
  331.         __constant_copy_to_user_asm(res, to, from, tmp, 8, l, l,);
  332.         break;
  333.     case 9:
  334.         __constant_copy_to_user_asm(res, to, from, tmp, 9, l, l, b);
  335.         break;
  336.     case 10:
  337.         __constant_copy_to_user_asm(res, to, from, tmp, 10, l, l, w);
  338.         break;
  339.     case 12:
  340.         __constant_copy_to_user_asm(res, to, from, tmp, 12, l, l, l);
  341.         break;
  342.     default:
  343.         /* limit the inlined version to 3 moves */
  344.         return __generic_copy_to_user(to, from, n);
  345.     }
  346.  
  347.     return res;
  348. }
  349.  
  350. #define __copy_from_user(to, from, n)        \
  351. (__builtin_constant_p(n) ?            \
  352.  __constant_copy_from_user(to, from, n) :    \
  353.  __generic_copy_from_user(to, from, n))
  354.  
  355. #define __copy_to_user(to, from, n)        \
  356. (__builtin_constant_p(n) ?            \
  357.  __constant_copy_to_user(to, from, n) :        \
  358.  __generic_copy_to_user(to, from, n))
  359.  
  360. #define __copy_to_user_inatomic        __copy_to_user
  361. #define __copy_from_user_inatomic    __copy_from_user
  362.  
  363. #define copy_from_user(to, from, n)    __copy_from_user(to, from, n)
  364. #define copy_to_user(to, from, n)    __copy_to_user(to, from, n)
  365.  
  366. long strncpy_from_user(char *dst, const char __user *src, long count);
  367. long strnlen_user(const char __user *src, long n);
  368. unsigned long __clear_user(void __user *to, unsigned long n);
  369.  
  370. #define clear_user    __clear_user
  371.  
  372. #define strlen_user(str) strnlen_user(str, 32767)
  373.  
  374. #endif /* _M68K_UACCESS_H */
  375.