2009-08-04 13:06:01 +04:00
# include <linux/mm.h>
# include <asm/mmu_context.h>
2012-03-30 14:29:57 +04:00
# include <asm/cache_insns.h>
2009-08-04 13:06:01 +04:00
# include <asm/cacheflush.h>
2012-03-28 21:30:03 +04:00
# include <asm/traps.h>
2009-08-04 13:06:01 +04:00
/*
* Write back the dirty D - caches , but not invalidate them .
*
* START : Virtual Address ( U0 , P1 , or P3 )
* SIZE : Size of the region .
*/
2009-08-15 07:29:49 +04:00
static void sh4__flush_wback_region ( void * start , int size )
2009-08-04 13:06:01 +04:00
{
2009-08-14 20:57:36 +04:00
reg_size_t aligned_start , v , cnt , end ;
2009-08-04 13:06:01 +04:00
2009-08-14 20:57:36 +04:00
aligned_start = register_align ( start ) ;
v = aligned_start & ~ ( L1_CACHE_BYTES - 1 ) ;
end = ( aligned_start + size + L1_CACHE_BYTES - 1 )
2009-08-04 13:06:01 +04:00
& ~ ( L1_CACHE_BYTES - 1 ) ;
2009-08-04 13:09:54 +04:00
cnt = ( end - v ) / L1_CACHE_BYTES ;
while ( cnt > = 8 ) {
2009-08-15 20:50:17 +04:00
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
2009-08-04 13:09:54 +04:00
cnt - = 8 ;
}
while ( cnt ) {
2009-08-15 20:50:17 +04:00
__ocbwb ( v ) ; v + = L1_CACHE_BYTES ;
2009-08-04 13:09:54 +04:00
cnt - - ;
2009-08-04 13:06:01 +04:00
}
}
/*
* Write back the dirty D - caches and invalidate them .
*
* START : Virtual Address ( U0 , P1 , or P3 )
* SIZE : Size of the region .
*/
2009-08-15 07:29:49 +04:00
static void sh4__flush_purge_region ( void * start , int size )
2009-08-04 13:06:01 +04:00
{
2009-08-14 20:57:36 +04:00
reg_size_t aligned_start , v , cnt , end ;
2009-08-04 13:06:01 +04:00
2009-08-14 20:57:36 +04:00
aligned_start = register_align ( start ) ;
v = aligned_start & ~ ( L1_CACHE_BYTES - 1 ) ;
end = ( aligned_start + size + L1_CACHE_BYTES - 1 )
2009-08-04 13:06:01 +04:00
& ~ ( L1_CACHE_BYTES - 1 ) ;
2009-08-04 13:09:54 +04:00
cnt = ( end - v ) / L1_CACHE_BYTES ;
while ( cnt > = 8 ) {
2009-08-15 20:50:17 +04:00
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
2009-08-04 13:09:54 +04:00
cnt - = 8 ;
}
while ( cnt ) {
2009-08-15 20:50:17 +04:00
__ocbp ( v ) ; v + = L1_CACHE_BYTES ;
2009-08-04 13:09:54 +04:00
cnt - - ;
2009-08-04 13:06:01 +04:00
}
}
/*
* No write back please
*/
2009-08-15 07:29:49 +04:00
static void sh4__flush_invalidate_region ( void * start , int size )
2009-08-04 13:06:01 +04:00
{
2009-08-14 20:57:36 +04:00
reg_size_t aligned_start , v , cnt , end ;
2009-08-04 13:06:01 +04:00
2009-08-14 20:57:36 +04:00
aligned_start = register_align ( start ) ;
v = aligned_start & ~ ( L1_CACHE_BYTES - 1 ) ;
end = ( aligned_start + size + L1_CACHE_BYTES - 1 )
2009-08-04 13:06:01 +04:00
& ~ ( L1_CACHE_BYTES - 1 ) ;
2009-08-04 13:09:54 +04:00
cnt = ( end - v ) / L1_CACHE_BYTES ;
while ( cnt > = 8 ) {
2009-08-15 20:50:17 +04:00
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
2009-08-04 13:09:54 +04:00
cnt - = 8 ;
}
while ( cnt ) {
2009-08-15 20:50:17 +04:00
__ocbi ( v ) ; v + = L1_CACHE_BYTES ;
2009-08-04 13:09:54 +04:00
cnt - - ;
2009-08-04 13:06:01 +04:00
}
}
2009-08-15 07:29:49 +04:00
void __init sh4__flush_region_init ( void )
{
__flush_wback_region = sh4__flush_wback_region ;
__flush_invalidate_region = sh4__flush_invalidate_region ;
__flush_purge_region = sh4__flush_purge_region ;
}