Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:58

0001 /**
0002  * @file
0003  *
0004  * #ingroup RTEMSBSPsPowerPCShared
0005  *
0006  * @brief Header file for the Cache Manager PowerPC support.
0007  */
0008 
0009 /*
0010  *  Cache Management Support Routines for the MC68040
0011  * Modified for MPC8260 Andy Dachs <a.dachs@sstl.co.uk>
0012  * Surrey Satellite Technology Limited (SSTL), 2001
0013  */
0014 
0015 #include <rtems.h>
0016 #include <rtems/powerpc/powerpc.h>
0017 #include <rtems/powerpc/registers.h>
0018 
0019 /* Provide the CPU defines only if we have a cache */
0020 #if PPC_CACHE_ALIGNMENT != PPC_NO_CACHE_ALIGNMENT
0021   #define CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
0022   #define CPU_INSTRUCTION_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
0023 #endif
0024 
0025 #define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
0026 
0027 static inline size_t _CPU_cache_get_data_cache_size(uint32_t level)
0028 {
0029   switch (level) {
0030     case 0:
0031       /* Fall through */
0032 #ifdef PPC_CACHE_DATA_L3_SIZE
0033     case 3:
0034       return PPC_CACHE_DATA_L3_SIZE;
0035 #endif
0036 #ifdef PPC_CACHE_DATA_L2_SIZE
0037     case 2:
0038       return PPC_CACHE_DATA_L2_SIZE;
0039 #endif
0040 #ifdef PPC_CACHE_DATA_L1_SIZE
0041     case 1:
0042       return PPC_CACHE_DATA_L1_SIZE;
0043 #endif
0044     default:
0045       return 0;
0046   }
0047 }
0048 
0049 static inline size_t _CPU_cache_get_instruction_cache_size(uint32_t level)
0050 {
0051   switch (level) {
0052     case 0:
0053       /* Fall through */
0054 #ifdef PPC_CACHE_INSTRUCTION_L3_SIZE
0055     case 3:
0056       return PPC_CACHE_INSTRUCTION_L3_SIZE;
0057 #endif
0058 #ifdef PPC_CACHE_INSTRUCTION_L2_SIZE
0059     case 2:
0060       return PPC_CACHE_INSTRUCTION_L2_SIZE;
0061 #endif
0062 #ifdef PPC_CACHE_INSTRUCTION_L1_SIZE
0063     case 1:
0064       return PPC_CACHE_INSTRUCTION_L1_SIZE;
0065 #endif
0066     default:
0067       return 0;
0068   }
0069 }
0070 
0071 /*
0072  * CACHE MANAGER: The following functions are CPU-specific.
0073  * They provide the basic implementation for the rtems_* cache
0074  * management routines. If a given function has no meaning for the CPU,
0075  * it does nothing by default.
0076  *
0077  * FIXME: Some functions simply have not been implemented.
0078  */
0079 
0080 #if defined(ppc603) || defined(ppc603e) || defined(mpc8260) /* And possibly others */
0081 
0082 /* Helpful macros */
0083 #define PPC_Get_HID0( _value ) \
0084   do { \
0085       _value = 0;        /* to avoid warnings */ \
0086       __asm__ volatile( \
0087           "mfspr %0, 0x3f0;"     /* get HID0 */ \
0088           "isync" \
0089           : "=r" (_value) \
0090           : "0" (_value) \
0091       ); \
0092   } while (0)
0093 
0094 #define PPC_Set_HID0( _value ) \
0095   do { \
0096       __asm__ volatile( \
0097           "isync;" \
0098           "mtspr 0x3f0, %0;"     /* load HID0 */ \
0099           "isync" \
0100           : "=r" (_value) \
0101           : "0" (_value) \
0102       ); \
0103   } while (0)
0104 
0105 static inline void _CPU_cache_enable_data(void)
0106 {
0107   uint32_t   value;
0108   PPC_Get_HID0( value );
0109   value |= HID0_DCE;        /* set DCE bit */
0110   PPC_Set_HID0( value );
0111 }
0112 
0113 static inline void _CPU_cache_disable_data(void)
0114 {
0115   uint32_t   value;
0116   PPC_Get_HID0( value );
0117   value &= ~HID0_DCE;        /* clear DCE bit */
0118   PPC_Set_HID0( value );
0119 }
0120 
0121 static inline void _CPU_cache_invalidate_entire_data(void)
0122 {
0123   uint32_t  value;
0124   PPC_Get_HID0( value );
0125   value |= HID0_DCI;        /* set data flash invalidate bit */
0126   PPC_Set_HID0( value );
0127   value &= ~HID0_DCI;        /* clear data flash invalidate bit */
0128   PPC_Set_HID0( value );
0129 }
0130 
0131 static inline void _CPU_cache_freeze_data(void)
0132 {
0133   uint32_t  value;
0134   PPC_Get_HID0( value );
0135   value |= HID0_DLOCK;        /* set data cache lock bit */
0136   PPC_Set_HID0( value );
0137 }
0138 
0139 static inline void _CPU_cache_unfreeze_data(void)
0140 {
0141   uint32_t  value;
0142   PPC_Get_HID0( value );
0143   value &= ~HID0_DLOCK;        /* set data cache lock bit */
0144   PPC_Set_HID0( value );
0145 }
0146 
0147 static inline void _CPU_cache_flush_entire_data(void)
0148 {
0149   /*
0150    * FIXME: how can we do this?
0151    */
0152 }
0153 
0154 static inline void _CPU_cache_enable_instruction(void)
0155 {
0156   uint32_t   value;
0157   PPC_Get_HID0( value );
0158   value |= 0x00008000;       /* Set ICE bit */
0159   PPC_Set_HID0( value );
0160 }
0161 
0162 static inline void _CPU_cache_disable_instruction(void)
0163 {
0164   uint32_t   value;
0165   PPC_Get_HID0( value );
0166   value &= 0xFFFF7FFF;       /* Clear ICE bit */
0167   PPC_Set_HID0( value );
0168 }
0169 
0170 static inline void _CPU_cache_invalidate_entire_instruction(void)
0171 {
0172   uint32_t  value;
0173   PPC_Get_HID0( value );
0174   value |= HID0_ICFI;        /* set data flash invalidate bit */
0175   PPC_Set_HID0( value );
0176   value &= ~HID0_ICFI;        /* clear data flash invalidate bit */
0177   PPC_Set_HID0( value );
0178 }
0179 
0180 static inline void _CPU_cache_freeze_instruction(void)
0181 {
0182   uint32_t  value;
0183   PPC_Get_HID0( value );
0184   value |= HID0_ILOCK;        /* set instruction cache lock bit */
0185   PPC_Set_HID0( value );
0186 }
0187 
0188 static inline void _CPU_cache_unfreeze_instruction(void)
0189 {
0190   uint32_t  value;
0191   PPC_Get_HID0( value );
0192   value &= ~HID0_ILOCK;        /* set instruction cache lock bit */
0193   PPC_Set_HID0( value );
0194 }
0195 
0196 #elif ( defined(mpx8xx) || defined(mpc860) || defined(mpc821) )
0197 
0198 #define mtspr(_spr,_reg) \
0199   __asm__ volatile ( "mtspr %0, %1\n" : : "i" ((_spr)), "r" ((_reg)) )
0200 #define isync \
0201   __asm__ volatile ("isync\n"::)
0202 
0203 static inline void _CPU_cache_flush_entire_data(void) {}
0204 static inline void _CPU_cache_invalidate_entire_data(void) {}
0205 static inline void _CPU_cache_freeze_data(void) {}
0206 static inline void _CPU_cache_unfreeze_data(void) {}
0207 
0208 static inline void _CPU_cache_enable_data(void)
0209 {
0210   uint32_t   r1;
0211   r1 = (0x2<<24);
0212   mtspr( 568, r1 );
0213   isync;
0214 }
0215 
0216 static inline void _CPU_cache_disable_data(void)
0217 {
0218   uint32_t   r1;
0219   r1 = (0x4<<24);
0220   mtspr( 568, r1 );
0221   isync;
0222 }
0223 
0224 static inline void _CPU_cache_invalidate_entire_instruction(void) {}
0225 static inline void _CPU_cache_freeze_instruction(void) {}
0226 static inline void _CPU_cache_unfreeze_instruction(void) {}
0227 
0228 static inline void _CPU_cache_enable_instruction(void)
0229 {
0230   uint32_t   r1;
0231   r1 = (0x2<<24);
0232   mtspr( 560, r1 );
0233   isync;
0234 }
0235 
0236 static inline void _CPU_cache_disable_instruction(void)
0237 {
0238   uint32_t   r1;
0239   r1 = (0x4<<24);
0240   mtspr( 560, r1 );
0241   isync;
0242 }
0243 
0244 #else
0245 
0246 static inline void _CPU_cache_flush_entire_data(void)
0247 {
0248     /* Void */
0249 }
0250 
0251 static inline void _CPU_cache_invalidate_entire_data(void)
0252 {
0253     /* Void */
0254 }
0255 
0256 static inline void _CPU_cache_freeze_data(void)
0257 {
0258     /* Void */
0259 }
0260 
0261 static inline void _CPU_cache_unfreeze_data(void)
0262 {
0263     /* Void */
0264 }
0265 
0266 static inline void _CPU_cache_enable_data(void)
0267 {
0268     /* Void */
0269 }
0270 
0271 static inline void _CPU_cache_disable_data(void)
0272 {
0273     /* Void */
0274 }
0275 
0276 static inline void _CPU_cache_invalidate_entire_instruction(void)
0277 {
0278     /* Void */
0279 }
0280 
0281 static inline void _CPU_cache_freeze_instruction(void)
0282 {
0283     /* Void */
0284 }
0285 
0286 static inline void _CPU_cache_unfreeze_instruction(void)
0287 {
0288     /* Void */
0289 }
0290 
0291 static inline void _CPU_cache_enable_instruction(void)
0292 {
0293     /* Void */
0294 }
0295 
0296 static inline void _CPU_cache_disable_instruction(void)
0297 {
0298     /* Void */
0299 }
0300 
0301 #endif
0302 
0303 static inline void _CPU_cache_invalidate_1_data_line(const void *addr)
0304 {
0305   __asm__ volatile ( "dcbi 0,%0" :: "r" (addr) : "memory" );
0306 }
0307 
0308 static inline void _CPU_cache_flush_1_data_line(const void *addr)
0309 {
0310   __asm__ volatile ( "dcbf 0,%0" :: "r" (addr) : "memory" );
0311 }
0312 
0313 
0314 static inline void _CPU_cache_invalidate_1_instruction_line(const void *addr)
0315 {
0316   __asm__ volatile ( "icbi 0,%0" :: "r" (addr) : "memory");
0317 }
0318 
0319 #include "../../../bsps/shared/cache/cacheimpl.h"