From e1d7bf002efda1f6319bd8aa64ad1c9712103d54 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 26 Feb 2014 11:08:31 +0100 Subject: rtems: Add cache size functions Add rtems_cache_get_data_cache_size() and rtems_cache_get_instruction_cache_size(). --- c/src/lib/libcpu/shared/src/cache_manager.c | 21 ++++++++++++++++ cpukit/rtems/include/rtems/rtems/cache.h | 20 +++++++++++++++ testsuites/sptests/spcache01/init.c | 38 ++++++++++++++++++++++++++--- testsuites/sptests/spcache01/spcache01.scn | 6 +++++ 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 @@ -60,6 +60,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. * 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 -- cgit v1.2.3