1/* 2 * User space memory access functions 3 * 4 * Copyright (C) 1999, 2002 Niibe Yutaka 5 * Copyright (C) 2003 - 2008 Paul Mundt 6 * 7 * Based on: 8 * MIPS implementation version 1.15 by 9 * Copyright (C) 1996, 1997, 1998 by Ralf Baechle 10 * and i386 version. 11 */ 12#ifndef __ASM_SH_UACCESS_32_H 13#define __ASM_SH_UACCESS_32_H 14 15#define __get_user_size(x,ptr,size,retval) \ 16do { \ 17 retval = 0; \ 18 switch (size) { \ 19 case 1: \ 20 __get_user_asm(x, ptr, retval, "b"); \ 21 break; \ 22 case 2: \ 23 __get_user_asm(x, ptr, retval, "w"); \ 24 break; \ 25 case 4: \ 26 __get_user_asm(x, ptr, retval, "l"); \ 27 break; \ 28 default: \ 29 __get_user_unknown(); \ 30 break; \ 31 } \ 32} while (0) 33 34#ifdef CONFIG_MMU 35#define __get_user_asm(x, addr, err, insn) \ 36({ \ 37__asm__ __volatile__( \ 38 "1:\n\t" \ 39 "mov." insn " %2, %1\n\t" \ 40 "2:\n" \ 41 ".section .fixup,\"ax\"\n" \ 42 "3:\n\t" \ 43 "mov #0, %1\n\t" \ 44 "mov.l 4f, %0\n\t" \ 45 "jmp @%0\n\t" \ 46 " mov %3, %0\n\t" \ 47 ".balign 4\n" \ 48 "4: .long 2b\n\t" \ 49 ".previous\n" \ 50 ".section __ex_table,\"a\"\n\t" \ 51 ".long 1b, 3b\n\t" \ 52 ".previous" \ 53 :"=&r" (err), "=&r" (x) \ 54 :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); }) 55#else 56#define __get_user_asm(x, addr, err, insn) \ 57do { \ 58 __asm__ __volatile__ ( \ 59 "mov." insn " %1, %0\n\t" \ 60 : "=&r" (x) \ 61 : "m" (__m(addr)) \ 62 ); \ 63} while (0) 64#endif /* CONFIG_MMU */ 65 66extern void __get_user_unknown(void); 67 68#define __put_user_size(x,ptr,size,retval) \ 69do { \ 70 retval = 0; \ 71 switch (size) { \ 72 case 1: \ 73 __put_user_asm(x, ptr, retval, "b"); \ 74 break; \ 75 case 2: \ 76 __put_user_asm(x, ptr, retval, "w"); \ 77 break; \ 78 case 4: \ 79 __put_user_asm(x, ptr, retval, "l"); \ 80 break; \ 81 case 8: \ 82 __put_user_u64(x, ptr, retval); \ 83 break; \ 84 default: \ 85 __put_user_unknown(); \ 86 } \ 87} while (0) 88 89#ifdef CONFIG_MMU 90#define __put_user_asm(x, addr, err, insn) \ 91do { \ 92 __asm__ __volatile__ ( \ 93 "1:\n\t" \ 94 "mov." insn " %1, %2\n\t" \ 95 "2:\n" \ 96 ".section .fixup,\"ax\"\n" \ 97 "3:\n\t" \ 98 "mov.l 4f, %0\n\t" \ 99 "jmp @%0\n\t" \ 100 " mov %3, %0\n\t" \ 101 ".balign 4\n" \ 102 "4: .long 2b\n\t" \ 103 ".previous\n" \ 104 ".section __ex_table,\"a\"\n\t" \ 105 ".long 1b, 3b\n\t" \ 106 ".previous" \ 107 : "=&r" (err) \ 108 : "r" (x), "m" (__m(addr)), "i" (-EFAULT), \ 109 "0" (err) \ 110 : "memory" \ 111 ); \ 112} while (0) 113#else 114#define __put_user_asm(x, addr, err, insn) \ 115do { \ 116 __asm__ __volatile__ ( \ 117 "mov." insn " %0, %1\n\t" \ 118 : /* no outputs */ \ 119 : "r" (x), "m" (__m(addr)) \ 120 : "memory" \ 121 ); \ 122} while (0) 123#endif /* CONFIG_MMU */ 124 125#if defined(CONFIG_CPU_LITTLE_ENDIAN) 126#define __put_user_u64(val,addr,retval) \ 127({ \ 128__asm__ __volatile__( \ 129 "1:\n\t" \ 130 "mov.l %R1,%2\n\t" \ 131 "mov.l %S1,%T2\n\t" \ 132 "2:\n" \ 133 ".section .fixup,\"ax\"\n" \ 134 "3:\n\t" \ 135 "mov.l 4f,%0\n\t" \ 136 "jmp @%0\n\t" \ 137 " mov %3,%0\n\t" \ 138 ".balign 4\n" \ 139 "4: .long 2b\n\t" \ 140 ".previous\n" \ 141 ".section __ex_table,\"a\"\n\t" \ 142 ".long 1b, 3b\n\t" \ 143 ".previous" \ 144 : "=r" (retval) \ 145 : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \ 146 : "memory"); }) 147#else 148#define __put_user_u64(val,addr,retval) \ 149({ \ 150__asm__ __volatile__( \ 151 "1:\n\t" \ 152 "mov.l %S1,%2\n\t" \ 153 "mov.l %R1,%T2\n\t" \ 154 "2:\n" \ 155 ".section .fixup,\"ax\"\n" \ 156 "3:\n\t" \ 157 "mov.l 4f,%0\n\t" \ 158 "jmp @%0\n\t" \ 159 " mov %3,%0\n\t" \ 160 ".balign 4\n" \ 161 "4: .long 2b\n\t" \ 162 ".previous\n" \ 163 ".section __ex_table,\"a\"\n\t" \ 164 ".long 1b, 3b\n\t" \ 165 ".previous" \ 166 : "=r" (retval) \ 167 : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \ 168 : "memory"); }) 169#endif 170 171extern void __put_user_unknown(void); 172 173#endif /* __ASM_SH_UACCESS_32_H */ 174