162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#ifndef __ASM_CSKY_UACCESS_H 462306a36Sopenharmony_ci#define __ASM_CSKY_UACCESS_H 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* 762306a36Sopenharmony_ci * __put_user_fn 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ciextern int __put_user_bad(void); 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#define __put_user_asm_b(x, ptr, err) \ 1262306a36Sopenharmony_cido { \ 1362306a36Sopenharmony_ci int errcode; \ 1462306a36Sopenharmony_ci __asm__ __volatile__( \ 1562306a36Sopenharmony_ci "1: stb %1, (%2,0) \n" \ 1662306a36Sopenharmony_ci " br 3f \n" \ 1762306a36Sopenharmony_ci "2: mov %0, %3 \n" \ 1862306a36Sopenharmony_ci " br 3f \n" \ 1962306a36Sopenharmony_ci ".section __ex_table, \"a\" \n" \ 2062306a36Sopenharmony_ci ".align 2 \n" \ 2162306a36Sopenharmony_ci ".long 1b,2b \n" \ 2262306a36Sopenharmony_ci ".previous \n" \ 2362306a36Sopenharmony_ci "3: \n" \ 2462306a36Sopenharmony_ci : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \ 2562306a36Sopenharmony_ci : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \ 2662306a36Sopenharmony_ci : "memory"); \ 2762306a36Sopenharmony_ci} while (0) 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define __put_user_asm_h(x, ptr, err) \ 3062306a36Sopenharmony_cido { \ 3162306a36Sopenharmony_ci int errcode; \ 3262306a36Sopenharmony_ci __asm__ __volatile__( \ 3362306a36Sopenharmony_ci "1: sth %1, (%2,0) \n" \ 3462306a36Sopenharmony_ci " br 3f \n" \ 3562306a36Sopenharmony_ci "2: mov %0, %3 \n" \ 3662306a36Sopenharmony_ci " br 3f \n" \ 3762306a36Sopenharmony_ci ".section __ex_table, \"a\" \n" \ 3862306a36Sopenharmony_ci ".align 2 \n" \ 3962306a36Sopenharmony_ci ".long 1b,2b \n" \ 4062306a36Sopenharmony_ci ".previous \n" \ 4162306a36Sopenharmony_ci "3: \n" \ 4262306a36Sopenharmony_ci : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \ 4362306a36Sopenharmony_ci : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \ 4462306a36Sopenharmony_ci : "memory"); \ 4562306a36Sopenharmony_ci} while (0) 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define __put_user_asm_w(x, ptr, err) \ 4862306a36Sopenharmony_cido { \ 4962306a36Sopenharmony_ci int errcode; \ 5062306a36Sopenharmony_ci __asm__ __volatile__( \ 5162306a36Sopenharmony_ci "1: stw %1, (%2,0) \n" \ 5262306a36Sopenharmony_ci " br 3f \n" \ 5362306a36Sopenharmony_ci "2: mov %0, %3 \n" \ 5462306a36Sopenharmony_ci " br 3f \n" \ 5562306a36Sopenharmony_ci ".section __ex_table,\"a\" \n" \ 5662306a36Sopenharmony_ci ".align 2 \n" \ 5762306a36Sopenharmony_ci ".long 1b, 2b \n" \ 5862306a36Sopenharmony_ci ".previous \n" \ 5962306a36Sopenharmony_ci "3: \n" \ 6062306a36Sopenharmony_ci : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \ 6162306a36Sopenharmony_ci : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \ 6262306a36Sopenharmony_ci : "memory"); \ 6362306a36Sopenharmony_ci} while (0) 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#define __put_user_asm_64(x, ptr, err) \ 6662306a36Sopenharmony_cido { \ 6762306a36Sopenharmony_ci int tmp; \ 6862306a36Sopenharmony_ci int errcode; \ 6962306a36Sopenharmony_ci \ 7062306a36Sopenharmony_ci __asm__ __volatile__( \ 7162306a36Sopenharmony_ci " ldw %3, (%1, 0) \n" \ 7262306a36Sopenharmony_ci "1: stw %3, (%2, 0) \n" \ 7362306a36Sopenharmony_ci " ldw %3, (%1, 4) \n" \ 7462306a36Sopenharmony_ci "2: stw %3, (%2, 4) \n" \ 7562306a36Sopenharmony_ci " br 4f \n" \ 7662306a36Sopenharmony_ci "3: mov %0, %4 \n" \ 7762306a36Sopenharmony_ci " br 4f \n" \ 7862306a36Sopenharmony_ci ".section __ex_table, \"a\" \n" \ 7962306a36Sopenharmony_ci ".align 2 \n" \ 8062306a36Sopenharmony_ci ".long 1b, 3b \n" \ 8162306a36Sopenharmony_ci ".long 2b, 3b \n" \ 8262306a36Sopenharmony_ci ".previous \n" \ 8362306a36Sopenharmony_ci "4: \n" \ 8462306a36Sopenharmony_ci : "=r"(err), "=r"(x), "=r"(ptr), \ 8562306a36Sopenharmony_ci "=r"(tmp), "=r"(errcode) \ 8662306a36Sopenharmony_ci : "0"(err), "1"(x), "2"(ptr), "3"(0), \ 8762306a36Sopenharmony_ci "4"(-EFAULT) \ 8862306a36Sopenharmony_ci : "memory"); \ 8962306a36Sopenharmony_ci} while (0) 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic inline int __put_user_fn(size_t size, void __user *ptr, void *x) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci int retval = 0; 9462306a36Sopenharmony_ci u32 tmp; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci switch (size) { 9762306a36Sopenharmony_ci case 1: 9862306a36Sopenharmony_ci tmp = *(u8 *)x; 9962306a36Sopenharmony_ci __put_user_asm_b(tmp, ptr, retval); 10062306a36Sopenharmony_ci break; 10162306a36Sopenharmony_ci case 2: 10262306a36Sopenharmony_ci tmp = *(u16 *)x; 10362306a36Sopenharmony_ci __put_user_asm_h(tmp, ptr, retval); 10462306a36Sopenharmony_ci break; 10562306a36Sopenharmony_ci case 4: 10662306a36Sopenharmony_ci tmp = *(u32 *)x; 10762306a36Sopenharmony_ci __put_user_asm_w(tmp, ptr, retval); 10862306a36Sopenharmony_ci break; 10962306a36Sopenharmony_ci case 8: 11062306a36Sopenharmony_ci __put_user_asm_64(x, (u64 *)ptr, retval); 11162306a36Sopenharmony_ci break; 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci return retval; 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci#define __put_user_fn __put_user_fn 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/* 11962306a36Sopenharmony_ci * __get_user_fn 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_ciextern int __get_user_bad(void); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci#define __get_user_asm_common(x, ptr, ins, err) \ 12462306a36Sopenharmony_cido { \ 12562306a36Sopenharmony_ci int errcode; \ 12662306a36Sopenharmony_ci __asm__ __volatile__( \ 12762306a36Sopenharmony_ci "1: " ins " %1, (%4, 0) \n" \ 12862306a36Sopenharmony_ci " br 3f \n" \ 12962306a36Sopenharmony_ci "2: mov %0, %2 \n" \ 13062306a36Sopenharmony_ci " movi %1, 0 \n" \ 13162306a36Sopenharmony_ci " br 3f \n" \ 13262306a36Sopenharmony_ci ".section __ex_table,\"a\" \n" \ 13362306a36Sopenharmony_ci ".align 2 \n" \ 13462306a36Sopenharmony_ci ".long 1b, 2b \n" \ 13562306a36Sopenharmony_ci ".previous \n" \ 13662306a36Sopenharmony_ci "3: \n" \ 13762306a36Sopenharmony_ci : "=r"(err), "=r"(x), "=r"(errcode) \ 13862306a36Sopenharmony_ci : "0"(0), "r"(ptr), "2"(-EFAULT) \ 13962306a36Sopenharmony_ci : "memory"); \ 14062306a36Sopenharmony_ci} while (0) 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci#define __get_user_asm_64(x, ptr, err) \ 14362306a36Sopenharmony_cido { \ 14462306a36Sopenharmony_ci int tmp; \ 14562306a36Sopenharmony_ci int errcode; \ 14662306a36Sopenharmony_ci \ 14762306a36Sopenharmony_ci __asm__ __volatile__( \ 14862306a36Sopenharmony_ci "1: ldw %3, (%2, 0) \n" \ 14962306a36Sopenharmony_ci " stw %3, (%1, 0) \n" \ 15062306a36Sopenharmony_ci "2: ldw %3, (%2, 4) \n" \ 15162306a36Sopenharmony_ci " stw %3, (%1, 4) \n" \ 15262306a36Sopenharmony_ci " br 4f \n" \ 15362306a36Sopenharmony_ci "3: mov %0, %4 \n" \ 15462306a36Sopenharmony_ci " br 4f \n" \ 15562306a36Sopenharmony_ci ".section __ex_table, \"a\" \n" \ 15662306a36Sopenharmony_ci ".align 2 \n" \ 15762306a36Sopenharmony_ci ".long 1b, 3b \n" \ 15862306a36Sopenharmony_ci ".long 2b, 3b \n" \ 15962306a36Sopenharmony_ci ".previous \n" \ 16062306a36Sopenharmony_ci "4: \n" \ 16162306a36Sopenharmony_ci : "=r"(err), "=r"(x), "=r"(ptr), \ 16262306a36Sopenharmony_ci "=r"(tmp), "=r"(errcode) \ 16362306a36Sopenharmony_ci : "0"(err), "1"(x), "2"(ptr), "3"(0), \ 16462306a36Sopenharmony_ci "4"(-EFAULT) \ 16562306a36Sopenharmony_ci : "memory"); \ 16662306a36Sopenharmony_ci} while (0) 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cistatic inline int __get_user_fn(size_t size, const void __user *ptr, void *x) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci int retval; 17162306a36Sopenharmony_ci u32 tmp; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci switch (size) { 17462306a36Sopenharmony_ci case 1: 17562306a36Sopenharmony_ci __get_user_asm_common(tmp, ptr, "ldb", retval); 17662306a36Sopenharmony_ci *(u8 *)x = (u8)tmp; 17762306a36Sopenharmony_ci break; 17862306a36Sopenharmony_ci case 2: 17962306a36Sopenharmony_ci __get_user_asm_common(tmp, ptr, "ldh", retval); 18062306a36Sopenharmony_ci *(u16 *)x = (u16)tmp; 18162306a36Sopenharmony_ci break; 18262306a36Sopenharmony_ci case 4: 18362306a36Sopenharmony_ci __get_user_asm_common(tmp, ptr, "ldw", retval); 18462306a36Sopenharmony_ci *(u32 *)x = (u32)tmp; 18562306a36Sopenharmony_ci break; 18662306a36Sopenharmony_ci case 8: 18762306a36Sopenharmony_ci __get_user_asm_64(x, ptr, retval); 18862306a36Sopenharmony_ci break; 18962306a36Sopenharmony_ci } 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci return retval; 19262306a36Sopenharmony_ci} 19362306a36Sopenharmony_ci#define __get_user_fn __get_user_fn 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ciunsigned long raw_copy_from_user(void *to, const void *from, unsigned long n); 19662306a36Sopenharmony_ciunsigned long raw_copy_to_user(void *to, const void *from, unsigned long n); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ciunsigned long __clear_user(void __user *to, unsigned long n); 19962306a36Sopenharmony_ci#define __clear_user __clear_user 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci#include <asm-generic/uaccess.h> 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#endif /* __ASM_CSKY_UACCESS_H */ 204