1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2f15cbe6fSPaul Mundt /* 3f15cbe6fSPaul Mundt * User space memory access functions 4f15cbe6fSPaul Mundt * 5f15cbe6fSPaul Mundt * Copyright (C) 1999, 2002 Niibe Yutaka 6f15cbe6fSPaul Mundt * Copyright (C) 2003 - 2008 Paul Mundt 7f15cbe6fSPaul Mundt * 8f15cbe6fSPaul Mundt * Based on: 9f15cbe6fSPaul Mundt * MIPS implementation version 1.15 by 10f15cbe6fSPaul Mundt * Copyright (C) 1996, 1997, 1998 by Ralf Baechle 11f15cbe6fSPaul Mundt * and i386 version. 12f15cbe6fSPaul Mundt */ 13f15cbe6fSPaul Mundt #ifndef __ASM_SH_UACCESS_32_H 14f15cbe6fSPaul Mundt #define __ASM_SH_UACCESS_32_H 15f15cbe6fSPaul Mundt 16f15cbe6fSPaul Mundt #define __get_user_size(x,ptr,size,retval) \ 17f15cbe6fSPaul Mundt do { \ 18f15cbe6fSPaul Mundt retval = 0; \ 19f15cbe6fSPaul Mundt switch (size) { \ 20f15cbe6fSPaul Mundt case 1: \ 21f15cbe6fSPaul Mundt __get_user_asm(x, ptr, retval, "b"); \ 22f15cbe6fSPaul Mundt break; \ 23f15cbe6fSPaul Mundt case 2: \ 24f15cbe6fSPaul Mundt __get_user_asm(x, ptr, retval, "w"); \ 25f15cbe6fSPaul Mundt break; \ 26f15cbe6fSPaul Mundt case 4: \ 27f15cbe6fSPaul Mundt __get_user_asm(x, ptr, retval, "l"); \ 28f15cbe6fSPaul Mundt break; \ 292d2b308aSJohn Paul Adrian Glaubitz case 8: \ 302d2b308aSJohn Paul Adrian Glaubitz __get_user_u64(x, ptr, retval); \ 312d2b308aSJohn Paul Adrian Glaubitz break; \ 32f15cbe6fSPaul Mundt default: \ 33f15cbe6fSPaul Mundt __get_user_unknown(); \ 34f15cbe6fSPaul Mundt break; \ 35f15cbe6fSPaul Mundt } \ 36f15cbe6fSPaul Mundt } while (0) 37f15cbe6fSPaul Mundt 38f15cbe6fSPaul Mundt #ifdef CONFIG_MMU 39f15cbe6fSPaul Mundt #define __get_user_asm(x, addr, err, insn) \ 40f15cbe6fSPaul Mundt ({ \ 41f15cbe6fSPaul Mundt __asm__ __volatile__( \ 42f15cbe6fSPaul Mundt "1:\n\t" \ 43f15cbe6fSPaul Mundt "mov." insn " %2, %1\n\t" \ 44f15cbe6fSPaul Mundt "2:\n" \ 45f15cbe6fSPaul Mundt ".section .fixup,\"ax\"\n" \ 46f15cbe6fSPaul Mundt "3:\n\t" \ 47f15cbe6fSPaul Mundt "mov #0, %1\n\t" \ 48f15cbe6fSPaul Mundt "mov.l 4f, %0\n\t" \ 49f15cbe6fSPaul Mundt "jmp @%0\n\t" \ 50f15cbe6fSPaul Mundt " mov %3, %0\n\t" \ 51f15cbe6fSPaul Mundt ".balign 4\n" \ 52f15cbe6fSPaul Mundt "4: .long 2b\n\t" \ 53f15cbe6fSPaul Mundt ".previous\n" \ 54f15cbe6fSPaul Mundt ".section __ex_table,\"a\"\n\t" \ 55f15cbe6fSPaul Mundt ".long 1b, 3b\n\t" \ 56f15cbe6fSPaul Mundt ".previous" \ 57f15cbe6fSPaul Mundt :"=&r" (err), "=&r" (x) \ 58f15cbe6fSPaul Mundt :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); }) 59f15cbe6fSPaul Mundt #else 60f15cbe6fSPaul Mundt #define __get_user_asm(x, addr, err, insn) \ 61f15cbe6fSPaul Mundt do { \ 62f15cbe6fSPaul Mundt __asm__ __volatile__ ( \ 63f15cbe6fSPaul Mundt "mov." insn " %1, %0\n\t" \ 64f15cbe6fSPaul Mundt : "=&r" (x) \ 65f15cbe6fSPaul Mundt : "m" (__m(addr)) \ 66f15cbe6fSPaul Mundt ); \ 67f15cbe6fSPaul Mundt } while (0) 68f15cbe6fSPaul Mundt #endif /* CONFIG_MMU */ 69f15cbe6fSPaul Mundt 70f15cbe6fSPaul Mundt extern void __get_user_unknown(void); 71f15cbe6fSPaul Mundt 722d2b308aSJohn Paul Adrian Glaubitz #if defined(CONFIG_CPU_LITTLE_ENDIAN) 732d2b308aSJohn Paul Adrian Glaubitz #define __get_user_u64(x, addr, err) \ 742d2b308aSJohn Paul Adrian Glaubitz ({ \ 752d2b308aSJohn Paul Adrian Glaubitz __asm__ __volatile__( \ 762d2b308aSJohn Paul Adrian Glaubitz "1:\n\t" \ 772d2b308aSJohn Paul Adrian Glaubitz "mov.l %2,%R1\n\t" \ 782d2b308aSJohn Paul Adrian Glaubitz "mov.l %T2,%S1\n\t" \ 792d2b308aSJohn Paul Adrian Glaubitz "2:\n" \ 802d2b308aSJohn Paul Adrian Glaubitz ".section .fixup,\"ax\"\n" \ 812d2b308aSJohn Paul Adrian Glaubitz "3:\n\t" \ 822d2b308aSJohn Paul Adrian Glaubitz "mov #0,%R1\n\t" \ 832d2b308aSJohn Paul Adrian Glaubitz "mov #0,%S1\n\t" \ 842d2b308aSJohn Paul Adrian Glaubitz "mov.l 4f, %0\n\t" \ 852d2b308aSJohn Paul Adrian Glaubitz "jmp @%0\n\t" \ 862d2b308aSJohn Paul Adrian Glaubitz " mov %3, %0\n\t" \ 872d2b308aSJohn Paul Adrian Glaubitz ".balign 4\n" \ 882d2b308aSJohn Paul Adrian Glaubitz "4: .long 2b\n\t" \ 892d2b308aSJohn Paul Adrian Glaubitz ".previous\n" \ 902d2b308aSJohn Paul Adrian Glaubitz ".section __ex_table,\"a\"\n\t" \ 912d2b308aSJohn Paul Adrian Glaubitz ".long 1b, 3b\n\t" \ 922d2b308aSJohn Paul Adrian Glaubitz ".long 1b + 2, 3b\n\t" \ 932d2b308aSJohn Paul Adrian Glaubitz ".previous" \ 942d2b308aSJohn Paul Adrian Glaubitz :"=&r" (err), "=&r" (x) \ 952d2b308aSJohn Paul Adrian Glaubitz :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); }) 962d2b308aSJohn Paul Adrian Glaubitz #else 972d2b308aSJohn Paul Adrian Glaubitz #define __get_user_u64(x, addr, err) \ 982d2b308aSJohn Paul Adrian Glaubitz ({ \ 992d2b308aSJohn Paul Adrian Glaubitz __asm__ __volatile__( \ 1002d2b308aSJohn Paul Adrian Glaubitz "1:\n\t" \ 1012d2b308aSJohn Paul Adrian Glaubitz "mov.l %2,%S1\n\t" \ 1022d2b308aSJohn Paul Adrian Glaubitz "mov.l %T2,%R1\n\t" \ 1032d2b308aSJohn Paul Adrian Glaubitz "2:\n" \ 1042d2b308aSJohn Paul Adrian Glaubitz ".section .fixup,\"ax\"\n" \ 1052d2b308aSJohn Paul Adrian Glaubitz "3:\n\t" \ 1062d2b308aSJohn Paul Adrian Glaubitz "mov #0,%S1\n\t" \ 1072d2b308aSJohn Paul Adrian Glaubitz "mov #0,%R1\n\t" \ 1082d2b308aSJohn Paul Adrian Glaubitz "mov.l 4f, %0\n\t" \ 1092d2b308aSJohn Paul Adrian Glaubitz "jmp @%0\n\t" \ 1102d2b308aSJohn Paul Adrian Glaubitz " mov %3, %0\n\t" \ 1112d2b308aSJohn Paul Adrian Glaubitz ".balign 4\n" \ 1122d2b308aSJohn Paul Adrian Glaubitz "4: .long 2b\n\t" \ 1132d2b308aSJohn Paul Adrian Glaubitz ".previous\n" \ 1142d2b308aSJohn Paul Adrian Glaubitz ".section __ex_table,\"a\"\n\t" \ 1152d2b308aSJohn Paul Adrian Glaubitz ".long 1b, 3b\n\t" \ 1162d2b308aSJohn Paul Adrian Glaubitz ".long 1b + 2, 3b\n\t" \ 1172d2b308aSJohn Paul Adrian Glaubitz ".previous" \ 1182d2b308aSJohn Paul Adrian Glaubitz :"=&r" (err), "=&r" (x) \ 1192d2b308aSJohn Paul Adrian Glaubitz :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); }) 1202d2b308aSJohn Paul Adrian Glaubitz #endif 1212d2b308aSJohn Paul Adrian Glaubitz 122f15cbe6fSPaul Mundt #define __put_user_size(x,ptr,size,retval) \ 123f15cbe6fSPaul Mundt do { \ 124f15cbe6fSPaul Mundt retval = 0; \ 125f15cbe6fSPaul Mundt switch (size) { \ 126f15cbe6fSPaul Mundt case 1: \ 127f15cbe6fSPaul Mundt __put_user_asm(x, ptr, retval, "b"); \ 128f15cbe6fSPaul Mundt break; \ 129f15cbe6fSPaul Mundt case 2: \ 130f15cbe6fSPaul Mundt __put_user_asm(x, ptr, retval, "w"); \ 131f15cbe6fSPaul Mundt break; \ 132f15cbe6fSPaul Mundt case 4: \ 1336de9c648SOGAWA Hirofumi __put_user_asm(x, ptr, retval, "l"); \ 134f15cbe6fSPaul Mundt break; \ 135f15cbe6fSPaul Mundt case 8: \ 136f15cbe6fSPaul Mundt __put_user_u64(x, ptr, retval); \ 137f15cbe6fSPaul Mundt break; \ 138f15cbe6fSPaul Mundt default: \ 139f15cbe6fSPaul Mundt __put_user_unknown(); \ 140f15cbe6fSPaul Mundt } \ 141f15cbe6fSPaul Mundt } while (0) 142f15cbe6fSPaul Mundt 143f15cbe6fSPaul Mundt #ifdef CONFIG_MMU 144f15cbe6fSPaul Mundt #define __put_user_asm(x, addr, err, insn) \ 145f15cbe6fSPaul Mundt do { \ 146f15cbe6fSPaul Mundt __asm__ __volatile__ ( \ 147f15cbe6fSPaul Mundt "1:\n\t" \ 148f15cbe6fSPaul Mundt "mov." insn " %1, %2\n\t" \ 149f15cbe6fSPaul Mundt "2:\n" \ 150f15cbe6fSPaul Mundt ".section .fixup,\"ax\"\n" \ 151f15cbe6fSPaul Mundt "3:\n\t" \ 152f15cbe6fSPaul Mundt "mov.l 4f, %0\n\t" \ 153f15cbe6fSPaul Mundt "jmp @%0\n\t" \ 154f15cbe6fSPaul Mundt " mov %3, %0\n\t" \ 155f15cbe6fSPaul Mundt ".balign 4\n" \ 156f15cbe6fSPaul Mundt "4: .long 2b\n\t" \ 157f15cbe6fSPaul Mundt ".previous\n" \ 158f15cbe6fSPaul Mundt ".section __ex_table,\"a\"\n\t" \ 159f15cbe6fSPaul Mundt ".long 1b, 3b\n\t" \ 160f15cbe6fSPaul Mundt ".previous" \ 161f15cbe6fSPaul Mundt : "=&r" (err) \ 162f15cbe6fSPaul Mundt : "r" (x), "m" (__m(addr)), "i" (-EFAULT), \ 163f15cbe6fSPaul Mundt "0" (err) \ 164f15cbe6fSPaul Mundt : "memory" \ 165f15cbe6fSPaul Mundt ); \ 166f15cbe6fSPaul Mundt } while (0) 167f15cbe6fSPaul Mundt #else 168f15cbe6fSPaul Mundt #define __put_user_asm(x, addr, err, insn) \ 169f15cbe6fSPaul Mundt do { \ 170f15cbe6fSPaul Mundt __asm__ __volatile__ ( \ 171f15cbe6fSPaul Mundt "mov." insn " %0, %1\n\t" \ 172f15cbe6fSPaul Mundt : /* no outputs */ \ 173f15cbe6fSPaul Mundt : "r" (x), "m" (__m(addr)) \ 174f15cbe6fSPaul Mundt : "memory" \ 175f15cbe6fSPaul Mundt ); \ 176f15cbe6fSPaul Mundt } while (0) 177f15cbe6fSPaul Mundt #endif /* CONFIG_MMU */ 178f15cbe6fSPaul Mundt 179f15cbe6fSPaul Mundt #if defined(CONFIG_CPU_LITTLE_ENDIAN) 180f15cbe6fSPaul Mundt #define __put_user_u64(val,addr,retval) \ 181f15cbe6fSPaul Mundt ({ \ 182f15cbe6fSPaul Mundt __asm__ __volatile__( \ 183f15cbe6fSPaul Mundt "1:\n\t" \ 184f15cbe6fSPaul Mundt "mov.l %R1,%2\n\t" \ 185f15cbe6fSPaul Mundt "mov.l %S1,%T2\n\t" \ 186f15cbe6fSPaul Mundt "2:\n" \ 187f15cbe6fSPaul Mundt ".section .fixup,\"ax\"\n" \ 188f15cbe6fSPaul Mundt "3:\n\t" \ 189f15cbe6fSPaul Mundt "mov.l 4f,%0\n\t" \ 190f15cbe6fSPaul Mundt "jmp @%0\n\t" \ 191f15cbe6fSPaul Mundt " mov %3,%0\n\t" \ 192f15cbe6fSPaul Mundt ".balign 4\n" \ 193f15cbe6fSPaul Mundt "4: .long 2b\n\t" \ 194f15cbe6fSPaul Mundt ".previous\n" \ 195f15cbe6fSPaul Mundt ".section __ex_table,\"a\"\n\t" \ 196f15cbe6fSPaul Mundt ".long 1b, 3b\n\t" \ 197f15cbe6fSPaul Mundt ".previous" \ 198f15cbe6fSPaul Mundt : "=r" (retval) \ 199f15cbe6fSPaul Mundt : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \ 200f15cbe6fSPaul Mundt : "memory"); }) 201f15cbe6fSPaul Mundt #else 202f15cbe6fSPaul Mundt #define __put_user_u64(val,addr,retval) \ 203f15cbe6fSPaul Mundt ({ \ 204f15cbe6fSPaul Mundt __asm__ __volatile__( \ 205f15cbe6fSPaul Mundt "1:\n\t" \ 206f15cbe6fSPaul Mundt "mov.l %S1,%2\n\t" \ 207f15cbe6fSPaul Mundt "mov.l %R1,%T2\n\t" \ 208f15cbe6fSPaul Mundt "2:\n" \ 209f15cbe6fSPaul Mundt ".section .fixup,\"ax\"\n" \ 210f15cbe6fSPaul Mundt "3:\n\t" \ 211f15cbe6fSPaul Mundt "mov.l 4f,%0\n\t" \ 212f15cbe6fSPaul Mundt "jmp @%0\n\t" \ 213f15cbe6fSPaul Mundt " mov %3,%0\n\t" \ 214f15cbe6fSPaul Mundt ".balign 4\n" \ 215f15cbe6fSPaul Mundt "4: .long 2b\n\t" \ 216f15cbe6fSPaul Mundt ".previous\n" \ 217f15cbe6fSPaul Mundt ".section __ex_table,\"a\"\n\t" \ 218f15cbe6fSPaul Mundt ".long 1b, 3b\n\t" \ 219f15cbe6fSPaul Mundt ".previous" \ 220f15cbe6fSPaul Mundt : "=r" (retval) \ 221f15cbe6fSPaul Mundt : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \ 222f15cbe6fSPaul Mundt : "memory"); }) 223f15cbe6fSPaul Mundt #endif 224f15cbe6fSPaul Mundt 225f15cbe6fSPaul Mundt extern void __put_user_unknown(void); 226f15cbe6fSPaul Mundt 227f15cbe6fSPaul Mundt #endif /* __ASM_SH_UACCESS_32_H */ 228