Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:08

0001 /**
0002  * @file
0003  *
0004  * @ingroup RTEMSBSPsSPARCLEON3
0005  *
0006  * @brief This source file contains the implementation of the Cache Manager.
0007  */
0008 
0009 /*
0010  * Copyright (c) 2014 embedded brains GmbH & Co. KG
0011  *
0012  * The license and distribution terms for this file may be
0013  * found in the file LICENSE in this distribution or at
0014  * http://www.rtems.org/license/LICENSE.
0015  */
0016 
0017 #include <grlib/l2cache-regs.h>
0018 #include <grlib/io.h>
0019 
0020 #include <bsp/leon3.h>
0021 
0022 #if !defined(LEON3_L2CACHE_BASE)
0023 #include <grlib/ambapp.h>
0024 #endif
0025 
0026 #if !defined(LEON3_L2CACHE_BASE) || LEON3_L2CACHE_BASE != 0
0027 #define LEON3_MAYBE_HAS_L2CACHE
0028 #endif
0029 
0030 #define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
0031 
0032 #define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
0033 
0034 #define CPU_CACHE_NO_INSTRUCTION_CACHE_SNOOPING
0035 
0036 #define CPU_INSTRUCTION_CACHE_ALIGNMENT 64
0037 
0038 #define CPU_DATA_CACHE_ALIGNMENT 64
0039 
0040 #if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
0041 rtems_interrupt_lock leon3_l2c_lock =
0042   RTEMS_INTERRUPT_LOCK_INITIALIZER( "LEON3 L2C" );
0043 #endif
0044 
0045 static inline uint32_t l2c_load_32(const volatile uint32_t *address)
0046 {
0047   rtems_interrupt_lock_context lock_context;
0048   uint32_t value;
0049 
0050   rtems_interrupt_lock_acquire(&leon3_l2c_lock, &lock_context);
0051   value = grlib_load_32(address);
0052   rtems_interrupt_lock_release(&leon3_l2c_lock, &lock_context);
0053 
0054   return value;
0055 }
0056 
0057 #if !defined(LEON3_L2CACHE_BASE)
0058 static inline l2cache *get_l2c_regs(void)
0059 {
0060   struct ambapp_dev *adev;
0061 
0062   adev = (struct ambapp_dev *) ambapp_for_each(
0063     ambapp_plb(),
0064     OPTIONS_ALL | OPTIONS_AHB_SLVS,
0065     VENDOR_GAISLER,
0066     GAISLER_L2CACHE,
0067     ambapp_find_by_idx,
0068     NULL
0069   );
0070 
0071   if (adev == NULL) {
0072     return NULL;
0073   }
0074 
0075   return (l2cache *) DEV_TO_AHB(adev)->start[1];
0076 }
0077 #endif
0078 
0079 static inline size_t get_l1_size(uint32_t l1_cfg)
0080 {
0081   uint32_t ways = ((l1_cfg >> 24) & 0x7) + 1;
0082   uint32_t wsize = UINT32_C(1) << (((l1_cfg >> 20) & 0xf) + 10);
0083 
0084   return ways * wsize;
0085 }
0086 
0087 #if defined(LEON3_MAYBE_HAS_L2CACHE)
0088 static inline size_t get_l2_size(void)
0089 {
0090   l2cache *regs;
0091   unsigned status;
0092   unsigned ways;
0093   unsigned set_size;
0094 
0095 #if defined(LEON3_L2CACHE_BASE)
0096   regs = (l2cache *) LEON3_L2CACHE_BASE;
0097 #else
0098   regs = get_l2c_regs();
0099 
0100   if (regs == NULL) {
0101     return 0;
0102   }
0103 #endif
0104 
0105   status = l2c_load_32(&regs->l2cs);
0106   ways = L2CACHE_L2CS_WAY_GET(status) + 1;
0107   set_size = L2CACHE_L2CS_WAY_SIZE_GET(status) * 1024;
0108 
0109   return ways * set_size;
0110 }
0111 
0112 static inline size_t get_max_size(size_t a, size_t b)
0113 {
0114   return a < b ? b : a;
0115 }
0116 #endif
0117 
0118 static inline size_t get_cache_size(uint32_t level, uint32_t l1_cfg)
0119 {
0120   size_t size;
0121 
0122   switch (level) {
0123     case 0:
0124 #if defined(LEON3_MAYBE_HAS_L2CACHE)
0125       size = get_max_size(get_l1_size(l1_cfg), get_l2_size());
0126 #else
0127       size = get_l1_size(l1_cfg);
0128 #endif
0129       break;
0130     case 1:
0131       size = get_l1_size(l1_cfg);
0132       break;
0133 #if defined(LEON3_MAYBE_HAS_L2CACHE)
0134     case 2:
0135       size = get_l2_size();
0136       break;
0137 #endif
0138     default:
0139       size = 0;
0140       break;
0141   }
0142 
0143   return size;
0144 }
0145 
0146 static inline size_t _CPU_cache_get_data_cache_size(uint32_t level)
0147 {
0148   return get_cache_size(level, leon3_get_data_cache_config_register());
0149 }
0150 
0151 static inline void _CPU_cache_flush_data_range(
0152   const void *d_addr,
0153   size_t n_bytes
0154 )
0155 {
0156   /* TODO */
0157 }
0158 
0159 static inline void _CPU_cache_invalidate_data_range(
0160   const void *d_addr,
0161   size_t n_bytes
0162 )
0163 {
0164   /* TODO */
0165 }
0166 
0167 static inline void _CPU_cache_freeze_data(void)
0168 {
0169   /* TODO */
0170 }
0171 
0172 static inline void _CPU_cache_unfreeze_data(void)
0173 {
0174   /* TODO */
0175 }
0176 
0177 static inline void _CPU_cache_invalidate_entire_instruction(void)
0178 {
0179   uint32_t cache_reg = leon3_get_cache_control_register();
0180 
0181   cache_reg |= LEON3_REG_CACHE_CTRL_FI;
0182   leon3_set_cache_control_register(cache_reg);
0183 }
0184 
0185 static inline void _CPU_cache_invalidate_instruction_range(
0186   const void *i_addr,
0187   size_t n_bytes
0188 )
0189 {
0190   _CPU_cache_invalidate_entire_instruction();
0191 }
0192 
0193 static inline void _CPU_cache_freeze_instruction(void)
0194 {
0195   /* TODO */
0196 }
0197 
0198 static inline void _CPU_cache_unfreeze_instruction(void)
0199 {
0200   /* TODO */
0201 }
0202 
0203 static inline void _CPU_cache_flush_entire_data(void)
0204 {
0205   /* TODO */
0206 }
0207 
0208 static inline void _CPU_cache_invalidate_entire_data(void)
0209 {
0210   /* TODO */
0211 }
0212 
0213 static inline void _CPU_cache_enable_data(void)
0214 {
0215   /* TODO */
0216 }
0217 
0218 static inline void _CPU_cache_disable_data(void)
0219 {
0220   /* TODO */
0221 }
0222 
0223 static inline size_t _CPU_cache_get_instruction_cache_size( uint32_t level )
0224 {
0225   return get_cache_size(level, leon3_get_inst_cache_config_register());
0226 }
0227 
0228 static inline void _CPU_cache_enable_instruction(void)
0229 {
0230   /* TODO */
0231 }
0232 
0233 static inline void _CPU_cache_disable_instruction(void)
0234 {
0235   /* TODO */
0236 }
0237 
0238 #include "../../../shared/cache/cacheimpl.h"