@ -37,82 +37,59 @@ static inline unsigned long dcache_line_size(void)
return 2 < < dl ;
}
# define cache_loop(start, end, lsize, ops...) do { \
const void * addr = ( const void * ) ( start & ~ ( lsize - 1 ) ) ; \
const void * aend = ( const void * ) ( ( end - 1 ) & ~ ( lsize - 1 ) ) ; \
const unsigned int cache_ops [ ] = { ops } ; \
unsigned int i ; \
\
for ( ; addr < = aend ; addr + = lsize ) { \
for ( i = 0 ; i < ARRAY_SIZE ( cache_ops ) ; i + + ) \
mips_cache ( cache_ops [ i ] , addr ) ; \
} \
} while ( 0 )
void flush_cache ( ulong start_addr , ulong size )
{
unsigned long ilsize = icache_line_size ( ) ;
unsigned long dlsize = dcache_line_size ( ) ;
const void * addr , * aend ;
/* aend will be miscalculated when size is zero, so we return here */
if ( size = = 0 )
return ;
addr = ( const void * ) ( start_addr & ~ ( dlsize - 1 ) ) ;
aend = ( const void * ) ( ( start_addr + size - 1 ) & ~ ( dlsize - 1 ) ) ;
if ( ilsize = = dlsize ) {
/* flush I-cache & D-cache simultaneously */
while ( 1 ) {
mips_cache ( HIT_WRITEBACK_INV_D , addr ) ;
mips_cache ( HIT_INVALIDATE_I , addr ) ;
if ( addr = = aend )
break ;
addr + = dlsize ;
}
cache_loop ( start_addr , start_addr + size , ilsize ,
HIT_WRITEBACK_INV_D , HIT_INVALIDATE_I ) ;
return ;
}
/* flush D-cache */
while ( 1 ) {
mips_cache ( HIT_WRITEBACK_INV_D , addr ) ;
if ( addr = = aend )
break ;
addr + = dlsize ;
}
cache_loop ( start_addr , start_addr + size , dlsize , HIT_WRITEBACK_INV_D ) ;
/* flush I-cache */
addr = ( const void * ) ( start_addr & ~ ( ilsize - 1 ) ) ;
aend = ( const void * ) ( ( start_addr + size - 1 ) & ~ ( ilsize - 1 ) ) ;
while ( 1 ) {
mips_cache ( HIT_INVALIDATE_I , addr ) ;
if ( addr = = aend )
break ;
addr + = ilsize ;
}
cache_loop ( start_addr , start_addr + size , ilsize , HIT_INVALIDATE_I ) ;
}
void flush_dcache_range ( ulong start_addr , ulong stop )
{
unsigned long lsize = dcache_line_size ( ) ;
const void * addr = ( const void * ) ( start_addr & ~ ( lsize - 1 ) ) ;
const void * aend = ( const void * ) ( ( stop - 1 ) & ~ ( lsize - 1 ) ) ;
/* aend will be miscalculated when size is zero, so we return here */
if ( start_addr = = stop )
return ;
while ( 1 ) {
mips_cache ( HIT_WRITEBACK_INV_D , addr ) ;
if ( addr = = aend )
break ;
addr + = lsize ;
}
cache_loop ( start_addr , stop , lsize , HIT_WRITEBACK_INV_D ) ;
}
void invalidate_dcache_range ( ulong start_addr , ulong stop )
{
unsigned long lsize = dcache_line_size ( ) ;
const void * addr = ( const void * ) ( start_addr & ~ ( lsize - 1 ) ) ;
const void * aend = ( const void * ) ( ( stop - 1 ) & ~ ( lsize - 1 ) ) ;
/* aend will be miscalculated when size is zero, so we return here */
if ( start_addr = = stop )
return ;
while ( 1 ) {
mips_cache ( HIT_INVALIDATE_D , addr ) ;
if ( addr = = aend )
break ;
addr + = lsize ;
}
cache_loop ( start_addr , stop , lsize , HIT_INVALIDATE_I ) ;
}