1a583158cSAtsushi Nemoto/* 2a583158cSAtsushi Nemoto * This file is subject to the terms and conditions of the GNU General Public 3a583158cSAtsushi Nemoto * License. See the file "COPYING" in the main directory of this archive 4a583158cSAtsushi Nemoto * for more details. 5a583158cSAtsushi Nemoto * 6a583158cSAtsushi Nemoto * Copyright (C) 1998, 1999, 2000 by Ralf Baechle 7a583158cSAtsushi Nemoto * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 826c5e07dSSteven J. Hill * Copyright (C) 2007 by Maciej W. Rozycki 926c5e07dSSteven J. Hill * Copyright (C) 2011, 2012 MIPS Technologies, Inc. 10a583158cSAtsushi Nemoto */ 11a583158cSAtsushi Nemoto#include <asm/asm.h> 12a583158cSAtsushi Nemoto#include <asm/asm-offsets.h> 13576a2f0cSPaul Burton#include <asm/export.h> 14a583158cSAtsushi Nemoto#include <asm/regdef.h> 15a583158cSAtsushi Nemoto 16a583158cSAtsushi Nemoto#if LONGSIZE == 4 17a583158cSAtsushi Nemoto#define LONG_S_L swl 18a583158cSAtsushi Nemoto#define LONG_S_R swr 19a583158cSAtsushi Nemoto#else 20a583158cSAtsushi Nemoto#define LONG_S_L sdl 21a583158cSAtsushi Nemoto#define LONG_S_R sdr 22a583158cSAtsushi Nemoto#endif 23a583158cSAtsushi Nemoto 2426c5e07dSSteven J. Hill#ifdef CONFIG_CPU_MICROMIPS 2526c5e07dSSteven J. Hill#define STORSIZE (LONGSIZE * 2) 2626c5e07dSSteven J. Hill#define STORMASK (STORSIZE - 1) 2726c5e07dSSteven J. Hill#define FILL64RG t8 2826c5e07dSSteven J. Hill#define FILLPTRG t7 2926c5e07dSSteven J. Hill#undef LONG_S 3026c5e07dSSteven J. Hill#define LONG_S LONG_SP 3126c5e07dSSteven J. Hill#else 3226c5e07dSSteven J. Hill#define STORSIZE LONGSIZE 3326c5e07dSSteven J. Hill#define STORMASK LONGMASK 3426c5e07dSSteven J. Hill#define FILL64RG a1 3526c5e07dSSteven J. Hill#define FILLPTRG t0 3626c5e07dSSteven J. Hill#endif 3726c5e07dSSteven J. Hill 386d5155c2SMarkos Chandras#define LEGACY_MODE 1 396d5155c2SMarkos Chandras#define EVA_MODE 2 406d5155c2SMarkos Chandras 41fd9720e9SMarkos Chandras/* 42fd9720e9SMarkos Chandras * No need to protect it with EVA #ifdefery. The generated block of code 43fd9720e9SMarkos Chandras * will never be assembled if EVA is not enabled. 44fd9720e9SMarkos Chandras */ 45fd9720e9SMarkos Chandras#define __EVAFY(insn, reg, addr) __BUILD_EVA_INSN(insn##e, reg, addr) 46fd9720e9SMarkos Chandras#define ___BUILD_EVA_INSN(insn, reg, addr) __EVAFY(insn, reg, addr) 47fd9720e9SMarkos Chandras 48a583158cSAtsushi Nemoto#define EX(insn,reg,addr,handler) \ 49fd9720e9SMarkos Chandras .if \mode == LEGACY_MODE; \ 50a583158cSAtsushi Nemoto9: insn reg, addr; \ 51fd9720e9SMarkos Chandras .else; \ 52fd9720e9SMarkos Chandras9: ___BUILD_EVA_INSN(insn, reg, addr); \ 53fd9720e9SMarkos Chandras .endif; \ 54a583158cSAtsushi Nemoto .section __ex_table,"a"; \ 55a583158cSAtsushi Nemoto PTR 9b, handler; \ 56a583158cSAtsushi Nemoto .previous 57a583158cSAtsushi Nemoto 58fd9720e9SMarkos Chandras .macro f_fill64 dst, offset, val, fixup, mode 5926c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 0 * STORSIZE)(\dst), \fixup) 6026c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 1 * STORSIZE)(\dst), \fixup) 6126c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 2 * STORSIZE)(\dst), \fixup) 6226c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 3 * STORSIZE)(\dst), \fixup) 6326c5e07dSSteven J. Hill#if ((defined(CONFIG_CPU_MICROMIPS) && (LONGSIZE == 4)) || !defined(CONFIG_CPU_MICROMIPS)) 6426c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 4 * STORSIZE)(\dst), \fixup) 6526c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 5 * STORSIZE)(\dst), \fixup) 6626c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 6 * STORSIZE)(\dst), \fixup) 6726c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 7 * STORSIZE)(\dst), \fixup) 6826c5e07dSSteven J. Hill#endif 6926c5e07dSSteven J. Hill#if (!defined(CONFIG_CPU_MICROMIPS) && (LONGSIZE == 4)) 7026c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 8 * STORSIZE)(\dst), \fixup) 7126c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 9 * STORSIZE)(\dst), \fixup) 7226c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 10 * STORSIZE)(\dst), \fixup) 7326c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 11 * STORSIZE)(\dst), \fixup) 7426c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 12 * STORSIZE)(\dst), \fixup) 7526c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 13 * STORSIZE)(\dst), \fixup) 7626c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 14 * STORSIZE)(\dst), \fixup) 7726c5e07dSSteven J. Hill EX(LONG_S, \val, (\offset + 15 * STORSIZE)(\dst), \fixup) 78a583158cSAtsushi Nemoto#endif 79a583158cSAtsushi Nemoto .endm 80a583158cSAtsushi Nemoto 81a583158cSAtsushi Nemoto .set noreorder 82a583158cSAtsushi Nemoto .align 5 83a583158cSAtsushi Nemoto 846d5155c2SMarkos Chandras /* 856d5155c2SMarkos Chandras * Macro to generate the __bzero{,_user} symbol 866d5155c2SMarkos Chandras * Arguments: 876d5155c2SMarkos Chandras * mode: LEGACY_MODE or EVA_MODE 886d5155c2SMarkos Chandras */ 896d5155c2SMarkos Chandras .macro __BUILD_BZERO mode 906d5155c2SMarkos Chandras /* Initialize __memset if this is the first time we call this macro */ 916d5155c2SMarkos Chandras .ifnotdef __memset 926d5155c2SMarkos Chandras .set __memset, 1 936d5155c2SMarkos Chandras .hidden __memset /* Make sure it does not leak */ 946d5155c2SMarkos Chandras .endif 95a583158cSAtsushi Nemoto 9626c5e07dSSteven J. Hill sltiu t0, a2, STORSIZE /* very small region? */ 976d5155c2SMarkos Chandras bnez t0, .Lsmall_memset\@ 9826c5e07dSSteven J. Hill andi t0, a0, STORMASK /* aligned? */ 99a583158cSAtsushi Nemoto 10026c5e07dSSteven J. Hill#ifdef CONFIG_CPU_MICROMIPS 10126c5e07dSSteven J. Hill move t8, a1 /* used by 'swp' instruction */ 10226c5e07dSSteven J. Hill move t9, a1 10326c5e07dSSteven J. Hill#endif 104619b6e18SMaciej W. Rozycki#ifndef CONFIG_CPU_DADDI_WORKAROUNDS 105a583158cSAtsushi Nemoto beqz t0, 1f 10626c5e07dSSteven J. Hill PTR_SUBU t0, STORSIZE /* alignment in bytes */ 107619b6e18SMaciej W. Rozycki#else 108619b6e18SMaciej W. Rozycki .set noat 10926c5e07dSSteven J. Hill li AT, STORSIZE 110619b6e18SMaciej W. Rozycki beqz t0, 1f 111619b6e18SMaciej W. Rozycki PTR_SUBU t0, AT /* alignment in bytes */ 112619b6e18SMaciej W. Rozycki .set at 113619b6e18SMaciej W. Rozycki#endif 114a583158cSAtsushi Nemoto 1158c56208aSLeonid Yegoshin#ifndef CONFIG_CPU_MIPSR6 116930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 117a583158cSAtsushi Nemoto#ifdef __MIPSEB__ 1186d5155c2SMarkos Chandras EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ 119dd2adea4SMarkos Chandras#else 1206d5155c2SMarkos Chandras EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ 121a583158cSAtsushi Nemoto#endif 122a583158cSAtsushi Nemoto PTR_SUBU a0, t0 /* long align ptr */ 123a583158cSAtsushi Nemoto PTR_ADDU a2, t0 /* correct size */ 124a583158cSAtsushi Nemoto 1258c56208aSLeonid Yegoshin#else /* CONFIG_CPU_MIPSR6 */ 1268c56208aSLeonid Yegoshin#define STORE_BYTE(N) \ 1278c56208aSLeonid Yegoshin EX(sb, a1, N(a0), .Lbyte_fixup\@); \ 1288c56208aSLeonid Yegoshin beqz t0, 0f; \ 1298c56208aSLeonid Yegoshin PTR_ADDU t0, 1; 1308c56208aSLeonid Yegoshin 1318c56208aSLeonid Yegoshin PTR_ADDU a2, t0 /* correct size */ 1328c56208aSLeonid Yegoshin PTR_ADDU t0, 1 1338c56208aSLeonid Yegoshin STORE_BYTE(0) 1348c56208aSLeonid Yegoshin STORE_BYTE(1) 1358c56208aSLeonid Yegoshin#if LONGSIZE == 4 1368c56208aSLeonid Yegoshin EX(sb, a1, 2(a0), .Lbyte_fixup\@) 1378c56208aSLeonid Yegoshin#else 1388c56208aSLeonid Yegoshin STORE_BYTE(2) 1398c56208aSLeonid Yegoshin STORE_BYTE(3) 1408c56208aSLeonid Yegoshin STORE_BYTE(4) 1418c56208aSLeonid Yegoshin STORE_BYTE(5) 1428c56208aSLeonid Yegoshin EX(sb, a1, 6(a0), .Lbyte_fixup\@) 1438c56208aSLeonid Yegoshin#endif 1448c56208aSLeonid Yegoshin0: 1458c56208aSLeonid Yegoshin ori a0, STORMASK 1468c56208aSLeonid Yegoshin xori a0, STORMASK 1478c56208aSLeonid Yegoshin PTR_ADDIU a0, STORSIZE 1488c56208aSLeonid Yegoshin#endif /* CONFIG_CPU_MIPSR6 */ 149a583158cSAtsushi Nemoto1: ori t1, a2, 0x3f /* # of full blocks */ 150a583158cSAtsushi Nemoto xori t1, 0x3f 1516d5155c2SMarkos Chandras beqz t1, .Lmemset_partial\@ /* no block to fill */ 15226c5e07dSSteven J. Hill andi t0, a2, 0x40-STORSIZE 153a583158cSAtsushi Nemoto 154a583158cSAtsushi Nemoto PTR_ADDU t1, a0 /* end address */ 155a583158cSAtsushi Nemoto .set reorder 156a583158cSAtsushi Nemoto1: PTR_ADDIU a0, 64 157930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 158fd9720e9SMarkos Chandras f_fill64 a0, -64, FILL64RG, .Lfwd_fixup\@, \mode 159a583158cSAtsushi Nemoto bne t1, a0, 1b 160a583158cSAtsushi Nemoto .set noreorder 161a583158cSAtsushi Nemoto 1626d5155c2SMarkos Chandras.Lmemset_partial\@: 163930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 164a583158cSAtsushi Nemoto PTR_LA t1, 2f /* where to start */ 16526c5e07dSSteven J. Hill#ifdef CONFIG_CPU_MICROMIPS 16626c5e07dSSteven J. Hill LONG_SRL t7, t0, 1 16726c5e07dSSteven J. Hill#endif 168a583158cSAtsushi Nemoto#if LONGSIZE == 4 16926c5e07dSSteven J. Hill PTR_SUBU t1, FILLPTRG 170a583158cSAtsushi Nemoto#else 171a583158cSAtsushi Nemoto .set noat 17226c5e07dSSteven J. Hill LONG_SRL AT, FILLPTRG, 1 173a583158cSAtsushi Nemoto PTR_SUBU t1, AT 174619b6e18SMaciej W. Rozycki .set at 175a583158cSAtsushi Nemoto#endif 176a583158cSAtsushi Nemoto jr t1 177a583158cSAtsushi Nemoto PTR_ADDU a0, t0 /* dest ptr */ 178a583158cSAtsushi Nemoto 179a583158cSAtsushi Nemoto .set push 180a583158cSAtsushi Nemoto .set noreorder 181a583158cSAtsushi Nemoto .set nomacro 1826d5155c2SMarkos Chandras /* ... but first do longs ... */ 183fd9720e9SMarkos Chandras f_fill64 a0, -64, FILL64RG, .Lpartial_fixup\@, \mode 184a583158cSAtsushi Nemoto2: .set pop 18526c5e07dSSteven J. Hill andi a2, STORMASK /* At most one long to go */ 186a583158cSAtsushi Nemoto 187a583158cSAtsushi Nemoto beqz a2, 1f 1888c56208aSLeonid Yegoshin#ifndef CONFIG_CPU_MIPSR6 189a583158cSAtsushi Nemoto PTR_ADDU a0, a2 /* What's left */ 190930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 191a583158cSAtsushi Nemoto#ifdef __MIPSEB__ 1926d5155c2SMarkos Chandras EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@) 193dd2adea4SMarkos Chandras#else 1946d5155c2SMarkos Chandras EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@) 195a583158cSAtsushi Nemoto#endif 1968c56208aSLeonid Yegoshin#else 1978c56208aSLeonid Yegoshin PTR_SUBU t0, $0, a2 1988c56208aSLeonid Yegoshin PTR_ADDIU t0, 1 1998c56208aSLeonid Yegoshin STORE_BYTE(0) 2008c56208aSLeonid Yegoshin STORE_BYTE(1) 2018c56208aSLeonid Yegoshin#if LONGSIZE == 4 2028c56208aSLeonid Yegoshin EX(sb, a1, 2(a0), .Lbyte_fixup\@) 2038c56208aSLeonid Yegoshin#else 2048c56208aSLeonid Yegoshin STORE_BYTE(2) 2058c56208aSLeonid Yegoshin STORE_BYTE(3) 2068c56208aSLeonid Yegoshin STORE_BYTE(4) 2078c56208aSLeonid Yegoshin STORE_BYTE(5) 2088c56208aSLeonid Yegoshin EX(sb, a1, 6(a0), .Lbyte_fixup\@) 2098c56208aSLeonid Yegoshin#endif 2108c56208aSLeonid Yegoshin0: 2118c56208aSLeonid Yegoshin#endif 212a583158cSAtsushi Nemoto1: jr ra 213a583158cSAtsushi Nemoto move a2, zero 214a583158cSAtsushi Nemoto 2156d5155c2SMarkos Chandras.Lsmall_memset\@: 216a583158cSAtsushi Nemoto beqz a2, 2f 217a583158cSAtsushi Nemoto PTR_ADDU t1, a0, a2 218a583158cSAtsushi Nemoto 219a583158cSAtsushi Nemoto1: PTR_ADDIU a0, 1 /* fill bytewise */ 220930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 221a583158cSAtsushi Nemoto bne t1, a0, 1b 2228a8158c8SMatt Redfearn EX(sb, a1, -1(a0), .Lsmall_fixup\@) 223a583158cSAtsushi Nemoto 224a583158cSAtsushi Nemoto2: jr ra /* done */ 225a583158cSAtsushi Nemoto move a2, zero 2266d5155c2SMarkos Chandras .if __memset == 1 227a583158cSAtsushi Nemoto END(memset) 2286d5155c2SMarkos Chandras .set __memset, 0 2296d5155c2SMarkos Chandras .hidden __memset 2306d5155c2SMarkos Chandras .endif 231a583158cSAtsushi Nemoto 2328e85f275SMaciej W. Rozycki#ifdef CONFIG_CPU_MIPSR6 2338c56208aSLeonid Yegoshin.Lbyte_fixup\@: 2348c56208aSLeonid Yegoshin PTR_SUBU a2, $0, t0 2358c56208aSLeonid Yegoshin jr ra 2368c56208aSLeonid Yegoshin PTR_ADDIU a2, 1 2378e85f275SMaciej W. Rozycki#endif /* CONFIG_CPU_MIPSR6 */ 2388c56208aSLeonid Yegoshin 2396d5155c2SMarkos Chandras.Lfirst_fixup\@: 240a583158cSAtsushi Nemoto jr ra 241a583158cSAtsushi Nemoto nop 242a583158cSAtsushi Nemoto 2436d5155c2SMarkos Chandras.Lfwd_fixup\@: 244a583158cSAtsushi Nemoto PTR_L t0, TI_TASK($28) 245a583158cSAtsushi Nemoto andi a2, 0x3f 246e5674ad6STony Wu LONG_L t0, THREAD_BUADDR(t0) 247a583158cSAtsushi Nemoto LONG_ADDU a2, t1 248a583158cSAtsushi Nemoto jr ra 249a583158cSAtsushi Nemoto LONG_SUBU a2, t0 250a583158cSAtsushi Nemoto 2516d5155c2SMarkos Chandras.Lpartial_fixup\@: 252a583158cSAtsushi Nemoto PTR_L t0, TI_TASK($28) 25326c5e07dSSteven J. Hill andi a2, STORMASK 254e5674ad6STony Wu LONG_L t0, THREAD_BUADDR(t0) 255*daf70d89SMatt Redfearn LONG_ADDU a2, a0 256a583158cSAtsushi Nemoto jr ra 257a583158cSAtsushi Nemoto LONG_SUBU a2, t0 258a583158cSAtsushi Nemoto 2596d5155c2SMarkos Chandras.Llast_fixup\@: 260a583158cSAtsushi Nemoto jr ra 26126c5e07dSSteven J. Hill andi v1, a2, STORMASK 2626d5155c2SMarkos Chandras 2638a8158c8SMatt Redfearn.Lsmall_fixup\@: 2648a8158c8SMatt Redfearn PTR_SUBU a2, t1, a0 2658a8158c8SMatt Redfearn jr ra 2668a8158c8SMatt Redfearn PTR_ADDIU a2, 1 2678a8158c8SMatt Redfearn 2686d5155c2SMarkos Chandras .endm 2696d5155c2SMarkos Chandras 2706d5155c2SMarkos Chandras/* 2716d5155c2SMarkos Chandras * memset(void *s, int c, size_t n) 2726d5155c2SMarkos Chandras * 2736d5155c2SMarkos Chandras * a0: start of area to clear 2746d5155c2SMarkos Chandras * a1: char to fill with 2756d5155c2SMarkos Chandras * a2: size of area to clear 2766d5155c2SMarkos Chandras */ 2776d5155c2SMarkos Chandras 2786d5155c2SMarkos ChandrasLEAF(memset) 279576a2f0cSPaul BurtonEXPORT_SYMBOL(memset) 2806d5155c2SMarkos Chandras beqz a1, 1f 2816d5155c2SMarkos Chandras move v0, a0 /* result */ 2826d5155c2SMarkos Chandras 2836d5155c2SMarkos Chandras andi a1, 0xff /* spread fillword */ 2846d5155c2SMarkos Chandras LONG_SLL t1, a1, 8 2856d5155c2SMarkos Chandras or a1, t1 2866d5155c2SMarkos Chandras LONG_SLL t1, a1, 16 2876d5155c2SMarkos Chandras#if LONGSIZE == 8 2886d5155c2SMarkos Chandras or a1, t1 2896d5155c2SMarkos Chandras LONG_SLL t1, a1, 32 2906d5155c2SMarkos Chandras#endif 2916d5155c2SMarkos Chandras or a1, t1 2926d5155c2SMarkos Chandras1: 293fd9720e9SMarkos Chandras#ifndef CONFIG_EVA 2946d5155c2SMarkos ChandrasFEXPORT(__bzero) 295576a2f0cSPaul BurtonEXPORT_SYMBOL(__bzero) 296d6a428fbSJames Hogan#else 297d6a428fbSJames HoganFEXPORT(__bzero_kernel) 298576a2f0cSPaul BurtonEXPORT_SYMBOL(__bzero_kernel) 299fd9720e9SMarkos Chandras#endif 3006d5155c2SMarkos Chandras __BUILD_BZERO LEGACY_MODE 301fd9720e9SMarkos Chandras 302fd9720e9SMarkos Chandras#ifdef CONFIG_EVA 303fd9720e9SMarkos ChandrasLEAF(__bzero) 304576a2f0cSPaul BurtonEXPORT_SYMBOL(__bzero) 305fd9720e9SMarkos Chandras __BUILD_BZERO EVA_MODE 306fd9720e9SMarkos ChandrasEND(__bzero) 307fd9720e9SMarkos Chandras#endif 308