11da177e4SLinus Torvalds/* 21da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 31da177e4SLinus Torvalds * License. See the file "COPYING" in the main directory of this archive 41da177e4SLinus Torvalds * for more details. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Unified implementation of memcpy, memmove and the __copy_user backend. 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org) 91da177e4SLinus Torvalds * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. 101da177e4SLinus Torvalds * Copyright (C) 2002 Broadcom, Inc. 111da177e4SLinus Torvalds * memcpy/copy_user author: Mark Vandevoorde 12619b6e18SMaciej W. Rozycki * Copyright (C) 2007 Maciej W. Rozycki 135bc05971SMarkos Chandras * Copyright (C) 2014 Imagination Technologies Ltd. 141da177e4SLinus Torvalds * 151da177e4SLinus Torvalds * Mnemonic names for arguments to memcpy/__copy_user 161da177e4SLinus Torvalds */ 17e5adb877SRalf Baechle 18e5adb877SRalf Baechle/* 19e5adb877SRalf Baechle * Hack to resolve longstanding prefetch issue 20e5adb877SRalf Baechle * 21e5adb877SRalf Baechle * Prefetching may be fatal on some systems if we're prefetching beyond the 22e5adb877SRalf Baechle * end of memory on some systems. It's also a seriously bad idea on non 23e5adb877SRalf Baechle * dma-coherent systems. 24e5adb877SRalf Baechle */ 25634286f1SRalf Baechle#ifdef CONFIG_DMA_NONCOHERENT 26e5adb877SRalf Baechle#undef CONFIG_CPU_HAS_PREFETCH 27e5adb877SRalf Baechle#endif 28e5adb877SRalf Baechle#ifdef CONFIG_MIPS_MALTA 29e5adb877SRalf Baechle#undef CONFIG_CPU_HAS_PREFETCH 30e5adb877SRalf Baechle#endif 313daf281fSLeonid Yegoshin#ifdef CONFIG_CPU_MIPSR6 323daf281fSLeonid Yegoshin#undef CONFIG_CPU_HAS_PREFETCH 333daf281fSLeonid Yegoshin#endif 34e5adb877SRalf Baechle 35*9259e15bSMasahiro Yamada#include <linux/export.h> 361da177e4SLinus Torvalds#include <asm/asm.h> 37048eb582SSam Ravnborg#include <asm/asm-offsets.h> 381da177e4SLinus Torvalds#include <asm/regdef.h> 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds#define dst a0 411da177e4SLinus Torvalds#define src a1 421da177e4SLinus Torvalds#define len a2 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds/* 451da177e4SLinus Torvalds * Spec 461da177e4SLinus Torvalds * 471da177e4SLinus Torvalds * memcpy copies len bytes from src to dst and sets v0 to dst. 481da177e4SLinus Torvalds * It assumes that 491da177e4SLinus Torvalds * - src and dst don't overlap 501da177e4SLinus Torvalds * - src is readable 511da177e4SLinus Torvalds * - dst is writable 521da177e4SLinus Torvalds * memcpy uses the standard calling convention 531da177e4SLinus Torvalds * 541da177e4SLinus Torvalds * __copy_user copies up to len bytes from src to dst and sets a2 (len) to 551da177e4SLinus Torvalds * the number of uncopied bytes due to an exception caused by a read or write. 561da177e4SLinus Torvalds * __copy_user assumes that src and dst don't overlap, and that the call is 571da177e4SLinus Torvalds * implementing one of the following: 581da177e4SLinus Torvalds * copy_to_user 591da177e4SLinus Torvalds * - src is readable (no exceptions when reading src) 601da177e4SLinus Torvalds * copy_from_user 611da177e4SLinus Torvalds * - dst is writable (no exceptions when writing dst) 621da177e4SLinus Torvalds * __copy_user uses a non-standard calling convention; see 631da177e4SLinus Torvalds * include/asm-mips/uaccess.h 641da177e4SLinus Torvalds * 651da177e4SLinus Torvalds * When an exception happens on a load, the handler must 661da177e4SLinus Torvalds # ensure that all of the destination buffer is overwritten to prevent 671da177e4SLinus Torvalds * leaking information to user mode programs. 681da177e4SLinus Torvalds */ 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds/* 711da177e4SLinus Torvalds * Implementation 721da177e4SLinus Torvalds */ 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds/* 751da177e4SLinus Torvalds * The exception handler for loads requires that: 761da177e4SLinus Torvalds * 1- AT contain the address of the byte just past the end of the source 771da177e4SLinus Torvalds * of the copy, 781da177e4SLinus Torvalds * 2- src_entry <= src < AT, and 791da177e4SLinus Torvalds * 3- (dst - src) == (dst_entry - src_entry), 801da177e4SLinus Torvalds * The _entry suffix denotes values when __copy_user was called. 811da177e4SLinus Torvalds * 821da177e4SLinus Torvalds * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user 831da177e4SLinus Torvalds * (2) is met by incrementing src by the number of bytes copied 841da177e4SLinus Torvalds * (3) is met by not doing loads between a pair of increments of dst and src 851da177e4SLinus Torvalds * 861da177e4SLinus Torvalds * The exception handlers for stores adjust len (if necessary) and return. 871da177e4SLinus Torvalds * These handlers do not need to overwrite any data. 881da177e4SLinus Torvalds * 891da177e4SLinus Torvalds * For __rmemcpy and memmove an exception is always a kernel bug, therefore 901da177e4SLinus Torvalds * they're not protected. 911da177e4SLinus Torvalds */ 921da177e4SLinus Torvalds 935bc05971SMarkos Chandras/* Instruction type */ 945bc05971SMarkos Chandras#define LD_INSN 1 955bc05971SMarkos Chandras#define ST_INSN 2 96bda4d986SMarkos Chandras/* Pretech type */ 97bda4d986SMarkos Chandras#define SRC_PREFETCH 1 98bda4d986SMarkos Chandras#define DST_PREFETCH 2 99cf62a8b8SMarkos Chandras#define LEGACY_MODE 1 100cf62a8b8SMarkos Chandras#define EVA_MODE 2 101cf62a8b8SMarkos Chandras#define USEROP 1 102cf62a8b8SMarkos Chandras#define KERNELOP 2 1035bc05971SMarkos Chandras 1045bc05971SMarkos Chandras/* 1055bc05971SMarkos Chandras * Wrapper to add an entry in the exception table 1065bc05971SMarkos Chandras * in case the insn causes a memory exception. 1075bc05971SMarkos Chandras * Arguments: 1085bc05971SMarkos Chandras * insn : Load/store instruction 1095bc05971SMarkos Chandras * type : Instruction type 1105bc05971SMarkos Chandras * reg : Register 1115bc05971SMarkos Chandras * addr : Address 1125bc05971SMarkos Chandras * handler : Exception handler 1135bc05971SMarkos Chandras */ 114cf62a8b8SMarkos Chandras 1155bc05971SMarkos Chandras#define EXC(insn, type, reg, addr, handler) \ 116cf62a8b8SMarkos Chandras .if \mode == LEGACY_MODE; \ 1175bc05971SMarkos Chandras9: insn reg, addr; \ 1181da177e4SLinus Torvalds .section __ex_table,"a"; \ 119fa62f39dSThomas Bogendoerfer PTR_WD 9b, handler; \ 120cf62a8b8SMarkos Chandras .previous; \ 121cd26cb41SMarkos Chandras /* This is assembled in EVA mode */ \ 122cd26cb41SMarkos Chandras .else; \ 123cd26cb41SMarkos Chandras /* If loading from user or storing to user */ \ 124cd26cb41SMarkos Chandras .if ((\from == USEROP) && (type == LD_INSN)) || \ 125cd26cb41SMarkos Chandras ((\to == USEROP) && (type == ST_INSN)); \ 126cd26cb41SMarkos Chandras9: __BUILD_EVA_INSN(insn##e, reg, addr); \ 127cd26cb41SMarkos Chandras .section __ex_table,"a"; \ 128fa62f39dSThomas Bogendoerfer PTR_WD 9b, handler; \ 129cd26cb41SMarkos Chandras .previous; \ 130cd26cb41SMarkos Chandras .else; \ 131cd26cb41SMarkos Chandras /* \ 132cd26cb41SMarkos Chandras * Still in EVA, but no need for \ 133cd26cb41SMarkos Chandras * exception handler or EVA insn \ 134cd26cb41SMarkos Chandras */ \ 135cd26cb41SMarkos Chandras insn reg, addr; \ 136cd26cb41SMarkos Chandras .endif; \ 137cf62a8b8SMarkos Chandras .endif 138cd26cb41SMarkos Chandras 1391da177e4SLinus Torvalds/* 1401da177e4SLinus Torvalds * Only on the 64-bit kernel we can made use of 64-bit registers. 1411da177e4SLinus Torvalds */ 142875d43e7SRalf Baechle#ifdef CONFIG_64BIT 1431da177e4SLinus Torvalds#define USE_DOUBLE 1441da177e4SLinus Torvalds#endif 1451da177e4SLinus Torvalds 1461da177e4SLinus Torvalds#ifdef USE_DOUBLE 1471da177e4SLinus Torvalds 1485bc05971SMarkos Chandras#define LOADK ld /* No exception */ 1495bc05971SMarkos Chandras#define LOAD(reg, addr, handler) EXC(ld, LD_INSN, reg, addr, handler) 1505bc05971SMarkos Chandras#define LOADL(reg, addr, handler) EXC(ldl, LD_INSN, reg, addr, handler) 1515bc05971SMarkos Chandras#define LOADR(reg, addr, handler) EXC(ldr, LD_INSN, reg, addr, handler) 1525bc05971SMarkos Chandras#define STOREL(reg, addr, handler) EXC(sdl, ST_INSN, reg, addr, handler) 1535bc05971SMarkos Chandras#define STORER(reg, addr, handler) EXC(sdr, ST_INSN, reg, addr, handler) 1545bc05971SMarkos Chandras#define STORE(reg, addr, handler) EXC(sd, ST_INSN, reg, addr, handler) 1551da177e4SLinus Torvalds#define ADD daddu 1561da177e4SLinus Torvalds#define SUB dsubu 1571da177e4SLinus Torvalds#define SRL dsrl 1581da177e4SLinus Torvalds#define SRA dsra 1591da177e4SLinus Torvalds#define SLL dsll 1601da177e4SLinus Torvalds#define SLLV dsllv 1611da177e4SLinus Torvalds#define SRLV dsrlv 1621da177e4SLinus Torvalds#define NBYTES 8 1631da177e4SLinus Torvalds#define LOG_NBYTES 3 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds/* 1661da177e4SLinus Torvalds * As we are sharing code base with the mips32 tree (which use the o32 ABI 1671da177e4SLinus Torvalds * register definitions). We need to redefine the register definitions from 1681da177e4SLinus Torvalds * the n64 ABI register naming to the o32 ABI register naming. 1691da177e4SLinus Torvalds */ 1701da177e4SLinus Torvalds#undef t0 1711da177e4SLinus Torvalds#undef t1 1721da177e4SLinus Torvalds#undef t2 1731da177e4SLinus Torvalds#undef t3 1741da177e4SLinus Torvalds#define t0 $8 1751da177e4SLinus Torvalds#define t1 $9 1761da177e4SLinus Torvalds#define t2 $10 1771da177e4SLinus Torvalds#define t3 $11 1781da177e4SLinus Torvalds#define t4 $12 1791da177e4SLinus Torvalds#define t5 $13 1801da177e4SLinus Torvalds#define t6 $14 1811da177e4SLinus Torvalds#define t7 $15 1821da177e4SLinus Torvalds 1831da177e4SLinus Torvalds#else 1841da177e4SLinus Torvalds 1855bc05971SMarkos Chandras#define LOADK lw /* No exception */ 1865bc05971SMarkos Chandras#define LOAD(reg, addr, handler) EXC(lw, LD_INSN, reg, addr, handler) 1875bc05971SMarkos Chandras#define LOADL(reg, addr, handler) EXC(lwl, LD_INSN, reg, addr, handler) 1885bc05971SMarkos Chandras#define LOADR(reg, addr, handler) EXC(lwr, LD_INSN, reg, addr, handler) 1895bc05971SMarkos Chandras#define STOREL(reg, addr, handler) EXC(swl, ST_INSN, reg, addr, handler) 1905bc05971SMarkos Chandras#define STORER(reg, addr, handler) EXC(swr, ST_INSN, reg, addr, handler) 1915bc05971SMarkos Chandras#define STORE(reg, addr, handler) EXC(sw, ST_INSN, reg, addr, handler) 1921da177e4SLinus Torvalds#define ADD addu 1931da177e4SLinus Torvalds#define SUB subu 1941da177e4SLinus Torvalds#define SRL srl 1951da177e4SLinus Torvalds#define SLL sll 1961da177e4SLinus Torvalds#define SRA sra 1971da177e4SLinus Torvalds#define SLLV sllv 1981da177e4SLinus Torvalds#define SRLV srlv 1991da177e4SLinus Torvalds#define NBYTES 4 2001da177e4SLinus Torvalds#define LOG_NBYTES 2 2011da177e4SLinus Torvalds 2021da177e4SLinus Torvalds#endif /* USE_DOUBLE */ 2031da177e4SLinus Torvalds 2045bc05971SMarkos Chandras#define LOADB(reg, addr, handler) EXC(lb, LD_INSN, reg, addr, handler) 2055bc05971SMarkos Chandras#define STOREB(reg, addr, handler) EXC(sb, ST_INSN, reg, addr, handler) 2065bc05971SMarkos Chandras 2071d6fb222SPaul Burton#ifdef CONFIG_CPU_HAS_PREFETCH 208cf62a8b8SMarkos Chandras# define _PREF(hint, addr, type) \ 209cf62a8b8SMarkos Chandras .if \mode == LEGACY_MODE; \ 2101d6fb222SPaul Burton kernel_pref(hint, addr); \ 211cd26cb41SMarkos Chandras .else; \ 212cd26cb41SMarkos Chandras .if ((\from == USEROP) && (type == SRC_PREFETCH)) || \ 213cd26cb41SMarkos Chandras ((\to == USEROP) && (type == DST_PREFETCH)); \ 214cd26cb41SMarkos Chandras /* \ 215cd26cb41SMarkos Chandras * PREFE has only 9 bits for the offset \ 216cd26cb41SMarkos Chandras * compared to PREF which has 16, so it may \ 217cd26cb41SMarkos Chandras * need to use the $at register but this \ 218cd26cb41SMarkos Chandras * register should remain intact because it's \ 219cd26cb41SMarkos Chandras * used later on. Therefore use $v1. \ 220cd26cb41SMarkos Chandras */ \ 221cd26cb41SMarkos Chandras .set at=v1; \ 2221d6fb222SPaul Burton user_pref(hint, addr); \ 223cd26cb41SMarkos Chandras .set noat; \ 224cd26cb41SMarkos Chandras .else; \ 2251d6fb222SPaul Burton kernel_pref(hint, addr); \ 226cd26cb41SMarkos Chandras .endif; \ 227cf62a8b8SMarkos Chandras .endif 2281d6fb222SPaul Burton#else 2291d6fb222SPaul Burton# define _PREF(hint, addr, type) 2301d6fb222SPaul Burton#endif 231bda4d986SMarkos Chandras 232bda4d986SMarkos Chandras#define PREFS(hint, addr) _PREF(hint, addr, SRC_PREFETCH) 233bda4d986SMarkos Chandras#define PREFD(hint, addr) _PREF(hint, addr, DST_PREFETCH) 234bda4d986SMarkos Chandras 2351da177e4SLinus Torvalds#ifdef CONFIG_CPU_LITTLE_ENDIAN 2361da177e4SLinus Torvalds#define LDFIRST LOADR 2371da177e4SLinus Torvalds#define LDREST LOADL 2381da177e4SLinus Torvalds#define STFIRST STORER 2391da177e4SLinus Torvalds#define STREST STOREL 2401da177e4SLinus Torvalds#define SHIFT_DISCARD SLLV 2411da177e4SLinus Torvalds#else 2421da177e4SLinus Torvalds#define LDFIRST LOADL 2431da177e4SLinus Torvalds#define LDREST LOADR 2441da177e4SLinus Torvalds#define STFIRST STOREL 2451da177e4SLinus Torvalds#define STREST STORER 2461da177e4SLinus Torvalds#define SHIFT_DISCARD SRLV 2471da177e4SLinus Torvalds#endif 2481da177e4SLinus Torvalds 2491da177e4SLinus Torvalds#define FIRST(unit) ((unit)*NBYTES) 2501da177e4SLinus Torvalds#define REST(unit) (FIRST(unit)+NBYTES-1) 2511da177e4SLinus Torvalds#define UNIT(unit) FIRST(unit) 2521da177e4SLinus Torvalds 2531da177e4SLinus Torvalds#define ADDRMASK (NBYTES-1) 2541da177e4SLinus Torvalds 2551da177e4SLinus Torvalds .text 2561da177e4SLinus Torvalds .set noreorder 257619b6e18SMaciej W. Rozycki#ifndef CONFIG_CPU_DADDI_WORKAROUNDS 2581da177e4SLinus Torvalds .set noat 259619b6e18SMaciej W. Rozycki#else 260619b6e18SMaciej W. Rozycki .set at=v1 261619b6e18SMaciej W. Rozycki#endif 2621da177e4SLinus Torvalds 263cf62a8b8SMarkos Chandras .align 5 264bb0757ebSDavid Daney 265bb0757ebSDavid Daney /* 266cf62a8b8SMarkos Chandras * Macro to build the __copy_user common code 267209b8778SAndrea Gelmini * Arguments: 268cf62a8b8SMarkos Chandras * mode : LEGACY_MODE or EVA_MODE 269cf62a8b8SMarkos Chandras * from : Source operand. USEROP or KERNELOP 270cf62a8b8SMarkos Chandras * to : Destination operand. USEROP or KERNELOP 2711da177e4SLinus Torvalds */ 272cf62a8b8SMarkos Chandras .macro __BUILD_COPY_USER mode, from, to 273cf62a8b8SMarkos Chandras 274cf62a8b8SMarkos Chandras /* initialize __memcpy if this the first time we execute this macro */ 275cf62a8b8SMarkos Chandras .ifnotdef __memcpy 276cf62a8b8SMarkos Chandras .set __memcpy, 1 277cf62a8b8SMarkos Chandras .hidden __memcpy /* make sure it does not leak */ 278cf62a8b8SMarkos Chandras .endif 279cf62a8b8SMarkos Chandras 2801da177e4SLinus Torvalds /* 2811da177e4SLinus Torvalds * Note: dst & src may be unaligned, len may be 0 2821da177e4SLinus Torvalds * Temps 2831da177e4SLinus Torvalds */ 2841da177e4SLinus Torvalds#define rem t8 2851da177e4SLinus Torvalds 286930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 2871da177e4SLinus Torvalds /* 2881da177e4SLinus Torvalds * The "issue break"s below are very approximate. 2891da177e4SLinus Torvalds * Issue delays for dcache fills will perturb the schedule, as will 2901da177e4SLinus Torvalds * load queue full replay traps, etc. 2911da177e4SLinus Torvalds * 2921da177e4SLinus Torvalds * If len < NBYTES use byte operations. 2931da177e4SLinus Torvalds */ 294bda4d986SMarkos Chandras PREFS( 0, 0(src) ) 295bda4d986SMarkos Chandras PREFD( 1, 0(dst) ) 2961da177e4SLinus Torvalds sltu t2, len, NBYTES 2971da177e4SLinus Torvalds and t1, dst, ADDRMASK 298bda4d986SMarkos Chandras PREFS( 0, 1*32(src) ) 299bda4d986SMarkos Chandras PREFD( 1, 1*32(dst) ) 300cf62a8b8SMarkos Chandras bnez t2, .Lcopy_bytes_checklen\@ 3011da177e4SLinus Torvalds and t0, src, ADDRMASK 302bda4d986SMarkos Chandras PREFS( 0, 2*32(src) ) 303bda4d986SMarkos Chandras PREFD( 1, 2*32(dst) ) 30418d84e2eSAlexander Lobakin#ifndef CONFIG_CPU_NO_LOAD_STORE_LR 305cf62a8b8SMarkos Chandras bnez t1, .Ldst_unaligned\@ 3061da177e4SLinus Torvalds nop 307cf62a8b8SMarkos Chandras bnez t0, .Lsrc_unaligned_dst_aligned\@ 30818d84e2eSAlexander Lobakin#else /* CONFIG_CPU_NO_LOAD_STORE_LR */ 309b0ce4bd5SLeonid Yegoshin or t0, t0, t1 310b0ce4bd5SLeonid Yegoshin bnez t0, .Lcopy_unaligned_bytes\@ 31118d84e2eSAlexander Lobakin#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 3121da177e4SLinus Torvalds /* 3131da177e4SLinus Torvalds * use delay slot for fall-through 3141da177e4SLinus Torvalds * src and dst are aligned; need to compute rem 3151da177e4SLinus Torvalds */ 316cf62a8b8SMarkos Chandras.Lboth_aligned\@: 3171da177e4SLinus Torvalds SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter 318cf62a8b8SMarkos Chandras beqz t0, .Lcleanup_both_aligned\@ # len < 8*NBYTES 3191da177e4SLinus Torvalds and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) 320bda4d986SMarkos Chandras PREFS( 0, 3*32(src) ) 321bda4d986SMarkos Chandras PREFD( 1, 3*32(dst) ) 3221da177e4SLinus Torvalds .align 4 3231da177e4SLinus Torvalds1: 324930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 325cf62a8b8SMarkos Chandras LOAD(t0, UNIT(0)(src), .Ll_exc\@) 326cf62a8b8SMarkos Chandras LOAD(t1, UNIT(1)(src), .Ll_exc_copy\@) 327cf62a8b8SMarkos Chandras LOAD(t2, UNIT(2)(src), .Ll_exc_copy\@) 328cf62a8b8SMarkos Chandras LOAD(t3, UNIT(3)(src), .Ll_exc_copy\@) 3291da177e4SLinus Torvalds SUB len, len, 8*NBYTES 330cf62a8b8SMarkos Chandras LOAD(t4, UNIT(4)(src), .Ll_exc_copy\@) 331cf62a8b8SMarkos Chandras LOAD(t7, UNIT(5)(src), .Ll_exc_copy\@) 332cf62a8b8SMarkos Chandras STORE(t0, UNIT(0)(dst), .Ls_exc_p8u\@) 333cf62a8b8SMarkos Chandras STORE(t1, UNIT(1)(dst), .Ls_exc_p7u\@) 334cf62a8b8SMarkos Chandras LOAD(t0, UNIT(6)(src), .Ll_exc_copy\@) 335cf62a8b8SMarkos Chandras LOAD(t1, UNIT(7)(src), .Ll_exc_copy\@) 3361da177e4SLinus Torvalds ADD src, src, 8*NBYTES 3371da177e4SLinus Torvalds ADD dst, dst, 8*NBYTES 338cf62a8b8SMarkos Chandras STORE(t2, UNIT(-6)(dst), .Ls_exc_p6u\@) 339cf62a8b8SMarkos Chandras STORE(t3, UNIT(-5)(dst), .Ls_exc_p5u\@) 340cf62a8b8SMarkos Chandras STORE(t4, UNIT(-4)(dst), .Ls_exc_p4u\@) 341cf62a8b8SMarkos Chandras STORE(t7, UNIT(-3)(dst), .Ls_exc_p3u\@) 342cf62a8b8SMarkos Chandras STORE(t0, UNIT(-2)(dst), .Ls_exc_p2u\@) 343cf62a8b8SMarkos Chandras STORE(t1, UNIT(-1)(dst), .Ls_exc_p1u\@) 344bda4d986SMarkos Chandras PREFS( 0, 8*32(src) ) 345bda4d986SMarkos Chandras PREFD( 1, 8*32(dst) ) 3461da177e4SLinus Torvalds bne len, rem, 1b 3471da177e4SLinus Torvalds nop 3481da177e4SLinus Torvalds 3491da177e4SLinus Torvalds /* 3501da177e4SLinus Torvalds * len == rem == the number of bytes left to copy < 8*NBYTES 3511da177e4SLinus Torvalds */ 352cf62a8b8SMarkos Chandras.Lcleanup_both_aligned\@: 353cf62a8b8SMarkos Chandras beqz len, .Ldone\@ 3541da177e4SLinus Torvalds sltu t0, len, 4*NBYTES 355cf62a8b8SMarkos Chandras bnez t0, .Lless_than_4units\@ 3561da177e4SLinus Torvalds and rem, len, (NBYTES-1) # rem = len % NBYTES 3571da177e4SLinus Torvalds /* 3581da177e4SLinus Torvalds * len >= 4*NBYTES 3591da177e4SLinus Torvalds */ 360cf62a8b8SMarkos Chandras LOAD( t0, UNIT(0)(src), .Ll_exc\@) 361cf62a8b8SMarkos Chandras LOAD( t1, UNIT(1)(src), .Ll_exc_copy\@) 362cf62a8b8SMarkos Chandras LOAD( t2, UNIT(2)(src), .Ll_exc_copy\@) 363cf62a8b8SMarkos Chandras LOAD( t3, UNIT(3)(src), .Ll_exc_copy\@) 3641da177e4SLinus Torvalds SUB len, len, 4*NBYTES 3651da177e4SLinus Torvalds ADD src, src, 4*NBYTES 366930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 367cf62a8b8SMarkos Chandras STORE(t0, UNIT(0)(dst), .Ls_exc_p4u\@) 368cf62a8b8SMarkos Chandras STORE(t1, UNIT(1)(dst), .Ls_exc_p3u\@) 369cf62a8b8SMarkos Chandras STORE(t2, UNIT(2)(dst), .Ls_exc_p2u\@) 370cf62a8b8SMarkos Chandras STORE(t3, UNIT(3)(dst), .Ls_exc_p1u\@) 371619b6e18SMaciej W. Rozycki .set reorder /* DADDI_WAR */ 3721da177e4SLinus Torvalds ADD dst, dst, 4*NBYTES 373cf62a8b8SMarkos Chandras beqz len, .Ldone\@ 374619b6e18SMaciej W. Rozycki .set noreorder 375cf62a8b8SMarkos Chandras.Lless_than_4units\@: 3761da177e4SLinus Torvalds /* 3771da177e4SLinus Torvalds * rem = len % NBYTES 3781da177e4SLinus Torvalds */ 379cf62a8b8SMarkos Chandras beq rem, len, .Lcopy_bytes\@ 3801da177e4SLinus Torvalds nop 3811da177e4SLinus Torvalds1: 382930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 383cf62a8b8SMarkos Chandras LOAD(t0, 0(src), .Ll_exc\@) 3841da177e4SLinus Torvalds ADD src, src, NBYTES 3851da177e4SLinus Torvalds SUB len, len, NBYTES 386cf62a8b8SMarkos Chandras STORE(t0, 0(dst), .Ls_exc_p1u\@) 387619b6e18SMaciej W. Rozycki .set reorder /* DADDI_WAR */ 3881da177e4SLinus Torvalds ADD dst, dst, NBYTES 389619b6e18SMaciej W. Rozycki bne rem, len, 1b 390619b6e18SMaciej W. Rozycki .set noreorder 3911da177e4SLinus Torvalds 39218d84e2eSAlexander Lobakin#ifndef CONFIG_CPU_NO_LOAD_STORE_LR 3931da177e4SLinus Torvalds /* 3941da177e4SLinus Torvalds * src and dst are aligned, need to copy rem bytes (rem < NBYTES) 3951da177e4SLinus Torvalds * A loop would do only a byte at a time with possible branch 3961da177e4SLinus Torvalds * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE 3971da177e4SLinus Torvalds * because can't assume read-access to dst. Instead, use 3981da177e4SLinus Torvalds * STREST dst, which doesn't require read access to dst. 3991da177e4SLinus Torvalds * 4001da177e4SLinus Torvalds * This code should perform better than a simple loop on modern, 4011da177e4SLinus Torvalds * wide-issue mips processors because the code has fewer branches and 4021da177e4SLinus Torvalds * more instruction-level parallelism. 4031da177e4SLinus Torvalds */ 4041da177e4SLinus Torvalds#define bits t2 405cf62a8b8SMarkos Chandras beqz len, .Ldone\@ 4061da177e4SLinus Torvalds ADD t1, dst, len # t1 is just past last byte of dst 4071da177e4SLinus Torvalds li bits, 8*NBYTES 4081da177e4SLinus Torvalds SLL rem, len, 3 # rem = number of bits to keep 409cf62a8b8SMarkos Chandras LOAD(t0, 0(src), .Ll_exc\@) 4101da177e4SLinus Torvalds SUB bits, bits, rem # bits = number of bits to discard 4111da177e4SLinus Torvalds SHIFT_DISCARD t0, t0, bits 412cf62a8b8SMarkos Chandras STREST(t0, -1(t1), .Ls_exc\@) 4131da177e4SLinus Torvalds jr ra 4141da177e4SLinus Torvalds move len, zero 415cf62a8b8SMarkos Chandras.Ldst_unaligned\@: 4161da177e4SLinus Torvalds /* 4171da177e4SLinus Torvalds * dst is unaligned 4181da177e4SLinus Torvalds * t0 = src & ADDRMASK 4191da177e4SLinus Torvalds * t1 = dst & ADDRMASK; T1 > 0 4201da177e4SLinus Torvalds * len >= NBYTES 4211da177e4SLinus Torvalds * 4221da177e4SLinus Torvalds * Copy enough bytes to align dst 4231da177e4SLinus Torvalds * Set match = (src and dst have same alignment) 4241da177e4SLinus Torvalds */ 4251da177e4SLinus Torvalds#define match rem 426cf62a8b8SMarkos Chandras LDFIRST(t3, FIRST(0)(src), .Ll_exc\@) 4271da177e4SLinus Torvalds ADD t2, zero, NBYTES 428cf62a8b8SMarkos Chandras LDREST(t3, REST(0)(src), .Ll_exc_copy\@) 4291da177e4SLinus Torvalds SUB t2, t2, t1 # t2 = number of bytes copied 4301da177e4SLinus Torvalds xor match, t0, t1 431930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 432cf62a8b8SMarkos Chandras STFIRST(t3, FIRST(0)(dst), .Ls_exc\@) 433cf62a8b8SMarkos Chandras beq len, t2, .Ldone\@ 4341da177e4SLinus Torvalds SUB len, len, t2 4351da177e4SLinus Torvalds ADD dst, dst, t2 436cf62a8b8SMarkos Chandras beqz match, .Lboth_aligned\@ 4371da177e4SLinus Torvalds ADD src, src, t2 4381da177e4SLinus Torvalds 439cf62a8b8SMarkos Chandras.Lsrc_unaligned_dst_aligned\@: 4401da177e4SLinus Torvalds SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter 441bda4d986SMarkos Chandras PREFS( 0, 3*32(src) ) 442cf62a8b8SMarkos Chandras beqz t0, .Lcleanup_src_unaligned\@ 4431da177e4SLinus Torvalds and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES 444bda4d986SMarkos Chandras PREFD( 1, 3*32(dst) ) 4451da177e4SLinus Torvalds1: 4461da177e4SLinus Torvalds/* 4471da177e4SLinus Torvalds * Avoid consecutive LD*'s to the same register since some mips 4481da177e4SLinus Torvalds * implementations can't issue them in the same cycle. 4491da177e4SLinus Torvalds * It's OK to load FIRST(N+1) before REST(N) because the two addresses 4501da177e4SLinus Torvalds * are to the same unit (unless src is aligned, but it's not). 4511da177e4SLinus Torvalds */ 452930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 453cf62a8b8SMarkos Chandras LDFIRST(t0, FIRST(0)(src), .Ll_exc\@) 454cf62a8b8SMarkos Chandras LDFIRST(t1, FIRST(1)(src), .Ll_exc_copy\@) 4551da177e4SLinus Torvalds SUB len, len, 4*NBYTES 456cf62a8b8SMarkos Chandras LDREST(t0, REST(0)(src), .Ll_exc_copy\@) 457cf62a8b8SMarkos Chandras LDREST(t1, REST(1)(src), .Ll_exc_copy\@) 458cf62a8b8SMarkos Chandras LDFIRST(t2, FIRST(2)(src), .Ll_exc_copy\@) 459cf62a8b8SMarkos Chandras LDFIRST(t3, FIRST(3)(src), .Ll_exc_copy\@) 460cf62a8b8SMarkos Chandras LDREST(t2, REST(2)(src), .Ll_exc_copy\@) 461cf62a8b8SMarkos Chandras LDREST(t3, REST(3)(src), .Ll_exc_copy\@) 462bda4d986SMarkos Chandras PREFS( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) 4631da177e4SLinus Torvalds ADD src, src, 4*NBYTES 4641da177e4SLinus Torvalds#ifdef CONFIG_CPU_SB1 4651da177e4SLinus Torvalds nop # improves slotting 4661da177e4SLinus Torvalds#endif 467cf62a8b8SMarkos Chandras STORE(t0, UNIT(0)(dst), .Ls_exc_p4u\@) 468cf62a8b8SMarkos Chandras STORE(t1, UNIT(1)(dst), .Ls_exc_p3u\@) 469cf62a8b8SMarkos Chandras STORE(t2, UNIT(2)(dst), .Ls_exc_p2u\@) 470cf62a8b8SMarkos Chandras STORE(t3, UNIT(3)(dst), .Ls_exc_p1u\@) 471bda4d986SMarkos Chandras PREFD( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) 472619b6e18SMaciej W. Rozycki .set reorder /* DADDI_WAR */ 4731da177e4SLinus Torvalds ADD dst, dst, 4*NBYTES 474619b6e18SMaciej W. Rozycki bne len, rem, 1b 475619b6e18SMaciej W. Rozycki .set noreorder 4761da177e4SLinus Torvalds 477cf62a8b8SMarkos Chandras.Lcleanup_src_unaligned\@: 478cf62a8b8SMarkos Chandras beqz len, .Ldone\@ 4791da177e4SLinus Torvalds and rem, len, NBYTES-1 # rem = len % NBYTES 480cf62a8b8SMarkos Chandras beq rem, len, .Lcopy_bytes\@ 4811da177e4SLinus Torvalds nop 4821da177e4SLinus Torvalds1: 483930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 484cf62a8b8SMarkos Chandras LDFIRST(t0, FIRST(0)(src), .Ll_exc\@) 485cf62a8b8SMarkos Chandras LDREST(t0, REST(0)(src), .Ll_exc_copy\@) 4861da177e4SLinus Torvalds ADD src, src, NBYTES 4871da177e4SLinus Torvalds SUB len, len, NBYTES 488cf62a8b8SMarkos Chandras STORE(t0, 0(dst), .Ls_exc_p1u\@) 489619b6e18SMaciej W. Rozycki .set reorder /* DADDI_WAR */ 4901da177e4SLinus Torvalds ADD dst, dst, NBYTES 491619b6e18SMaciej W. Rozycki bne len, rem, 1b 492619b6e18SMaciej W. Rozycki .set noreorder 4931da177e4SLinus Torvalds 49418d84e2eSAlexander Lobakin#endif /* !CONFIG_CPU_NO_LOAD_STORE_LR */ 495cf62a8b8SMarkos Chandras.Lcopy_bytes_checklen\@: 496cf62a8b8SMarkos Chandras beqz len, .Ldone\@ 4971da177e4SLinus Torvalds nop 498cf62a8b8SMarkos Chandras.Lcopy_bytes\@: 4991da177e4SLinus Torvalds /* 0 < len < NBYTES */ 500930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 5011da177e4SLinus Torvalds#define COPY_BYTE(N) \ 502cf62a8b8SMarkos Chandras LOADB(t0, N(src), .Ll_exc\@); \ 5031da177e4SLinus Torvalds SUB len, len, 1; \ 504cf62a8b8SMarkos Chandras beqz len, .Ldone\@; \ 505cf62a8b8SMarkos Chandras STOREB(t0, N(dst), .Ls_exc_p1\@) 5061da177e4SLinus Torvalds 5071da177e4SLinus Torvalds COPY_BYTE(0) 5081da177e4SLinus Torvalds COPY_BYTE(1) 5091da177e4SLinus Torvalds#ifdef USE_DOUBLE 5101da177e4SLinus Torvalds COPY_BYTE(2) 5111da177e4SLinus Torvalds COPY_BYTE(3) 5121da177e4SLinus Torvalds COPY_BYTE(4) 5131da177e4SLinus Torvalds COPY_BYTE(5) 5141da177e4SLinus Torvalds#endif 515cf62a8b8SMarkos Chandras LOADB(t0, NBYTES-2(src), .Ll_exc\@) 5161da177e4SLinus Torvalds SUB len, len, 1 5171da177e4SLinus Torvalds jr ra 518cf62a8b8SMarkos Chandras STOREB(t0, NBYTES-2(dst), .Ls_exc_p1\@) 519cf62a8b8SMarkos Chandras.Ldone\@: 5201da177e4SLinus Torvalds jr ra 52151b1029dSMarkos Chandras nop 522b0ce4bd5SLeonid Yegoshin 52318d84e2eSAlexander Lobakin#ifdef CONFIG_CPU_NO_LOAD_STORE_LR 524b0ce4bd5SLeonid Yegoshin.Lcopy_unaligned_bytes\@: 525b0ce4bd5SLeonid Yegoshin1: 526b0ce4bd5SLeonid Yegoshin COPY_BYTE(0) 527b0ce4bd5SLeonid Yegoshin COPY_BYTE(1) 528b0ce4bd5SLeonid Yegoshin COPY_BYTE(2) 529b0ce4bd5SLeonid Yegoshin COPY_BYTE(3) 530b0ce4bd5SLeonid Yegoshin COPY_BYTE(4) 531b0ce4bd5SLeonid Yegoshin COPY_BYTE(5) 532b0ce4bd5SLeonid Yegoshin COPY_BYTE(6) 533b0ce4bd5SLeonid Yegoshin COPY_BYTE(7) 534b0ce4bd5SLeonid Yegoshin ADD src, src, 8 535b0ce4bd5SLeonid Yegoshin b 1b 536b0ce4bd5SLeonid Yegoshin ADD dst, dst, 8 53718d84e2eSAlexander Lobakin#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */ 538cf62a8b8SMarkos Chandras .if __memcpy == 1 5391da177e4SLinus Torvalds END(memcpy) 540cf62a8b8SMarkos Chandras .set __memcpy, 0 541cf62a8b8SMarkos Chandras .hidden __memcpy 542cf62a8b8SMarkos Chandras .endif 5431da177e4SLinus Torvalds 544cf62a8b8SMarkos Chandras.Ll_exc_copy\@: 5451da177e4SLinus Torvalds /* 5461da177e4SLinus Torvalds * Copy bytes from src until faulting load address (or until a 5471da177e4SLinus Torvalds * lb faults) 5481da177e4SLinus Torvalds * 5491da177e4SLinus Torvalds * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28) 5501da177e4SLinus Torvalds * may be more than a byte beyond the last address. 5511da177e4SLinus Torvalds * Hence, the lb below may get an exception. 5521da177e4SLinus Torvalds * 5531da177e4SLinus Torvalds * Assumes src < THREAD_BUADDR($28) 5541da177e4SLinus Torvalds */ 5555bc05971SMarkos Chandras LOADK t0, TI_TASK($28) 5561da177e4SLinus Torvalds nop 5575bc05971SMarkos Chandras LOADK t0, THREAD_BUADDR(t0) 5581da177e4SLinus Torvalds1: 559cf62a8b8SMarkos Chandras LOADB(t1, 0(src), .Ll_exc\@) 5601da177e4SLinus Torvalds ADD src, src, 1 5611da177e4SLinus Torvalds sb t1, 0(dst) # can't fault -- we're copy_from_user 562619b6e18SMaciej W. Rozycki .set reorder /* DADDI_WAR */ 5631da177e4SLinus Torvalds ADD dst, dst, 1 564619b6e18SMaciej W. Rozycki bne src, t0, 1b 565619b6e18SMaciej W. Rozycki .set noreorder 566cf62a8b8SMarkos Chandras.Ll_exc\@: 5675bc05971SMarkos Chandras LOADK t0, TI_TASK($28) 5681da177e4SLinus Torvalds nop 5695bc05971SMarkos Chandras LOADK t0, THREAD_BUADDR(t0) # t0 is just past last good address 5701da177e4SLinus Torvalds nop 5711da177e4SLinus Torvalds SUB len, AT, t0 # len number of uncopied bytes 5721da177e4SLinus Torvalds jr ra 5731da177e4SLinus Torvalds nop 5741da177e4SLinus Torvalds 5751da177e4SLinus Torvalds#define SEXC(n) \ 576619b6e18SMaciej W. Rozycki .set reorder; /* DADDI_WAR */ \ 577cf62a8b8SMarkos Chandras.Ls_exc_p ## n ## u\@: \ 578619b6e18SMaciej W. Rozycki ADD len, len, n*NBYTES; \ 5791da177e4SLinus Torvalds jr ra; \ 580619b6e18SMaciej W. Rozycki .set noreorder 5811da177e4SLinus Torvalds 5821da177e4SLinus TorvaldsSEXC(8) 5831da177e4SLinus TorvaldsSEXC(7) 5841da177e4SLinus TorvaldsSEXC(6) 5851da177e4SLinus TorvaldsSEXC(5) 5861da177e4SLinus TorvaldsSEXC(4) 5871da177e4SLinus TorvaldsSEXC(3) 5881da177e4SLinus TorvaldsSEXC(2) 5891da177e4SLinus TorvaldsSEXC(1) 5901da177e4SLinus Torvalds 591cf62a8b8SMarkos Chandras.Ls_exc_p1\@: 592619b6e18SMaciej W. Rozycki .set reorder /* DADDI_WAR */ 5931da177e4SLinus Torvalds ADD len, len, 1 594619b6e18SMaciej W. Rozycki jr ra 595619b6e18SMaciej W. Rozycki .set noreorder 596cf62a8b8SMarkos Chandras.Ls_exc\@: 5971da177e4SLinus Torvalds jr ra 5981da177e4SLinus Torvalds nop 599cf62a8b8SMarkos Chandras .endm 6001da177e4SLinus Torvalds 60178bdbbacSMasahiro Yamada#ifndef CONFIG_HAVE_PLAT_MEMCPY 6021da177e4SLinus Torvalds .align 5 6031da177e4SLinus TorvaldsLEAF(memmove) 604576a2f0cSPaul BurtonEXPORT_SYMBOL(memmove) 6051da177e4SLinus Torvalds ADD t0, a0, a2 6061da177e4SLinus Torvalds ADD t1, a1, a2 6071da177e4SLinus Torvalds sltu t0, a1, t0 # dst + len <= src -> memcpy 6081da177e4SLinus Torvalds sltu t1, a0, t1 # dst >= src + len -> memcpy 6091da177e4SLinus Torvalds and t0, t1 610c5ec1983SRalf Baechle beqz t0, .L__memcpy 6111da177e4SLinus Torvalds move v0, a0 /* return value */ 612c5ec1983SRalf Baechle beqz a2, .Lr_out 6131da177e4SLinus Torvalds END(memmove) 6141da177e4SLinus Torvalds 6151da177e4SLinus Torvalds /* fall through to __rmemcpy */ 6161da177e4SLinus TorvaldsLEAF(__rmemcpy) /* a0=dst a1=src a2=len */ 6171da177e4SLinus Torvalds sltu t0, a1, a0 618c5ec1983SRalf Baechle beqz t0, .Lr_end_bytes_up # src >= dst 6191da177e4SLinus Torvalds nop 6201da177e4SLinus Torvalds ADD a0, a2 # dst = dst + len 6211da177e4SLinus Torvalds ADD a1, a2 # src = src + len 6221da177e4SLinus Torvalds 623c5ec1983SRalf Baechle.Lr_end_bytes: 624930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 6251da177e4SLinus Torvalds lb t0, -1(a1) 6261da177e4SLinus Torvalds SUB a2, a2, 0x1 6271da177e4SLinus Torvalds sb t0, -1(a0) 6281da177e4SLinus Torvalds SUB a1, a1, 0x1 629619b6e18SMaciej W. Rozycki .set reorder /* DADDI_WAR */ 6301da177e4SLinus Torvalds SUB a0, a0, 0x1 631c5ec1983SRalf Baechle bnez a2, .Lr_end_bytes 632619b6e18SMaciej W. Rozycki .set noreorder 6331da177e4SLinus Torvalds 634c5ec1983SRalf Baechle.Lr_out: 6351da177e4SLinus Torvalds jr ra 6361da177e4SLinus Torvalds move a2, zero 6371da177e4SLinus Torvalds 638c5ec1983SRalf Baechle.Lr_end_bytes_up: 639930bff88SThomas Bogendoerfer R10KCBARRIER(0(ra)) 6401da177e4SLinus Torvalds lb t0, (a1) 6411da177e4SLinus Torvalds SUB a2, a2, 0x1 6421da177e4SLinus Torvalds sb t0, (a0) 6431da177e4SLinus Torvalds ADD a1, a1, 0x1 644619b6e18SMaciej W. Rozycki .set reorder /* DADDI_WAR */ 6451da177e4SLinus Torvalds ADD a0, a0, 0x1 646c5ec1983SRalf Baechle bnez a2, .Lr_end_bytes_up 647619b6e18SMaciej W. Rozycki .set noreorder 6481da177e4SLinus Torvalds 6491da177e4SLinus Torvalds jr ra 6501da177e4SLinus Torvalds move a2, zero 6511da177e4SLinus Torvalds END(__rmemcpy) 652cf62a8b8SMarkos Chandras 653cf62a8b8SMarkos Chandras/* 654cf62a8b8SMarkos Chandras * A combined memcpy/__copy_user 655cf62a8b8SMarkos Chandras * __copy_user sets len to 0 for success; else to an upper bound of 656cf62a8b8SMarkos Chandras * the number of uncopied bytes. 657cf62a8b8SMarkos Chandras * memcpy sets v0 to dst. 658cf62a8b8SMarkos Chandras */ 659cf62a8b8SMarkos Chandras .align 5 660cf62a8b8SMarkos ChandrasLEAF(memcpy) /* a0=dst a1=src a2=len */ 661576a2f0cSPaul BurtonEXPORT_SYMBOL(memcpy) 662cf62a8b8SMarkos Chandras move v0, dst /* return value */ 663cf62a8b8SMarkos Chandras.L__memcpy: 66404324f44SThomas Bogendoerfer#ifndef CONFIG_EVA 66504324f44SThomas BogendoerferFEXPORT(__raw_copy_from_user) 66604324f44SThomas BogendoerferEXPORT_SYMBOL(__raw_copy_from_user) 66704324f44SThomas BogendoerferFEXPORT(__raw_copy_to_user) 66804324f44SThomas BogendoerferEXPORT_SYMBOL(__raw_copy_to_user) 66904324f44SThomas Bogendoerfer#endif 670cf62a8b8SMarkos Chandras /* Legacy Mode, user <-> user */ 671cf62a8b8SMarkos Chandras __BUILD_COPY_USER LEGACY_MODE USEROP USEROP 672cd26cb41SMarkos Chandras 67378bdbbacSMasahiro Yamada#endif 67478bdbbacSMasahiro Yamada 675cd26cb41SMarkos Chandras#ifdef CONFIG_EVA 676cd26cb41SMarkos Chandras 677cd26cb41SMarkos Chandras/* 678cd26cb41SMarkos Chandras * For EVA we need distinct symbols for reading and writing to user space. 679cd26cb41SMarkos Chandras * This is because we need to use specific EVA instructions to perform the 680cd26cb41SMarkos Chandras * virtual <-> physical translation when a virtual address is actually in user 681cd26cb41SMarkos Chandras * space 682cd26cb41SMarkos Chandras */ 683cd26cb41SMarkos Chandras 684cd26cb41SMarkos Chandras/* 685cd26cb41SMarkos Chandras * __copy_from_user (EVA) 686cd26cb41SMarkos Chandras */ 687cd26cb41SMarkos Chandras 68804324f44SThomas BogendoerferLEAF(__raw_copy_from_user) 68904324f44SThomas BogendoerferEXPORT_SYMBOL(__raw_copy_from_user) 690cd26cb41SMarkos Chandras __BUILD_COPY_USER EVA_MODE USEROP KERNELOP 69104324f44SThomas BogendoerferEND(__raw_copy_from_user) 692cd26cb41SMarkos Chandras 693cd26cb41SMarkos Chandras 694cd26cb41SMarkos Chandras 695cd26cb41SMarkos Chandras/* 696cd26cb41SMarkos Chandras * __copy_to_user (EVA) 697cd26cb41SMarkos Chandras */ 698cd26cb41SMarkos Chandras 69904324f44SThomas BogendoerferLEAF(__raw_copy_to_user) 70004324f44SThomas BogendoerferEXPORT_SYMBOL(__raw_copy_to_user) 701cd26cb41SMarkos Chandras__BUILD_COPY_USER EVA_MODE KERNELOP USEROP 70204324f44SThomas BogendoerferEND(__raw_copy_to_user) 703cd26cb41SMarkos Chandras 704cd26cb41SMarkos Chandras#endif 705