summaryrefslogtreecommitdiffstats
path: root/bsps/sparc/leon3/start/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/sparc/leon3/start/cache.c')
-rw-r--r--bsps/sparc/leon3/start/cache.c90
1 files changed, 60 insertions, 30 deletions
diff --git a/bsps/sparc/leon3/start/cache.c b/bsps/sparc/leon3/start/cache.c
index c428efa119..11af2f4d01 100644
--- a/bsps/sparc/leon3/start/cache.c
+++ b/bsps/sparc/leon3/start/cache.c
@@ -1,19 +1,31 @@
-/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+/**
+ * @file
*
- * embedded brains GmbH
- * Dornierstr. 4
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
+ * @ingroup RTEMSBSPsSPARCLEON3
+ *
+ * @brief This source file contains the implementation of the Cache Manager.
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
-#include <amba.h>
-#include <leon.h>
+#include <grlib/l2cache-regs.h>
+#include <grlib/io.h>
+
+#include <bsp/leon3.h>
+
+#if !defined(LEON3_L2CACHE_BASE)
+#include <grlib/ambapp.h>
+#endif
+
+#if !defined(LEON3_L2CACHE_BASE) || LEON3_L2CACHE_BASE != 0
+#define LEON3_MAYBE_HAS_L2CACHE
+#endif
#define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
@@ -25,12 +37,12 @@
#define CPU_DATA_CACHE_ALIGNMENT 64
-static inline volatile struct l2c_regs *get_l2c_regs(void)
+#if !defined(LEON3_L2CACHE_BASE)
+static inline l2cache *get_l2c_regs(void)
{
- volatile struct l2c_regs *l2c = NULL;
struct ambapp_dev *adev;
- adev = (void *) ambapp_for_each(
+ adev = (struct ambapp_dev *) ambapp_for_each(
ambapp_plb(),
OPTIONS_ALL | OPTIONS_AHB_SLVS,
VENDOR_GAISLER,
@@ -38,28 +50,14 @@ static inline volatile struct l2c_regs *get_l2c_regs(void)
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;
+ if (adev == NULL) {
+ return NULL;
}
- return size;
+ return (l2cache *) DEV_TO_AHB(adev)->start[1];
}
+#endif
static inline size_t get_l1_size(uint32_t l1_cfg)
{
@@ -69,10 +67,36 @@ static inline size_t get_l1_size(uint32_t l1_cfg)
return ways * wsize;
}
+#if defined(LEON3_MAYBE_HAS_L2CACHE)
+static inline size_t get_l2_size(void)
+{
+ l2cache *regs;
+ unsigned status;
+ unsigned ways;
+ unsigned set_size;
+
+#if defined(LEON3_L2CACHE_BASE)
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+#else
+ regs = get_l2c_regs();
+
+ if (regs == NULL) {
+ return 0;
+ }
+#endif
+
+ status = grlib_load_32(&regs->l2cs);
+ ways = L2CACHE_L2CS_WAY_GET(status) + 1;
+ set_size = L2CACHE_L2CS_WAY_SIZE_GET(status) * 1024;
+
+ return ways * set_size;
+}
+
static inline size_t get_max_size(size_t a, size_t b)
{
return a < b ? b : a;
}
+#endif
static inline size_t get_cache_size(uint32_t level, uint32_t l1_cfg)
{
@@ -80,14 +104,20 @@ static inline size_t get_cache_size(uint32_t level, uint32_t l1_cfg)
switch (level) {
case 0:
+#if defined(LEON3_MAYBE_HAS_L2CACHE)
size = get_max_size(get_l1_size(l1_cfg), get_l2_size());
+#else
+ size = get_l1_size(l1_cfg);
+#endif
break;
case 1:
size = get_l1_size(l1_cfg);
break;
+#if defined(LEON3_MAYBE_HAS_L2CACHE)
case 2:
size = get_l2_size();
break;
+#endif
default:
size = 0;
break;