1373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* 2373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * User address space access functions. 3373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * The non-inlined parts of asm-metag/uaccess.h are here. 4373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 5373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Copyright (C) 2006, Imagination Technologies. 6373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Copyright (C) 2000, Axis Communications AB. 7373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 8373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Written by Hans-Peter Nilsson. 9373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Pieces used from memcpy, originally by Kenny Ranerup long time ago. 10373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Modified for Meta by Will Newton. 11373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 12373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 139da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James Hogan#include <linux/export.h> 14373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#include <linux/uaccess.h> 15373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#include <asm/cache.h> /* def of L1_CACHE_BYTES */ 16373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 17373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define USE_RAPF 18373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define RAPF_MIN_BUF_SIZE (3*L1_CACHE_BYTES) 19373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 20373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 21373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* The "double write" in this code is because the Meta will not fault 22373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * immediately unless the memory pipe is forced to by e.g. a data stall or 23373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * another memory op. The second write should be discarded by the write 24373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * combiner so should have virtually no cost. 25373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 26373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 27373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_user_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 28373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( \ 29373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan COPY \ 30373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" \ 31373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" \ 32373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D1Ar1,#0\n" \ 33373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan FIXUP \ 34373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D1Ar1,#HI(1b)\n" \ 35373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D1Ar1,#LO(1b)\n" \ 36373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 37373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" \ 38373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan TENTRY \ 39373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 40373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (to), "=r" (from), "=r" (ret) \ 41373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "0" (to), "1" (from), "2" (ret) \ 42373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D1Ar1", "memory") 43373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 44373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 45373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_1(to, from, ret) \ 46373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_cont(to, from, ret, \ 47373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 48373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 49373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETB [%0++],D1Ar1\n", \ 50373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %2,%2,#1\n", \ 51373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n") 52373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 53373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 54373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_cont(to, from, ret, \ 55373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW D1Ar1,[%1++]\n" \ 56373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0],D1Ar1\n" \ 57373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETW [%0++],D1Ar1\n" COPY, \ 58373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %2,%2,#2\n" FIXUP, \ 59373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n" TENTRY) 60373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 61373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_2(to, from, ret) \ 62373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_2x_cont(to, from, ret, "", "", "") 63373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 64373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_3(to, from, ret) \ 65373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_2x_cont(to, from, ret, \ 66373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 67373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 68373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETB [%0++],D1Ar1\n", \ 69373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %2,%2,#1\n", \ 70373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n") 71373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 72373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 73373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_cont(to, from, ret, \ 74373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD D1Ar1,[%1++]\n" \ 75373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0],D1Ar1\n" \ 76373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETD [%0++],D1Ar1\n" COPY, \ 77373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %2,%2,#4\n" FIXUP, \ 78373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n" TENTRY) 79373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 80373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_4(to, from, ret) \ 81373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_4x_cont(to, from, ret, "", "", "") 82373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 83373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_5(to, from, ret) \ 84373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_4x_cont(to, from, ret, \ 85373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 86373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 87373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETB [%0++],D1Ar1\n", \ 88373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %2,%2,#1\n", \ 89373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n") 90373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 91373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 92373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_4x_cont(to, from, ret, \ 93373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW D1Ar1,[%1++]\n" \ 94373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0],D1Ar1\n" \ 95373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETW [%0++],D1Ar1\n" COPY, \ 96373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %2,%2,#2\n" FIXUP, \ 97373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n" TENTRY) 98373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 99373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_6(to, from, ret) \ 100373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_6x_cont(to, from, ret, "", "", "") 101373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 102373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_7(to, from, ret) \ 103373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_6x_cont(to, from, ret, \ 104373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 105373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 106373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETB [%0++],D1Ar1\n", \ 107373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %2,%2,#1\n", \ 108373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n") 109373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 110373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 111373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_4x_cont(to, from, ret, \ 112373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD D1Ar1,[%1++]\n" \ 113373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0],D1Ar1\n" \ 114373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETD [%0++],D1Ar1\n" COPY, \ 115373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %2,%2,#4\n" FIXUP, \ 116373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n" TENTRY) 117373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 118373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_8(to, from, ret) \ 119373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_8x_cont(to, from, ret, "", "", "") 120373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 121373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_9(to, from, ret) \ 122373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_8x_cont(to, from, ret, \ 123373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 124373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 125373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETB [%0++],D1Ar1\n", \ 126373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %2,%2,#1\n", \ 127373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n") 128373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 129373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 130373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_8x_cont(to, from, ret, \ 131373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW D1Ar1,[%1++]\n" \ 132373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0],D1Ar1\n" \ 133373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETW [%0++],D1Ar1\n" COPY, \ 134373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %2,%2,#2\n" FIXUP, \ 135373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n" TENTRY) 136373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 137373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_10(to, from, ret) \ 138373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_10x_cont(to, from, ret, "", "", "") 139373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 140373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_11(to, from, ret) \ 141373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_10x_cont(to, from, ret, \ 142373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 143373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 144373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETB [%0++],D1Ar1\n", \ 145373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %2,%2,#1\n", \ 146373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n") 147373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 148373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 149373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_8x_cont(to, from, ret, \ 150373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD D1Ar1,[%1++]\n" \ 151373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0],D1Ar1\n" \ 152373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETD [%0++],D1Ar1\n" COPY, \ 153373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %2,%2,#4\n" FIXUP, \ 154373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n" TENTRY) 155373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_12(to, from, ret) \ 156373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_12x_cont(to, from, ret, "", "", "") 157373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 158373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_13(to, from, ret) \ 159373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_12x_cont(to, from, ret, \ 160373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 161373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 162373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETB [%0++],D1Ar1\n", \ 163373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %2,%2,#1\n", \ 164373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n") 165373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 166373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 167373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_12x_cont(to, from, ret, \ 168373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW D1Ar1,[%1++]\n" \ 169373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0],D1Ar1\n" \ 170373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETW [%0++],D1Ar1\n" COPY, \ 171373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %2,%2,#2\n" FIXUP, \ 172373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n" TENTRY) 173373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 174373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_14(to, from, ret) \ 175373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_14x_cont(to, from, ret, "", "", "") 176373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 177373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_15(to, from, ret) \ 178373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_14x_cont(to, from, ret, \ 179373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 180373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 181373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "10: SETB [%0++],D1Ar1\n", \ 182373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "11: ADD %2,%2,#1\n", \ 183373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 10b,11b\n") 184373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 185373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 186373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_12x_cont(to, from, ret, \ 187373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD D1Ar1,[%1++]\n" \ 188373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0],D1Ar1\n" \ 189373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETD [%0++],D1Ar1\n" COPY, \ 190373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %2,%2,#4\n" FIXUP, \ 191373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n" TENTRY) 192373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 193373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_16(to, from, ret) \ 194373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_16x_cont(to, from, ret, "", "", "") 195373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 196373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_8x64(to, from, ret) \ 197373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( \ 198373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETL D0Ar2,D1Ar1,[%1++]\n" \ 199373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETL [%0],D0Ar2,D1Ar1\n" \ 200373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETL [%0++],D0Ar2,D1Ar1\n" \ 201373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" \ 202373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" \ 203373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %2,%2,#8\n" \ 204373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0Ar2,#HI(1b)\n" \ 205373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0Ar2,#LO(1b)\n" \ 206373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 207373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" \ 208373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n" \ 209373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 210373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (to), "=r" (from), "=r" (ret) \ 211373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "0" (to), "1" (from), "2" (ret) \ 212373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D1Ar1", "D0Ar2", "memory") 213373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 214373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* 215373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * optimized copying loop using RAPF when 64 bit aligned 216373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 217373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * n will be automatically decremented inside the loop 218373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * ret will be left intact. if error occurs we will rewind 219373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * so that the original non optimized code will fill up 220373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * this value correctly. 221373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 222373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * on fault: 223373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * > n will hold total number of uncopied bytes 224373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 225373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * > {'to','from'} will be rewind back so that 226373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * the non-optimized code will do the proper fix up 227373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 228373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * DCACHE drops the cacheline which helps in reducing cache 229373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * pollution. 230373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 231373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * We introduce an extra SETL at the end of the loop to 232373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * ensure we don't fall off the loop before we catch all 233373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * erros. 234373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 235373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * NOTICE: 236373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * LSM_STEP in TXSTATUS must be cleared in fix up code. 237373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * since we're using M{S,G}ETL, a fault might happen at 238373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * any address in the middle of M{S,G}ETL causing 239373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * the value of LSM_STEP to be incorrect which can 240373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * cause subsequent use of M{S,G}ET{L,D} to go wrong. 241373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * ie: if LSM_STEP was 1 when a fault occurs, the 242373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * next call to M{S,G}ET{L,D} will skip the first 243373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * copy/getting as it think that the first 1 has already 244373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * been done. 245373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 246373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 247373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_user_64bit_rapf_loop( \ 248373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan to, from, ret, n, id, FIXUP) \ 249373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( \ 250373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".balign 8\n" \ 251373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV RAPF, %1\n" \ 252373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETL [A0StP++], D0Ar6, D0FrT, D0.5, D0.6, D0.7\n" \ 253373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV D0Ar6, #0\n" \ 254373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "LSR D1Ar5, %3, #6\n" \ 255373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB TXRPT, D1Ar5, #2\n" \ 256373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV RAPF, %1\n" \ 257373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "$Lloop"id":\n" \ 258373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "ADD RAPF, %1, #64\n" \ 259373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "21:\n" \ 260373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 261373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "22:\n" \ 262373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 263373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #32\n" \ 264373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "23:\n" \ 265373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 266373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "24:\n" \ 267373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 268373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #32\n" \ 269373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "DCACHE [%1+#-64], D0Ar6\n" \ 270373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "BR $Lloop"id"\n" \ 271373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan \ 272373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV RAPF, %1\n" \ 273373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "25:\n" \ 274373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 275373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "26:\n" \ 276373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 277373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #32\n" \ 278373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "27:\n" \ 279373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 280373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "28:\n" \ 281373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 282373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %0, %0, #8\n" \ 283373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "29:\n" \ 284373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SETL [%0++], D0.7, D1.7\n" \ 285373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #32\n" \ 286373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:" \ 287373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "DCACHE [%1+#-64], D0Ar6\n" \ 288373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0Ar6, D1Ar5, [A0StP+#-40]\n" \ 289373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0FrT, D1RtP, [A0StP+#-32]\n" \ 290373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0.5, D1.5, [A0StP+#-24]\n" \ 291373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0.6, D1.6, [A0StP+#-16]\n" \ 292373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0.7, D1.7, [A0StP+#-8]\n" \ 293373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB A0StP, A0StP, #40\n" \ 294373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" \ 295373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4:\n" \ 296373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " ADD %0, %0, #8\n" \ 297373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3:\n" \ 298373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D0Ar2, TXSTATUS\n" \ 299373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D1Ar1, TXSTATUS\n" \ 300373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " AND D1Ar1, D1Ar1, #0xFFFFF8FF\n" \ 301373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV TXSTATUS, D1Ar1\n" \ 302373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan FIXUP \ 303373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0Ar2,#HI(1b)\n" \ 304373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0Ar2,#LO(1b)\n" \ 305373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 306373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" \ 307373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 21b,3b\n" \ 308373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 22b,3b\n" \ 309373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 23b,3b\n" \ 310373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 24b,3b\n" \ 311373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 25b,3b\n" \ 312373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 26b,3b\n" \ 313373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 27b,3b\n" \ 314373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 28b,3b\n" \ 315373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 29b,4b\n" \ 316373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 317373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ 318373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "0" (to), "1" (from), "2" (ret), "3" (n) \ 319373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D1Ar1", "D0Ar2", "memory") 320373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 321373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* rewind 'to' and 'from' pointers when a fault occurs 322373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 323373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Rationale: 324373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * A fault always occurs on writing to user buffer. A fault 325373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * is at a single address, so we need to rewind by only 4 326373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * bytes. 327373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Since we do a complete read from kernel buffer before 328373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * writing, we need to rewind it also. The amount to be 329373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * rewind equals the number of faulty writes in MSETD 330373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * which is: [4 - (LSM_STEP-1)]*8 331373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * LSM_STEP is bits 10:8 in TXSTATUS which is already read 332373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * and stored in D0Ar2 333373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 334373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * NOTE: If a fault occurs at the last operation in M{G,S}ETL 335373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * LSM_STEP will be 0. ie: we do 4 writes in our case, if 336373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * a fault happens at the 4th write, LSM_STEP will be 0 337373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * instead of 4. The code copes with that. 338373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 339373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * n is updated by the number of successful writes, which is: 340373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * n = n - (LSM_STEP-1)*8 341373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 342373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ 343373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ 344373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "LSR D0Ar2, D0Ar2, #8\n" \ 345373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "AND D0Ar2, D0Ar2, #0x7\n" \ 346373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "ADDZ D0Ar2, D0Ar2, #4\n" \ 347373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB D0Ar2, D0Ar2, #1\n" \ 348373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV D1Ar1, #4\n" \ 349373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB D0Ar2, D1Ar1, D0Ar2\n" \ 350373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "LSL D0Ar2, D0Ar2, #3\n" \ 351373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "LSL D1Ar1, D1Ar1, #3\n" \ 352373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB D1Ar1, D1Ar1, D0Ar2\n" \ 353373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %0, %0, #8\n" \ 354373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %1, %1,D0Ar2\n" \ 355373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, D1Ar1\n") 356373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 357373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* 358373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * optimized copying loop using RAPF when 32 bit aligned 359373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 360373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * n will be automatically decremented inside the loop 361373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * ret will be left intact. if error occurs we will rewind 362373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * so that the original non optimized code will fill up 363373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * this value correctly. 364373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 365373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * on fault: 366373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * > n will hold total number of uncopied bytes 367373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 368373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * > {'to','from'} will be rewind back so that 369373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * the non-optimized code will do the proper fix up 370373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 371373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * DCACHE drops the cacheline which helps in reducing cache 372373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * pollution. 373373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 374373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * We introduce an extra SETD at the end of the loop to 375373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * ensure we don't fall off the loop before we catch all 376373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * erros. 377373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 378373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * NOTICE: 379373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * LSM_STEP in TXSTATUS must be cleared in fix up code. 380373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * since we're using M{S,G}ETL, a fault might happen at 381373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * any address in the middle of M{S,G}ETL causing 382373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * the value of LSM_STEP to be incorrect which can 383373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * cause subsequent use of M{S,G}ET{L,D} to go wrong. 384373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * ie: if LSM_STEP was 1 when a fault occurs, the 385373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * next call to M{S,G}ET{L,D} will skip the first 386373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * copy/getting as it think that the first 1 has already 387373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * been done. 388373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 389373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 390373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_user_32bit_rapf_loop( \ 391373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan to, from, ret, n, id, FIXUP) \ 392373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( \ 393373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".balign 8\n" \ 394373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV RAPF, %1\n" \ 395373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETL [A0StP++], D0Ar6, D0FrT, D0.5, D0.6, D0.7\n" \ 396373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV D0Ar6, #0\n" \ 397373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "LSR D1Ar5, %3, #6\n" \ 398373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB TXRPT, D1Ar5, #2\n" \ 399373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV RAPF, %1\n" \ 400373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "$Lloop"id":\n" \ 401373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "ADD RAPF, %1, #64\n" \ 402373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "21:\n" \ 403373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 404373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "22:\n" \ 405373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 406373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #16\n" \ 407373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "23:\n" \ 408373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 409373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "24:\n" \ 410373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 411373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #16\n" \ 412373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "25:\n" \ 413373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 414373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "26:\n" \ 415373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 416373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #16\n" \ 417373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "27:\n" \ 418373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 419373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "28:\n" \ 420373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 421373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #16\n" \ 422373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "DCACHE [%1+#-64], D0Ar6\n" \ 423373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "BR $Lloop"id"\n" \ 424373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan \ 425373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV RAPF, %1\n" \ 426373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "29:\n" \ 427373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 428373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "30:\n" \ 429373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 430373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #16\n" \ 431373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "31:\n" \ 432373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 433373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "32:\n" \ 434373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 435373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #16\n" \ 436373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "33:\n" \ 437373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 438373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "34:\n" \ 439373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 440373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #16\n" \ 441373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "35:\n" \ 442373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ 443373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "36:\n" \ 444373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ 445373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %0, %0, #4\n" \ 446373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "37:\n" \ 447373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SETD [%0++], D0.7\n" \ 448373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, #16\n" \ 449373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:" \ 450373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "DCACHE [%1+#-64], D0Ar6\n" \ 451373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0Ar6, D1Ar5, [A0StP+#-40]\n" \ 452373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0FrT, D1RtP, [A0StP+#-32]\n" \ 453373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0.5, D1.5, [A0StP+#-24]\n" \ 454373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0.6, D1.6, [A0StP+#-16]\n" \ 455373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "GETL D0.7, D1.7, [A0StP+#-8]\n" \ 456373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB A0StP, A0StP, #40\n" \ 457373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" \ 458373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4:\n" \ 459373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " ADD %0, %0, #4\n" \ 460373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3:\n" \ 461373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D0Ar2, TXSTATUS\n" \ 462373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D1Ar1, TXSTATUS\n" \ 463373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " AND D1Ar1, D1Ar1, #0xFFFFF8FF\n" \ 464373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV TXSTATUS, D1Ar1\n" \ 465373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan FIXUP \ 466373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0Ar2,#HI(1b)\n" \ 467373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0Ar2,#LO(1b)\n" \ 468373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 469373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" \ 470373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 21b,3b\n" \ 471373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 22b,3b\n" \ 472373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 23b,3b\n" \ 473373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 24b,3b\n" \ 474373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 25b,3b\n" \ 475373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 26b,3b\n" \ 476373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 27b,3b\n" \ 477373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 28b,3b\n" \ 478373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 29b,3b\n" \ 479373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 30b,3b\n" \ 480373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 31b,3b\n" \ 481373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 32b,3b\n" \ 482373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 33b,3b\n" \ 483373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 34b,3b\n" \ 484373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 35b,3b\n" \ 485373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 36b,3b\n" \ 486373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 37b,4b\n" \ 487373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 488373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ 489373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "0" (to), "1" (from), "2" (ret), "3" (n) \ 490373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D1Ar1", "D0Ar2", "memory") 491373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 492373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* rewind 'to' and 'from' pointers when a fault occurs 493373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 494373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Rationale: 495373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * A fault always occurs on writing to user buffer. A fault 496373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * is at a single address, so we need to rewind by only 4 497373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * bytes. 498373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Since we do a complete read from kernel buffer before 499373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * writing, we need to rewind it also. The amount to be 500373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * rewind equals the number of faulty writes in MSETD 501373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * which is: [4 - (LSM_STEP-1)]*4 502373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * LSM_STEP is bits 10:8 in TXSTATUS which is already read 503373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * and stored in D0Ar2 504373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 505373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * NOTE: If a fault occurs at the last operation in M{G,S}ETL 506373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * LSM_STEP will be 0. ie: we do 4 writes in our case, if 507373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * a fault happens at the 4th write, LSM_STEP will be 0 508373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * instead of 4. The code copes with that. 509373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 510373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * n is updated by the number of successful writes, which is: 511373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * n = n - (LSM_STEP-1)*4 512373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 513373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ 514373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ 515373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "LSR D0Ar2, D0Ar2, #8\n" \ 516373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "AND D0Ar2, D0Ar2, #0x7\n" \ 517373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "ADDZ D0Ar2, D0Ar2, #4\n" \ 518373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB D0Ar2, D0Ar2, #1\n" \ 519373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "MOV D1Ar1, #4\n" \ 520373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB D0Ar2, D1Ar1, D0Ar2\n" \ 521373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "LSL D0Ar2, D0Ar2, #2\n" \ 522373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "LSL D1Ar1, D1Ar1, #2\n" \ 523373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB D1Ar1, D1Ar1, D0Ar2\n" \ 524373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %0, %0, #4\n" \ 525373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %1, %1, D0Ar2\n" \ 526373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %3, %3, D1Ar1\n") 527373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 528373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganunsigned long __copy_user(void __user *pdst, const void *psrc, 529373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan unsigned long n) 530373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 531373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register char __user *dst asm ("A0.2") = pdst; 532373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register const char *src asm ("A1.2") = psrc; 533373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan unsigned long retn = 0; 534373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 535373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (n == 0) 536373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return 0; 537373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 538373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if ((unsigned long) src & 1) { 539373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_1(dst, src, retn); 540373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n--; 541373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 542373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if ((unsigned long) dst & 1) { 543373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* Worst case - byte copy */ 544373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n > 0) { 545373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_1(dst, src, retn); 546373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n--; 547373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 548373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 549373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (((unsigned long) src & 2) && n >= 2) { 550373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_2(dst, src, retn); 551373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 2; 552373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 553373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if ((unsigned long) dst & 2) { 554373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* Second worst case - word copy */ 555373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 2) { 556373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_2(dst, src, retn); 557373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 2; 558373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 559373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 560373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 561373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#ifdef USE_RAPF 562373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* 64 bit copy loop */ 563373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (!(((unsigned long) src | (__force unsigned long) dst) & 7)) { 564373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (n >= RAPF_MIN_BUF_SIZE) { 565373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* copy user using 64 bit rapf copy */ 566373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_64bit_rapf_loop(dst, src, retn, 567373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n, "64cu"); 568373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 569373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 8) { 570373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_8x64(dst, src, retn); 571373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 8; 572373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 573373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 574373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (n >= RAPF_MIN_BUF_SIZE) { 575373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* copy user using 32 bit rapf copy */ 576373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_32bit_rapf_loop(dst, src, retn, n, "32cu"); 577373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 578373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#else 579373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* 64 bit copy loop */ 580373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (!(((unsigned long) src | (__force unsigned long) dst) & 7)) { 581373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 8) { 582373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_8x64(dst, src, retn); 583373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 8; 584373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 585373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 586373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#endif 587373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 588373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 16) { 589373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_16(dst, src, retn); 590373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 16; 591373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 592373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 593373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 4) { 594373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_4(dst, src, retn); 595373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 4; 596373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 597373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 598373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan switch (n) { 599373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 0: 600373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 601373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 1: 602373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_1(dst, src, retn); 603373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 604373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 2: 605373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_2(dst, src, retn); 606373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 607373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 3: 608373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_to_user_3(dst, src, retn); 609373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 610373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 611373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 612373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return retn; 613373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 6149da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__copy_user); 615373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 616373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_1(to, from, ret) \ 617373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_cont(to, from, ret, \ 618373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 619373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETB [%0++],D1Ar1\n", \ 620373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %2,%2,#1\n" \ 621373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0++],D1Ar1\n", \ 622373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n") 623373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 624373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 625373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_cont(to, from, ret, \ 626373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW D1Ar1,[%1++]\n" \ 627373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETW [%0++],D1Ar1\n" COPY, \ 628373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %2,%2,#2\n" \ 629373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0++],D1Ar1\n" FIXUP, \ 630373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n" TENTRY) 631373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 632373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_2(to, from, ret) \ 633373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_2x_cont(to, from, ret, "", "", "") 634373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 635373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_3(to, from, ret) \ 636373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_2x_cont(to, from, ret, \ 637373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 638373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETB [%0++],D1Ar1\n", \ 639373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %2,%2,#1\n" \ 640373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0++],D1Ar1\n", \ 641373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n") 642373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 643373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 644373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_cont(to, from, ret, \ 645373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD D1Ar1,[%1++]\n" \ 646373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETD [%0++],D1Ar1\n" COPY, \ 647373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %2,%2,#4\n" \ 648373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0++],D1Ar1\n" FIXUP, \ 649373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n" TENTRY) 650373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 651373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_4(to, from, ret) \ 652373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") 653373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 654373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_5(to, from, ret) \ 655373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_4x_cont(to, from, ret, \ 656373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 657373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETB [%0++],D1Ar1\n", \ 658373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %2,%2,#1\n" \ 659373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0++],D1Ar1\n", \ 660373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n") 661373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 662373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 663373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_4x_cont(to, from, ret, \ 664373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW D1Ar1,[%1++]\n" \ 665373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETW [%0++],D1Ar1\n" COPY, \ 666373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %2,%2,#2\n" \ 667373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0++],D1Ar1\n" FIXUP, \ 668373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n" TENTRY) 669373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 670373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_6(to, from, ret) \ 671373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") 672373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 673373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_7(to, from, ret) \ 674373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_6x_cont(to, from, ret, \ 675373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 676373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETB [%0++],D1Ar1\n", \ 677373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %2,%2,#1\n" \ 678373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0++],D1Ar1\n", \ 679373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n") 680373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 681373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 682373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_4x_cont(to, from, ret, \ 683373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD D1Ar1,[%1++]\n" \ 684373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETD [%0++],D1Ar1\n" COPY, \ 685373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %2,%2,#4\n" \ 686373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0++],D1Ar1\n" FIXUP, \ 687373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n" TENTRY) 688373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 689373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_8(to, from, ret) \ 690373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") 691373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 692373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_9(to, from, ret) \ 693373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_8x_cont(to, from, ret, \ 694373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 695373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETB [%0++],D1Ar1\n", \ 696373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %2,%2,#1\n" \ 697373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0++],D1Ar1\n", \ 698373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n") 699373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 700373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 701373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_8x_cont(to, from, ret, \ 702373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW D1Ar1,[%1++]\n" \ 703373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETW [%0++],D1Ar1\n" COPY, \ 704373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %2,%2,#2\n" \ 705373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0++],D1Ar1\n" FIXUP, \ 706373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n" TENTRY) 707373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 708373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_10(to, from, ret) \ 709373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") 710373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 711373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_11(to, from, ret) \ 712373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_10x_cont(to, from, ret, \ 713373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 714373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETB [%0++],D1Ar1\n", \ 715373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %2,%2,#1\n" \ 716373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0++],D1Ar1\n", \ 717373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n") 718373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 719373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 720373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_8x_cont(to, from, ret, \ 721373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD D1Ar1,[%1++]\n" \ 722373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETD [%0++],D1Ar1\n" COPY, \ 723373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %2,%2,#4\n" \ 724373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0++],D1Ar1\n" FIXUP, \ 725373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n" TENTRY) 726373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 727373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_12(to, from, ret) \ 728373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") 729373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 730373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_13(to, from, ret) \ 731373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_12x_cont(to, from, ret, \ 732373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 733373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETB [%0++],D1Ar1\n", \ 734373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %2,%2,#1\n" \ 735373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0++],D1Ar1\n", \ 736373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n") 737373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 738373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 739373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_12x_cont(to, from, ret, \ 740373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW D1Ar1,[%1++]\n" \ 741373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETW [%0++],D1Ar1\n" COPY, \ 742373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %2,%2,#2\n" \ 743373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0++],D1Ar1\n" FIXUP, \ 744373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n" TENTRY) 745373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 746373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_14(to, from, ret) \ 747373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") 748373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 749373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_15(to, from, ret) \ 750373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_14x_cont(to, from, ret, \ 751373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D1Ar1,[%1++]\n" \ 752373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "10: SETB [%0++],D1Ar1\n", \ 753373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "11: ADD %2,%2,#1\n" \ 754373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0++],D1Ar1\n", \ 755373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 10b,11b\n") 756373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 757373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ 758373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_12x_cont(to, from, ret, \ 759373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD D1Ar1,[%1++]\n" \ 760373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETD [%0++],D1Ar1\n" COPY, \ 761373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %2,%2,#4\n" \ 762373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0++],D1Ar1\n" FIXUP, \ 763373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n" TENTRY) 764373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 765373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_16(to, from, ret) \ 766373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") 767373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 768373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_8x64(to, from, ret) \ 769373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( \ 770373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETL D0Ar2,D1Ar1,[%1++]\n" \ 771373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETL [%0++],D0Ar2,D1Ar1\n" \ 772373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" \ 773373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" \ 774373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D1Ar1,#0\n" \ 775373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D0Ar2,#0\n" \ 776373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %2,%2,#8\n" \ 777373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETL [%0++],D0Ar2,D1Ar1\n" \ 778373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0Ar2,#HI(1b)\n" \ 779373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0Ar2,#LO(1b)\n" \ 780373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 781373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" \ 782373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n" \ 783373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 784373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=a" (to), "=r" (from), "=r" (ret) \ 785373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "0" (to), "1" (from), "2" (ret) \ 786373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D1Ar1", "D0Ar2", "memory") 787373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 788373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* rewind 'from' pointer when a fault occurs 789373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 790373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Rationale: 791373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * A fault occurs while reading from user buffer, which is the 792373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * source. Since the fault is at a single address, we only 793373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * need to rewind by 8 bytes. 794373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Since we don't write to kernel buffer until we read first, 795373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * the kernel buffer is at the right state and needn't be 796373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * corrected. 797373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 798373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \ 799373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ 800373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %1, %1, #8\n") 801373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 802373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* rewind 'from' pointer when a fault occurs 803373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 804373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Rationale: 805373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * A fault occurs while reading from user buffer, which is the 806373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * source. Since the fault is at a single address, we only 807373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * need to rewind by 4 bytes. 808373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Since we don't write to kernel buffer until we read first, 809373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * the kernel buffer is at the right state and needn't be 810373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * corrected. 811373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 812373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \ 813373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ 814373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "SUB %1, %1, #4\n") 815373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 816373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 817373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* Copy from user to kernel, zeroing the bytes that were inaccessible in 818373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan userland. The return-value is the number of bytes that were 819373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan inaccessible. */ 820373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganunsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, 821373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan unsigned long n) 822373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 823373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register char *dst asm ("A0.2") = pdst; 824373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register const char __user *src asm ("A1.2") = psrc; 825373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan unsigned long retn = 0; 826373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 827373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (n == 0) 828373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return 0; 829373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 830373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if ((unsigned long) src & 1) { 831373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_1(dst, src, retn); 832373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n--; 833373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 834373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if ((unsigned long) dst & 1) { 835373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* Worst case - byte copy */ 836373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n > 0) { 837373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_1(dst, src, retn); 838373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n--; 839373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (retn) 840373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan goto copy_exception_bytes; 841373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 842373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 843373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (((unsigned long) src & 2) && n >= 2) { 844373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_2(dst, src, retn); 845373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 2; 846373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 847373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if ((unsigned long) dst & 2) { 848373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* Second worst case - word copy */ 849373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 2) { 850373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_2(dst, src, retn); 851373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 2; 852373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (retn) 853373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan goto copy_exception_bytes; 854373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 855373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 856373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 857373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* We only need one check after the unalignment-adjustments, 858373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan because if both adjustments were done, either both or 859373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan neither reference had an exception. */ 860373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (retn != 0) 861373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan goto copy_exception_bytes; 862373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 863373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#ifdef USE_RAPF 864373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* 64 bit copy loop */ 865373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (!(((unsigned long) src | (unsigned long) dst) & 7)) { 866373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (n >= RAPF_MIN_BUF_SIZE) { 867373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* Copy using fast 64bit rapf */ 868373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_64bit_rapf_loop(dst, src, retn, 869373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n, "64cuz"); 870373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 871373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 8) { 872373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_8x64(dst, src, retn); 873373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 8; 874373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (retn) 875373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan goto copy_exception_bytes; 876373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 877373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 878373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 879373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (n >= RAPF_MIN_BUF_SIZE) { 880373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* Copy using fast 32bit rapf */ 881373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_32bit_rapf_loop(dst, src, retn, 882373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n, "32cuz"); 883373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 884373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#else 885373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* 64 bit copy loop */ 886373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (!(((unsigned long) src | (unsigned long) dst) & 7)) { 887373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 8) { 888373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_8x64(dst, src, retn); 889373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 8; 890373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (retn) 891373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan goto copy_exception_bytes; 892373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 893373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 894373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#endif 895373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 896373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 4) { 897373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_4(dst, src, retn); 898373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 4; 899373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 900373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (retn) 901373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan goto copy_exception_bytes; 902373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 903373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 904373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* If we get here, there were no memory read faults. */ 905373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan switch (n) { 906373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* These copies are at least "naturally aligned" (so we don't 907373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan have to check each byte), due to the src alignment code. 908373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan The *_3 case *will* get the correct count for retn. */ 909373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 0: 910373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* This case deliberately left in (if you have doubts check the 911373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan generated assembly code). */ 912373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 913373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 1: 914373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_1(dst, src, retn); 915373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 916373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 2: 917373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_2(dst, src, retn); 918373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 919373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 3: 920373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_copy_from_user_3(dst, src, retn); 921373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 922373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 923373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 924373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* If we get here, retn correctly reflects the number of failing 925373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan bytes. */ 926373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return retn; 927373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 928373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan copy_exception_bytes: 929373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* We already have "retn" bytes cleared, and need to clear the 930373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan remaining "n" bytes. A non-optimized simple byte-for-byte in-line 931373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan memset is preferred here, since this isn't speed-critical code and 932373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan we'd rather have this a leaf-function than calling memset. */ 933373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan { 934373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan char *endp; 935373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan for (endp = dst + n; dst < endp; dst++) 936373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan *dst = 0; 937373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 938373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 939373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return retn + n; 940373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 9419da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__copy_user_zeroing); 942373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 943373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_8x64(to, ret) \ 944373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( \ 945373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D0Ar2,#0\n" \ 946373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D1Ar1,#0\n" \ 947373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETL [%0],D0Ar2,D1Ar1\n" \ 948373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETL [%0++],D0Ar2,D1Ar1\n" \ 949373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" \ 950373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" \ 951373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %1,%1,#8\n" \ 952373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0Ar2,#HI(1b)\n" \ 953373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0Ar2,#LO(1b)\n" \ 954373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 955373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" \ 956373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n" \ 957373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 958373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (to), "=r" (ret) \ 959373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "0" (to), "1" (ret) \ 960373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D1Ar1", "D0Ar2", "memory") 961373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 962373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan/* Zero userspace. */ 963373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 964373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear(to, ret, CLEAR, FIXUP, TENTRY) \ 965373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( \ 966373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D1Ar1,#0\n" \ 967373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan CLEAR \ 968373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" \ 969373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" \ 970373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan FIXUP \ 971373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D1Ar1,#HI(1b)\n" \ 972373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D1Ar1,#LO(1b)\n" \ 973373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" \ 974373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" \ 975373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan TENTRY \ 976373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous" \ 977373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (to), "=r" (ret) \ 978373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "0" (to), "1" (ret) \ 979373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D1Ar1", "memory") 980373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 981373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_1(to, ret) \ 982373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear(to, ret, \ 983373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 984373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETB [%0++],D1Ar1\n", \ 985373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %1,%1,#1\n", \ 986373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n") 987373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 988373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_2(to, ret) \ 989373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear(to, ret, \ 990373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%0],D1Ar1\n" \ 991373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETW [%0++],D1Ar1\n", \ 992373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %1,%1,#2\n", \ 993373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n") 994373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 995373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_3(to, ret) \ 996373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear(to, ret, \ 997373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETW [%0++],D1Ar1\n" \ 998373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%0],D1Ar1\n" \ 999373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: SETB [%0++],D1Ar1\n", \ 1000373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: ADD %1,%1,#2\n" \ 1001373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %1,%1,#1\n", \ 1002373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,4b\n" \ 1003373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 3b,5b\n") 1004373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1005373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_4x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ 1006373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear(to, ret, \ 1007373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0],D1Ar1\n" \ 1008373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2: SETD [%0++],D1Ar1\n" CLEAR, \ 1009373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: ADD %1,%1,#4\n" FIXUP, \ 1010373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,3b\n" TENTRY) 1011373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1012373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_4(to, ret) \ 1013373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_4x_cont(to, ret, "", "", "") 1014373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1015373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_8x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ 1016373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_4x_cont(to, ret, \ 1017373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0],D1Ar1\n" \ 1018373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4: SETD [%0++],D1Ar1\n" CLEAR, \ 1019373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5: ADD %1,%1,#4\n" FIXUP, \ 1020373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 4b,5b\n" TENTRY) 1021373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1022373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_8(to, ret) \ 1023373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_8x_cont(to, ret, "", "", "") 1024373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1025373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_12x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ 1026373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_8x_cont(to, ret, \ 1027373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0],D1Ar1\n" \ 1028373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "6: SETD [%0++],D1Ar1\n" CLEAR, \ 1029373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "7: ADD %1,%1,#4\n" FIXUP, \ 1030373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 6b,7b\n" TENTRY) 1031373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1032373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_12(to, ret) \ 1033373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_12x_cont(to, ret, "", "", "") 1034373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1035373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_16x_cont(to, ret, CLEAR, FIXUP, TENTRY) \ 1036373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_12x_cont(to, ret, \ 1037373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%0],D1Ar1\n" \ 1038373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "8: SETD [%0++],D1Ar1\n" CLEAR, \ 1039373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "9: ADD %1,%1,#4\n" FIXUP, \ 1040373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 8b,9b\n" TENTRY) 1041373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1042373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan#define __asm_clear_16(to, ret) \ 1043373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_16x_cont(to, ret, "", "", "") 1044373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1045373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganunsigned long __do_clear_user(void __user *pto, unsigned long pn) 1046373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1047373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register char __user *dst asm ("D0Re0") = pto; 1048373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned long n asm ("D1Re0") = pn; 1049373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned long retn asm ("D0Ar6") = 0; 1050373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1051373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if ((unsigned long) dst & 1) { 1052373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_1(dst, retn); 1053373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n--; 1054373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 1055373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1056373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if ((unsigned long) dst & 2) { 1057373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_2(dst, retn); 1058373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 2; 1059373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 1060373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1061373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* 64 bit copy loop */ 1062373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (!((__force unsigned long) dst & 7)) { 1063373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 8) { 1064373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_8x64(dst, retn); 1065373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 8; 1066373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 1067373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 1068373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1069373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 16) { 1070373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_16(dst, retn); 1071373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 16; 1072373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 1073373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1074373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan while (n >= 4) { 1075373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_4(dst, retn); 1076373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan n -= 4; 1077373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 1078373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1079373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan switch (n) { 1080373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 0: 1081373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 1082373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 1: 1083373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_1(dst, retn); 1084373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 1085373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 2: 1086373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_2(dst, retn); 1087373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 1088373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan case 3: 1089373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan __asm_clear_3(dst, retn); 1090373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan break; 1091373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan } 1092373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1093373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return retn; 1094373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 10959da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__do_clear_user); 1096373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1097373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganunsigned char __get_user_asm_b(const void __user *addr, long *err) 1098373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1099373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned char x asm ("D0Re0") = 0; 1100373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( 1101373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB %0,[%2]\n" 1102373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1103373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB %0,[%2]\n" 1104373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1105373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" 1106373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: MOV D0FrT,%3\n" 1107373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%1],D0FrT\n" 1108373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(2b)\n" 1109373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(2b)\n" 1110373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1111373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" 1112373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 1b,3b\n" 1113373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1114373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (x) 1115373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "r" (err), "r" (addr), "P" (-EFAULT) 1116373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT"); 1117373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return x; 1118373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 11199da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__get_user_asm_b); 1120373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1121373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganunsigned short __get_user_asm_w(const void __user *addr, long *err) 1122373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1123373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned short x asm ("D0Re0") = 0; 1124373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( 1125373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW %0,[%2]\n" 1126373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1127373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETW %0,[%2]\n" 1128373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1129373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" 1130373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: MOV D0FrT,%3\n" 1131373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%1],D0FrT\n" 1132373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(2b)\n" 1133373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(2b)\n" 1134373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1135373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" 1136373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 1b,3b\n" 1137373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1138373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (x) 1139373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "r" (err), "r" (addr), "P" (-EFAULT) 1140373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT"); 1141373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return x; 1142373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 11439da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__get_user_asm_w); 1144373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1145373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganunsigned int __get_user_asm_d(const void __user *addr, long *err) 1146373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1147373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned int x asm ("D0Re0") = 0; 1148373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( 1149373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD %0,[%2]\n" 1150373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1151373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETD %0,[%2]\n" 1152373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1153373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" 1154373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: MOV D0FrT,%3\n" 1155373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%1],D0FrT\n" 1156373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(2b)\n" 1157373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(2b)\n" 1158373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1159373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" 1160373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 1b,3b\n" 1161373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1162373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (x) 1163373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "r" (err), "r" (addr), "P" (-EFAULT) 1164373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT"); 1165373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return x; 1166373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 11679da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__get_user_asm_d); 1168373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1169373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganlong __put_user_asm_b(unsigned int x, void __user *addr) 1170373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1171373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned int err asm ("D0Re0") = 0; 1172373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( 1173373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV %0,#0\n" 1174373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%2],%1\n" 1175373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1176373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%2],%1\n" 1177373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1178373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".section .fixup,\"ax\"\n" 1179373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: MOV %0,%3\n" 1180373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(2b)\n" 1181373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(2b)\n" 1182373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".previous\n" 1183373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".section __ex_table,\"a\"\n" 1184373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 1b,3b\n" 1185373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".previous" 1186373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r"(err) 1187373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "d" (x), "a" (addr), "P"(-EFAULT) 1188373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT"); 1189373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return err; 1190373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 11919da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__put_user_asm_b); 1192373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1193373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganlong __put_user_asm_w(unsigned int x, void __user *addr) 1194373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1195373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned int err asm ("D0Re0") = 0; 1196373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( 1197373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV %0,#0\n" 1198373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%2],%1\n" 1199373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1200373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETW [%2],%1\n" 1201373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1202373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".section .fixup,\"ax\"\n" 1203373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: MOV %0,%3\n" 1204373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(2b)\n" 1205373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(2b)\n" 1206373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".previous\n" 1207373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".section __ex_table,\"a\"\n" 1208373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 1b,3b\n" 1209373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".previous" 1210373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r"(err) 1211373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "d" (x), "a" (addr), "P"(-EFAULT) 1212373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT"); 1213373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return err; 1214373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 12159da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__put_user_asm_w); 1216373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1217373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganlong __put_user_asm_d(unsigned int x, void __user *addr) 1218373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1219373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned int err asm ("D0Re0") = 0; 1220373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( 1221373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV %0,#0\n" 1222373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%2],%1\n" 1223373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1224373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETD [%2],%1\n" 1225373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1226373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".section .fixup,\"ax\"\n" 1227373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: MOV %0,%3\n" 1228373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(2b)\n" 1229373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(2b)\n" 1230373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".previous\n" 1231373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".section __ex_table,\"a\"\n" 1232373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 1b,3b\n" 1233373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".previous" 1234373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r"(err) 1235373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "d" (x), "a" (addr), "P"(-EFAULT) 1236373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT"); 1237373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return err; 1238373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 12399da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__put_user_asm_d); 1240373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1241373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganlong __put_user_asm_l(unsigned long long x, void __user *addr) 1242373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1243373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan register unsigned int err asm ("D0Re0") = 0; 1244373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile ( 1245373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV %0,#0\n" 1246373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETL [%2],%1,%t1\n" 1247373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1248373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETL [%2],%1,%t1\n" 1249373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1250373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".section .fixup,\"ax\"\n" 1251373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3: MOV %0,%3\n" 1252373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(2b)\n" 1253373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(2b)\n" 1254373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".previous\n" 1255373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".section __ex_table,\"a\"\n" 1256373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 1b,3b\n" 1257373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan ".previous" 1258373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r"(err) 1259373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "d" (x), "a" (addr), "P"(-EFAULT) 1260373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT"); 1261373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return err; 1262373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 12639da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__put_user_asm_l); 1264373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1265373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganlong strnlen_user(const char __user *src, long count) 1266373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1267373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan long res; 1268373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1269373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (!access_ok(VERIFY_READ, src, 0)) 1270373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return 0; 1271373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1272373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile (" MOV D0Ar4, %1\n" 1273373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV D0Ar6, %2\n" 1274373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "0:\n" 1275373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SUBS D0FrT, D0Ar6, #0\n" 1276373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SUB D0Ar6, D0Ar6, #1\n" 1277373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " BLE 2f\n" 1278373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D0FrT, [D0Ar4+#1++]\n" 1279373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1280373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " TST D0FrT, #255\n" 1281373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " BNE 0b\n" 1282373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1283373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SUB %0, %2, D0Ar6\n" 1284373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3:\n" 1285373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" 1286373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4:\n" 1287373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV %0, #0\n" 1288373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(3b)\n" 1289373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(3b)\n" 1290373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1291373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" 1292373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 1b,4b\n" 1293373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1294373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (res) 1295373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "r" (src), "r" (count) 1296373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT", "D0Ar4", "D0Ar6", "cc"); 1297373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1298373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return res; 1299373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 13009da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(strnlen_user); 1301373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1302373cd784d0fc83f076c899ca7da50ecca7286e42James Hoganlong __strncpy_from_user(char *dst, const char __user *src, long count) 1303373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan{ 1304373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan long res; 1305373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1306373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan if (count == 0) 1307373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return 0; 1308373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1309373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan /* 1310373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * Currently, in 2.4.0-test9, most ports use a simple byte-copy loop. 1311373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * So do we. 1312373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 1313373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * This code is deduced from: 1314373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 1315373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * char tmp2; 1316373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * long tmp1, tmp3; 1317373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * tmp1 = count; 1318373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * while ((*dst++ = (tmp2 = *src++)) != 0 1319373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * && --tmp1) 1320373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * ; 1321373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 1322373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * res = count - tmp1; 1323373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * 1324373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan * with tweaks. 1325373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan */ 1326373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1327373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan asm volatile (" MOV %0,%3\n" 1328373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "1:\n" 1329373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " GETB D0FrT,[%2++]\n" 1330373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "2:\n" 1331373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " CMP D0FrT,#0\n" 1332373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SETB [%1++],D0FrT\n" 1333373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " BEQ 3f\n" 1334373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SUBS %0,%0,#1\n" 1335373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " BNZ 1b\n" 1336373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "3:\n" 1337373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " SUB %0,%3,%0\n" 1338373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "4:\n" 1339373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section .fixup,\"ax\"\n" 1340373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan "5:\n" 1341373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOV %0,%7\n" 1342373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " MOVT D0FrT,#HI(4b)\n" 1343373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " JUMP D0FrT,#LO(4b)\n" 1344373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous\n" 1345373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .section __ex_table,\"a\"\n" 1346373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .long 2b,5b\n" 1347373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan " .previous" 1348373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "=r" (res), "=r" (dst), "=r" (src), "=r" (count) 1349373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "3" (count), "1" (dst), "2" (src), "P" (-EFAULT) 1350373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan : "D0FrT", "memory", "cc"); 1351373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan 1352373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan return res; 1353373cd784d0fc83f076c899ca7da50ecca7286e42James Hogan} 13549da3ee9aa8a9c9fcf94188d4c0ae280afbeb63c1James HoganEXPORT_SYMBOL(__strncpy_from_user); 1355