2008-10-31 16:08:02 +03:00
/*
* linux / arch / arm / mm / copypage - xsc3 . S
*
* Copyright ( C ) 2004 Intel Corp .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* Adapted for 3 rd gen XScale core , no more mini - dcache
* Author : Matt Gilbert ( matthew . m . gilbert @ intel . com )
*/
# include <linux/init.h>
2008-10-31 18:08:35 +03:00
# include <linux/highmem.h>
2008-10-31 16:08:02 +03:00
/*
* General note :
* We don ' t really want write - allocate cache behaviour for these functions
* since that will just eat through 8 K of the cache .
*/
/*
2008-10-31 18:08:35 +03:00
* XSC3 optimised copy_user_highpage
2008-10-31 16:08:02 +03:00
*
* The source page may have some clean entries in the cache already , but we
* can safely ignore them - break_cow ( ) will flush them out of the cache
* if we eventually end up using our copied page .
*
*/
2018-11-07 19:49:00 +03:00
static void xsc3_mc_copy_user_page ( void * kto , const void * kfrom )
2008-10-31 16:08:02 +03:00
{
2018-11-07 19:49:00 +03:00
int tmp ;
asm volatile ( " \
pld [ % 1 , # 0 ] \ n \
pld [ % 1 , # 32 ] \ n \
1 : pld [ % 1 , # 64 ] \ n \
pld [ % 1 , # 96 ] \ n \
2008-10-31 16:08:02 +03:00
\ n \
2018-11-09 06:26:39 +03:00
2 : ldrd r2 , r3 , [ % 1 ] , # 8 \ n \
ldrd r4 , r5 , [ % 1 ] , # 8 \ n \
2018-11-07 19:49:00 +03:00
mcr p15 , 0 , % 0 , c7 , c6 , 1 @ invalidate \ n \
2018-11-09 06:26:39 +03:00
strd r2 , r3 , [ % 0 ] , # 8 \ n \
ldrd r2 , r3 , [ % 1 ] , # 8 \ n \
strd r4 , r5 , [ % 0 ] , # 8 \ n \
ldrd r4 , r5 , [ % 1 ] , # 8 \ n \
strd r2 , r3 , [ % 0 ] , # 8 \ n \
strd r4 , r5 , [ % 0 ] , # 8 \ n \
ldrd r2 , r3 , [ % 1 ] , # 8 \ n \
ldrd r4 , r5 , [ % 1 ] , # 8 \ n \
2018-11-07 19:49:00 +03:00
mcr p15 , 0 , % 0 , c7 , c6 , 1 @ invalidate \ n \
2018-11-09 06:26:39 +03:00
strd r2 , r3 , [ % 0 ] , # 8 \ n \
ldrd r2 , r3 , [ % 1 ] , # 8 \ n \
2018-11-07 19:49:00 +03:00
subs % 2 , % 2 , # 1 \ n \
2018-11-09 06:26:39 +03:00
strd r4 , r5 , [ % 0 ] , # 8 \ n \
ldrd r4 , r5 , [ % 1 ] , # 8 \ n \
strd r2 , r3 , [ % 0 ] , # 8 \ n \
strd r4 , r5 , [ % 0 ] , # 8 \ n \
2008-10-31 16:08:02 +03:00
bgt 1 b \ n \
2018-11-07 19:49:00 +03:00
beq 2 b "
: " +&r " ( kto ) , " +&r " ( kfrom ) , " =&r " ( tmp )
: " 2 " ( PAGE_SIZE / 64 - 1 )
: " r2 " , " r3 " , " r4 " , " r5 " ) ;
2008-10-31 16:08:02 +03:00
}
2008-10-31 18:08:35 +03:00
void xsc3_mc_copy_user_highpage ( struct page * to , struct page * from ,
2009-10-05 18:17:45 +04:00
unsigned long vaddr , struct vm_area_struct * vma )
2008-10-31 18:08:35 +03:00
{
void * kto , * kfrom ;
2011-11-25 19:14:15 +04:00
kto = kmap_atomic ( to ) ;
kfrom = kmap_atomic ( from ) ;
2009-10-05 18:34:22 +04:00
flush_cache_page ( vma , vaddr , page_to_pfn ( from ) ) ;
2008-10-31 18:08:35 +03:00
xsc3_mc_copy_user_page ( kto , kfrom ) ;
2011-11-25 19:14:15 +04:00
kunmap_atomic ( kfrom ) ;
kunmap_atomic ( kto ) ;
2008-10-31 18:08:35 +03:00
}
2008-10-31 16:08:02 +03:00
/*
* XScale optimised clear_user_page
*/
2008-10-31 19:32:19 +03:00
void xsc3_mc_clear_user_highpage ( struct page * page , unsigned long vaddr )
2008-10-31 16:08:02 +03:00
{
2011-11-25 19:14:15 +04:00
void * ptr , * kaddr = kmap_atomic ( page ) ;
2008-11-04 10:42:27 +03:00
asm volatile ( " \
mov r1 , % 2 \ n \
2008-10-31 16:08:02 +03:00
mov r2 , # 0 \ n \
mov r3 , # 0 \ n \
2008-10-31 19:32:19 +03:00
1 : mcr p15 , 0 , % 0 , c7 , c6 , 1 @ invalidate line \ n \
2018-11-09 06:26:39 +03:00
strd r2 , r3 , [ % 0 ] , # 8 \ n \
strd r2 , r3 , [ % 0 ] , # 8 \ n \
strd r2 , r3 , [ % 0 ] , # 8 \ n \
strd r2 , r3 , [ % 0 ] , # 8 \ n \
2008-10-31 16:08:02 +03:00
subs r1 , r1 , # 1 \ n \
2008-10-31 19:32:19 +03:00
bne 1 b "
2008-11-04 10:42:27 +03:00
: " =r " ( ptr )
: " 0 " ( kaddr ) , " I " ( PAGE_SIZE / 32 )
2008-10-31 19:32:19 +03:00
: " r1 " , " r2 " , " r3 " ) ;
2011-11-25 19:14:15 +04:00
kunmap_atomic ( kaddr ) ;
2008-10-31 16:08:02 +03:00
}
struct cpu_user_fns xsc3_mc_user_fns __initdata = {
2008-10-31 19:32:19 +03:00
. cpu_clear_user_highpage = xsc3_mc_clear_user_highpage ,
2008-10-31 18:08:35 +03:00
. cpu_copy_user_highpage = xsc3_mc_copy_user_highpage ,
2008-10-31 16:08:02 +03:00
} ;