summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/lib/libcpu/shared/src/cache_manager.c42
-rw-r--r--cpukit/libcsupport/src/cachealignedalloc.c2
-rw-r--r--cpukit/rtems/include/rtems/rtems/cache.h29
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.
*