summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-26 11:08:31 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-28 09:06:16 +0100
commite1d7bf002efda1f6319bd8aa64ad1c9712103d54 (patch)
tree2bc5f9f3c1a2cda166b209a54cd493fd4ed47ee2
parentrtems: Use size_t for cache line size (diff)
downloadrtems-e1d7bf002efda1f6319bd8aa64ad1c9712103d54.tar.bz2
rtems: Add cache size functions
Add rtems_cache_get_data_cache_size() and rtems_cache_get_instruction_cache_size().
-rw-r--r--c/src/lib/libcpu/shared/src/cache_manager.c21
-rw-r--r--cpukit/rtems/include/rtems/rtems/cache.h20
-rw-r--r--testsuites/sptests/spcache01/init.c38
-rw-r--r--testsuites/sptests/spcache01/spcache01.scn6
4 files changed, 81 insertions, 4 deletions
diff --git a/c/src/lib/libcpu/shared/src/cache_manager.c b/c/src/lib/libcpu/shared/src/cache_manager.c
index 8fa0477748..c55f12c823 100644
--- a/c/src/lib/libcpu/shared/src/cache_manager.c
+++ b/c/src/lib/libcpu/shared/src/cache_manager.c
@@ -160,6 +160,16 @@ rtems_cache_get_data_line_size( void )
}
+size_t
+rtems_cache_get_data_cache_size( uint32_t level )
+{
+#if defined(CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS)
+ return _CPU_cache_get_data_cache_size( level );
+#else
+ return 0;
+#endif
+}
+
/*
* This function freezes the data cache; cache lines
* are not replaced.
@@ -275,6 +285,17 @@ rtems_cache_get_instruction_line_size( void )
}
+size_t
+rtems_cache_get_instruction_cache_size( uint32_t level )
+{
+#if defined(CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS)
+ return _CPU_cache_get_instruction_cache_size( level );
+#else
+ return 0;
+#endif
+}
+
+
/*
* This function freezes the instruction cache; cache lines
* are not replaced.
diff --git a/cpukit/rtems/include/rtems/rtems/cache.h b/cpukit/rtems/include/rtems/rtems/cache.h
index 2faf620e24..8da143f8eb 100644
--- a/cpukit/rtems/include/rtems/rtems/cache.h
+++ b/cpukit/rtems/include/rtems/rtems/cache.h
@@ -61,6 +61,26 @@ size_t rtems_cache_get_data_line_size( void );
size_t rtems_cache_get_instruction_line_size( void );
/**
+ * @brief Returns the data cache size in bytes.
+ *
+ * @param[in] level The cache level of interest. The cache level zero
+ * specifies the entire data cache.
+ *
+ * @returns The data cache size in bytes of the specified level.
+ */
+size_t rtems_cache_get_data_cache_size( uint32_t level );
+
+/**
+ * @brief Returns the instruction cache size in bytes.
+ *
+ * @param[in] level The cache level of interest. The cache level zero
+ * specifies the entire instruction cache.
+ *
+ * @returns The instruction cache size in bytes of the specified level.
+ */
+size_t rtems_cache_get_instruction_cache_size( uint32_t level );
+
+/**
* @brief Flushes multiple data cache lines.
*
* Dirty cache lines covering the area are transfered to memory. Depending on
diff --git a/testsuites/sptests/spcache01/init.c b/testsuites/sptests/spcache01/init.c
index f3028371b6..858aedcfd9 100644
--- a/testsuites/sptests/spcache01/init.c
+++ b/testsuites/sptests/spcache01/init.c
@@ -163,12 +163,28 @@ static void test_timing(void)
rtems_interrupt_lock lock = RTEMS_INTERRUPT_LOCK_INITIALIZER;
size_t data_size = sizeof(data);
uint64_t d[3];
+ uint32_t cache_level;
+ size_t cache_size;
printf(
- "data cache line size %zi bytes\n",
- rtems_cache_get_data_line_size()
+ "data cache line size %zi bytes\n"
+ "data cache size %zi bytes\n",
+ rtems_cache_get_data_line_size(),
+ rtems_cache_get_data_cache_size(0)
);
+ cache_level = 1;
+ cache_size = rtems_cache_get_data_cache_size(cache_level);
+ while (cache_size > 0) {
+ printf(
+ "data cache level %" PRIu32 " size %zi bytes\n",
+ cache_level,
+ cache_size
+ );
+ ++cache_level;
+ cache_size = rtems_cache_get_data_cache_size(cache_level);
+ }
+
rtems_interrupt_lock_acquire(&lock, level);
d[0] = load();
@@ -290,10 +306,24 @@ static void test_timing(void)
);
printf(
- "instruction cache line size %zi bytes\n",
- rtems_cache_get_instruction_line_size()
+ "instruction cache line size %zi bytes\n"
+ "instruction cache size %zi bytes\n",
+ rtems_cache_get_instruction_line_size(),
+ rtems_cache_get_instruction_cache_size(0)
);
+ cache_level = 1;
+ cache_size = rtems_cache_get_instruction_cache_size(cache_level);
+ while (cache_size > 0) {
+ printf(
+ "instruction cache level %" PRIu32 " size %zi bytes\n",
+ cache_level,
+ cache_size
+ );
+ ++cache_level;
+ cache_size = rtems_cache_get_instruction_cache_size(cache_level);
+ }
+
rtems_interrupt_lock_acquire(&lock, level);
d[0] = do_some_work();
diff --git a/testsuites/sptests/spcache01/spcache01.scn b/testsuites/sptests/spcache01/spcache01.scn
index c2f1eb6826..80139451ef 100644
--- a/testsuites/sptests/spcache01/spcache01.scn
+++ b/testsuites/sptests/spcache01/spcache01.scn
@@ -3,6 +3,9 @@ data cache flush and invalidate test
data cache operations by line passed the test
data cache operations by line passed the test (copy-back cache detected)
data cache line size 32 bytes
+data cache size 262144 bytes
+data cache level 1 size 32768 bytes
+data cache level 2 size 262144 bytes
load 4096 bytes with flush entire data
duration with normal cache 12660 ns
duration with warm cache 2580 ns
@@ -28,6 +31,9 @@ store 4096 bytes with invalidate multiple data
duration with warm cache 2580 ns
duration with invalidated cache 2640 ns
instruction cache line size 32 bytes
+instruction cache size 262144 bytes
+instruction cache level 1 size 32768 bytes
+instruction cache level 2 size 262144 bytes
invalidate entire instruction
duration with normal cache 5780 ns
duration with warm cache 640 ns