[rtems commit] or1k: Avoid multiple iterations over cache

Sebastian Huber sebh at rtems.org
Mon Nov 28 06:31:46 UTC 2016


Module:    rtems
Branch:    master
Commit:    9bf9068bb85367a23e285db416cc5fd62eb9dcc2
Changeset: http://git.rtems.org/rtems/commit/?id=9bf9068bb85367a23e285db416cc5fd62eb9dcc2

Author:    Martin Erik Werner <martinerikwerner.aac at gmail.com>
Date:      Fri Nov 25 19:21:44 2016 +0100

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.

---

 c/src/lib/libcpu/or1k/shared/cache/cache.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/c/src/lib/libcpu/or1k/shared/cache/cache.c b/c/src/lib/libcpu/or1k/shared/cache/cache.c
index 6c1f9d9..47bc8f8 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 )  {



More information about the vc mailing list