1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (c) 1996, 1998, 1999, 2004 by Ralf Baechle 7 * Copyright (c) 1999 Silicon Graphics, Inc. 8 */ 9#include <asm/asm.h> 10#include <asm/asm-offsets.h> 11#include <asm/export.h> 12#include <asm/regdef.h> 13 14#define EX(insn,reg,addr,handler) \ 159: insn reg, addr; \ 16 .section __ex_table,"a"; \ 17 PTR 9b, handler; \ 18 .previous 19 20/* 21 * Return the size of a string including the ending NUL character up to a 22 * maximum of a1 or 0 in case of error. 23 * 24 * Note: for performance reasons we deliberately accept that a user may 25 * make strlen_user and strnlen_user access the first few KSEG0 26 * bytes. There's nothing secret there. On 64-bit accessing beyond 27 * the maximum is a tad hairier ... 28 */ 29 .macro __BUILD_STRNLEN_ASM func 30LEAF(__strnlen_\func\()_asm) 31 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok? 32 and v0, a0 33 bnez v0, .Lfault\@ 34 35FEXPORT(__strnlen_\func\()_nocheck_asm) 36 move v0, a0 37 PTR_ADDU a1, a0 # stop pointer 381: 39#ifdef CONFIG_CPU_DADDI_WORKAROUNDS 40 .set noat 41 li AT, 1 42#endif 43 beq v0, a1, 1f # limit reached? 44.ifeqs "\func", "kernel" 45 EX(lb, t0, (v0), .Lfault\@) 46.else 47 EX(lbe, t0, (v0), .Lfault\@) 48.endif 49 .set noreorder 50 bnez t0, 1b 511: 52#ifndef CONFIG_CPU_DADDI_WORKAROUNDS 53 PTR_ADDIU v0, 1 54#else 55 PTR_ADDU v0, AT 56 .set at 57#endif 58 .set reorder 59 PTR_SUBU v0, a0 60 jr ra 61 END(__strnlen_\func\()_asm) 62 63.Lfault\@: 64 move v0, zero 65 jr ra 66 .endm 67 68#ifndef CONFIG_EVA 69 /* Set aliases */ 70 .global __strnlen_user_asm 71 .global __strnlen_user_nocheck_asm 72 .set __strnlen_user_asm, __strnlen_kernel_asm 73 .set __strnlen_user_nocheck_asm, __strnlen_kernel_nocheck_asm 74EXPORT_SYMBOL(__strnlen_user_asm) 75EXPORT_SYMBOL(__strnlen_user_nocheck_asm) 76#endif 77 78__BUILD_STRNLEN_ASM kernel 79EXPORT_SYMBOL(__strnlen_kernel_asm) 80EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm) 81 82#ifdef CONFIG_EVA 83 84 .set push 85 .set eva 86__BUILD_STRNLEN_ASM user 87 .set pop 88EXPORT_SYMBOL(__strnlen_user_asm) 89EXPORT_SYMBOL(__strnlen_user_nocheck_asm) 90#endif 91