1 /* 2 * linux/arch/arm/mm/copypage-feroceon.S 3 * 4 * Copyright (C) 2008 Marvell Semiconductors 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * This handles copy_user_page and clear_user_page on Feroceon 11 * more optimally than the generic implementations. 12 */ 13 #include <linux/init.h> 14 15 #include <asm/page.h> 16 17 void __attribute__((naked)) 18 feroceon_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr) 19 { 20 asm("\ 21 stmfd sp!, {r4-r9, lr} \n\ 22 mov ip, %0 \n\ 23 1: mov lr, r1 \n\ 24 ldmia r1!, {r2 - r9} \n\ 25 pld [lr, #32] \n\ 26 pld [lr, #64] \n\ 27 pld [lr, #96] \n\ 28 pld [lr, #128] \n\ 29 pld [lr, #160] \n\ 30 pld [lr, #192] \n\ 31 pld [lr, #224] \n\ 32 stmia r0, {r2 - r9} \n\ 33 ldmia r1!, {r2 - r9} \n\ 34 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 35 add r0, r0, #32 \n\ 36 stmia r0, {r2 - r9} \n\ 37 ldmia r1!, {r2 - r9} \n\ 38 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 39 add r0, r0, #32 \n\ 40 stmia r0, {r2 - r9} \n\ 41 ldmia r1!, {r2 - r9} \n\ 42 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 43 add r0, r0, #32 \n\ 44 stmia r0, {r2 - r9} \n\ 45 ldmia r1!, {r2 - r9} \n\ 46 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 47 add r0, r0, #32 \n\ 48 stmia r0, {r2 - r9} \n\ 49 ldmia r1!, {r2 - r9} \n\ 50 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 51 add r0, r0, #32 \n\ 52 stmia r0, {r2 - r9} \n\ 53 ldmia r1!, {r2 - r9} \n\ 54 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 55 add r0, r0, #32 \n\ 56 stmia r0, {r2 - r9} \n\ 57 ldmia r1!, {r2 - r9} \n\ 58 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 59 add r0, r0, #32 \n\ 60 stmia r0, {r2 - r9} \n\ 61 subs ip, ip, #(32 * 8) \n\ 62 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 63 add r0, r0, #32 \n\ 64 bne 1b \n\ 65 mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\ 66 ldmfd sp!, {r4-r9, pc}" 67 : 68 : "I" (PAGE_SIZE)); 69 } 70 71 void __attribute__((naked)) 72 feroceon_clear_user_page(void *kaddr, unsigned long vaddr) 73 { 74 asm("\ 75 stmfd sp!, {r4-r7, lr} \n\ 76 mov r1, %0 \n\ 77 mov r2, #0 \n\ 78 mov r3, #0 \n\ 79 mov r4, #0 \n\ 80 mov r5, #0 \n\ 81 mov r6, #0 \n\ 82 mov r7, #0 \n\ 83 mov ip, #0 \n\ 84 mov lr, #0 \n\ 85 1: stmia r0, {r2-r7, ip, lr} \n\ 86 subs r1, r1, #1 \n\ 87 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 88 add r0, r0, #32 \n\ 89 bne 1b \n\ 90 mcr p15, 0, r1, c7, c10, 4 @ drain WB\n\ 91 ldmfd sp!, {r4-r7, pc}" 92 : 93 : "I" (PAGE_SIZE / 32)); 94 } 95 96 struct cpu_user_fns feroceon_user_fns __initdata = { 97 .cpu_clear_user_page = feroceon_clear_user_page, 98 .cpu_copy_user_page = feroceon_copy_user_page, 99 }; 100 101