0001
0002
0003
0004 #include <linux/uaccess.h>
0005 #include <linux/types.h>
0006
0007 unsigned long raw_copy_from_user(void *to, const void *from,
0008 unsigned long n)
0009 {
0010 int tmp, nsave;
0011
0012 __asm__ __volatile__(
0013 "0: cmpnei %1, 0 \n"
0014 " bf 7f \n"
0015 " mov %3, %1 \n"
0016 " or %3, %2 \n"
0017 " andi %3, 3 \n"
0018 " cmpnei %3, 0 \n"
0019 " bf 1f \n"
0020 " br 5f \n"
0021 "1: cmplti %0, 16 \n"
0022 " bt 3f \n"
0023 "2: ldw %3, (%2, 0) \n"
0024 "10: ldw %4, (%2, 4) \n"
0025 " stw %3, (%1, 0) \n"
0026 " stw %4, (%1, 4) \n"
0027 "11: ldw %3, (%2, 8) \n"
0028 "12: ldw %4, (%2, 12) \n"
0029 " stw %3, (%1, 8) \n"
0030 " stw %4, (%1, 12) \n"
0031 " addi %2, 16 \n"
0032 " addi %1, 16 \n"
0033 " subi %0, 16 \n"
0034 " br 1b \n"
0035 "3: cmplti %0, 4 \n"
0036 " bt 5f \n"
0037 "4: ldw %3, (%2, 0) \n"
0038 " stw %3, (%1, 0) \n"
0039 " addi %2, 4 \n"
0040 " addi %1, 4 \n"
0041 " subi %0, 4 \n"
0042 " br 3b \n"
0043 "5: cmpnei %0, 0 \n"
0044 " bf 7f \n"
0045 "6: ldb %3, (%2, 0) \n"
0046 " stb %3, (%1, 0) \n"
0047 " addi %2, 1 \n"
0048 " addi %1, 1 \n"
0049 " subi %0, 1 \n"
0050 " br 5b \n"
0051 "8: stw %3, (%1, 0) \n"
0052 " subi %0, 4 \n"
0053 " bf 7f \n"
0054 "9: subi %0, 8 \n"
0055 " bf 7f \n"
0056 "13: stw %3, (%1, 8) \n"
0057 " subi %0, 12 \n"
0058 " bf 7f \n"
0059 ".section __ex_table, \"a\" \n"
0060 ".align 2 \n"
0061 ".long 2b, 7f \n"
0062 ".long 4b, 7f \n"
0063 ".long 6b, 7f \n"
0064 ".long 10b, 8b \n"
0065 ".long 11b, 9b \n"
0066 ".long 12b,13b \n"
0067 ".previous \n"
0068 "7: \n"
0069 : "=r"(n), "=r"(to), "=r"(from), "=r"(nsave),
0070 "=r"(tmp)
0071 : "0"(n), "1"(to), "2"(from)
0072 : "memory");
0073
0074 return n;
0075 }
0076 EXPORT_SYMBOL(raw_copy_from_user);
0077
0078 unsigned long raw_copy_to_user(void *to, const void *from,
0079 unsigned long n)
0080 {
0081 int w0, w1, w2, w3;
0082
0083 __asm__ __volatile__(
0084 "0: cmpnei %1, 0 \n"
0085 " bf 8f \n"
0086 " mov %3, %1 \n"
0087 " or %3, %2 \n"
0088 " andi %3, 3 \n"
0089 " cmpnei %3, 0 \n"
0090 " bf 1f \n"
0091 " br 5f \n"
0092 "1: cmplti %0, 16 \n"
0093 " bt 3f \n"
0094 " ldw %3, (%2, 0) \n"
0095 " ldw %4, (%2, 4) \n"
0096 " ldw %5, (%2, 8) \n"
0097 " ldw %6, (%2, 12) \n"
0098 "2: stw %3, (%1, 0) \n"
0099 "9: stw %4, (%1, 4) \n"
0100 "10: stw %5, (%1, 8) \n"
0101 "11: stw %6, (%1, 12) \n"
0102 " addi %2, 16 \n"
0103 " addi %1, 16 \n"
0104 " subi %0, 16 \n"
0105 " br 1b \n"
0106 "3: cmplti %0, 4 \n"
0107 " bt 5f \n"
0108 " ldw %3, (%2, 0) \n"
0109 "4: stw %3, (%1, 0) \n"
0110 " addi %2, 4 \n"
0111 " addi %1, 4 \n"
0112 " subi %0, 4 \n"
0113 " br 3b \n"
0114 "5: cmpnei %0, 0 \n"
0115 " bf 13f \n"
0116 " ldb %3, (%2, 0) \n"
0117 "6: stb %3, (%1, 0) \n"
0118 " addi %2, 1 \n"
0119 " addi %1, 1 \n"
0120 " subi %0, 1 \n"
0121 " br 5b \n"
0122 "7: subi %0, 4 \n"
0123 "8: subi %0, 4 \n"
0124 "12: subi %0, 4 \n"
0125 " br 13f \n"
0126 ".section __ex_table, \"a\" \n"
0127 ".align 2 \n"
0128 ".long 2b, 13f \n"
0129 ".long 4b, 13f \n"
0130 ".long 6b, 13f \n"
0131 ".long 9b, 12b \n"
0132 ".long 10b, 8b \n"
0133 ".long 11b, 7b \n"
0134 ".previous \n"
0135 "13: \n"
0136 : "=r"(n), "=r"(to), "=r"(from), "=r"(w0),
0137 "=r"(w1), "=r"(w2), "=r"(w3)
0138 : "0"(n), "1"(to), "2"(from)
0139 : "memory");
0140
0141 return n;
0142 }
0143 EXPORT_SYMBOL(raw_copy_to_user);
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 unsigned long
0157 __clear_user(void __user *to, unsigned long n)
0158 {
0159 int data, value, tmp;
0160
0161 __asm__ __volatile__(
0162 "0: cmpnei %1, 0 \n"
0163 " bf 7f \n"
0164 " mov %3, %1 \n"
0165 " andi %3, 3 \n"
0166 " cmpnei %3, 0 \n"
0167 " bf 1f \n"
0168 " br 5f \n"
0169 "1: cmplti %0, 32 \n"
0170 " bt 3f \n"
0171 "8: stw %2, (%1, 0) \n"
0172 "10: stw %2, (%1, 4) \n"
0173 "11: stw %2, (%1, 8) \n"
0174 "12: stw %2, (%1, 12) \n"
0175 "13: stw %2, (%1, 16) \n"
0176 "14: stw %2, (%1, 20) \n"
0177 "15: stw %2, (%1, 24) \n"
0178 "16: stw %2, (%1, 28) \n"
0179 " addi %1, 32 \n"
0180 " subi %0, 32 \n"
0181 " br 1b \n"
0182 "3: cmplti %0, 4 \n"
0183 " bt 5f \n"
0184 "4: stw %2, (%1, 0) \n"
0185 " addi %1, 4 \n"
0186 " subi %0, 4 \n"
0187 " br 3b \n"
0188 "5: cmpnei %0, 0 \n"
0189 "9: bf 7f \n"
0190 "6: stb %2, (%1, 0) \n"
0191 " addi %1, 1 \n"
0192 " subi %0, 1 \n"
0193 " br 5b \n"
0194 ".section __ex_table,\"a\" \n"
0195 ".align 2 \n"
0196 ".long 8b, 9b \n"
0197 ".long 10b, 9b \n"
0198 ".long 11b, 9b \n"
0199 ".long 12b, 9b \n"
0200 ".long 13b, 9b \n"
0201 ".long 14b, 9b \n"
0202 ".long 15b, 9b \n"
0203 ".long 16b, 9b \n"
0204 ".long 4b, 9b \n"
0205 ".long 6b, 9b \n"
0206 ".previous \n"
0207 "7: \n"
0208 : "=r"(n), "=r" (data), "=r"(value), "=r"(tmp)
0209 : "0"(n), "1"(to), "2"(0)
0210 : "memory");
0211
0212 return n;
0213 }
0214 EXPORT_SYMBOL(__clear_user);