home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-m68k / uaccess.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  21.0 KB  |  890 lines

  1. #ifndef __M68K_UACCESS_H
  2. #define __M68K_UACCESS_H
  3.  
  4. /*
  5.  * User space memory access functions
  6.  */
  7. #include <linux/errno.h>
  8. #include <linux/sched.h>
  9. #include <asm/segment.h>
  10.  
  11. #define VERIFY_READ    0
  12. #define VERIFY_WRITE    1
  13.  
  14. /* We let the MMU do all checking */
  15. #define access_ok(type,addr,size) 1
  16.  
  17. /*
  18.  * The exception table consists of pairs of addresses: the first is the
  19.  * address of an instruction that is allowed to fault, and the second is
  20.  * the address at which the program should continue.  No registers are
  21.  * modified, so it is entirely up to the continuation code to figure out
  22.  * what to do.
  23.  *
  24.  * All the routines below use bits of fixup code that are out of line
  25.  * with the main instruction path.  This means when everything is well,
  26.  * we don't even have to jump over them.  Further, they do not intrude
  27.  * on our cache or tlb entries.
  28.  */
  29.  
  30. struct exception_table_entry
  31. {
  32.     unsigned long insn, fixup;
  33. };
  34.  
  35.  
  36. /*
  37.  * These are the main single-value transfer routines.  They automatically
  38.  * use the right size if we just have the right pointer type.
  39.  */
  40.  
  41. #define put_user(x, ptr)                \
  42. ({                            \
  43.     int __pu_err;                    \
  44.     typeof(*(ptr)) __pu_val = (x);            \
  45.     __chk_user_ptr(ptr);                \
  46.     switch (sizeof (*(ptr))) {                \
  47.     case 1:                        \
  48.     __put_user_asm(__pu_err, __pu_val, ptr, b);    \
  49.     break;                        \
  50.     case 2:                        \
  51.     __put_user_asm(__pu_err, __pu_val, ptr, w);    \
  52.     break;                        \
  53.     case 4:                        \
  54.     __put_user_asm(__pu_err, __pu_val, ptr, l);    \
  55.     break;                        \
  56.     case 8:                                             \
  57.        __pu_err = __constant_copy_to_user(ptr, &__pu_val, 8);        \
  58.        break;                                           \
  59.     default:                        \
  60.     __pu_err = __put_user_bad();            \
  61.     break;                        \
  62.     }                            \
  63.     __pu_err;                        \
  64. })
  65. #define __put_user(x, ptr) put_user(x, ptr)
  66.  
  67. extern int __put_user_bad(void);
  68.  
  69. /*
  70.  * Tell gcc we read from memory instead of writing: this is because
  71.  * we do not write to any memory gcc knows about, so there are no
  72.  * aliasing issues.
  73.  */
  74. #define __put_user_asm(err,x,ptr,bwl)            \
  75. __asm__ __volatile__                    \
  76.     ("21:moves" #bwl " %2,%1\n"                \
  77.      "1:\n"                        \
  78.      ".section .fixup,\"ax\"\n"                \
  79.      "   .even\n"                    \
  80.      "2: movel %3,%0\n"                    \
  81.      "   jra 1b\n"                    \
  82.      ".previous\n"                    \
  83.      ".section __ex_table,\"a\"\n"            \
  84.      "   .align 4\n"                    \
  85.      "   .long 21b,2b\n"                \
  86.      "   .long 1b,2b\n"                    \
  87.      ".previous"                    \
  88.      : "=d"(err)                    \
  89.      : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
  90.  
  91. #define get_user(x, ptr)                    \
  92. ({                                \
  93.     int __gu_err;                        \
  94.     typeof(*(ptr)) __gu_val;                    \
  95.     __chk_user_ptr(ptr);                    \
  96.     switch (sizeof(*(ptr))) {                    \
  97.     case 1:                            \
  98.     __get_user_asm(__gu_err, __gu_val, ptr, b, "=d");    \
  99.     break;                            \
  100.     case 2:                            \
  101.     __get_user_asm(__gu_err, __gu_val, ptr, w, "=r");    \
  102.     break;                            \
  103.     case 4:                            \
  104.     __get_user_asm(__gu_err, __gu_val, ptr, l, "=r");    \
  105.     break;                            \
  106.     case 8:                                                     \
  107.         __gu_err = __constant_copy_from_user(&__gu_val, ptr, 8);  \
  108.         break;                                                  \
  109.     default:                            \
  110.     __gu_val = (typeof(*(ptr)))0;                \
  111.     __gu_err = __get_user_bad();                \
  112.     break;                            \
  113.     }                                \
  114.     (x) = __gu_val;                        \
  115.     __gu_err;                            \
  116. })
  117. #define __get_user(x, ptr) get_user(x, ptr)
  118.  
  119. extern int __get_user_bad(void);
  120.  
  121. #define __get_user_asm(err,x,ptr,bwl,reg)    \
  122. __asm__ __volatile__                \
  123.     ("1: moves" #bwl " %2,%1\n"            \
  124.      "2:\n"                    \
  125.      ".section .fixup,\"ax\"\n"            \
  126.      "   .even\n"                \
  127.      "3: movel %3,%0\n"                \
  128.      "   sub" #bwl " %1,%1\n"            \
  129.      "   jra 2b\n"                \
  130.      ".previous\n"                \
  131.      ".section __ex_table,\"a\"\n"        \
  132.      "   .align 4\n"                \
  133.      "   .long 1b,3b\n"                \
  134.      ".previous"                \
  135.      : "=d"(err), reg(x)            \
  136.      : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
  137.  
  138. static inline unsigned long
  139. __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
  140. {
  141.     unsigned long tmp;
  142.     __asm__ __volatile__
  143.     ("   tstl %2\n"
  144.      "   jeq 2f\n"
  145.      "1: movesl (%1)+,%3\n"
  146.      "   movel %3,(%0)+\n"
  147.      "   subql #1,%2\n"
  148.      "   jne 1b\n"
  149.      "2: movel %4,%2\n"
  150.      "   bclr #1,%2\n"
  151.      "   jeq 4f\n"
  152.      "3: movesw (%1)+,%3\n"
  153.      "   movew %3,(%0)+\n"
  154.      "4: bclr #0,%2\n"
  155.      "   jeq 6f\n"
  156.      "5: movesb (%1)+,%3\n"
  157.      "   moveb %3,(%0)+\n"
  158.      "6:\n"
  159.      ".section .fixup,\"ax\"\n"
  160.      "   .even\n"
  161.      "7: movel %2,%%d0\n"
  162.      "71:clrl (%0)+\n"
  163.      "   subql #1,%%d0\n"
  164.      "   jne 71b\n"
  165.      "   lsll #2,%2\n"
  166.      "   addl %4,%2\n"
  167.      "   btst #1,%4\n"
  168.      "   jne 81f\n"
  169.      "   btst #0,%4\n"
  170.      "   jne 91f\n"
  171.      "   jra 6b\n"
  172.      "8: addql #2,%2\n"
  173.      "81:clrw (%0)+\n"
  174.      "   btst #0,%4\n"
  175.      "   jne 91f\n"
  176.      "   jra 6b\n"
  177.      "9: addql #1,%2\n"
  178.      "91:clrb (%0)+\n"
  179.      "   jra 6b\n"
  180.          ".previous\n"
  181.      ".section __ex_table,\"a\"\n"
  182.      "   .align 4\n"
  183.      "   .long 1b,7b\n"
  184.      "   .long 3b,8b\n"
  185.      "   .long 5b,9b\n"
  186.      ".previous"
  187.      : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
  188.      : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
  189.      : "d0", "memory");
  190.     return n;
  191. }
  192.  
  193. static inline unsigned long
  194. __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
  195. {
  196.     unsigned long tmp;
  197.     __asm__ __volatile__
  198.     ("   tstl %2\n"
  199.      "   jeq 3f\n"
  200.      "1: movel (%1)+,%3\n"
  201.      "22:movesl %3,(%0)+\n"
  202.      "2: subql #1,%2\n"
  203.      "   jne 1b\n"
  204.      "3: movel %4,%2\n"
  205.      "   bclr #1,%2\n"
  206.      "   jeq 4f\n"
  207.      "   movew (%1)+,%3\n"
  208.      "24:movesw %3,(%0)+\n"
  209.      "4: bclr #0,%2\n"
  210.      "   jeq 5f\n"
  211.      "   moveb (%1)+,%3\n"
  212.      "25:movesb %3,(%0)+\n"
  213.      "5:\n"
  214.      ".section .fixup,\"ax\"\n"
  215.      "   .even\n"
  216.      "60:addql #1,%2\n"
  217.      "6: lsll #2,%2\n"
  218.      "   addl %4,%2\n"
  219.      "   jra 5b\n"
  220.      "7: addql #2,%2\n"
  221.      "   jra 5b\n"
  222.      "8: addql #1,%2\n"
  223.      "   jra 5b\n"
  224.      ".previous\n"
  225.      ".section __ex_table,\"a\"\n"
  226.      "   .align 4\n"
  227.      "   .long 1b,60b\n"
  228.      "   .long 22b,6b\n"
  229.      "   .long 2b,6b\n"
  230.      "   .long 24b,7b\n"
  231.      "   .long 3b,60b\n"
  232.      "   .long 4b,7b\n"
  233.      "   .long 25b,8b\n"
  234.      "   .long 5b,8b\n"
  235.      ".previous"
  236.      : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
  237.      : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4)
  238.      : "memory");
  239.     return n;
  240. }
  241.  
  242. #define __copy_from_user_big(to, from, n, fixup, copy)    \
  243.     __asm__ __volatile__                \
  244.     ("10: movesl (%1)+,%%d0\n"            \
  245.      "    movel %%d0,(%0)+\n"            \
  246.      "    subql #1,%2\n"                \
  247.      "    jne 10b\n"                \
  248.      ".section .fixup,\"ax\"\n"            \
  249.      "    .even\n"                    \
  250.      "11: movel %2,%%d0\n"                \
  251.      "13: clrl (%0)+\n"                \
  252.      "    subql #1,%%d0\n"                \
  253.      "    jne 13b\n"                \
  254.      "    lsll #2,%2\n"                \
  255.      fixup "\n"                    \
  256.      "    jra 12f\n"                \
  257.      ".previous\n"                    \
  258.      ".section __ex_table,\"a\"\n"            \
  259.      "    .align 4\n"                \
  260.      "    .long 10b,11b\n"                \
  261.      ".previous\n"                    \
  262.      copy "\n"                    \
  263.      "12:"                        \
  264.      : "=a"(to), "=a"(from), "=d"(n)        \
  265.      : "0"(to), "1"(from), "2"(n/4)            \
  266.      : "d0", "memory")
  267.  
  268. static inline unsigned long
  269. __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
  270. {
  271.     switch (n) {
  272.     case 0:
  273.     break;
  274.     case 1:
  275.     __asm__ __volatile__
  276.         ("1: movesb (%1)+,%%d0\n"
  277.          "   moveb %%d0,(%0)+\n"
  278.          "2:\n"
  279.          ".section .fixup,\"ax\"\n"
  280.          "   .even\n"
  281.          "3: addql #1,%2\n"
  282.          "   clrb (%0)+\n"
  283.          "   jra 2b\n"
  284.          ".previous\n"
  285.          ".section __ex_table,\"a\"\n"
  286.          "   .align 4\n"
  287.          "   .long 1b,3b\n"
  288.          ".previous"
  289.          : "=a"(to), "=a"(from), "=d"(n)
  290.          : "0"(to), "1"(from), "2"(0)
  291.          : "d0", "memory");
  292.     break;
  293.     case 2:
  294.     __asm__ __volatile__
  295.         ("1: movesw (%1)+,%%d0\n"
  296.          "   movew %%d0,(%0)+\n"
  297.          "2:\n"
  298.          ".section .fixup,\"ax\"\n"
  299.          "   .even\n"
  300.          "3: addql #2,%2\n"
  301.          "   clrw (%0)+\n"
  302.          "   jra 2b\n"
  303.          ".previous\n"
  304.          ".section __ex_table,\"a\"\n"
  305.          "   .align 4\n"
  306.          "   .long 1b,3b\n"
  307.          ".previous"
  308.          : "=a"(to), "=a"(from), "=d"(n)
  309.          : "0"(to), "1"(from), "2"(0)
  310.          : "d0", "memory");
  311.     break;
  312.     case 3:
  313.     __asm__ __volatile__
  314.         ("1: movesw (%1)+,%%d0\n"
  315.          "   movew %%d0,(%0)+\n"
  316.          "2: movesb (%1)+,%%d0\n"
  317.          "   moveb %%d0,(%0)+\n"
  318.          "3:"
  319.          ".section .fixup,\"ax\"\n"
  320.          "   .even\n"
  321.          "4: addql #2,%2\n"
  322.          "   clrw (%0)+\n"
  323.          "5: addql #1,%2\n"
  324.          "   clrb (%0)+\n"
  325.          "   jra 3b\n"
  326.          ".previous\n"
  327.          ".section __ex_table,\"a\"\n"
  328.          "   .align 4\n"
  329.          "   .long 1b,4b\n"
  330.          "   .long 2b,5b\n"
  331.          ".previous"
  332.          : "=a"(to), "=a"(from), "=d"(n)
  333.          : "0"(to), "1"(from), "2"(0)
  334.          : "d0", "memory");
  335.     break;
  336.     case 4:
  337.     __asm__ __volatile__
  338.         ("1: movesl (%1)+,%%d0\n"
  339.          "   movel %%d0,(%0)+\n"
  340.          "2:"
  341.          ".section .fixup,\"ax\"\n"
  342.          "   .even\n"
  343.          "3: addql #4,%2\n"
  344.          "   clrl (%0)+\n"
  345.          "   jra 2b\n"
  346.          ".previous\n"
  347.          ".section __ex_table,\"a\"\n"
  348.          "   .align 4\n"
  349.          "   .long 1b,3b\n"
  350.          ".previous"
  351.          : "=a"(to), "=a"(from), "=d"(n)
  352.          : "0"(to), "1"(from), "2"(0)
  353.          : "d0", "memory");
  354.     break;
  355.     case 8:
  356.     __asm__ __volatile__
  357.         ("1: movesl (%1)+,%%d0\n"
  358.          "   movel %%d0,(%0)+\n"
  359.          "2: movesl (%1)+,%%d0\n"
  360.          "   movel %%d0,(%0)+\n"
  361.          "3:"
  362.          ".section .fixup,\"ax\"\n"
  363.          "   .even\n"
  364.          "4: addql #4,%2\n"
  365.          "   clrl (%0)+\n"
  366.          "5: addql #4,%2\n"
  367.          "   clrl (%0)+\n"
  368.          "   jra 3b\n"
  369.          ".previous\n"
  370.          ".section __ex_table,\"a\"\n"
  371.          "   .align 4\n"
  372.          "   .long 1b,4b\n"
  373.          "   .long 2b,5b\n"
  374.          ".previous"
  375.          : "=a"(to), "=a"(from), "=d"(n)
  376.          : "0"(to), "1"(from), "2"(0)
  377.          : "d0", "memory");
  378.     break;
  379.     case 12:
  380.     __asm__ __volatile__
  381.         ("1: movesl (%1)+,%%d0\n"
  382.          "   movel %%d0,(%0)+\n"
  383.          "2: movesl (%1)+,%%d0\n"
  384.          "   movel %%d0,(%0)+\n"
  385.          "3: movesl (%1)+,%%d0\n"
  386.          "   movel %%d0,(%0)+\n"
  387.          "4:"
  388.          ".section .fixup,\"ax\"\n"
  389.          "   .even\n"
  390.          "5: addql #4,%2\n"
  391.          "   clrl (%0)+\n"
  392.          "6: addql #4,%2\n"
  393.          "   clrl (%0)+\n"
  394.          "7: addql #4,%2\n"
  395.          "   clrl (%0)+\n"
  396.          "   jra 4b\n"
  397.          ".previous\n"
  398.          ".section __ex_table,\"a\"\n"
  399.          "   .align 4\n"
  400.          "   .long 1b,5b\n"
  401.          "   .long 2b,6b\n"
  402.          "   .long 3b,7b\n"
  403.          ".previous"
  404.          : "=a"(to), "=a"(from), "=d"(n)
  405.          : "0"(to), "1"(from), "2"(0)
  406.          : "d0", "memory");
  407.     break;
  408.     case 16:
  409.     __asm__ __volatile__
  410.         ("1: movesl (%1)+,%%d0\n"
  411.          "   movel %%d0,(%0)+\n"
  412.          "2: movesl (%1)+,%%d0\n"
  413.          "   movel %%d0,(%0)+\n"
  414.          "3: movesl (%1)+,%%d0\n"
  415.          "   movel %%d0,(%0)+\n"
  416.          "4: movesl (%1)+,%%d0\n"
  417.          "   movel %%d0,(%0)+\n"
  418.          "5:"
  419.          ".section .fixup,\"ax\"\n"
  420.          "   .even\n"
  421.          "6: addql #4,%2\n"
  422.          "   clrl (%0)+\n"
  423.          "7: addql #4,%2\n"
  424.          "   clrl (%0)+\n"
  425.          "8: addql #4,%2\n"
  426.          "   clrl (%0)+\n"
  427.          "9: addql #4,%2\n"
  428.          "   clrl (%0)+\n"
  429.          "   jra 5b\n"
  430.          ".previous\n"
  431.          ".section __ex_table,\"a\"\n"
  432.          "   .align 4\n"
  433.          "   .long 1b,6b\n"
  434.          "   .long 2b,7b\n"
  435.          "   .long 3b,8b\n"
  436.          "   .long 4b,9b\n"
  437.          ".previous"
  438.          : "=a"(to), "=a"(from), "=d"(n)
  439.          : "0"(to), "1"(from), "2"(0)
  440.          : "d0", "memory");
  441.     break;
  442.     default:
  443.     switch (n & 3) {
  444.     case 0:
  445.         __copy_from_user_big(to, from, n, "", "");
  446.         break;
  447.     case 1:
  448.         __copy_from_user_big(to, from, n,
  449.                  /* fixup */
  450.                  "1: addql #1,%2\n"
  451.                  "   clrb (%0)+",
  452.                  /* copy */
  453.                  "2: movesb (%1)+,%%d0\n"
  454.                  "   moveb %%d0,(%0)+\n"
  455.                  ".section __ex_table,\"a\"\n"
  456.                  "   .long 2b,1b\n"
  457.                  ".previous");
  458.         break;
  459.     case 2:
  460.         __copy_from_user_big(to, from, n,
  461.                  /* fixup */
  462.                  "1: addql #2,%2\n"
  463.                  "   clrw (%0)+",
  464.                  /* copy */
  465.                  "2: movesw (%1)+,%%d0\n"
  466.                  "   movew %%d0,(%0)+\n"
  467.                  ".section __ex_table,\"a\"\n"
  468.                  "   .long 2b,1b\n"
  469.                  ".previous");
  470.         break;
  471.     case 3:
  472.         __copy_from_user_big(to, from, n,
  473.                  /* fixup */
  474.                  "1: addql #2,%2\n"
  475.                  "   clrw (%0)+\n"
  476.                  "2: addql #1,%2\n"
  477.                  "   clrb (%0)+",
  478.                  /* copy */
  479.                  "3: movesw (%1)+,%%d0\n"
  480.                  "   movew %%d0,(%0)+\n"
  481.                  "4: movesb (%1)+,%%d0\n"
  482.                  "   moveb %%d0,(%0)+\n"
  483.                  ".section __ex_table,\"a\"\n"
  484.                  "   .long 3b,1b\n"
  485.                  "   .long 4b,2b\n"
  486.                  ".previous");
  487.         break;
  488.     }
  489.     break;
  490.     }
  491.     return n;
  492. }
  493.  
  494. #define __copy_to_user_big(to, from, n, fixup, copy)    \
  495.     __asm__ __volatile__                \
  496.     ("10: movel (%1)+,%%d0\n"            \
  497.      "31: movesl %%d0,(%0)+\n"            \
  498.      "11: subql #1,%2\n"                \
  499.      "    jne 10b\n"                \
  500.      "41:\n"                    \
  501.      ".section .fixup,\"ax\"\n"            \
  502.      "   .even\n"                    \
  503.      "22: addql #1,%2\n"                \
  504.      "12: lsll #2,%2\n"                \
  505.      fixup "\n"                    \
  506.      "    jra 13f\n"                \
  507.      ".previous\n"                    \
  508.      ".section __ex_table,\"a\"\n"            \
  509.      "    .align 4\n"                \
  510.      "    .long 10b,22b\n"                \
  511.      "    .long 31b,12b\n"                \
  512.      "    .long 11b,12b\n"                \
  513.      "    .long 41b,22b\n"                \
  514.      ".previous\n"                    \
  515.      copy "\n"                    \
  516.      "13:"                        \
  517.      : "=a"(to), "=a"(from), "=d"(n)        \
  518.      : "0"(to), "1"(from), "2"(n/4)            \
  519.      : "d0", "memory")
  520.  
  521. #define __copy_to_user_inatomic __copy_to_user
  522. #define __copy_from_user_inatomic __copy_from_user
  523.  
  524. static inline unsigned long
  525. __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
  526. {
  527.     switch (n) {
  528.     case 0:
  529.     break;
  530.     case 1:
  531.     __asm__ __volatile__
  532.         ("   moveb (%1)+,%%d0\n"
  533.          "21:movesb %%d0,(%0)+\n"
  534.          "1:\n"
  535.          ".section .fixup,\"ax\"\n"
  536.          "   .even\n"
  537.          "2: addql #1,%2\n"
  538.          "   jra 1b\n"
  539.          ".previous\n"
  540.          ".section __ex_table,\"a\"\n"
  541.          "   .align 4\n  "
  542.          "   .long 21b,2b\n"
  543.          "   .long 1b,2b\n"
  544.          ".previous"
  545.          : "=a"(to), "=a"(from), "=d"(n)
  546.          : "0"(to), "1"(from), "2"(0)
  547.          : "d0", "memory");
  548.     break;
  549.     case 2:
  550.     __asm__ __volatile__
  551.         ("   movew (%1)+,%%d0\n"
  552.          "21:movesw %%d0,(%0)+\n"
  553.          "1:\n"
  554.          ".section .fixup,\"ax\"\n"
  555.          "   .even\n"
  556.          "2: addql #2,%2\n"
  557.          "   jra 1b\n"
  558.          ".previous\n"
  559.          ".section __ex_table,\"a\"\n"
  560.          "   .align 4\n"
  561.          "   .long 21b,2b\n"
  562.          "   .long 1b,2b\n"
  563.          ".previous"
  564.          : "=a"(to), "=a"(from), "=d"(n)
  565.          : "0"(to), "1"(from), "2"(0)
  566.          : "d0", "memory");
  567.     break;
  568.     case 3:
  569.     __asm__ __volatile__
  570.         ("   movew (%1)+,%%d0\n"
  571.          "21:movesw %%d0,(%0)+\n"
  572.          "1: moveb (%1)+,%%d0\n"
  573.          "22:movesb %%d0,(%0)+\n"
  574.          "2:\n"
  575.          ".section .fixup,\"ax\"\n"
  576.          "   .even\n"
  577.          "3: addql #2,%2\n"
  578.          "4: addql #1,%2\n"
  579.          "   jra 2b\n"
  580.          ".previous\n"
  581.          ".section __ex_table,\"a\"\n"
  582.          "   .align 4\n"
  583.          "   .long 21b,3b\n"
  584.          "   .long 1b,3b\n"
  585.          "   .long 22b,4b\n"
  586.          "   .long 2b,4b\n"
  587.          ".previous"
  588.          : "=a"(to), "=a"(from), "=d"(n)
  589.          : "0"(to), "1"(from), "2"(0)
  590.          : "d0", "memory");
  591.     break;
  592.     case 4:
  593.     __asm__ __volatile__
  594.         ("   movel (%1)+,%%d0\n"
  595.          "21:movesl %%d0,(%0)+\n"
  596.          "1:\n"
  597.          ".section .fixup,\"ax\"\n"
  598.          "   .even\n"
  599.          "2: addql #4,%2\n"
  600.          "   jra 1b\n"
  601.          ".previous\n"
  602.          ".section __ex_table,\"a\"\n"
  603.          "   .align 4\n"
  604.          "   .long 21b,2b\n"
  605.          "   .long 1b,2b\n"
  606.          ".previous"
  607.          : "=a"(to), "=a"(from), "=d"(n)
  608.          : "0"(to), "1"(from), "2"(0)
  609.          : "d0", "memory");
  610.     break;
  611.     case 8:
  612.     __asm__ __volatile__
  613.         ("   movel (%1)+,%%d0\n"
  614.          "21:movesl %%d0,(%0)+\n"
  615.          "1: movel (%1)+,%%d0\n"
  616.          "22:movesl %%d0,(%0)+\n"
  617.          "2:\n"
  618.          ".section .fixup,\"ax\"\n"
  619.          "   .even\n"
  620.          "3: addql #4,%2\n"
  621.          "4: addql #4,%2\n"
  622.          "   jra 2b\n"
  623.          ".previous\n"
  624.          ".section __ex_table,\"a\"\n"
  625.          "   .align 4\n"
  626.          "   .long 21b,3b\n"
  627.          "   .long 1b,3b\n"
  628.          "   .long 22b,4b\n"
  629.          "   .long 2b,4b\n"
  630.          ".previous"
  631.          : "=a"(to), "=a"(from), "=d"(n)
  632.          : "0"(to), "1"(from), "2"(0)
  633.          : "d0", "memory");
  634.     break;
  635.     case 12:
  636.     __asm__ __volatile__
  637.         ("   movel (%1)+,%%d0\n"
  638.          "21:movesl %%d0,(%0)+\n"
  639.          "1: movel (%1)+,%%d0\n"
  640.          "22:movesl %%d0,(%0)+\n"
  641.          "2: movel (%1)+,%%d0\n"
  642.          "23:movesl %%d0,(%0)+\n"
  643.          "3:\n"
  644.          ".section .fixup,\"ax\"\n"
  645.          "   .even\n"
  646.          "4: addql #4,%2\n"
  647.          "5: addql #4,%2\n"
  648.          "6: addql #4,%2\n"
  649.          "   jra 3b\n"
  650.          ".previous\n"
  651.          ".section __ex_table,\"a\"\n"
  652.          "   .align 4\n"
  653.          "   .long 21b,4b\n"
  654.          "   .long 1b,4b\n"
  655.          "   .long 22b,5b\n"
  656.          "   .long 2b,5b\n"
  657.          "   .long 23b,6b\n"
  658.          "   .long 3b,6b\n"
  659.          ".previous"
  660.          : "=a"(to), "=a"(from), "=d"(n)
  661.          : "0"(to), "1"(from), "2"(0)
  662.          : "d0", "memory");
  663.     break;
  664.     case 16:
  665.     __asm__ __volatile__
  666.         ("   movel (%1)+,%%d0\n"
  667.          "21:movesl %%d0,(%0)+\n"
  668.          "1: movel (%1)+,%%d0\n"
  669.          "22:movesl %%d0,(%0)+\n"
  670.          "2: movel (%1)+,%%d0\n"
  671.          "23:movesl %%d0,(%0)+\n"
  672.          "3: movel (%1)+,%%d0\n"
  673.          "24:movesl %%d0,(%0)+\n"
  674.          "4:"
  675.          ".section .fixup,\"ax\"\n"
  676.          "   .even\n"
  677.          "5: addql #4,%2\n"
  678.          "6: addql #4,%2\n"
  679.          "7: addql #4,%2\n"
  680.          "8: addql #4,%2\n"
  681.          "   jra 4b\n"
  682.          ".previous\n"
  683.          ".section __ex_table,\"a\"\n"
  684.          "   .align 4\n"
  685.          "   .long 21b,5b\n"
  686.          "   .long 1b,5b\n"
  687.          "   .long 22b,6b\n"
  688.          "   .long 2b,6b\n"
  689.          "   .long 23b,7b\n"
  690.          "   .long 3b,7b\n"
  691.          "   .long 24b,8b\n"
  692.          "   .long 4b,8b\n"
  693.          ".previous"
  694.          : "=a"(to), "=a"(from), "=d"(n)
  695.          : "0"(to), "1"(from), "2"(0)
  696.          : "d0", "memory");
  697.     break;
  698.     default:
  699.     switch (n & 3) {
  700.     case 0:
  701.         __copy_to_user_big(to, from, n, "", "");
  702.         break;
  703.     case 1:
  704.         __copy_to_user_big(to, from, n,
  705.                    /* fixup */
  706.                    "1: addql #1,%2",
  707.                    /* copy */
  708.                    "   moveb (%1)+,%%d0\n"
  709.                    "22:movesb %%d0,(%0)+\n"
  710.                    "2:"
  711.                    ".section __ex_table,\"a\"\n"
  712.                    "   .long 22b,1b\n"
  713.                    "   .long 2b,1b\n"
  714.                    ".previous");
  715.         break;
  716.     case 2:
  717.         __copy_to_user_big(to, from, n,
  718.                    /* fixup */
  719.                    "1: addql #2,%2",
  720.                    /* copy */
  721.                    "   movew (%1)+,%%d0\n"
  722.                    "22:movesw %%d0,(%0)+\n"
  723.                    "2:"
  724.                    ".section __ex_table,\"a\"\n"
  725.                    "   .long 22b,1b\n"
  726.                    "   .long 2b,1b\n"
  727.                    ".previous");
  728.         break;
  729.     case 3:
  730.         __copy_to_user_big(to, from, n,
  731.                    /* fixup */
  732.                    "1: addql #2,%2\n"
  733.                    "2: addql #1,%2",
  734.                    /* copy */
  735.                    "   movew (%1)+,%%d0\n"
  736.                    "23:movesw %%d0,(%0)+\n"
  737.                    "3: moveb (%1)+,%%d0\n"
  738.                    "24:movesb %%d0,(%0)+\n"
  739.                    "4:"
  740.                    ".section __ex_table,\"a\"\n"
  741.                    "   .long 23b,1b\n"
  742.                    "   .long 3b,1b\n"
  743.                    "   .long 24b,2b\n"
  744.                    "   .long 4b,2b\n"
  745.                    ".previous");
  746.         break;
  747.     }
  748.     break;
  749.     }
  750.     return n;
  751. }
  752.  
  753. #define copy_from_user(to, from, n)        \
  754. (__builtin_constant_p(n) ?            \
  755.  __constant_copy_from_user(to, from, n) :    \
  756.  __generic_copy_from_user(to, from, n))
  757.  
  758. #define copy_to_user(to, from, n)        \
  759. (__builtin_constant_p(n) ?            \
  760.  __constant_copy_to_user(to, from, n) :        \
  761.  __generic_copy_to_user(to, from, n))
  762.  
  763. #define __copy_from_user(to, from, n) copy_from_user(to, from, n)
  764. #define __copy_to_user(to, from, n) copy_to_user(to, from, n)
  765.  
  766. /*
  767.  * Copy a null terminated string from userspace.
  768.  */
  769.  
  770. static inline long
  771. strncpy_from_user(char *dst, const char __user *src, long count)
  772. {
  773.     long res;
  774.     if (count == 0) return count;
  775.     __asm__ __volatile__
  776.     ("1: movesb (%2)+,%%d0\n"
  777.      "12:moveb %%d0,(%1)+\n"
  778.      "   jeq 2f\n"
  779.      "   subql #1,%3\n"
  780.      "   jne 1b\n"
  781.      "2: subl %3,%0\n"
  782.      "3:\n"
  783.      ".section .fixup,\"ax\"\n"
  784.      "   .even\n"
  785.      "4: movel %4,%0\n"
  786.      "   jra 3b\n"
  787.      ".previous\n"
  788.      ".section __ex_table,\"a\"\n"
  789.      "   .align 4\n"
  790.      "   .long 1b,4b\n"
  791.      "   .long 12b,4b\n"
  792.      ".previous"
  793.      : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
  794.      : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
  795.      : "d0", "memory");
  796.     return res;
  797. }
  798.  
  799. /*
  800.  * Return the size of a string (including the ending 0)
  801.  *
  802.  * Return 0 on exception, a value greater than N if too long
  803.  */
  804. static inline long strnlen_user(const char __user *src, long n)
  805. {
  806.     long res;
  807.  
  808.     res = -(unsigned long)src;
  809.     __asm__ __volatile__
  810.         ("1:\n"
  811.          "   tstl %2\n"
  812.          "   jeq 3f\n"
  813.          "2: movesb (%1)+,%%d0\n"
  814.          "22:\n"
  815.          "   subql #1,%2\n"
  816.          "   tstb %%d0\n"
  817.          "   jne 1b\n"
  818.          "   jra 4f\n"
  819.          "3:\n"
  820.          "   addql #1,%0\n"
  821.          "4:\n"
  822.          "   addl %1,%0\n"
  823.          "5:\n"
  824.          ".section .fixup,\"ax\"\n"
  825.          "   .even\n"
  826.          "6: moveq %3,%0\n"
  827.          "   jra 5b\n"
  828.          ".previous\n"
  829.          ".section __ex_table,\"a\"\n"
  830.          "   .align 4\n"
  831.          "   .long 2b,6b\n"
  832.          "   .long 22b,6b\n"
  833.          ".previous"
  834.          : "=d"(res), "=a"(src), "=d"(n)
  835.          : "i"(0), "0"(res), "1"(src), "2"(n)
  836.          : "d0");
  837.     return res;
  838. }
  839.  
  840. #define strlen_user(str) strnlen_user(str, 32767)
  841.  
  842. /*
  843.  * Zero Userspace
  844.  */
  845.  
  846. static inline unsigned long
  847. clear_user(void __user *to, unsigned long n)
  848. {
  849.     __asm__ __volatile__
  850.     ("   tstl %1\n"
  851.      "   jeq 3f\n"
  852.      "1: movesl %3,(%0)+\n"
  853.      "2: subql #1,%1\n"
  854.      "   jne 1b\n"
  855.      "3: movel %2,%1\n"
  856.      "   bclr #1,%1\n"
  857.      "   jeq 4f\n"
  858.      "24:movesw %3,(%0)+\n"
  859.      "4: bclr #0,%1\n"
  860.      "   jeq 5f\n"
  861.      "25:movesb %3,(%0)+\n"
  862.      "5:\n"
  863.      ".section .fixup,\"ax\"\n"
  864.      "   .even\n"
  865.      "61:addql #1,%1\n"
  866.      "6: lsll #2,%1\n"
  867.      "   addl %2,%1\n"
  868.      "   jra 5b\n"
  869.      "7: addql #2,%1\n"
  870.      "   jra 5b\n"
  871.      "8: addql #1,%1\n"
  872.      "   jra 5b\n"
  873.      ".previous\n"
  874.      ".section __ex_table,\"a\"\n"
  875.      "   .align 4\n"
  876.      "   .long 1b,61b\n"
  877.      "   .long 2b,6b\n"
  878.      "   .long 3b,61b\n"
  879.      "   .long 24b,7b\n"
  880.      "   .long 4b,7b\n"
  881.      "   .long 25b,8b\n"
  882.      "   .long 5b,8b\n"
  883.      ".previous"
  884.      : "=a"(to), "=d"(n)
  885.      : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
  886.     return n;
  887. }
  888.  
  889. #endif /* _M68K_UACCESS_H */
  890.