1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 6#include <asm/alternative-asm.h> 7#include <asm/asm.h> 8#include <asm/asmmacro.h> 9#include <asm/asm-extable.h> 10#include <asm/cpu.h> 11#include <asm/export.h> 12#include <asm/regdef.h> 13 14.irp to, 0, 1, 2, 3, 4, 5, 6, 7 15.L_fixup_handle_\to\(): 16 addi.d a0, a2, (\to) * (-8) 17 jr ra 18.endr 19 20SYM_FUNC_START(__copy_user) 21 /* 22 * Some CPUs support hardware unaligned access 23 */ 24 ALTERNATIVE "b __copy_user_generic", \ 25 "b __copy_user_fast", CPU_FEATURE_UAL 26SYM_FUNC_END(__copy_user) 27 28EXPORT_SYMBOL(__copy_user) 29 30/* 31 * unsigned long __copy_user_generic(void *to, const void *from, size_t n) 32 * 33 * a0: to 34 * a1: from 35 * a2: n 36 */ 37SYM_FUNC_START(__copy_user_generic) 38 beqz a2, 3f 39 401: ld.b t0, a1, 0 412: st.b t0, a0, 0 42 addi.d a0, a0, 1 43 addi.d a1, a1, 1 44 addi.d a2, a2, -1 45 bgtz a2, 1b 46 473: move a0, a2 48 jr ra 49 50 _asm_extable 1b, .L_fixup_handle_0 51 _asm_extable 2b, .L_fixup_handle_0 52SYM_FUNC_END(__copy_user_generic) 53 54/* 55 * unsigned long __copy_user_fast(void *to, const void *from, unsigned long n) 56 * 57 * a0: to 58 * a1: from 59 * a2: n 60 */ 61SYM_FUNC_START(__copy_user_fast) 62 beqz a2, 19f 63 64 ori a3, zero, 64 65 blt a2, a3, 17f 66 67 /* copy 64 bytes at a time */ 681: ld.d t0, a1, 0 692: ld.d t1, a1, 8 703: ld.d t2, a1, 16 714: ld.d t3, a1, 24 725: ld.d t4, a1, 32 736: ld.d t5, a1, 40 747: ld.d t6, a1, 48 758: ld.d t7, a1, 56 769: st.d t0, a0, 0 7710: st.d t1, a0, 8 7811: st.d t2, a0, 16 7912: st.d t3, a0, 24 8013: st.d t4, a0, 32 8114: st.d t5, a0, 40 8215: st.d t6, a0, 48 8316: st.d t7, a0, 56 84 85 addi.d a0, a0, 64 86 addi.d a1, a1, 64 87 addi.d a2, a2, -64 88 bge a2, a3, 1b 89 90 beqz a2, 19f 91 92 /* copy the remaining bytes */ 9317: ld.b t0, a1, 0 9418: st.b t0, a0, 0 95 addi.d a0, a0, 1 96 addi.d a1, a1, 1 97 addi.d a2, a2, -1 98 bgt a2, zero, 17b 99 100 /* return */ 10119: move a0, a2 102 jr ra 103 104 /* fixup and ex_table */ 105 _asm_extable 1b, .L_fixup_handle_0 106 _asm_extable 2b, .L_fixup_handle_1 107 _asm_extable 3b, .L_fixup_handle_2 108 _asm_extable 4b, .L_fixup_handle_3 109 _asm_extable 5b, .L_fixup_handle_4 110 _asm_extable 6b, .L_fixup_handle_5 111 _asm_extable 7b, .L_fixup_handle_6 112 _asm_extable 8b, .L_fixup_handle_7 113 _asm_extable 9b, .L_fixup_handle_0 114 _asm_extable 10b, .L_fixup_handle_1 115 _asm_extable 11b, .L_fixup_handle_2 116 _asm_extable 12b, .L_fixup_handle_3 117 _asm_extable 13b, .L_fixup_handle_4 118 _asm_extable 14b, .L_fixup_handle_5 119 _asm_extable 15b, .L_fixup_handle_6 120 _asm_extable 16b, .L_fixup_handle_7 121 _asm_extable 17b, .L_fixup_handle_0 122 _asm_extable 18b, .L_fixup_handle_0 123SYM_FUNC_END(__copy_user_fast) 124