1559671e0SHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */ 2559671e0SHuacai Chen/* 3559671e0SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4559671e0SHuacai Chen */ 5559671e0SHuacai Chen 6*a275a82dSHuacai Chen#include <asm/alternative-asm.h> 7559671e0SHuacai Chen#include <asm/asm.h> 8559671e0SHuacai Chen#include <asm/asmmacro.h> 9508f28c6SYouling Tang#include <asm/asm-extable.h> 10*a275a82dSHuacai Chen#include <asm/cpu.h> 11559671e0SHuacai Chen#include <asm/export.h> 12559671e0SHuacai Chen#include <asm/regdef.h> 13559671e0SHuacai Chen 14*a275a82dSHuacai Chen.irp to, 0, 1, 2, 3, 4, 5, 6, 7 15912bcfafSYouling Tang.L_fixup_handle_\to\(): 16912bcfafSYouling Tang addi.d a0, a1, (\to) * (-8) 17559671e0SHuacai Chen jr ra 18912bcfafSYouling Tang.endr 19559671e0SHuacai Chen 20*a275a82dSHuacai ChenSYM_FUNC_START(__clear_user) 21559671e0SHuacai Chen /* 22*a275a82dSHuacai Chen * Some CPUs support hardware unaligned access 23*a275a82dSHuacai Chen */ 24*a275a82dSHuacai Chen ALTERNATIVE "b __clear_user_generic", \ 25*a275a82dSHuacai Chen "b __clear_user_fast", CPU_FEATURE_UAL 26*a275a82dSHuacai ChenSYM_FUNC_END(__clear_user) 27*a275a82dSHuacai Chen 28*a275a82dSHuacai ChenEXPORT_SYMBOL(__clear_user) 29*a275a82dSHuacai Chen 30*a275a82dSHuacai Chen/* 31*a275a82dSHuacai Chen * unsigned long __clear_user_generic(void *addr, size_t size) 32559671e0SHuacai Chen * 33559671e0SHuacai Chen * a0: addr 34559671e0SHuacai Chen * a1: size 35559671e0SHuacai Chen */ 36*a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_generic) 37559671e0SHuacai Chen beqz a1, 2f 38559671e0SHuacai Chen 39559671e0SHuacai Chen1: st.b zero, a0, 0 40559671e0SHuacai Chen addi.d a0, a0, 1 41559671e0SHuacai Chen addi.d a1, a1, -1 421fdb9a92SWANG Xuerui bgtz a1, 1b 43559671e0SHuacai Chen 44559671e0SHuacai Chen2: move a0, a1 45559671e0SHuacai Chen jr ra 46559671e0SHuacai Chen 47912bcfafSYouling Tang _asm_extable 1b, .L_fixup_handle_0 48*a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_generic) 49559671e0SHuacai Chen 50*a275a82dSHuacai Chen/* 51*a275a82dSHuacai Chen * unsigned long __clear_user_fast(void *addr, unsigned long size) 52*a275a82dSHuacai Chen * 53*a275a82dSHuacai Chen * a0: addr 54*a275a82dSHuacai Chen * a1: size 55*a275a82dSHuacai Chen */ 56*a275a82dSHuacai ChenSYM_FUNC_START(__clear_user_fast) 57*a275a82dSHuacai Chen beqz a1, 10f 58*a275a82dSHuacai Chen 59*a275a82dSHuacai Chen ori a2, zero, 64 60*a275a82dSHuacai Chen blt a1, a2, 9f 61*a275a82dSHuacai Chen 62*a275a82dSHuacai Chen /* set 64 bytes at a time */ 63*a275a82dSHuacai Chen1: st.d zero, a0, 0 64*a275a82dSHuacai Chen2: st.d zero, a0, 8 65*a275a82dSHuacai Chen3: st.d zero, a0, 16 66*a275a82dSHuacai Chen4: st.d zero, a0, 24 67*a275a82dSHuacai Chen5: st.d zero, a0, 32 68*a275a82dSHuacai Chen6: st.d zero, a0, 40 69*a275a82dSHuacai Chen7: st.d zero, a0, 48 70*a275a82dSHuacai Chen8: st.d zero, a0, 56 71*a275a82dSHuacai Chen 72*a275a82dSHuacai Chen addi.d a0, a0, 64 73*a275a82dSHuacai Chen addi.d a1, a1, -64 74*a275a82dSHuacai Chen bge a1, a2, 1b 75*a275a82dSHuacai Chen 76*a275a82dSHuacai Chen beqz a1, 10f 77*a275a82dSHuacai Chen 78*a275a82dSHuacai Chen /* set the remaining bytes */ 79*a275a82dSHuacai Chen9: st.b zero, a0, 0 80*a275a82dSHuacai Chen addi.d a0, a0, 1 81*a275a82dSHuacai Chen addi.d a1, a1, -1 82*a275a82dSHuacai Chen bgt a1, zero, 9b 83*a275a82dSHuacai Chen 84*a275a82dSHuacai Chen /* return */ 85*a275a82dSHuacai Chen10: move a0, a1 86*a275a82dSHuacai Chen jr ra 87*a275a82dSHuacai Chen 88*a275a82dSHuacai Chen /* fixup and ex_table */ 89*a275a82dSHuacai Chen _asm_extable 1b, .L_fixup_handle_0 90*a275a82dSHuacai Chen _asm_extable 2b, .L_fixup_handle_1 91*a275a82dSHuacai Chen _asm_extable 3b, .L_fixup_handle_2 92*a275a82dSHuacai Chen _asm_extable 4b, .L_fixup_handle_3 93*a275a82dSHuacai Chen _asm_extable 5b, .L_fixup_handle_4 94*a275a82dSHuacai Chen _asm_extable 6b, .L_fixup_handle_5 95*a275a82dSHuacai Chen _asm_extable 7b, .L_fixup_handle_6 96*a275a82dSHuacai Chen _asm_extable 8b, .L_fixup_handle_7 97*a275a82dSHuacai Chen _asm_extable 9b, .L_fixup_handle_0 98*a275a82dSHuacai ChenSYM_FUNC_END(__clear_user_fast) 99