diff options
Diffstat (limited to 'c/src/lib/libcpu')
-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 ) { |