0001
0002
0003 #ifndef __ASM_CSKY_UACCESS_H
0004 #define __ASM_CSKY_UACCESS_H
0005
0006
0007
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
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