summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-26 11:31:51 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-28 09:06:19 +0100
commit9ec4a48dde1cb18b1fe22c4831f2fa987c37d300 (patch)
treebd95eff1cabdcdee352b42535142a15979518c42 /c/src/lib/libbsp/sparc
parentbsp/leon3: Add L2C registers (diff)
downloadrtems-9ec4a48dde1cb18b1fe22c4831f2fa987c37d300.tar.bz2
bsp/leon3: Add L2 cache support
Diffstat (limited to 'c/src/lib/libbsp/sparc')
-rw-r--r--c/src/lib/libbsp/sparc/leon3/include/cache_.h88
1 files changed, 88 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/sparc/leon3/include/cache_.h b/c/src/lib/libbsp/sparc/leon3/include/cache_.h
index eafbb48b31..a3f4af8056 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/cache_.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/cache_.h
@@ -15,14 +15,97 @@
#ifndef LEON3_CACHE_H
#define LEON3_CACHE_H
+#include <amba.h>
+#include <leon.h>
+
#ifdef __cplusplus
extern "C" {
#endif
#define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
+#define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
+
#define CPU_INSTRUCTION_CACHE_ALIGNMENT 64
+#define CPU_DATA_CACHE_ALIGNMENT 64
+
+static inline volatile struct l2c_regs *get_l2c_regs(void)
+{
+ volatile struct l2c_regs *l2c = NULL;
+ struct ambapp_dev *adev;
+
+ adev = (void *) ambapp_for_each(
+ &ambapp_plb,
+ OPTIONS_ALL | OPTIONS_AHB_SLVS,
+ VENDOR_GAISLER,
+ GAISLER_L2CACHE,
+ ambapp_find_by_idx,
+ NULL
+ );
+ if (adev != NULL) {
+ l2c = (volatile struct l2c_regs *) DEV_TO_AHB(adev)->start[1];
+ }
+
+ return l2c;
+}
+
+static inline size_t get_l2_size(void)
+{
+ size_t size = 0;
+ volatile struct l2c_regs *l2c = get_l2c_regs();
+
+ if (l2c != NULL) {
+ unsigned status = l2c->status;
+ unsigned ways = (status & 0x3) + 1;
+ unsigned set_size = ((status & 0x7ff) >> 2) * 1024;
+
+ size = ways * set_size;
+ }
+
+ return size;
+}
+
+static inline size_t get_l1_size(uint32_t l1_cfg)
+{
+ uint32_t ways = ((l1_cfg >> 24) & 0x7) + 1;
+ uint32_t wsize = UINT32_C(1) << (((l1_cfg >> 20) & 0xf) + 10);
+
+ return ways * wsize;
+}
+
+static inline size_t get_max_size(size_t a, size_t b)
+{
+ return a < b ? b : a;
+}
+
+static inline size_t get_cache_size(uint32_t level, uint32_t l1_cfg)
+{
+ size_t size;
+
+ switch (level) {
+ case 0:
+ size = get_max_size(get_l1_size(l1_cfg), get_l2_size());
+ break;
+ case 1:
+ size = get_l1_size(l1_cfg);
+ break;
+ case 2:
+ size = get_l2_size();
+ break;
+ default:
+ size = 0;
+ break;
+ }
+
+ return size;
+}
+
+static inline size_t _CPU_cache_get_data_cache_size(uint32_t level)
+{
+ return get_cache_size(level, leon3_get_data_cache_config_register());
+}
+
static inline void _CPU_cache_flush_data_range(
const void *d_addr,
size_t n_bytes
@@ -92,6 +175,11 @@ static inline void _CPU_cache_disable_data(void)
/* TODO */
}
+static inline size_t _CPU_cache_get_instruction_cache_size( uint32_t level )
+{
+ return get_cache_size(level, leon3_get_inst_cache_config_register());
+}
+
static inline void _CPU_cache_enable_instruction(void)
{
/* TODO */