15ccc6af5SLey Foon Tan /* 25ccc6af5SLey Foon Tan * This file is subject to the terms and conditions of the GNU General Public 35ccc6af5SLey Foon Tan * License. See the file "COPYING" in the main directory of this archive 45ccc6af5SLey Foon Tan * for more details. 55ccc6af5SLey Foon Tan * 65ccc6af5SLey Foon Tan * Copyright (C) 2009, Wind River Systems Inc 75ccc6af5SLey Foon Tan * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com 85ccc6af5SLey Foon Tan */ 95ccc6af5SLey Foon Tan 105ccc6af5SLey Foon Tan #include <linux/export.h> 115ccc6af5SLey Foon Tan #include <linux/uaccess.h> 125ccc6af5SLey Foon Tan 13*de51d6ccSAl Viro asm(".global raw_copy_from_user\n" 14*de51d6ccSAl Viro " .type raw_copy_from_user, @function\n" 15*de51d6ccSAl Viro "raw_copy_from_user:\n" 165ccc6af5SLey Foon Tan " movi r2,7\n" 175ccc6af5SLey Foon Tan " mov r3,r4\n" 185ccc6af5SLey Foon Tan " bge r2,r6,1f\n" 195ccc6af5SLey Foon Tan " xor r2,r4,r5\n" 205ccc6af5SLey Foon Tan " andi r2,r2,3\n" 215ccc6af5SLey Foon Tan " movi r7,3\n" 225ccc6af5SLey Foon Tan " beq r2,zero,4f\n" 235ccc6af5SLey Foon Tan "1: addi r6,r6,-1\n" 245ccc6af5SLey Foon Tan " movi r2,-1\n" 255ccc6af5SLey Foon Tan " beq r6,r2,3f\n" 265ccc6af5SLey Foon Tan " mov r7,r2\n" 275ccc6af5SLey Foon Tan "2: ldbu r2,0(r5)\n" 285ccc6af5SLey Foon Tan " addi r6,r6,-1\n" 295ccc6af5SLey Foon Tan " addi r5,r5,1\n" 305ccc6af5SLey Foon Tan " stb r2,0(r3)\n" 315ccc6af5SLey Foon Tan " addi r3,r3,1\n" 325ccc6af5SLey Foon Tan " bne r6,r7,2b\n" 335ccc6af5SLey Foon Tan "3:\n" 345ccc6af5SLey Foon Tan " addi r2,r6,1\n" 355ccc6af5SLey Foon Tan " ret\n" 365ccc6af5SLey Foon Tan "13:mov r2,r6\n" 375ccc6af5SLey Foon Tan " ret\n" 385ccc6af5SLey Foon Tan "4: andi r2,r4,1\n" 395ccc6af5SLey Foon Tan " cmpeq r2,r2,zero\n" 405ccc6af5SLey Foon Tan " beq r2,zero,7f\n" 415ccc6af5SLey Foon Tan "5: andi r2,r3,2\n" 425ccc6af5SLey Foon Tan " beq r2,zero,6f\n" 435ccc6af5SLey Foon Tan "9: ldhu r2,0(r5)\n" 445ccc6af5SLey Foon Tan " addi r6,r6,-2\n" 455ccc6af5SLey Foon Tan " addi r5,r5,2\n" 465ccc6af5SLey Foon Tan " sth r2,0(r3)\n" 475ccc6af5SLey Foon Tan " addi r3,r3,2\n" 485ccc6af5SLey Foon Tan "6: bge r7,r6,1b\n" 495ccc6af5SLey Foon Tan "10:ldw r2,0(r5)\n" 505ccc6af5SLey Foon Tan " addi r6,r6,-4\n" 515ccc6af5SLey Foon Tan " addi r5,r5,4\n" 525ccc6af5SLey Foon Tan " stw r2,0(r3)\n" 535ccc6af5SLey Foon Tan " addi r3,r3,4\n" 545ccc6af5SLey Foon Tan " br 6b\n" 555ccc6af5SLey Foon Tan "7: ldbu r2,0(r5)\n" 565ccc6af5SLey Foon Tan " addi r6,r6,-1\n" 575ccc6af5SLey Foon Tan " addi r5,r5,1\n" 585ccc6af5SLey Foon Tan " addi r3,r4,1\n" 595ccc6af5SLey Foon Tan " stb r2,0(r4)\n" 605ccc6af5SLey Foon Tan " br 5b\n" 615ccc6af5SLey Foon Tan ".section __ex_table,\"a\"\n" 625ccc6af5SLey Foon Tan ".word 2b,3b\n" 635ccc6af5SLey Foon Tan ".word 9b,13b\n" 645ccc6af5SLey Foon Tan ".word 10b,13b\n" 655ccc6af5SLey Foon Tan ".word 7b,13b\n" 665ccc6af5SLey Foon Tan ".previous\n" 675ccc6af5SLey Foon Tan ); 68*de51d6ccSAl Viro EXPORT_SYMBOL(raw_copy_from_user); 695ccc6af5SLey Foon Tan 705ccc6af5SLey Foon Tan asm( 71*de51d6ccSAl Viro " .global raw_copy_to_user\n" 72*de51d6ccSAl Viro " .type raw_copy_to_user, @function\n" 73*de51d6ccSAl Viro "raw_copy_to_user:\n" 745ccc6af5SLey Foon Tan " movi r2,7\n" 755ccc6af5SLey Foon Tan " mov r3,r4\n" 765ccc6af5SLey Foon Tan " bge r2,r6,1f\n" 775ccc6af5SLey Foon Tan " xor r2,r4,r5\n" 785ccc6af5SLey Foon Tan " andi r2,r2,3\n" 795ccc6af5SLey Foon Tan " movi r7,3\n" 805ccc6af5SLey Foon Tan " beq r2,zero,4f\n" 815ccc6af5SLey Foon Tan /* Bail if we try to copy zero bytes */ 825ccc6af5SLey Foon Tan "1: addi r6,r6,-1\n" 835ccc6af5SLey Foon Tan " movi r2,-1\n" 845ccc6af5SLey Foon Tan " beq r6,r2,3f\n" 855ccc6af5SLey Foon Tan /* Copy byte by byte for small copies and if src^dst != 0 */ 865ccc6af5SLey Foon Tan " mov r7,r2\n" 875ccc6af5SLey Foon Tan "2: ldbu r2,0(r5)\n" 885ccc6af5SLey Foon Tan " addi r5,r5,1\n" 895ccc6af5SLey Foon Tan "9: stb r2,0(r3)\n" 905ccc6af5SLey Foon Tan " addi r6,r6,-1\n" 915ccc6af5SLey Foon Tan " addi r3,r3,1\n" 925ccc6af5SLey Foon Tan " bne r6,r7,2b\n" 935ccc6af5SLey Foon Tan "3: addi r2,r6,1\n" 945ccc6af5SLey Foon Tan " ret\n" 955ccc6af5SLey Foon Tan "13:mov r2,r6\n" 965ccc6af5SLey Foon Tan " ret\n" 975ccc6af5SLey Foon Tan /* If 'to' is an odd address byte copy */ 985ccc6af5SLey Foon Tan "4: andi r2,r4,1\n" 995ccc6af5SLey Foon Tan " cmpeq r2,r2,zero\n" 1005ccc6af5SLey Foon Tan " beq r2,zero,7f\n" 1015ccc6af5SLey Foon Tan /* If 'to' is not divideable by four copy halfwords */ 1025ccc6af5SLey Foon Tan "5: andi r2,r3,2\n" 1035ccc6af5SLey Foon Tan " beq r2,zero,6f\n" 1045ccc6af5SLey Foon Tan " ldhu r2,0(r5)\n" 1055ccc6af5SLey Foon Tan " addi r5,r5,2\n" 1065ccc6af5SLey Foon Tan "10:sth r2,0(r3)\n" 1075ccc6af5SLey Foon Tan " addi r6,r6,-2\n" 1085ccc6af5SLey Foon Tan " addi r3,r3,2\n" 1095ccc6af5SLey Foon Tan /* Copy words */ 1105ccc6af5SLey Foon Tan "6: bge r7,r6,1b\n" 1115ccc6af5SLey Foon Tan " ldw r2,0(r5)\n" 1125ccc6af5SLey Foon Tan " addi r5,r5,4\n" 1135ccc6af5SLey Foon Tan "11:stw r2,0(r3)\n" 1145ccc6af5SLey Foon Tan " addi r6,r6,-4\n" 1155ccc6af5SLey Foon Tan " addi r3,r3,4\n" 1165ccc6af5SLey Foon Tan " br 6b\n" 1175ccc6af5SLey Foon Tan /* Copy remaining bytes */ 1185ccc6af5SLey Foon Tan "7: ldbu r2,0(r5)\n" 1195ccc6af5SLey Foon Tan " addi r5,r5,1\n" 1205ccc6af5SLey Foon Tan " addi r3,r4,1\n" 1215ccc6af5SLey Foon Tan "12: stb r2,0(r4)\n" 1225ccc6af5SLey Foon Tan " addi r6,r6,-1\n" 1235ccc6af5SLey Foon Tan " br 5b\n" 1245ccc6af5SLey Foon Tan ".section __ex_table,\"a\"\n" 1255ccc6af5SLey Foon Tan ".word 9b,3b\n" 1265ccc6af5SLey Foon Tan ".word 10b,13b\n" 1275ccc6af5SLey Foon Tan ".word 11b,13b\n" 1285ccc6af5SLey Foon Tan ".word 12b,13b\n" 1295ccc6af5SLey Foon Tan ".previous\n"); 130*de51d6ccSAl Viro EXPORT_SYMBOL(raw_copy_to_user); 131