diff options
Diffstat (limited to 'bsps/sparc/leon3/start/cache.c')
-rw-r--r-- | bsps/sparc/leon3/start/cache.c | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/bsps/sparc/leon3/start/cache.c b/bsps/sparc/leon3/start/cache.c index 0273ad1d45..11af2f4d01 100644 --- a/bsps/sparc/leon3/start/cache.c +++ b/bsps/sparc/leon3/start/cache.c @@ -1,3 +1,11 @@ +/** + * @file + * + * @ingroup RTEMSBSPsSPARCLEON3 + * + * @brief This source file contains the implementation of the Cache Manager. + */ + /* * Copyright (c) 2014 embedded brains GmbH & Co. KG * @@ -6,8 +14,18 @@ * 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 @@ -19,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, @@ -32,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) { @@ -63,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(®s->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) { @@ -74,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; |