summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Erik Werner <martinerikwerner.aac@gmail.com>2016-11-25 19:21:40 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-28 07:30:44 +0100
commite639c026b9bbe2d2faab37d61d52f63bebcfce38 (patch)
tree324fd0e6da4f30fcf10c4a8c2bb014919ef3a9d7
parentlibblock: Fix for RTEMS_DEBUG (diff)
downloadrtems-e639c026b9bbe2d2faab37d61d52f63bebcfce38.tar.bz2
or1k: Add functions for entire cache operations
Add functions for flushing and invalidating whole cache. Since we don't have system calls that can operate on anything more than a single cache line, these simply retrieves the cache size and iterates over the full size, invalidating each line. The current implementation assumes that there's only one level of cache. These changes were contributed by Antmicro under contract by ÅAC Microtec AB. Close #2602
-rw-r--r--c/src/lib/libcpu/or1k/shared/cache/cache.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/c/src/lib/libcpu/or1k/shared/cache/cache.c b/c/src/lib/libcpu/or1k/shared/cache/cache.c
index 54728e1e1d..88cda1a00e 100644
--- a/c/src/lib/libcpu/or1k/shared/cache/cache.c
+++ b/c/src/lib/libcpu/or1k/shared/cache/cache.c
@@ -1,4 +1,8 @@
/*
+ * COPYRIGHT (c) 2014 ÅAC Microtec AB <www.aacmicrotec.com>
+ * Contributor(s):
+ * Karol Gugala <kgugala@antmicro.com>
+ *
* COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary@gmail.com>
*
* COPYRIGHT (c) 1989-2006
@@ -14,6 +18,7 @@
#include <rtems/score/or1k-utility.h>
#include <rtems/score/percpu.h>
#include <libcpu/cache.h>
+#include <cache_.h>
static inline void _CPU_OR1K_Cache_enable_data(void)
{
@@ -206,17 +211,51 @@ void _CPU_cache_unfreeze_instruction(void)
void _CPU_cache_flush_entire_data(void)
{
-
+ int addr;
+
+ /* We have only 0 level cache so we do not need to invalidate others */
+ for (
+ addr = _CPU_cache_get_data_cache_size(0);
+ addr > 0;
+ addr -= CPU_DATA_CACHE_ALIGNMENT
+ ) {
+ _CPU_OR1K_Cache_data_block_flush((uintptr_t) addr);
+ }
}
void _CPU_cache_invalidate_entire_data(void)
{
-
+ int addr;
+
+ /* We have only 0 level cache so we do not need to invalidate others */
+ for (
+ addr = _CPU_cache_get_data_cache_size(0);
+ addr > 0;
+ addr -= CPU_DATA_CACHE_ALIGNMENT
+ ) {
+ _CPU_cache_invalidate_1_data_line((uintptr_t) addr);
+ }
}
void _CPU_cache_invalidate_entire_instruction(void)
{
-
+ int addr;
+
+ /* We have only 0 level cache so we do not need to invalidate others */
+ for (
+ addr = _CPU_cache_get_instruction_cache_size(0);
+ addr > 0;
+ addr -= CPU_INSTRUCTION_CACHE_ALIGNMENT
+ ) {
+ _CPU_cache_invalidate_1_instruction_line((uintptr_t) addr);
+ }
+
+ /* Flush instructions out of instruction buffer */
+ __asm__ volatile("l.nop");
+ __asm__ volatile("l.nop");
+ __asm__ volatile("l.nop");
+ __asm__ volatile("l.nop");
+ __asm__ volatile("l.nop");
}
void _CPU_cache_enable_data(void)