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; \ 29f15cbe6fSPaul Mundt default: \ 30f15cbe6fSPaul Mundt __get_user_unknown(); \ 31f15cbe6fSPaul Mundt break; \ 32f15cbe6fSPaul Mundt } \ 33f15cbe6fSPaul Mundt } while (0) 34f15cbe6fSPaul Mundt 35f15cbe6fSPaul Mundt #ifdef CONFIG_MMU 36f15cbe6fSPaul Mundt #define __get_user_asm(x, addr, err, insn) \ 37f15cbe6fSPaul Mundt ({ \ 38f15cbe6fSPaul Mundt __asm__ __volatile__( \ 39f15cbe6fSPaul Mundt "1:\n\t" \ 40f15cbe6fSPaul Mundt "mov." insn " %2, %1\n\t" \ 41f15cbe6fSPaul Mundt "2:\n" \ 42f15cbe6fSPaul Mundt ".section .fixup,\"ax\"\n" \ 43f15cbe6fSPaul Mundt "3:\n\t" \ 44f15cbe6fSPaul Mundt "mov #0, %1\n\t" \ 45f15cbe6fSPaul Mundt "mov.l 4f, %0\n\t" \ 46f15cbe6fSPaul Mundt "jmp @%0\n\t" \ 47f15cbe6fSPaul Mundt " mov %3, %0\n\t" \ 48f15cbe6fSPaul Mundt ".balign 4\n" \ 49f15cbe6fSPaul Mundt "4: .long 2b\n\t" \ 50f15cbe6fSPaul Mundt ".previous\n" \ 51f15cbe6fSPaul Mundt ".section __ex_table,\"a\"\n\t" \ 52f15cbe6fSPaul Mundt ".long 1b, 3b\n\t" \ 53f15cbe6fSPaul Mundt ".previous" \ 54f15cbe6fSPaul Mundt :"=&r" (err), "=&r" (x) \ 55f15cbe6fSPaul Mundt :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); }) 56f15cbe6fSPaul Mundt #else 57f15cbe6fSPaul Mundt #define __get_user_asm(x, addr, err, insn) \ 58f15cbe6fSPaul Mundt do { \ 59f15cbe6fSPaul Mundt __asm__ __volatile__ ( \ 60f15cbe6fSPaul Mundt "mov." insn " %1, %0\n\t" \ 61f15cbe6fSPaul Mundt : "=&r" (x) \ 62f15cbe6fSPaul Mundt : "m" (__m(addr)) \ 63f15cbe6fSPaul Mundt ); \ 64f15cbe6fSPaul Mundt } while (0) 65f15cbe6fSPaul Mundt #endif /* CONFIG_MMU */ 66f15cbe6fSPaul Mundt 67f15cbe6fSPaul Mundt extern void __get_user_unknown(void); 68f15cbe6fSPaul Mundt 69f15cbe6fSPaul Mundt #define __put_user_size(x,ptr,size,retval) \ 70f15cbe6fSPaul Mundt do { \ 71f15cbe6fSPaul Mundt retval = 0; \ 72f15cbe6fSPaul Mundt switch (size) { \ 73f15cbe6fSPaul Mundt case 1: \ 74f15cbe6fSPaul Mundt __put_user_asm(x, ptr, retval, "b"); \ 75f15cbe6fSPaul Mundt break; \ 76f15cbe6fSPaul Mundt case 2: \ 77f15cbe6fSPaul Mundt __put_user_asm(x, ptr, retval, "w"); \ 78f15cbe6fSPaul Mundt break; \ 79f15cbe6fSPaul Mundt case 4: \ 806de9c648SOGAWA Hirofumi __put_user_asm(x, ptr, retval, "l"); \ 81f15cbe6fSPaul Mundt break; \ 82f15cbe6fSPaul Mundt case 8: \ 83f15cbe6fSPaul Mundt __put_user_u64(x, ptr, retval); \ 84f15cbe6fSPaul Mundt break; \ 85f15cbe6fSPaul Mundt default: \ 86f15cbe6fSPaul Mundt __put_user_unknown(); \ 87f15cbe6fSPaul Mundt } \ 88f15cbe6fSPaul Mundt } while (0) 89f15cbe6fSPaul Mundt 90f15cbe6fSPaul Mundt #ifdef CONFIG_MMU 91f15cbe6fSPaul Mundt #define __put_user_asm(x, addr, err, insn) \ 92f15cbe6fSPaul Mundt do { \ 93f15cbe6fSPaul Mundt __asm__ __volatile__ ( \ 94f15cbe6fSPaul Mundt "1:\n\t" \ 95f15cbe6fSPaul Mundt "mov." insn " %1, %2\n\t" \ 96f15cbe6fSPaul Mundt "2:\n" \ 97f15cbe6fSPaul Mundt ".section .fixup,\"ax\"\n" \ 98f15cbe6fSPaul Mundt "3:\n\t" \ 99f15cbe6fSPaul Mundt "mov.l 4f, %0\n\t" \ 100f15cbe6fSPaul Mundt "jmp @%0\n\t" \ 101f15cbe6fSPaul Mundt " mov %3, %0\n\t" \ 102f15cbe6fSPaul Mundt ".balign 4\n" \ 103f15cbe6fSPaul Mundt "4: .long 2b\n\t" \ 104f15cbe6fSPaul Mundt ".previous\n" \ 105f15cbe6fSPaul Mundt ".section __ex_table,\"a\"\n\t" \ 106f15cbe6fSPaul Mundt ".long 1b, 3b\n\t" \ 107f15cbe6fSPaul Mundt ".previous" \ 108f15cbe6fSPaul Mundt : "=&r" (err) \ 109f15cbe6fSPaul Mundt : "r" (x), "m" (__m(addr)), "i" (-EFAULT), \ 110f15cbe6fSPaul Mundt "0" (err) \ 111f15cbe6fSPaul Mundt : "memory" \ 112f15cbe6fSPaul Mundt ); \ 113f15cbe6fSPaul Mundt } while (0) 114f15cbe6fSPaul Mundt #else 115f15cbe6fSPaul Mundt #define __put_user_asm(x, addr, err, insn) \ 116f15cbe6fSPaul Mundt do { \ 117f15cbe6fSPaul Mundt __asm__ __volatile__ ( \ 118f15cbe6fSPaul Mundt "mov." insn " %0, %1\n\t" \ 119f15cbe6fSPaul Mundt : /* no outputs */ \ 120f15cbe6fSPaul Mundt : "r" (x), "m" (__m(addr)) \ 121f15cbe6fSPaul Mundt : "memory" \ 122f15cbe6fSPaul Mundt ); \ 123f15cbe6fSPaul Mundt } while (0) 124f15cbe6fSPaul Mundt #endif /* CONFIG_MMU */ 125f15cbe6fSPaul Mundt 126f15cbe6fSPaul Mundt #if defined(CONFIG_CPU_LITTLE_ENDIAN) 127f15cbe6fSPaul Mundt #define __put_user_u64(val,addr,retval) \ 128f15cbe6fSPaul Mundt ({ \ 129f15cbe6fSPaul Mundt __asm__ __volatile__( \ 130f15cbe6fSPaul Mundt "1:\n\t" \ 131f15cbe6fSPaul Mundt "mov.l %R1,%2\n\t" \ 132f15cbe6fSPaul Mundt "mov.l %S1,%T2\n\t" \ 133f15cbe6fSPaul Mundt "2:\n" \ 134f15cbe6fSPaul Mundt ".section .fixup,\"ax\"\n" \ 135f15cbe6fSPaul Mundt "3:\n\t" \ 136f15cbe6fSPaul Mundt "mov.l 4f,%0\n\t" \ 137f15cbe6fSPaul Mundt "jmp @%0\n\t" \ 138f15cbe6fSPaul Mundt " mov %3,%0\n\t" \ 139f15cbe6fSPaul Mundt ".balign 4\n" \ 140f15cbe6fSPaul Mundt "4: .long 2b\n\t" \ 141f15cbe6fSPaul Mundt ".previous\n" \ 142f15cbe6fSPaul Mundt ".section __ex_table,\"a\"\n\t" \ 143f15cbe6fSPaul Mundt ".long 1b, 3b\n\t" \ 144f15cbe6fSPaul Mundt ".previous" \ 145f15cbe6fSPaul Mundt : "=r" (retval) \ 146f15cbe6fSPaul Mundt : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \ 147f15cbe6fSPaul Mundt : "memory"); }) 148f15cbe6fSPaul Mundt #else 149f15cbe6fSPaul Mundt #define __put_user_u64(val,addr,retval) \ 150f15cbe6fSPaul Mundt ({ \ 151f15cbe6fSPaul Mundt __asm__ __volatile__( \ 152f15cbe6fSPaul Mundt "1:\n\t" \ 153f15cbe6fSPaul Mundt "mov.l %S1,%2\n\t" \ 154f15cbe6fSPaul Mundt "mov.l %R1,%T2\n\t" \ 155f15cbe6fSPaul Mundt "2:\n" \ 156f15cbe6fSPaul Mundt ".section .fixup,\"ax\"\n" \ 157f15cbe6fSPaul Mundt "3:\n\t" \ 158f15cbe6fSPaul Mundt "mov.l 4f,%0\n\t" \ 159f15cbe6fSPaul Mundt "jmp @%0\n\t" \ 160f15cbe6fSPaul Mundt " mov %3,%0\n\t" \ 161f15cbe6fSPaul Mundt ".balign 4\n" \ 162f15cbe6fSPaul Mundt "4: .long 2b\n\t" \ 163f15cbe6fSPaul Mundt ".previous\n" \ 164f15cbe6fSPaul Mundt ".section __ex_table,\"a\"\n\t" \ 165f15cbe6fSPaul Mundt ".long 1b, 3b\n\t" \ 166f15cbe6fSPaul Mundt ".previous" \ 167f15cbe6fSPaul Mundt : "=r" (retval) \ 168f15cbe6fSPaul Mundt : "r" (val), "m" (__m(addr)), "i" (-EFAULT), "0" (retval) \ 169f15cbe6fSPaul Mundt : "memory"); }) 170f15cbe6fSPaul Mundt #endif 171f15cbe6fSPaul Mundt 172f15cbe6fSPaul Mundt extern void __put_user_unknown(void); 173f15cbe6fSPaul Mundt 174f15cbe6fSPaul Mundt #endif /* __ASM_SH_UACCESS_32_H */ 175