18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2020-2021 Loongson Technology Corporation Limited 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <asm/alternative-asm.h> 78c2ecf20Sopenharmony_ci#include <asm/asm.h> 88c2ecf20Sopenharmony_ci#include <asm/asmmacro.h> 98c2ecf20Sopenharmony_ci#include <asm/asm-extable.h> 108c2ecf20Sopenharmony_ci#include <asm/cpu.h> 118c2ecf20Sopenharmony_ci#include <asm/export.h> 128c2ecf20Sopenharmony_ci#include <asm/regdef.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciSYM_FUNC_START(__copy_user) 158c2ecf20Sopenharmony_ci /* 168c2ecf20Sopenharmony_ci * Some CPUs support hardware unaligned access 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci ALTERNATIVE "b __copy_user_generic", \ 198c2ecf20Sopenharmony_ci "b __copy_user_fast", CPU_FEATURE_UAL 208c2ecf20Sopenharmony_ciSYM_FUNC_END(__copy_user) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__copy_user) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* 258c2ecf20Sopenharmony_ci * unsigned long __copy_user_generic(void *to, const void *from, size_t n) 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * a0: to 288c2ecf20Sopenharmony_ci * a1: from 298c2ecf20Sopenharmony_ci * a2: n 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_ciSYM_FUNC_START(__copy_user_generic) 328c2ecf20Sopenharmony_ci beqz a2, 3f 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci1: ld.b t0, a1, 0 358c2ecf20Sopenharmony_ci2: st.b t0, a0, 0 368c2ecf20Sopenharmony_ci addi.d a0, a0, 1 378c2ecf20Sopenharmony_ci addi.d a1, a1, 1 388c2ecf20Sopenharmony_ci addi.d a2, a2, -1 398c2ecf20Sopenharmony_ci bgt a2, zero, 1b 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci3: move a0, a2 428c2ecf20Sopenharmony_ci jr ra 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci _asm_extable 1b, 3b 458c2ecf20Sopenharmony_ci _asm_extable 2b, 3b 468c2ecf20Sopenharmony_ciSYM_FUNC_END(__copy_user_generic) 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* 498c2ecf20Sopenharmony_ci * unsigned long __copy_user_fast(void *to, const void *from, unsigned long n) 508c2ecf20Sopenharmony_ci * 518c2ecf20Sopenharmony_ci * a0: to 528c2ecf20Sopenharmony_ci * a1: from 538c2ecf20Sopenharmony_ci * a2: n 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_ciSYM_FUNC_START(__copy_user_fast) 568c2ecf20Sopenharmony_ci sltui t0, a2, 9 578c2ecf20Sopenharmony_ci bnez t0, .Lsmall 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci0: ld.d t0, a1, 0 608c2ecf20Sopenharmony_ci1: st.d t0, a0, 0 618c2ecf20Sopenharmony_ci add.d a3, a1, a2 628c2ecf20Sopenharmony_ci add.d a2, a0, a2 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci /* align up destination address */ 658c2ecf20Sopenharmony_ci andi t1, a0, 7 668c2ecf20Sopenharmony_ci sub.d t0, zero, t1 678c2ecf20Sopenharmony_ci addi.d t0, t0, 8 688c2ecf20Sopenharmony_ci add.d a1, a1, t0 698c2ecf20Sopenharmony_ci add.d a0, a0, t0 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci addi.d a4, a3, -64 728c2ecf20Sopenharmony_ci bgeu a1, a4, .Llt64 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /* copy 64 bytes at a time */ 758c2ecf20Sopenharmony_ci.Lloop64: 768c2ecf20Sopenharmony_ci2: ld.d t0, a1, 0 778c2ecf20Sopenharmony_ci3: ld.d t1, a1, 8 788c2ecf20Sopenharmony_ci4: ld.d t2, a1, 16 798c2ecf20Sopenharmony_ci5: ld.d t3, a1, 24 808c2ecf20Sopenharmony_ci6: ld.d t4, a1, 32 818c2ecf20Sopenharmony_ci7: ld.d t5, a1, 40 828c2ecf20Sopenharmony_ci8: ld.d t6, a1, 48 838c2ecf20Sopenharmony_ci9: ld.d t7, a1, 56 848c2ecf20Sopenharmony_ci10: st.d t0, a0, 0 858c2ecf20Sopenharmony_ci11: st.d t1, a0, 8 868c2ecf20Sopenharmony_ci12: st.d t2, a0, 16 878c2ecf20Sopenharmony_ci13: st.d t3, a0, 24 888c2ecf20Sopenharmony_ci14: st.d t4, a0, 32 898c2ecf20Sopenharmony_ci15: st.d t5, a0, 40 908c2ecf20Sopenharmony_ci16: st.d t6, a0, 48 918c2ecf20Sopenharmony_ci17: st.d t7, a0, 56 928c2ecf20Sopenharmony_ci addi.d a1, a1, 64 938c2ecf20Sopenharmony_ci addi.d a0, a0, 64 948c2ecf20Sopenharmony_ci bltu a1, a4, .Lloop64 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci /* copy the remaining bytes */ 978c2ecf20Sopenharmony_ci.Llt64: 988c2ecf20Sopenharmony_ci addi.d a4, a3, -32 998c2ecf20Sopenharmony_ci bgeu a1, a4, .Llt32 1008c2ecf20Sopenharmony_ci18: ld.d t0, a1, 0 1018c2ecf20Sopenharmony_ci19: ld.d t1, a1, 8 1028c2ecf20Sopenharmony_ci20: ld.d t2, a1, 16 1038c2ecf20Sopenharmony_ci21: ld.d t3, a1, 24 1048c2ecf20Sopenharmony_ci22: st.d t0, a0, 0 1058c2ecf20Sopenharmony_ci23: st.d t1, a0, 8 1068c2ecf20Sopenharmony_ci24: st.d t2, a0, 16 1078c2ecf20Sopenharmony_ci25: st.d t3, a0, 24 1088c2ecf20Sopenharmony_ci addi.d a1, a1, 32 1098c2ecf20Sopenharmony_ci addi.d a0, a0, 32 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci.Llt32: 1128c2ecf20Sopenharmony_ci addi.d a4, a3, -16 1138c2ecf20Sopenharmony_ci bgeu a1, a4, .Llt16 1148c2ecf20Sopenharmony_ci26: ld.d t0, a1, 0 1158c2ecf20Sopenharmony_ci27: ld.d t1, a1, 8 1168c2ecf20Sopenharmony_ci28: st.d t0, a0, 0 1178c2ecf20Sopenharmony_ci29: st.d t1, a0, 8 1188c2ecf20Sopenharmony_ci addi.d a1, a1, 16 1198c2ecf20Sopenharmony_ci addi.d a0, a0, 16 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci.Llt16: 1228c2ecf20Sopenharmony_ci addi.d a4, a3, -8 1238c2ecf20Sopenharmony_ci bgeu a1, a4, .Llt8 1248c2ecf20Sopenharmony_ci30: ld.d t0, a1, 0 1258c2ecf20Sopenharmony_ci31: st.d t0, a0, 0 1268c2ecf20Sopenharmony_ci addi.d a1, a1, 8 1278c2ecf20Sopenharmony_ci addi.d a0, a0, 8 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci.Llt8: 1308c2ecf20Sopenharmony_ci32: ld.d t0, a3, -8 1318c2ecf20Sopenharmony_ci33: st.d t0, a2, -8 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci /* return */ 1348c2ecf20Sopenharmony_ci move a0, zero 1358c2ecf20Sopenharmony_ci jr ra 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci .align 5 1388c2ecf20Sopenharmony_ci.Lsmall: 1398c2ecf20Sopenharmony_ci pcaddi t0, 8 1408c2ecf20Sopenharmony_ci slli.d a3, a2, 5 1418c2ecf20Sopenharmony_ci add.d t0, t0, a3 1428c2ecf20Sopenharmony_ci jr t0 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci .align 5 1458c2ecf20Sopenharmony_ci move a0, zero 1468c2ecf20Sopenharmony_ci jr ra 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci .align 5 1498c2ecf20Sopenharmony_ci34: ld.b t0, a1, 0 1508c2ecf20Sopenharmony_ci35: st.b t0, a0, 0 1518c2ecf20Sopenharmony_ci move a0, zero 1528c2ecf20Sopenharmony_ci jr ra 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci .align 5 1558c2ecf20Sopenharmony_ci36: ld.h t0, a1, 0 1568c2ecf20Sopenharmony_ci37: st.h t0, a0, 0 1578c2ecf20Sopenharmony_ci move a0, zero 1588c2ecf20Sopenharmony_ci jr ra 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci .align 5 1618c2ecf20Sopenharmony_ci38: ld.h t0, a1, 0 1628c2ecf20Sopenharmony_ci39: ld.b t1, a1, 2 1638c2ecf20Sopenharmony_ci40: st.h t0, a0, 0 1648c2ecf20Sopenharmony_ci41: st.b t1, a0, 2 1658c2ecf20Sopenharmony_ci move a0, zero 1668c2ecf20Sopenharmony_ci jr ra 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci .align 5 1698c2ecf20Sopenharmony_ci42: ld.w t0, a1, 0 1708c2ecf20Sopenharmony_ci43: st.w t0, a0, 0 1718c2ecf20Sopenharmony_ci move a0, zero 1728c2ecf20Sopenharmony_ci jr ra 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci .align 5 1758c2ecf20Sopenharmony_ci44: ld.w t0, a1, 0 1768c2ecf20Sopenharmony_ci45: ld.b t1, a1, 4 1778c2ecf20Sopenharmony_ci46: st.w t0, a0, 0 1788c2ecf20Sopenharmony_ci47: st.b t1, a0, 4 1798c2ecf20Sopenharmony_ci move a0, zero 1808c2ecf20Sopenharmony_ci jr ra 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci .align 5 1838c2ecf20Sopenharmony_ci48: ld.w t0, a1, 0 1848c2ecf20Sopenharmony_ci49: ld.h t1, a1, 4 1858c2ecf20Sopenharmony_ci50: st.w t0, a0, 0 1868c2ecf20Sopenharmony_ci51: st.h t1, a0, 4 1878c2ecf20Sopenharmony_ci move a0, zero 1888c2ecf20Sopenharmony_ci jr ra 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci .align 5 1918c2ecf20Sopenharmony_ci52: ld.w t0, a1, 0 1928c2ecf20Sopenharmony_ci53: ld.w t1, a1, 3 1938c2ecf20Sopenharmony_ci54: st.w t0, a0, 0 1948c2ecf20Sopenharmony_ci55: st.w t1, a0, 3 1958c2ecf20Sopenharmony_ci move a0, zero 1968c2ecf20Sopenharmony_ci jr ra 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci .align 5 1998c2ecf20Sopenharmony_ci56: ld.d t0, a1, 0 2008c2ecf20Sopenharmony_ci57: st.d t0, a0, 0 2018c2ecf20Sopenharmony_ci move a0, zero 2028c2ecf20Sopenharmony_ci jr ra 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci /* fixup and ex_table */ 2058c2ecf20Sopenharmony_ci.Llarge_fixup: 2068c2ecf20Sopenharmony_ci sub.d a2, a2, a0 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci.Lsmall_fixup: 2098c2ecf20Sopenharmony_ci58: ld.b t0, a1, 0 2108c2ecf20Sopenharmony_ci59: st.b t0, a0, 0 2118c2ecf20Sopenharmony_ci addi.d a0, a0, 1 2128c2ecf20Sopenharmony_ci addi.d a1, a1, 1 2138c2ecf20Sopenharmony_ci addi.d a2, a2, -1 2148c2ecf20Sopenharmony_ci bgt a2, zero, 58b 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci.Lexit: 2178c2ecf20Sopenharmony_ci move a0, a2 2188c2ecf20Sopenharmony_ci jr ra 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci _asm_extable 0b, .Lsmall_fixup 2218c2ecf20Sopenharmony_ci _asm_extable 1b, .Lsmall_fixup 2228c2ecf20Sopenharmony_ci _asm_extable 2b, .Llarge_fixup 2238c2ecf20Sopenharmony_ci _asm_extable 3b, .Llarge_fixup 2248c2ecf20Sopenharmony_ci _asm_extable 4b, .Llarge_fixup 2258c2ecf20Sopenharmony_ci _asm_extable 5b, .Llarge_fixup 2268c2ecf20Sopenharmony_ci _asm_extable 6b, .Llarge_fixup 2278c2ecf20Sopenharmony_ci _asm_extable 7b, .Llarge_fixup 2288c2ecf20Sopenharmony_ci _asm_extable 8b, .Llarge_fixup 2298c2ecf20Sopenharmony_ci _asm_extable 9b, .Llarge_fixup 2308c2ecf20Sopenharmony_ci _asm_extable 10b, .Llarge_fixup 2318c2ecf20Sopenharmony_ci _asm_extable 11b, .Llarge_fixup 2328c2ecf20Sopenharmony_ci _asm_extable 12b, .Llarge_fixup 2338c2ecf20Sopenharmony_ci _asm_extable 13b, .Llarge_fixup 2348c2ecf20Sopenharmony_ci _asm_extable 14b, .Llarge_fixup 2358c2ecf20Sopenharmony_ci _asm_extable 15b, .Llarge_fixup 2368c2ecf20Sopenharmony_ci _asm_extable 16b, .Llarge_fixup 2378c2ecf20Sopenharmony_ci _asm_extable 17b, .Llarge_fixup 2388c2ecf20Sopenharmony_ci _asm_extable 18b, .Llarge_fixup 2398c2ecf20Sopenharmony_ci _asm_extable 19b, .Llarge_fixup 2408c2ecf20Sopenharmony_ci _asm_extable 20b, .Llarge_fixup 2418c2ecf20Sopenharmony_ci _asm_extable 21b, .Llarge_fixup 2428c2ecf20Sopenharmony_ci _asm_extable 22b, .Llarge_fixup 2438c2ecf20Sopenharmony_ci _asm_extable 23b, .Llarge_fixup 2448c2ecf20Sopenharmony_ci _asm_extable 24b, .Llarge_fixup 2458c2ecf20Sopenharmony_ci _asm_extable 25b, .Llarge_fixup 2468c2ecf20Sopenharmony_ci _asm_extable 26b, .Llarge_fixup 2478c2ecf20Sopenharmony_ci _asm_extable 27b, .Llarge_fixup 2488c2ecf20Sopenharmony_ci _asm_extable 28b, .Llarge_fixup 2498c2ecf20Sopenharmony_ci _asm_extable 29b, .Llarge_fixup 2508c2ecf20Sopenharmony_ci _asm_extable 30b, .Llarge_fixup 2518c2ecf20Sopenharmony_ci _asm_extable 31b, .Llarge_fixup 2528c2ecf20Sopenharmony_ci _asm_extable 32b, .Llarge_fixup 2538c2ecf20Sopenharmony_ci _asm_extable 33b, .Llarge_fixup 2548c2ecf20Sopenharmony_ci _asm_extable 34b, .Lexit 2558c2ecf20Sopenharmony_ci _asm_extable 35b, .Lexit 2568c2ecf20Sopenharmony_ci _asm_extable 36b, .Lsmall_fixup 2578c2ecf20Sopenharmony_ci _asm_extable 37b, .Lsmall_fixup 2588c2ecf20Sopenharmony_ci _asm_extable 38b, .Lsmall_fixup 2598c2ecf20Sopenharmony_ci _asm_extable 39b, .Lsmall_fixup 2608c2ecf20Sopenharmony_ci _asm_extable 40b, .Lsmall_fixup 2618c2ecf20Sopenharmony_ci _asm_extable 41b, .Lsmall_fixup 2628c2ecf20Sopenharmony_ci _asm_extable 42b, .Lsmall_fixup 2638c2ecf20Sopenharmony_ci _asm_extable 43b, .Lsmall_fixup 2648c2ecf20Sopenharmony_ci _asm_extable 44b, .Lsmall_fixup 2658c2ecf20Sopenharmony_ci _asm_extable 45b, .Lsmall_fixup 2668c2ecf20Sopenharmony_ci _asm_extable 46b, .Lsmall_fixup 2678c2ecf20Sopenharmony_ci _asm_extable 47b, .Lsmall_fixup 2688c2ecf20Sopenharmony_ci _asm_extable 48b, .Lsmall_fixup 2698c2ecf20Sopenharmony_ci _asm_extable 49b, .Lsmall_fixup 2708c2ecf20Sopenharmony_ci _asm_extable 50b, .Lsmall_fixup 2718c2ecf20Sopenharmony_ci _asm_extable 51b, .Lsmall_fixup 2728c2ecf20Sopenharmony_ci _asm_extable 52b, .Lsmall_fixup 2738c2ecf20Sopenharmony_ci _asm_extable 53b, .Lsmall_fixup 2748c2ecf20Sopenharmony_ci _asm_extable 54b, .Lsmall_fixup 2758c2ecf20Sopenharmony_ci _asm_extable 55b, .Lsmall_fixup 2768c2ecf20Sopenharmony_ci _asm_extable 56b, .Lsmall_fixup 2778c2ecf20Sopenharmony_ci _asm_extable 57b, .Lsmall_fixup 2788c2ecf20Sopenharmony_ci _asm_extable 58b, .Lexit 2798c2ecf20Sopenharmony_ci _asm_extable 59b, .Lexit 2808c2ecf20Sopenharmony_ciSYM_FUNC_END(__copy_user_fast) 281