162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 362306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 462306a36Sopenharmony_ci * for more details. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 1996, 1998, 1999, 2004 by Ralf Baechle 762306a36Sopenharmony_ci * Copyright (c) 1999 Silicon Graphics, Inc. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#include <linux/export.h> 1062306a36Sopenharmony_ci#include <asm/asm.h> 1162306a36Sopenharmony_ci#include <asm/asm-offsets.h> 1262306a36Sopenharmony_ci#include <asm/regdef.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define EX(insn,reg,addr,handler) \ 1562306a36Sopenharmony_ci9: insn reg, addr; \ 1662306a36Sopenharmony_ci .section __ex_table,"a"; \ 1762306a36Sopenharmony_ci PTR_WD 9b, handler; \ 1862306a36Sopenharmony_ci .previous 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* 2162306a36Sopenharmony_ci * Return the size of a string including the ending NUL character up to a 2262306a36Sopenharmony_ci * maximum of a1 or 0 in case of error. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * Note: for performance reasons we deliberately accept that a user may 2562306a36Sopenharmony_ci * make strlen_user and strnlen_user access the first few KSEG0 2662306a36Sopenharmony_ci * bytes. There's nothing secret there. On 64-bit accessing beyond 2762306a36Sopenharmony_ci * the maximum is a tad hairier ... 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_ciLEAF(__strnlen_user_asm) 3062306a36Sopenharmony_ci move v0, a0 3162306a36Sopenharmony_ci PTR_ADDU a1, a0 # stop pointer 3262306a36Sopenharmony_ci1: 3362306a36Sopenharmony_ci#ifdef CONFIG_CPU_DADDI_WORKAROUNDS 3462306a36Sopenharmony_ci .set noat 3562306a36Sopenharmony_ci li AT, 1 3662306a36Sopenharmony_ci#endif 3762306a36Sopenharmony_ci beq v0, a1, 1f # limit reached? 3862306a36Sopenharmony_ci#ifdef CONFIG_EVA 3962306a36Sopenharmony_ci .set push 4062306a36Sopenharmony_ci .set eva 4162306a36Sopenharmony_ci EX(lbe, t0, (v0), .Lfault) 4262306a36Sopenharmony_ci .set pop 4362306a36Sopenharmony_ci#else 4462306a36Sopenharmony_ci EX(lb, t0, (v0), .Lfault) 4562306a36Sopenharmony_ci#endif 4662306a36Sopenharmony_ci .set noreorder 4762306a36Sopenharmony_ci bnez t0, 1b 4862306a36Sopenharmony_ci1: 4962306a36Sopenharmony_ci#ifndef CONFIG_CPU_DADDI_WORKAROUNDS 5062306a36Sopenharmony_ci PTR_ADDIU v0, 1 5162306a36Sopenharmony_ci#else 5262306a36Sopenharmony_ci PTR_ADDU v0, AT 5362306a36Sopenharmony_ci .set at 5462306a36Sopenharmony_ci#endif 5562306a36Sopenharmony_ci .set reorder 5662306a36Sopenharmony_ci PTR_SUBU v0, a0 5762306a36Sopenharmony_ci jr ra 5862306a36Sopenharmony_ci END(__strnlen_user_asm) 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci.Lfault: 6162306a36Sopenharmony_ci move v0, zero 6262306a36Sopenharmony_ci jr ra 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci EXPORT_SYMBOL(__strnlen_user_asm) 65