2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2009-03-25 14:10:01 +03:00
/*
* linux / arch / arm / lib / copypage - fa . S
*
* Copyright ( C ) 2005 Faraday Corp .
* Copyright ( C ) 2008 - 2009 Paulius Zaleckas < paulius . zaleckas @ teltonika . lt >
*
* Based on copypage - v4wb . S :
* Copyright ( C ) 1995 - 1999 Russell King
*/
# include <linux/init.h>
# include <linux/highmem.h>
/*
* Faraday optimised copy_user_page
*/
2018-11-07 19:49:00 +03:00
static void fa_copy_user_page ( void * kto , const void * kfrom )
2009-03-25 14:10:01 +03:00
{
2018-11-07 19:49:00 +03:00
int tmp ;
asm volatile ( " \
1 : ldmia % 1 ! , { r3 , r4 , ip , lr } @ 4 \ n \
stmia % 0 , { r3 , r4 , ip , lr } @ 4 \ n \
mcr p15 , 0 , % 0 , c7 , c14 , 1 @ 1 clean and invalidate D line \ n \
add % 0 , % 0 , # 16 @ 1 \ n \
ldmia % 1 ! , { r3 , r4 , ip , lr } @ 4 \ n \
stmia % 0 , { r3 , r4 , ip , lr } @ 4 \ n \
mcr p15 , 0 , % 0 , c7 , c14 , 1 @ 1 clean and invalidate D line \ n \
add % 0 , % 0 , # 16 @ 1 \ n \
subs % 2 , % 2 , # 1 @ 1 \ n \
2009-03-25 14:10:01 +03:00
bne 1 b @ 1 \ n \
2018-11-07 19:49:00 +03:00
mcr p15 , 0 , % 2 , c7 , c10 , 4 @ 1 drain WB "
: " +&r " ( kto ) , " +&r " ( kfrom ) , " =&r " ( tmp )
: " 2 " ( PAGE_SIZE / 32 )
: " r3 " , " r4 " , " ip " , " lr " ) ;
2009-03-25 14:10:01 +03:00
}
void fa_copy_user_highpage ( struct page * to , struct page * from ,
2010-04-27 14:45:10 +04:00
unsigned long vaddr , struct vm_area_struct * vma )
2009-03-25 14:10:01 +03:00
{
void * kto , * kfrom ;
2011-11-25 19:14:15 +04:00
kto = kmap_atomic ( to ) ;
kfrom = kmap_atomic ( from ) ;
2009-03-25 14:10:01 +03:00
fa_copy_user_page ( kto , kfrom ) ;
2011-11-25 19:14:15 +04:00
kunmap_atomic ( kfrom ) ;
kunmap_atomic ( kto ) ;
2009-03-25 14:10:01 +03:00
}
/*
* Faraday optimised clear_user_page
*
* Same story as above .
*/
void fa_clear_user_highpage ( struct page * page , unsigned long vaddr )
{
2011-11-25 19:14:15 +04:00
void * ptr , * kaddr = kmap_atomic ( page ) ;
2009-03-25 14:10:01 +03:00
asm volatile ( " \
mov r1 , % 2 @ 1 \ n \
mov r2 , # 0 @ 1 \ n \
mov r3 , # 0 @ 1 \ n \
mov ip , # 0 @ 1 \ n \
mov lr , # 0 @ 1 \ n \
1 : stmia % 0 , { r2 , r3 , ip , lr } @ 4 \ n \
mcr p15 , 0 , % 0 , c7 , c14 , 1 @ 1 clean and invalidate D line \ n \
add % 0 , % 0 , # 16 @ 1 \ n \
stmia % 0 , { r2 , r3 , ip , lr } @ 4 \ n \
mcr p15 , 0 , % 0 , c7 , c14 , 1 @ 1 clean and invalidate D line \ n \
add % 0 , % 0 , # 16 @ 1 \ n \
subs r1 , r1 , # 1 @ 1 \ n \
bne 1 b @ 1 \ n \
mcr p15 , 0 , r1 , c7 , c10 , 4 @ 1 drain WB "
: " =r " ( ptr )
: " 0 " ( kaddr ) , " I " ( PAGE_SIZE / 32 )
: " r1 " , " r2 " , " r3 " , " ip " , " lr " ) ;
2011-11-25 19:14:15 +04:00
kunmap_atomic ( kaddr ) ;
2009-03-25 14:10:01 +03:00
}
struct cpu_user_fns fa_user_fns __initdata = {
. cpu_clear_user_highpage = fa_clear_user_highpage ,
. cpu_copy_user_highpage = fa_copy_user_highpage ,
} ;