Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 
0003 #ifndef __ASM_CSKY_UACCESS_H
0004 #define __ASM_CSKY_UACCESS_H
0005 
0006 /*
0007  * __put_user_fn
0008  */
0009 extern int __put_user_bad(void);
0010 
0011 #define __put_user_asm_b(x, ptr, err)           \
0012 do {                            \
0013     int errcode;                    \
0014     __asm__ __volatile__(               \
0015     "1:     stb   %1, (%2,0)    \n"     \
0016     "       br    3f        \n"     \
0017     "2:     mov   %0, %3        \n"     \
0018     "       br    3f        \n"     \
0019     ".section __ex_table, \"a\" \n"     \
0020     ".align   2         \n"     \
0021     ".long    1b,2b         \n"     \
0022     ".previous          \n"     \
0023     "3:             \n"     \
0024     : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
0025     : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)  \
0026     : "memory");                    \
0027 } while (0)
0028 
0029 #define __put_user_asm_h(x, ptr, err)           \
0030 do {                            \
0031     int errcode;                    \
0032     __asm__ __volatile__(               \
0033     "1:     sth   %1, (%2,0)    \n"     \
0034     "       br    3f        \n"     \
0035     "2:     mov   %0, %3        \n"     \
0036     "       br    3f        \n"     \
0037     ".section __ex_table, \"a\" \n"     \
0038     ".align   2         \n"     \
0039     ".long    1b,2b         \n"     \
0040     ".previous          \n"     \
0041     "3:             \n"     \
0042     : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
0043     : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)  \
0044     : "memory");                    \
0045 } while (0)
0046 
0047 #define __put_user_asm_w(x, ptr, err)           \
0048 do {                            \
0049     int errcode;                    \
0050     __asm__ __volatile__(               \
0051     "1:     stw   %1, (%2,0)    \n"     \
0052     "       br    3f        \n"     \
0053     "2:     mov   %0, %3        \n"     \
0054     "       br    3f        \n"     \
0055     ".section __ex_table,\"a\"  \n"     \
0056     ".align   2         \n"     \
0057     ".long    1b, 2b        \n"     \
0058     ".previous          \n"     \
0059     "3:             \n"     \
0060     : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
0061     : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)  \
0062     : "memory");                    \
0063 } while (0)
0064 
0065 #define __put_user_asm_64(x, ptr, err)          \
0066 do {                            \
0067     int tmp;                    \
0068     int errcode;                    \
0069                             \
0070     __asm__ __volatile__(               \
0071     "     ldw     %3, (%1, 0)     \n"       \
0072     "1:   stw     %3, (%2, 0)     \n"       \
0073     "     ldw     %3, (%1, 4)     \n"       \
0074     "2:   stw     %3, (%2, 4)     \n"       \
0075     "     br      4f              \n"       \
0076     "3:   mov     %0, %4          \n"       \
0077     "     br      4f              \n"       \
0078     ".section __ex_table, \"a\"   \n"       \
0079     ".align   2                   \n"       \
0080     ".long    1b, 3b              \n"       \
0081     ".long    2b, 3b              \n"       \
0082     ".previous                    \n"       \
0083     "4:                           \n"       \
0084     : "=r"(err), "=r"(x), "=r"(ptr),        \
0085       "=r"(tmp), "=r"(errcode)          \
0086     : "0"(err), "1"(x), "2"(ptr), "3"(0),       \
0087       "4"(-EFAULT)                  \
0088     : "memory");                    \
0089 } while (0)
0090 
0091 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
0092 {
0093     int retval = 0;
0094     u32 tmp;
0095 
0096     switch (size) {
0097     case 1:
0098         tmp = *(u8 *)x;
0099         __put_user_asm_b(tmp, ptr, retval);
0100         break;
0101     case 2:
0102         tmp = *(u16 *)x;
0103         __put_user_asm_h(tmp, ptr, retval);
0104         break;
0105     case 4:
0106         tmp = *(u32 *)x;
0107         __put_user_asm_w(tmp, ptr, retval);
0108         break;
0109     case 8:
0110         __put_user_asm_64(x, (u64 *)ptr, retval);
0111         break;
0112     }
0113 
0114     return retval;
0115 }
0116 #define __put_user_fn __put_user_fn
0117 
0118 /*
0119  * __get_user_fn
0120  */
0121 extern int __get_user_bad(void);
0122 
0123 #define __get_user_asm_common(x, ptr, ins, err)     \
0124 do {                            \
0125     int errcode;                    \
0126     __asm__ __volatile__(               \
0127     "1:   " ins " %1, (%4, 0)   \n"     \
0128     "       br    3f        \n"     \
0129     "2:     mov   %0, %2        \n"     \
0130     "       movi  %1, 0     \n"     \
0131     "       br    3f        \n"     \
0132     ".section __ex_table,\"a\"      \n"     \
0133     ".align   2         \n"     \
0134     ".long    1b, 2b        \n"     \
0135     ".previous          \n"     \
0136     "3:             \n"         \
0137     : "=r"(err), "=r"(x), "=r"(errcode)     \
0138     : "0"(0), "r"(ptr), "2"(-EFAULT)        \
0139     : "memory");                    \
0140 } while (0)
0141 
0142 #define __get_user_asm_64(x, ptr, err)          \
0143 do {                            \
0144     int tmp;                    \
0145     int errcode;                    \
0146                             \
0147     __asm__ __volatile__(               \
0148     "1:   ldw     %3, (%2, 0)     \n"       \
0149     "     stw     %3, (%1, 0)     \n"       \
0150     "2:   ldw     %3, (%2, 4)     \n"       \
0151     "     stw     %3, (%1, 4)     \n"       \
0152     "     br      4f              \n"       \
0153     "3:   mov     %0, %4          \n"       \
0154     "     br      4f              \n"       \
0155     ".section __ex_table, \"a\"   \n"       \
0156     ".align   2                   \n"       \
0157     ".long    1b, 3b              \n"       \
0158     ".long    2b, 3b              \n"       \
0159     ".previous                    \n"       \
0160     "4:                           \n"       \
0161     : "=r"(err), "=r"(x), "=r"(ptr),        \
0162       "=r"(tmp), "=r"(errcode)          \
0163     : "0"(err), "1"(x), "2"(ptr), "3"(0),       \
0164       "4"(-EFAULT)                  \
0165     : "memory");                    \
0166 } while (0)
0167 
0168 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
0169 {
0170     int retval;
0171     u32 tmp;
0172 
0173     switch (size) {
0174     case 1:
0175         __get_user_asm_common(tmp, ptr, "ldb", retval);
0176         *(u8 *)x = (u8)tmp;
0177         break;
0178     case 2:
0179         __get_user_asm_common(tmp, ptr, "ldh", retval);
0180         *(u16 *)x = (u16)tmp;
0181         break;
0182     case 4:
0183         __get_user_asm_common(tmp, ptr, "ldw", retval);
0184         *(u32 *)x = (u32)tmp;
0185         break;
0186     case 8:
0187         __get_user_asm_64(x, ptr, retval);
0188         break;
0189     }
0190 
0191     return retval;
0192 }
0193 #define __get_user_fn __get_user_fn
0194 
0195 unsigned long raw_copy_from_user(void *to, const void *from, unsigned long n);
0196 unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n);
0197 
0198 unsigned long __clear_user(void __user *to, unsigned long n);
0199 #define __clear_user __clear_user
0200 
0201 #include <asm-generic/uaccess.h>
0202 
0203 #endif /* __ASM_CSKY_UACCESS_H */