162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/export.h> 762306a36Sopenharmony_ci#include <asm/alternative-asm.h> 862306a36Sopenharmony_ci#include <asm/asm.h> 962306a36Sopenharmony_ci#include <asm/asmmacro.h> 1062306a36Sopenharmony_ci#include <asm/asm-extable.h> 1162306a36Sopenharmony_ci#include <asm/cpu.h> 1262306a36Sopenharmony_ci#include <asm/regdef.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciSYM_FUNC_START(__clear_user) 1562306a36Sopenharmony_ci /* 1662306a36Sopenharmony_ci * Some CPUs support hardware unaligned access 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci ALTERNATIVE "b __clear_user_generic", \ 1962306a36Sopenharmony_ci "b __clear_user_fast", CPU_FEATURE_UAL 2062306a36Sopenharmony_ciSYM_FUNC_END(__clear_user) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ciEXPORT_SYMBOL(__clear_user) 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/* 2562306a36Sopenharmony_ci * unsigned long __clear_user_generic(void *addr, size_t size) 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * a0: addr 2862306a36Sopenharmony_ci * a1: size 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_ciSYM_FUNC_START(__clear_user_generic) 3162306a36Sopenharmony_ci beqz a1, 2f 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci1: st.b zero, a0, 0 3462306a36Sopenharmony_ci addi.d a0, a0, 1 3562306a36Sopenharmony_ci addi.d a1, a1, -1 3662306a36Sopenharmony_ci bgtz a1, 1b 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci2: move a0, a1 3962306a36Sopenharmony_ci jr ra 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci _asm_extable 1b, 2b 4262306a36Sopenharmony_ciSYM_FUNC_END(__clear_user_generic) 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* 4562306a36Sopenharmony_ci * unsigned long __clear_user_fast(void *addr, unsigned long size) 4662306a36Sopenharmony_ci * 4762306a36Sopenharmony_ci * a0: addr 4862306a36Sopenharmony_ci * a1: size 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ciSYM_FUNC_START(__clear_user_fast) 5162306a36Sopenharmony_ci sltui t0, a1, 9 5262306a36Sopenharmony_ci bnez t0, .Lsmall 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci add.d a2, a0, a1 5562306a36Sopenharmony_ci0: st.d zero, a0, 0 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci /* align up address */ 5862306a36Sopenharmony_ci addi.d a0, a0, 8 5962306a36Sopenharmony_ci bstrins.d a0, zero, 2, 0 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci addi.d a3, a2, -64 6262306a36Sopenharmony_ci bgeu a0, a3, .Llt64 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci /* set 64 bytes at a time */ 6562306a36Sopenharmony_ci.Lloop64: 6662306a36Sopenharmony_ci1: st.d zero, a0, 0 6762306a36Sopenharmony_ci2: st.d zero, a0, 8 6862306a36Sopenharmony_ci3: st.d zero, a0, 16 6962306a36Sopenharmony_ci4: st.d zero, a0, 24 7062306a36Sopenharmony_ci5: st.d zero, a0, 32 7162306a36Sopenharmony_ci6: st.d zero, a0, 40 7262306a36Sopenharmony_ci7: st.d zero, a0, 48 7362306a36Sopenharmony_ci8: st.d zero, a0, 56 7462306a36Sopenharmony_ci addi.d a0, a0, 64 7562306a36Sopenharmony_ci bltu a0, a3, .Lloop64 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci /* set the remaining bytes */ 7862306a36Sopenharmony_ci.Llt64: 7962306a36Sopenharmony_ci addi.d a3, a2, -32 8062306a36Sopenharmony_ci bgeu a0, a3, .Llt32 8162306a36Sopenharmony_ci9: st.d zero, a0, 0 8262306a36Sopenharmony_ci10: st.d zero, a0, 8 8362306a36Sopenharmony_ci11: st.d zero, a0, 16 8462306a36Sopenharmony_ci12: st.d zero, a0, 24 8562306a36Sopenharmony_ci addi.d a0, a0, 32 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci.Llt32: 8862306a36Sopenharmony_ci addi.d a3, a2, -16 8962306a36Sopenharmony_ci bgeu a0, a3, .Llt16 9062306a36Sopenharmony_ci13: st.d zero, a0, 0 9162306a36Sopenharmony_ci14: st.d zero, a0, 8 9262306a36Sopenharmony_ci addi.d a0, a0, 16 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci.Llt16: 9562306a36Sopenharmony_ci addi.d a3, a2, -8 9662306a36Sopenharmony_ci bgeu a0, a3, .Llt8 9762306a36Sopenharmony_ci15: st.d zero, a0, 0 9862306a36Sopenharmony_ci addi.d a0, a0, 8 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci.Llt8: 10162306a36Sopenharmony_ci16: st.d zero, a2, -8 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci /* return */ 10462306a36Sopenharmony_ci move a0, zero 10562306a36Sopenharmony_ci jr ra 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci .align 4 10862306a36Sopenharmony_ci.Lsmall: 10962306a36Sopenharmony_ci pcaddi t0, 4 11062306a36Sopenharmony_ci slli.d a2, a1, 4 11162306a36Sopenharmony_ci add.d t0, t0, a2 11262306a36Sopenharmony_ci jr t0 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci .align 4 11562306a36Sopenharmony_ci move a0, zero 11662306a36Sopenharmony_ci jr ra 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci .align 4 11962306a36Sopenharmony_ci17: st.b zero, a0, 0 12062306a36Sopenharmony_ci move a0, zero 12162306a36Sopenharmony_ci jr ra 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci .align 4 12462306a36Sopenharmony_ci18: st.h zero, a0, 0 12562306a36Sopenharmony_ci move a0, zero 12662306a36Sopenharmony_ci jr ra 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci .align 4 12962306a36Sopenharmony_ci19: st.h zero, a0, 0 13062306a36Sopenharmony_ci20: st.b zero, a0, 2 13162306a36Sopenharmony_ci move a0, zero 13262306a36Sopenharmony_ci jr ra 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci .align 4 13562306a36Sopenharmony_ci21: st.w zero, a0, 0 13662306a36Sopenharmony_ci move a0, zero 13762306a36Sopenharmony_ci jr ra 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci .align 4 14062306a36Sopenharmony_ci22: st.w zero, a0, 0 14162306a36Sopenharmony_ci23: st.b zero, a0, 4 14262306a36Sopenharmony_ci move a0, zero 14362306a36Sopenharmony_ci jr ra 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci .align 4 14662306a36Sopenharmony_ci24: st.w zero, a0, 0 14762306a36Sopenharmony_ci25: st.h zero, a0, 4 14862306a36Sopenharmony_ci move a0, zero 14962306a36Sopenharmony_ci jr ra 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci .align 4 15262306a36Sopenharmony_ci26: st.w zero, a0, 0 15362306a36Sopenharmony_ci27: st.w zero, a0, 3 15462306a36Sopenharmony_ci move a0, zero 15562306a36Sopenharmony_ci jr ra 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci .align 4 15862306a36Sopenharmony_ci28: st.d zero, a0, 0 15962306a36Sopenharmony_ci move a0, zero 16062306a36Sopenharmony_ci jr ra 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci /* fixup and ex_table */ 16362306a36Sopenharmony_ci.Llarge_fixup: 16462306a36Sopenharmony_ci sub.d a1, a2, a0 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci.Lsmall_fixup: 16762306a36Sopenharmony_ci29: st.b zero, a0, 0 16862306a36Sopenharmony_ci addi.d a0, a0, 1 16962306a36Sopenharmony_ci addi.d a1, a1, -1 17062306a36Sopenharmony_ci bgt a1, zero, 29b 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci.Lexit: 17362306a36Sopenharmony_ci move a0, a1 17462306a36Sopenharmony_ci jr ra 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci _asm_extable 0b, .Lsmall_fixup 17762306a36Sopenharmony_ci _asm_extable 1b, .Llarge_fixup 17862306a36Sopenharmony_ci _asm_extable 2b, .Llarge_fixup 17962306a36Sopenharmony_ci _asm_extable 3b, .Llarge_fixup 18062306a36Sopenharmony_ci _asm_extable 4b, .Llarge_fixup 18162306a36Sopenharmony_ci _asm_extable 5b, .Llarge_fixup 18262306a36Sopenharmony_ci _asm_extable 6b, .Llarge_fixup 18362306a36Sopenharmony_ci _asm_extable 7b, .Llarge_fixup 18462306a36Sopenharmony_ci _asm_extable 8b, .Llarge_fixup 18562306a36Sopenharmony_ci _asm_extable 9b, .Llarge_fixup 18662306a36Sopenharmony_ci _asm_extable 10b, .Llarge_fixup 18762306a36Sopenharmony_ci _asm_extable 11b, .Llarge_fixup 18862306a36Sopenharmony_ci _asm_extable 12b, .Llarge_fixup 18962306a36Sopenharmony_ci _asm_extable 13b, .Llarge_fixup 19062306a36Sopenharmony_ci _asm_extable 14b, .Llarge_fixup 19162306a36Sopenharmony_ci _asm_extable 15b, .Llarge_fixup 19262306a36Sopenharmony_ci _asm_extable 16b, .Llarge_fixup 19362306a36Sopenharmony_ci _asm_extable 17b, .Lexit 19462306a36Sopenharmony_ci _asm_extable 18b, .Lsmall_fixup 19562306a36Sopenharmony_ci _asm_extable 19b, .Lsmall_fixup 19662306a36Sopenharmony_ci _asm_extable 20b, .Lsmall_fixup 19762306a36Sopenharmony_ci _asm_extable 21b, .Lsmall_fixup 19862306a36Sopenharmony_ci _asm_extable 22b, .Lsmall_fixup 19962306a36Sopenharmony_ci _asm_extable 23b, .Lsmall_fixup 20062306a36Sopenharmony_ci _asm_extable 24b, .Lsmall_fixup 20162306a36Sopenharmony_ci _asm_extable 25b, .Lsmall_fixup 20262306a36Sopenharmony_ci _asm_extable 26b, .Lsmall_fixup 20362306a36Sopenharmony_ci _asm_extable 27b, .Lsmall_fixup 20462306a36Sopenharmony_ci _asm_extable 28b, .Lsmall_fixup 20562306a36Sopenharmony_ci _asm_extable 29b, .Lexit 20662306a36Sopenharmony_ciSYM_FUNC_END(__clear_user_fast) 207