Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/arch/arm/mm/copypage-feroceon.S
0004  *
0005  *  Copyright (C) 2008 Marvell Semiconductors
0006  *
0007  * This handles copy_user_highpage and clear_user_page on Feroceon
0008  * more optimally than the generic implementations.
0009  */
0010 #include <linux/init.h>
0011 #include <linux/highmem.h>
0012 
0013 static void feroceon_copy_user_page(void *kto, const void *kfrom)
0014 {
0015     int tmp;
0016 
0017     asm volatile ("\
0018 1:  ldmia   %1!, {r2 - r7, ip, lr}      \n\
0019     pld [%1, #0]            \n\
0020     pld [%1, #32]           \n\
0021     pld [%1, #64]           \n\
0022     pld [%1, #96]           \n\
0023     pld [%1, #128]          \n\
0024     pld [%1, #160]          \n\
0025     pld [%1, #192]          \n\
0026     stmia   %0, {r2 - r7, ip, lr}       \n\
0027     ldmia   %1!, {r2 - r7, ip, lr}      \n\
0028     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0029     add %0, %0, #32         \n\
0030     stmia   %0, {r2 - r7, ip, lr}       \n\
0031     ldmia   %1!, {r2 - r7, ip, lr}      \n\
0032     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0033     add %0, %0, #32         \n\
0034     stmia   %0, {r2 - r7, ip, lr}       \n\
0035     ldmia   %1!, {r2 - r7, ip, lr}      \n\
0036     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0037     add %0, %0, #32         \n\
0038     stmia   %0, {r2 - r7, ip, lr}       \n\
0039     ldmia   %1!, {r2 - r7, ip, lr}      \n\
0040     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0041     add %0, %0, #32         \n\
0042     stmia   %0, {r2 - r7, ip, lr}       \n\
0043     ldmia   %1!, {r2 - r7, ip, lr}      \n\
0044     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0045     add %0, %0, #32         \n\
0046     stmia   %0, {r2 - r7, ip, lr}       \n\
0047     ldmia   %1!, {r2 - r7, ip, lr}      \n\
0048     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0049     add %0, %0, #32         \n\
0050     stmia   %0, {r2 - r7, ip, lr}       \n\
0051     ldmia   %1!, {r2 - r7, ip, lr}      \n\
0052     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0053     add %0, %0, #32         \n\
0054     stmia   %0, {r2 - r7, ip, lr}       \n\
0055     subs    %2, %2, #(32 * 8)       \n\
0056     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0057     add %0, %0, #32         \n\
0058     bne 1b              \n\
0059     mcr p15, 0, %2, c7, c10, 4      @ drain WB"
0060     : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
0061     : "2" (PAGE_SIZE)
0062     : "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
0063 }
0064 
0065 void feroceon_copy_user_highpage(struct page *to, struct page *from,
0066     unsigned long vaddr, struct vm_area_struct *vma)
0067 {
0068     void *kto, *kfrom;
0069 
0070     kto = kmap_atomic(to);
0071     kfrom = kmap_atomic(from);
0072     flush_cache_page(vma, vaddr, page_to_pfn(from));
0073     feroceon_copy_user_page(kto, kfrom);
0074     kunmap_atomic(kfrom);
0075     kunmap_atomic(kto);
0076 }
0077 
0078 void feroceon_clear_user_highpage(struct page *page, unsigned long vaddr)
0079 {
0080     void *ptr, *kaddr = kmap_atomic(page);
0081     asm volatile ("\
0082     mov r1, %2              \n\
0083     mov r2, #0              \n\
0084     mov r3, #0              \n\
0085     mov r4, #0              \n\
0086     mov r5, #0              \n\
0087     mov r6, #0              \n\
0088     mov r7, #0              \n\
0089     mov ip, #0              \n\
0090     mov lr, #0              \n\
0091 1:  stmia   %0, {r2-r7, ip, lr}     \n\
0092     subs    r1, r1, #1          \n\
0093     mcr p15, 0, %0, c7, c14, 1      @ clean and invalidate D line\n\
0094     add %0, %0, #32         \n\
0095     bne 1b              \n\
0096     mcr p15, 0, r1, c7, c10, 4      @ drain WB"
0097     : "=r" (ptr)
0098     : "0" (kaddr), "I" (PAGE_SIZE / 32)
0099     : "r1", "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
0100     kunmap_atomic(kaddr);
0101 }
0102 
0103 struct cpu_user_fns feroceon_user_fns __initdata = {
0104     .cpu_clear_user_highpage = feroceon_clear_user_highpage,
0105     .cpu_copy_user_highpage = feroceon_copy_user_highpage,
0106 };
0107