diff options
author | Martin Erik Werner <martinerikwerner.aac@gmail.com> | 2016-11-25 19:21:44 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-11-28 07:30:44 +0100 |
commit | 9bf9068bb85367a23e285db416cc5fd62eb9dcc2 (patch) | |
tree | d31eec9acd1016f0b2767f02238a47bd062b6ef8 /c | |
parent | or1k: Remove secondary functions in cache manager (diff) | |
download | rtems-9bf9068bb85367a23e285db416cc5fd62eb9dcc2.tar.bz2 |
or1k: Avoid multiple iterations over cache
Previously, if the cache range operations were called with a range that
was larger than the cache size, this would lead to multiple iterations
over the cache, which is unnecessary.
Limit this so that if the range is larger than the cache size, the
operations will only iterate over the whole cache once.
Diffstat (limited to 'c')
-rw-r--r-- | c/src/lib/libcpu/or1k/shared/cache/cache.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/or1k/shared/cache/cache.c b/c/src/lib/libcpu/or1k/shared/cache/cache.c index 6c1f9d96a6..47bc8f814d 100644 --- a/c/src/lib/libcpu/or1k/shared/cache/cache.c +++ b/c/src/lib/libcpu/or1k/shared/cache/cache.c @@ -224,6 +224,15 @@ void _CPU_cache_flush_data_range(const void *d_addr, size_t n_bytes) final_address = (void *)((size_t)d_addr + n_bytes - 1); d_addr = (void *)((size_t)d_addr & ~(CPU_DATA_CACHE_ALIGNMENT - 1)); + if( final_address - d_addr > _CPU_cache_get_data_cache_size(0) ) { + /* + * Avoid iterating over the whole cache multiple times if the range is + * larger than the cache size. + */ + _CPU_cache_flush_entire_data(); + return; + } + _ISR_Local_disable (level); while( d_addr <= final_address ) { @@ -252,6 +261,15 @@ void _CPU_cache_invalidate_data_range(const void *d_addr, size_t n_bytes) final_address = (void *)((size_t)d_addr + n_bytes - 1); d_addr = (void *)((size_t)d_addr & ~(CPU_DATA_CACHE_ALIGNMENT - 1)); + if( final_address - d_addr > _CPU_cache_get_data_cache_size(0) ) { + /* + * Avoid iterating over the whole cache multiple times if the range is + * larger than the cache size. + */ + _CPU_cache_invalidate_entire_data(); + return; + } + _ISR_Local_disable (level); while( d_addr <= final_address ) { @@ -280,6 +298,15 @@ void _CPU_cache_invalidate_instruction_range(const void *i_addr, size_t n_bytes) final_address = (void *)((size_t)i_addr + n_bytes - 1); i_addr = (void *)((size_t)i_addr & ~(CPU_INSTRUCTION_CACHE_ALIGNMENT - 1)); + if( final_address - i_addr > _CPU_cache_get_data_cache_size(0) ) { + /* + * Avoid iterating over the whole cache multiple times if the range is + * larger than the cache size. + */ + _CPU_cache_invalidate_entire_instruction(); + return; + } + _ISR_Local_disable (level); while( i_addr <= final_address ) { |