diff options
-rw-r--r-- | c/src/lib/libcpu/shared/src/cache_manager.c | 42 | ||||
-rw-r--r-- | cpukit/libcsupport/src/cachealignedalloc.c | 2 | ||||
-rw-r--r-- | cpukit/rtems/include/rtems/rtems/cache.h | 29 |
3 files changed, 72 insertions, 1 deletions
diff --git a/c/src/lib/libcpu/shared/src/cache_manager.c b/c/src/lib/libcpu/shared/src/cache_manager.c index 202ea8e1ba..00d2476fa9 100644 --- a/c/src/lib/libcpu/shared/src/cache_manager.c +++ b/c/src/lib/libcpu/shared/src/cache_manager.c @@ -469,3 +469,45 @@ rtems_cache_disable_instruction( void ) _CPU_cache_disable_instruction(); #endif } + +/* Returns the maximal cache line size of all cache kinds in bytes. */ +size_t rtems_cache_get_maximal_line_size( void ) +{ +#if defined(CPU_MAXIMAL_CACHE_ALIGNMENT) + return CPU_MAXIMAL_CACHE_ALIGNMENT; +#endif + size_t max_line_size = 0; +#if defined(CPU_DATA_CACHE_ALIGNMENT) + { + size_t data_line_size = CPU_DATA_CACHE_ALIGNMENT; + if ( max_line_size < data_line_size ) + max_line_size = data_line_size; + } +#endif +#if defined(CPU_INSTRUCTION_CACHE_ALIGNMENT) + { + size_t instruction_line_size = CPU_INSTRUCTION_CACHE_ALIGNMENT; + if ( max_line_size < instruction_line_size ) + max_line_size = instruction_line_size; + } +#endif + return max_line_size; +} + +/* + * Purpose is to synchronize caches after code has been loaded + * or self modified. Actual implementation is simple only + * but it can and should be repaced by optimized version + * which does not need flush and invalidate all cache levels + * when code is changed. + */ +void +rtems_cache_instruction_sync_after_code_change( const void * code_addr, size_t n_bytes ) +{ +#if defined(CPU_CACHE_SUPPORT_PROVIDES_INSTRUCTION_SYNC_FUNCTION) + _CPU_cache_instruction_sync_after_code_change( code_addr, n_bytes ); +#else + rtems_cache_flush_multiple_data_lines( code_addr, n_bytes ); + rtems_cache_invalidate_multiple_instruction_lines( code_addr, n_bytes ); +#endif +} diff --git a/cpukit/libcsupport/src/cachealignedalloc.c b/cpukit/libcsupport/src/cachealignedalloc.c index a704859dbe..764fdfb331 100644 --- a/cpukit/libcsupport/src/cachealignedalloc.c +++ b/cpukit/libcsupport/src/cachealignedalloc.c @@ -15,7 +15,7 @@ void *rtems_cache_aligned_malloc( size_t nbytes ) { - size_t line_size = rtems_cache_get_data_line_size(); + size_t line_size = rtems_cache_get_maximal_line_size(); if ( line_size > 0 ) { /* Assume that the cache line size is a power of two */ diff --git a/cpukit/rtems/include/rtems/rtems/cache.h b/cpukit/rtems/include/rtems/rtems/cache.h index a7dcaa60fd..f1dc9bf03d 100644 --- a/cpukit/rtems/include/rtems/rtems/cache.h +++ b/cpukit/rtems/include/rtems/rtems/cache.h @@ -61,6 +61,17 @@ size_t rtems_cache_get_data_line_size( void ); size_t rtems_cache_get_instruction_line_size( void ); /** + * @brief Returns the maximal cache line size of all cache kinds in bytes. + * + * Returns computed or obtained maximal cache line size of all + * all caches in the system. + * + * @retval 0 No cache is present + * @retval positive The maximal cache line size in bytes. + */ +size_t rtems_cache_get_maximal_line_size( void ); + +/** * @brief Returns the data cache size in bytes. * * @param[in] level The cache level of interest. The cache level zero @@ -125,6 +136,24 @@ void rtems_cache_invalidate_multiple_instruction_lines( size_t size ); + +/** + * @brief Ensure necessary synchronization required after code changes + * + * When code is loaded or modified then many Harvard cache equipped + * systems require synchronization of main memory and or updated + * code in data cache to ensure visibility of change in all + * connected CPUs instruction memory view. This operation + * should be used by run time loader for example. + * + * @param[in] addr The start address of the area to invalidate. + * @param[in] size The size in bytes of the area to invalidate. + */ +void rtems_cache_instruction_sync_after_code_change( + const void * code_addr, + size_t n_bytes +); + /** * @brief Flushes the entire data cache. * |