Back to home page

LXR

 
 

    


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

0001 /**
0002  * @file
0003  *
0004  * @ingroup L2C310CacheSupport
0005  *
0006  * @brief This source file contains the implementation of the ARM L2C-310 cache
0007  *   controller support.
0008  */
0009 
0010 /*
0011  * Authorship
0012  * ----------
0013  * This software was created by
0014  *     R. Claus <claus@slac.stanford.edu>, 2013,
0015  *       Stanford Linear Accelerator Center, Stanford University.
0016  *
0017  * Acknowledgement of sponsorship
0018  * ------------------------------
0019  * This software was produced by
0020  *     the Stanford Linear Accelerator Center, Stanford University,
0021  *     under Contract DE-AC03-76SFO0515 with the Department of Energy.
0022  *
0023  * Government disclaimer of liability
0024  * ----------------------------------
0025  * Neither the United States nor the United States Department of Energy,
0026  * nor any of their employees, makes any warranty, express or implied, or
0027  * assumes any legal liability or responsibility for the accuracy,
0028  * completeness, or usefulness of any data, apparatus, product, or process
0029  * disclosed, or represents that its use would not infringe privately owned
0030  * rights.
0031  *
0032  * Stanford disclaimer of liability
0033  * --------------------------------
0034  * Stanford University makes no representations or warranties, express or
0035  * implied, nor assumes any liability for the use of this software.
0036  *
0037  * Stanford disclaimer of copyright
0038  * --------------------------------
0039  * Stanford University, owner of the copyright, hereby disclaims its
0040  * copyright and all other rights in this software.  Hence, anyone may
0041  * freely use it for any purpose without restriction.
0042  *
0043  * Maintenance of notices
0044  * ----------------------
0045  * In the interest of clarity regarding the origin and status of this
0046  * SLAC software, this and all the preceding Stanford University notices
0047  * are to remain affixed to any copy or derivative of this software made
0048  * or distributed by the recipient and are to be affixed to any copy of
0049  * software made or distributed by the recipient that contains a copy or
0050  * derivative of this software.
0051  *
0052  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
0053  */
0054 
0055 #include <assert.h>
0056 #include <bsp.h>
0057 #include <bsp/fatal.h>
0058 #include <libcpu/arm-cp15.h>
0059 #include <rtems.h>
0060 #include <rtems/score/smpimpl.h>
0061 #include <bsp/arm-release-id.h>
0062 #include <bsp/arm-errata.h>
0063 
0064 #include "cache-cp15.h"
0065 
0066 /**
0067  * @defgroup L2C310CacheSupport L2C-310 Cache Support
0068  *
0069  * @ingroup RTEMSImplClassicCache
0070  *
0071  * @brief This group contains the L2C-310 cache support.
0072  *
0073  * @{
0074  */
0075 
0076 /* These two defines also ensure that the rtems_cache_* functions have bodies */
0077 #define CPU_DATA_CACHE_ALIGNMENT ARM_CACHE_L1_CPU_DATA_ALIGNMENT
0078 #define CPU_INSTRUCTION_CACHE_ALIGNMENT ARM_CACHE_L1_CPU_INSTRUCTION_ALIGNMENT
0079 #if defined(__ARM_ARCH_7A__)
0080 /* Some/many ARM Cortex-A cores have L1 data line length 64 bytes */
0081 #define CPU_MAXIMAL_CACHE_ALIGNMENT 64
0082 #endif
0083 #define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS
0084 #define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
0085 
0086 #define L2C_310_DATA_LINE_MASK ( CPU_DATA_CACHE_ALIGNMENT - 1 )
0087 #define L2C_310_INSTRUCTION_LINE_MASK \
0088   ( CPU_INSTRUCTION_CACHE_ALIGNMENT \
0089     - 1 )
0090 #define L2C_310_NUM_WAYS 8
0091 #define L2C_310_WAY_MASK ( ( 1 << L2C_310_NUM_WAYS ) - 1 )
0092 
0093 #define L2C_310_MIN( a, b ) \
0094   ((a < b) ? (a) : (b))
0095 
0096 #define L2C_310_MAX_LOCKING_BYTES (4 * 1024)
0097 
0098 
0099 /* RTL release number as can be read from cache_id register */
0100 #define L2C_310_RTL_RELEASE_R0_P0 0x0
0101 #define L2C_310_RTL_RELEASE_R1_P0 0x2
0102 #define L2C_310_RTL_RELEASE_R2_P0 0x4
0103 #define L2C_310_RTL_RELEASE_R3_P0 0x5
0104 #define L2C_310_RTL_RELEASE_R3_P1 0x6
0105 #define L2C_310_RTL_RELEASE_R3_P2 0x8
0106 #define L2C_310_RTL_RELEASE_R3_P3 0x9
0107 
0108 #define BSP_ARM_L2C_310_RTL_RELEASE (BSP_ARM_L2C_310_ID & L2C_310_ID_RTL_MASK)
0109 
0110 /**
0111  * @brief L2CC Register Offsets
0112  */
0113 typedef struct {
0114   /** @brief Cache ID */
0115   uint32_t cache_id;
0116 #define L2C_310_ID_RTL_MASK 0x3f
0117 #define L2C_310_ID_PART_MASK ( 0xf << 6 )
0118 #define L2C_310_ID_PART_L210 ( 1 << 6 )
0119 #define L2C_310_ID_PART_L310 ( 3 << 6 )
0120 #define L2C_310_ID_IMPL_MASK ( 0xff << 24 )
0121   /** @brief Cache type */
0122   uint32_t cache_type;
0123 /** @brief 1 if data banking implemented, 0 if not */
0124 #define L2C_310_TYPE_DATA_BANKING_MASK 0x80000000
0125 /** @brief 11xy, where: x=1 if pl310_LOCKDOWN_BY_MASTER is defined, otherwise 0 */
0126 #define L2C_310_TYPE_CTYPE_MASK 0x1E000000
0127 /** @brief y=1 if pl310_LOCKDOWN_BY_LINE is defined, otherwise 0. */
0128 #define L2C_310_TYPE_CTYPE_SHIFT 25
0129 /** @brief 1 for Harvard architecture, 0 for unified architecture */
0130 #define L2C_310_TYPE_HARVARD_MASK 0x01000000
0131 /** @brief Data cache way size = 2 Exp(value + 2) KB */
0132 #define L2C_310_TYPE_SIZE_D_WAYS_MASK 0x00700000
0133 #define L2C_310_TYPE_SIZE_D_WAYS_SHIFT 20
0134 /** @brief Assoziativity aka number of data ways = (value * 8) + 8 */
0135 #define L2C_310_TYPE_NUM_D_WAYS_MASK 0x00040000
0136 #define L2C_310_TYPE_NUM_D_WAYS_SHIFT 18
0137 /** @brief Data cache line length 00 - 32 */
0138 #define L2C_310_TYPE_LENGTH_D_LINE_MASK 0x00003000
0139 #define L2C_310_TYPE_LENGTH_D_LINE_SHIFT 12
0140 #define L2C_310_TYPE_LENGTH_D_LINE_VAL_32 0x0
0141 /** @brief Instruction cache way size = 2 Exp(value + 2) KB */
0142 #define L2C_310_TYPE_SIZE_I_WAYS_MASK 0x00000700
0143 #define L2C_310_TYPE_SIZE_I_WAYS_SHIFT 8
0144 /** @brief Assoziativity aka number of instruction ways = (value * 8) + 8 */
0145 #define L2C_310_TYPE_NUM_I_WAYS_MASK 0x00000040
0146 #define L2C_310_TYPE_NUM_I_WAYS_SHIFT 6
0147 /** @brief Instruction cache line length 00 - 32 */
0148 #define L2C_310_TYPE_LENGTH_I_LINE_MASK 0x00000003
0149 #define L2C_310_TYPE_LENGTH_I_LINE_SHIFT 0
0150 #define L2C_310_TYPE_LENGTH_I_LINE_VAL_32 0x0
0151 
0152   uint8_t reserved_8[0x100 - 8];
0153   uint32_t ctrl; /* Control */
0154 /** @brief Enables the L2CC */
0155 #define L2C_310_CTRL_ENABLE 0x00000001
0156 
0157 #define L2C_310_CTRL_EXCL_CONFIG (1 << 12)
0158 
0159   /** @brief Auxiliary control */
0160   uint32_t aux_ctrl;
0161 
0162 /** @brief Early BRESP Enable */
0163 #define L2C_310_AUX_EBRESPE_MASK 0x40000000
0164 
0165 /** @brief Instruction Prefetch Enable */
0166 #define L2C_310_AUX_IPFE_MASK 0x20000000
0167 
0168 /** @brief Data Prefetch Enable */
0169 #define L2C_310_AUX_DPFE_MASK 0x10000000
0170 
0171 /** @brief Non-secure interrupt access control */
0172 #define L2C_310_AUX_NSIC_MASK 0x08000000
0173 
0174 /** @brief Non-secure lockdown enable */
0175 #define L2C_310_AUX_NSLE_MASK 0x04000000
0176 
0177 /** @brief Cache replacement policy */
0178 #define L2C_310_AUX_CRP_MASK 0x02000000
0179 
0180 /** @brief Force write allocate */
0181 #define L2C_310_AUX_FWE_MASK 0x01800000
0182 
0183 /** @brief Shared attribute override enable */
0184 #define L2C_310_AUX_SAOE_MASK 0x00400000
0185 
0186 /** @brief Parity enable */
0187 #define L2C_310_AUX_PE_MASK 0x00200000
0188 
0189 /** @brief Event monitor bus enable */
0190 #define L2C_310_AUX_EMBE_MASK 0x00100000
0191 
0192 /** @brief Way-size */
0193 #define L2C_310_AUX_WAY_SIZE_MASK 0x000E0000
0194 #define L2C_310_AUX_WAY_SIZE_SHIFT 17
0195 
0196 /** @brief Way-size */
0197 #define L2C_310_AUX_ASSOC_MASK 0x00010000
0198 
0199 /** @brief Shared attribute invalidate enable */
0200 #define L2C_310_AUX_SAIE_MASK 0x00002000
0201 
0202 /** @brief Exclusive cache configuration */
0203 #define L2C_310_AUX_EXCL_CACHE_MASK 0x00001000
0204 
0205 /** @brief Store buffer device limitation Enable */
0206 #define L2C_310_AUX_SBDLE_MASK 0x00000800
0207 
0208 /** @brief High Priority for SO and Dev Reads Enable */
0209 #define L2C_310_AUX_HPSODRE_MASK 0x00000400
0210 
0211 /** @brief Full line of zero enable */
0212 #define L2C_310_AUX_FLZE_MASK 0x00000001
0213 
0214 /** @brief Enable all prefetching, */
0215 #define L2C_310_AUX_REG_DEFAULT_MASK \
0216   ( L2C_310_AUX_WAY_SIZE_MASK & ( 0x3 << L2C_310_AUX_WAY_SIZE_SHIFT ) ) \
0217   | L2C_310_AUX_PE_MASK      /* Prefetch enable */ \
0218   | L2C_310_AUX_SAOE_MASK    /* Shared attribute override enable */ \
0219   | L2C_310_AUX_CRP_MASK     /* Cache replacement policy */ \
0220   | L2C_310_AUX_DPFE_MASK    /* Data prefetch enable */ \
0221   | L2C_310_AUX_IPFE_MASK    /* Instruction prefetch enable */ \
0222   | L2C_310_AUX_EBRESPE_MASK /* Early BRESP enable */
0223 
0224 #define L2C_310_AUX_REG_ZERO_MASK 0xFFF1FFFF
0225 
0226 /** @brief 1 cycle of latency, there is no additional latency fot tag RAM */
0227 #define L2C_310_RAM_1_CYCLE_LAT_VAL 0x00000000
0228 /** @brief 2 cycles of latency for tag RAM */
0229 #define L2C_310_RAM_2_CYCLE_LAT_VAL 0x00000001
0230 /** @brief 3 cycles of latency for tag RAM */
0231 #define L2C_310_RAM_3_CYCLE_LAT_VAL 0x00000002
0232 /** @brief 4 cycles of latency for tag RAM */
0233 #define L2C_310_RAM_4_CYCLE_LAT_VAL 0x00000003
0234 /** @brief 5 cycles of latency for tag RAM */
0235 #define L2C_310_RAM_5_CYCLE_LAT_VAL 0x00000004
0236 /** @brief 6 cycles of latency for tag RAM */
0237 #define L2C_310_RAM_6_CYCLE_LAT_VAL 0x00000005
0238 /** @brief 7 cycles of latency for tag RAM */
0239 #define L2C_310_RAM_7_CYCLE_LAT_VAL 0x00000006
0240 /** @brief 8 cycles of latency for tag RAM */
0241 #define L2C_310_RAM_8_CYCLE_LAT_VAL 0x00000007
0242 /** @brief Shift left setup latency values by this value */
0243 #define L2C_310_RAM_SETUP_SHIFT 0x00000000
0244 /** @brief Shift left read latency values by this value */
0245 #define L2C_310_RAM_READ_SHIFT 0x00000004
0246 /** @brief Shift left write latency values by this value */
0247 #define L2C_310_RAM_WRITE_SHIFT 0x00000008
0248 /** @brief Mask for RAM setup latency */
0249 #define L2C_310_RAM_SETUP_LAT_MASK 0x00000007
0250 /** @brief Mask for RAM read latency */
0251 #define L2C_310_RAM_READ_LAT_MASK 0x00000070
0252 /** @brief Mask for RAM read latency */
0253 #define L2C_310_RAM_WRITE_LAT_MASK 0x00000700
0254   /** @brief Latency for tag RAM */
0255   uint32_t tag_ram_ctrl;
0256 /* @brief Latency for tag RAM */
0257 #define L2C_310_TAG_RAM_DEFAULT_LAT \
0258   ( ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_SETUP_SHIFT ) \
0259     | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_READ_SHIFT ) \
0260     | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_WRITE_SHIFT ) )
0261   /** @brief Latency for data RAM */
0262   uint32_t data_ram_ctrl;
0263 /** @brief Latency for data RAM */
0264 #define L2C_310_DATA_RAM_DEFAULT_MASK \
0265   ( ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_SETUP_SHIFT ) \
0266     | ( L2C_310_RAM_3_CYCLE_LAT_VAL << L2C_310_RAM_READ_SHIFT ) \
0267     | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_WRITE_SHIFT ) )
0268 
0269   uint8_t reserved_110[0x200 - 0x110];
0270 
0271   /** @brief Event counter control */
0272   uint32_t ev_ctrl;
0273 
0274   /** @brief Event counter 1 configuration */
0275   uint32_t ev_cnt1_cfg;
0276 
0277   /** @brief Event counter 0 configuration */
0278   uint32_t ev_cnt0_cfg;
0279 
0280   /** @brief Event counter 1 value */
0281   uint32_t ev_cnt1;
0282 
0283   /** @brief Event counter 0 value */
0284   uint32_t ev_cnt0;
0285 
0286   /** @brief Interrupt enable mask */
0287   uint32_t int_mask;
0288 
0289   /** @brief Masked   interrupt status (read-only)*/
0290   uint32_t int_mask_status;
0291 
0292   /** @brief Unmasked interrupt status */
0293   uint32_t int_raw_status;
0294 
0295   /** @brief Interrupt clear */
0296   uint32_t int_clr;
0297 
0298 /**
0299  * @name Interrupt bit masks
0300  *
0301  * @{
0302  */
0303 
0304 /** @brief DECERR from L3 */
0305 #define L2C_310_INT_DECERR_MASK 0x00000100
0306 
0307 /** @brief SLVERR from L3 */
0308 #define L2C_310_INT_SLVERR_MASK 0x00000080
0309 
0310 /** @brief Error on L2 data RAM (Read) */
0311 #define L2C_310_INT_ERRRD_MASK 0x00000040
0312 
0313 /** @brief Error on L2 tag RAM (Read) */
0314 #define L2C_310_INT_ERRRT_MASK 0x00000020
0315 
0316 /** @brief Error on L2 data RAM (Write) */
0317 #define L2C_310_INT_ERRWD_MASK 0x00000010
0318 
0319 /** @brief Error on L2 tag RAM (Write) */
0320 #define L2C_310_INT_ERRWT_MASK 0x00000008
0321 
0322 /** @brief Parity Error on L2 data RAM (Read) */
0323 #define L2C_310_INT_PARRD_MASK 0x00000004
0324 
0325 /** @brief Parity Error on L2 tag RAM (Read) */
0326 #define L2C_310_INT_PARRT_MASK 0x00000002
0327 
0328 /** @brief Event Counter1/0 Overflow Increment */
0329 #define L2C_310_INT_ECNTR_MASK 0x00000001
0330 
0331 /** @} */
0332 
0333   uint8_t reserved_224[0x730 - 0x224];
0334 
0335   /** @brief Drain the STB */
0336   uint32_t cache_sync;
0337   uint8_t reserved_734[0x740 - 0x734];
0338   /** @brief ARM Errata 753970 for pl310-r3p0 */
0339   uint32_t dummy_cache_sync_reg;
0340   uint8_t reserved_744[0x770 - 0x744];
0341 
0342   /** @brief Invalidate line by PA */
0343   uint32_t inv_pa;
0344   uint8_t reserved_774[0x77c - 0x774];
0345 
0346   /** @brief Invalidate by Way */
0347   uint32_t inv_way;
0348   uint8_t reserved_780[0x7b0 - 0x780];
0349 
0350   /** @brief Clean Line by PA */
0351   uint32_t clean_pa;
0352   uint8_t reserved_7b4[0x7b8 - 0x7b4];
0353 
0354   /** @brief Clean Line by Set/Way */
0355   uint32_t clean_index;
0356 
0357   /** @brief Clean by Way */
0358   uint32_t clean_way;
0359   uint8_t reserved_7c0[0x7f0 - 0x7c0];
0360 
0361   /** @brief Clean and Invalidate Line by PA */
0362   uint32_t clean_inv_pa;
0363   uint8_t reserved_7f4[0x7f8 - 0x7f4];
0364 
0365   /** @brief Clean and Invalidate Line by Set/Way */
0366   uint32_t clean_inv_indx;
0367 
0368   /** @brief Clean and Invalidate by Way */
0369   uint32_t clean_inv_way;
0370 
0371   /** @brief Data        lock down 0 */
0372   uint32_t d_lockdown_0;
0373 
0374   /** @brief Instruction lock down 0 */
0375   uint32_t i_lockdown_0;
0376 
0377   /** @brief Data        lock down 1 */
0378   uint32_t d_lockdown_1;
0379 
0380   /** @brief Instruction lock down 1 */
0381   uint32_t i_lockdown_1;
0382 
0383   /** @brief Data        lock down 2 */
0384   uint32_t d_lockdown_2;
0385 
0386   /** @brief Instruction lock down 2 */
0387   uint32_t i_lockdown_2;
0388 
0389   /** @brief Data        lock down 3 */
0390   uint32_t d_lockdown_3;
0391 
0392   /** @brief Instruction lock down 3 */
0393   uint32_t i_lockdown_3;
0394 
0395   /** @brief Data        lock down 4 */
0396   uint32_t d_lockdown_4;
0397 
0398   /** @brief Instruction lock down 4 */
0399   uint32_t i_lockdown_4;
0400 
0401   /** @brief Data        lock down 5 */
0402   uint32_t d_lockdown_5;
0403 
0404   /** @brief Instruction lock down 5 */
0405   uint32_t i_lockdown_5;
0406 
0407   /** @brief Data        lock down 6 */
0408   uint32_t d_lockdown_6;
0409 
0410   /** @brief Instruction lock down 6 */
0411   uint32_t i_lockdown_6;
0412 
0413   /** @brief Data        lock down 7 */
0414   uint32_t d_lockdown_7;
0415 
0416   /** @brief Instruction lock down 7 */
0417   uint32_t i_lockdown_7;
0418 
0419   uint8_t reserved_940[0x950 - 0x940];
0420 
0421   /** @brief Lockdown by Line Enable */
0422   uint32_t lock_line_en;
0423 
0424   /** @brief Cache lockdown by way */
0425   uint32_t unlock_way;
0426 
0427   uint8_t reserved_958[0xc00 - 0x958];
0428 
0429   /** @brief Address range redirect, part 1 */
0430   uint32_t addr_filtering_start;
0431 
0432   /** @brief Address range redirect, part 2 */
0433   uint32_t addr_filtering_end;
0434 
0435 /** @brief Address filtering valid bits*/
0436 #define L2C_310_ADDR_FILTER_VALID_MASK 0xFFF00000
0437 
0438 /** @brief Address filtering enable bit*/
0439 #define L2C_310_ADDR_FILTER_ENABLE_MASK 0x00000001
0440 
0441   uint8_t reserved_c08[0xf40 - 0xc08];
0442 
0443   /** @brief Debug control */
0444   uint32_t debug_ctrl;
0445 
0446 /** @brief Debug SPIDEN bit */
0447 #define L2C_310_DEBUG_SPIDEN_MASK 0x00000004
0448 
0449 /** @brief Debug DWB bit, forces write through */
0450 #define L2C_310_DEBUG_DWB_MASK 0x00000002
0451 
0452 /** @brief Debug DCL bit, disables cache line fill */
0453 #define L2C_310_DEBUG_DCL_MASK 0x00000002
0454 
0455   uint8_t reserved_f44[0xf60 - 0xf44];
0456 
0457   /** @brief Purpose prefetch enables */
0458   uint32_t prefetch_ctrl;
0459 /** @brief Prefetch offset */
0460 #define L2C_310_PREFETCH_OFFSET_MASK 0x0000001F
0461   uint8_t reserved_f64[0xf80 - 0xf64];
0462 
0463   /** @brief Purpose power controls */
0464   uint32_t power_ctrl;
0465 } L2CC;
0466 
0467 rtems_interrupt_lock l2c_310_lock = RTEMS_INTERRUPT_LOCK_INITIALIZER(
0468   "L2-310 cache controller"
0469 );
0470 
0471 /* Errata table for the LC2 310 Level 2 cache from ARM.
0472 * Information taken from ARMs
0473 * "CoreLink controllers and peripherals
0474 * - System controllers
0475 * - L2C-310 Level 2 Cache Controller
0476 * - Revision r3p3
0477 * - Software Developer Errata Notice
0478 * - ARM CoreLink Level 2 Cache Controller (L2C-310 or PL310),
0479 *   r3 releases Software Developers Errata Notice"
0480 * Please see this document for more information on these erratas */
0481 #if BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R3_P0
0482 #define L2C_310_ERRATA_IS_APPLICABLE_753970
0483 #endif
0484 
0485 static bool l2c_310_errata_is_applicable_727913(
0486   uint32_t rtl_release
0487 )
0488 {
0489   bool is_applicable = false;
0490 
0491   switch ( rtl_release ) {
0492     case L2C_310_RTL_RELEASE_R3_P3:
0493     case L2C_310_RTL_RELEASE_R3_P2:
0494     case L2C_310_RTL_RELEASE_R3_P1:
0495     case L2C_310_RTL_RELEASE_R2_P0:
0496     case L2C_310_RTL_RELEASE_R1_P0:
0497     case L2C_310_RTL_RELEASE_R0_P0:
0498       is_applicable = false;
0499       break;
0500     case L2C_310_RTL_RELEASE_R3_P0:
0501       is_applicable = true;
0502       break;
0503     default:
0504       assert( 0 );
0505       break;
0506   }
0507 
0508   return is_applicable;
0509 }
0510 
0511 static bool l2c_310_errata_is_applicable_727914(
0512   uint32_t rtl_release
0513 )
0514 {
0515   bool is_applicable = false;
0516 
0517   switch ( rtl_release ) {
0518     case L2C_310_RTL_RELEASE_R3_P3:
0519     case L2C_310_RTL_RELEASE_R3_P2:
0520     case L2C_310_RTL_RELEASE_R3_P1:
0521     case L2C_310_RTL_RELEASE_R2_P0:
0522     case L2C_310_RTL_RELEASE_R1_P0:
0523     case L2C_310_RTL_RELEASE_R0_P0:
0524       is_applicable = false;
0525       break;
0526     case L2C_310_RTL_RELEASE_R3_P0:
0527       is_applicable = true;
0528       break;
0529     default:
0530       assert( 0 );
0531       break;
0532   }
0533 
0534   return is_applicable;
0535 }
0536 
0537 static bool l2c_310_errata_is_applicable_727915(
0538   uint32_t rtl_release
0539 )
0540 {
0541   bool is_applicable = false;
0542 
0543   switch ( rtl_release ) {
0544     case L2C_310_RTL_RELEASE_R3_P3:
0545     case L2C_310_RTL_RELEASE_R3_P2:
0546     case L2C_310_RTL_RELEASE_R3_P1:
0547     case L2C_310_RTL_RELEASE_R1_P0:
0548     case L2C_310_RTL_RELEASE_R0_P0:
0549       is_applicable = false;
0550       break;
0551     case L2C_310_RTL_RELEASE_R3_P0:
0552     case L2C_310_RTL_RELEASE_R2_P0:
0553       is_applicable = true;
0554       break;
0555     default:
0556       assert( 0 );
0557       break;
0558   }
0559 
0560   return is_applicable;
0561 }
0562 
0563 static bool l2c_310_errata_is_applicable_729806(
0564   uint32_t rtl_release
0565 )
0566 {
0567   bool is_applicable = false;
0568 
0569   switch ( rtl_release ) {
0570     case L2C_310_RTL_RELEASE_R3_P3:
0571     case L2C_310_RTL_RELEASE_R3_P2:
0572     case L2C_310_RTL_RELEASE_R2_P0:
0573     case L2C_310_RTL_RELEASE_R1_P0:
0574     case L2C_310_RTL_RELEASE_R0_P0:
0575       is_applicable = false;
0576       break;
0577     case L2C_310_RTL_RELEASE_R3_P1:
0578     case L2C_310_RTL_RELEASE_R3_P0:
0579       is_applicable = true;
0580       break;
0581     default:
0582       assert( 0 );
0583       break;
0584   }
0585 
0586   return is_applicable;
0587 }
0588 
0589 static bool l2c_310_errata_is_applicable_729815(
0590   uint32_t rtl_release
0591 )
0592 {
0593   bool is_applicable = false;
0594 
0595   switch ( rtl_release ) {
0596     case L2C_310_RTL_RELEASE_R3_P3:
0597     case L2C_310_RTL_RELEASE_R1_P0:
0598     case L2C_310_RTL_RELEASE_R0_P0:
0599       is_applicable = false;
0600       break;
0601     case L2C_310_RTL_RELEASE_R3_P2:
0602     case L2C_310_RTL_RELEASE_R3_P1:
0603     case L2C_310_RTL_RELEASE_R3_P0:
0604     case L2C_310_RTL_RELEASE_R2_P0:
0605       is_applicable = true;
0606       break;
0607     default:
0608       assert( 0 );
0609       break;
0610   }
0611 
0612   return is_applicable;
0613 }
0614 
0615 static bool l2c_310_errata_is_applicable_742884(
0616   uint32_t rtl_release
0617 )
0618 {
0619   bool is_applicable = false;
0620 
0621   switch ( rtl_release ) {
0622     case L2C_310_RTL_RELEASE_R3_P3:
0623     case L2C_310_RTL_RELEASE_R3_P2:
0624     case L2C_310_RTL_RELEASE_R3_P0:
0625     case L2C_310_RTL_RELEASE_R2_P0:
0626     case L2C_310_RTL_RELEASE_R1_P0:
0627     case L2C_310_RTL_RELEASE_R0_P0:
0628       is_applicable = false;
0629       break;
0630     case L2C_310_RTL_RELEASE_R3_P1:
0631       is_applicable = true;
0632       break;
0633     default:
0634       assert( 0 );
0635       break;
0636   }
0637 
0638   return is_applicable;
0639 }
0640 
0641 static bool l2c_310_errata_is_applicable_752271(
0642   uint32_t rtl_release
0643 )
0644 {
0645   bool is_applicable = false;
0646 
0647   switch ( rtl_release ) {
0648     case L2C_310_RTL_RELEASE_R3_P3:
0649     case L2C_310_RTL_RELEASE_R3_P2:
0650     case L2C_310_RTL_RELEASE_R2_P0:
0651     case L2C_310_RTL_RELEASE_R1_P0:
0652     case L2C_310_RTL_RELEASE_R0_P0:
0653       is_applicable = false;
0654       break;
0655     case L2C_310_RTL_RELEASE_R3_P1:
0656     case L2C_310_RTL_RELEASE_R3_P0:
0657       is_applicable = true;
0658       break;
0659     default:
0660       assert( 0 );
0661       break;
0662   }
0663 
0664   return is_applicable;
0665 }
0666 
0667 static bool l2c_310_errata_is_applicable_765569(
0668   uint32_t rtl_release
0669 )
0670 {
0671   bool is_applicable = false;
0672 
0673   switch ( rtl_release ) {
0674     case L2C_310_RTL_RELEASE_R3_P3:
0675     case L2C_310_RTL_RELEASE_R3_P2:
0676     case L2C_310_RTL_RELEASE_R3_P1:
0677     case L2C_310_RTL_RELEASE_R3_P0:
0678     case L2C_310_RTL_RELEASE_R2_P0:
0679     case L2C_310_RTL_RELEASE_R1_P0:
0680     case L2C_310_RTL_RELEASE_R0_P0:
0681       is_applicable = true;
0682       break;
0683     default:
0684       assert( 0 );
0685       break;
0686   }
0687 
0688   return is_applicable;
0689 }
0690 
0691 static bool l2c_310_errata_is_applicable_769419(
0692   uint32_t rtl_release
0693 )
0694 {
0695   bool is_applicable = false;
0696 
0697   switch ( rtl_release ) {
0698     case L2C_310_RTL_RELEASE_R3_P3:
0699     case L2C_310_RTL_RELEASE_R3_P2:
0700       is_applicable = false;
0701       break;
0702     case L2C_310_RTL_RELEASE_R3_P1:
0703     case L2C_310_RTL_RELEASE_R3_P0:
0704     case L2C_310_RTL_RELEASE_R2_P0:
0705     case L2C_310_RTL_RELEASE_R1_P0:
0706     case L2C_310_RTL_RELEASE_R0_P0:
0707       is_applicable = true;
0708       break;
0709     default:
0710       assert( 0 );
0711       break;
0712   }
0713 
0714   return is_applicable;
0715 }
0716 
0717 #if BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R0_P0 \
0718    || BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R1_P0
0719 #define L2C_310_ERRATA_IS_APPLICABLE_588369
0720 #endif
0721 
0722 #ifdef CACHE_ERRATA_CHECKS_FOR_IMPLEMENTED_ERRATAS
0723 static bool l2c_310_errata_is_applicable_754670(
0724   uint32_t rtl_release
0725 )
0726 {
0727   bool is_applicable = false;
0728 
0729   switch ( rtl_release ) {
0730     case L2C_310_RTL_RELEASE_R3_P3:
0731     case L2C_310_RTL_RELEASE_R3_P2:
0732     case L2C_310_RTL_RELEASE_R3_P1:
0733     case L2C_310_RTL_RELEASE_R3_P0:
0734     case L2C_310_RTL_RELEASE_R2_P0:
0735     case L2C_310_RTL_RELEASE_R1_P0:
0736     case L2C_310_RTL_RELEASE_R0_P0:
0737       is_applicable = true;
0738     break;
0739     default:
0740       assert( 0 );
0741       break;
0742   }
0743 
0744   return is_applicable;
0745 }
0746 #endif /* CACHE_ERRATA_CHECKS_FOR_IMPLEMENTED_ERRATAS */
0747 
0748 /* The common workaround for this erratum would be to add a
0749  * data synchronization barrier to the beginning of the abort handler.
0750  * But for RTEMS a call of the abort handler means a fatal condition anyway.
0751  * So there is no need to handle this erratum */
0752 #define CACHE_ARM_ERRATA_775420_HANDLER()                   \
0753   if( arm_errata_is_applicable_processor_errata_775420 ) {  \
0754   }                                                         \
0755 
0756 static void l2c_310_check_errata( uint32_t rtl_release )
0757 {
0758   /* This erratum gets handled within the sources */
0759   /* Unhandled erratum present: 588369 Errata 588369 says that clean + inv may
0760    * keep the cache line if it was clean. See ARMs documentation on the erratum
0761    * for a workaround */
0762   /* assert( ! l2c_310_errata_is_applicable_588369( rtl_release ) ); */
0763 
0764   /* Unhandled erratum present: 727913 Prefetch dropping feature can cause
0765    * incorrect behavior when PL310 handles reads that cross cache line
0766    * boundary */
0767   assert( ! l2c_310_errata_is_applicable_727913( rtl_release ) );
0768 
0769   /* Unhandled erratum present: 727914 Double linefill feature can cause
0770    * deadlock */
0771   assert( ! l2c_310_errata_is_applicable_727914( rtl_release ) );
0772 
0773   /* Unhandled erratum present: 727915 Background Clean and Invalidate by Way
0774    * operation can cause data corruption */
0775   assert( ! l2c_310_errata_is_applicable_727915( rtl_release ) );
0776 
0777   /* Unhandled erratum present: 729806 Speculative reads from the Cortex-A9
0778    * MPCore processor can cause deadlock */
0779   assert( ! l2c_310_errata_is_applicable_729806( rtl_release ) );
0780 
0781   if( l2c_310_errata_is_applicable_729815( rtl_release ) )
0782   {
0783     volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0784 
0785     assert( 0 == ( l2cc->aux_ctrl & L2C_310_AUX_HPSODRE_MASK ) );
0786 
0787     /* Erratum: 729815 The “High Priority for SO and Dev reads” feature can
0788      * cause Quality of Service issues to cacheable read transactions*/
0789 
0790     /* Conditions
0791        This problem occurs when the following conditions are met:
0792        1. Bit[10] “High Priority for SO and Dev reads enable” of the PL310
0793           Auxiliary Control Register is set to 1.
0794        2. PL310 receives a cacheable read that misses in the L2 cache.
0795        3. PL310 receives a continuous flow of Strongly Ordered or Device
0796           reads that take all address slots in the master interface.
0797        Workaround
0798        A workaround is only necessary in systems that are able to issue a
0799        continuous flow of Strongly Ordered or Device reads. In such a case,
0800        the workaround is to disable the “High Priority for SO and Dev reads”
0801        feature. This is the default behavior.*/
0802   }
0803 
0804   /* Unhandled erratum present: 742884 Double linefill feature might introduce
0805    * circular dependency and deadlock */
0806   assert( ! l2c_310_errata_is_applicable_742884( rtl_release ) );
0807 
0808   /* Unhandled erratum present: 752271 Double linefill feature can cause data
0809    * corruption */
0810   assert( ! l2c_310_errata_is_applicable_752271( rtl_release ) );
0811 
0812   /* This erratum can not be worked around: 754670 A continuous write flow can
0813    * stall a read targeting the same memory area
0814    * But this erratum does not lead to any data corruption */
0815   /* assert( ! l2c_310_errata_is_applicable_754670() ); */
0816 
0817   if( l2c_310_errata_is_applicable_765569( rtl_release ) )
0818   {
0819     volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0820 
0821     assert( !( ( l2cc->aux_ctrl & L2C_310_AUX_IPFE_MASK
0822                  || l2cc->aux_ctrl & L2C_310_AUX_DPFE_MASK )
0823                && ( ( l2cc->prefetch_ctrl & L2C_310_PREFETCH_OFFSET_MASK )
0824                     == 23 ) ) );
0825 
0826     /* Unhandled erratum present: 765569 Prefetcher can cross 4KB boundary if
0827      * offset is programmed with value 23 */
0828 
0829     /* Conditions
0830        This problem occurs when the following conditions are met:
0831        1. One of the Prefetch Enable bits (bits [29:28] of the Auxiliary or
0832           Prefetch Control Register) is set HIGH.
0833        2. The prefetch offset bits are programmed with value 23 (5'b10111).
0834        Workaround
0835        A workaround for this erratum is to program the prefetch offset with any
0836        value except 23.*/
0837   }
0838 
0839   /* Unhandled erratum present: 769419 No automatic Store Buffer drain,
0840    * visibility of written data requires an explicit Cache */
0841   assert( ! l2c_310_errata_is_applicable_769419( rtl_release ) );
0842 }
0843 
0844 static inline void
0845 l2c_310_sync( volatile L2CC *l2cc )
0846 {
0847 #ifdef L2C_310_ERRATA_IS_APPLICABLE_753970
0848   l2cc->dummy_cache_sync_reg = 0;
0849 #else
0850   l2cc->cache_sync = 0;
0851 #endif
0852 }
0853 
0854 static inline void
0855 l2c_310_flush_1_line( volatile L2CC *l2cc, uint32_t d_addr )
0856 {
0857 #ifdef L2C_310_ERRATA_IS_APPLICABLE_588369
0858   /*
0859   * Errata 588369 says that clean + inv may keep the
0860   * cache line if it was clean, the recommended
0861   * workaround is to clean then invalidate the cache
0862   * line, with write-back and cache linefill disabled.
0863   */
0864   l2cc->clean_pa     = d_addr;
0865   l2c_310_sync( l2cc );
0866   l2cc->inv_pa       = d_addr;
0867 #else
0868   l2cc->clean_inv_pa = d_addr;
0869 #endif
0870 }
0871 
0872 static inline void
0873 l2c_310_flush_range( const void* d_addr, const size_t n_bytes )
0874 {
0875   /* Back starting address up to start of a line and invalidate until ADDR_LAST */
0876   uint32_t       adx               = (uint32_t)d_addr
0877     & ~L2C_310_DATA_LINE_MASK;
0878   const uint32_t ADDR_LAST         =
0879     (uint32_t)( (size_t)d_addr + n_bytes - 1 );
0880   volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0881 
0882   if ( n_bytes == 0 ) {
0883     return;
0884   }
0885 
0886   for (; adx <= ADDR_LAST; adx += CPU_DATA_CACHE_ALIGNMENT ) {
0887     l2c_310_flush_1_line( l2cc, adx );
0888   }
0889 
0890   l2c_310_sync( l2cc );
0891 }
0892 
0893 static inline void
0894 l2c_310_flush_entire( void )
0895 {
0896   volatile L2CC               *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0897   rtems_interrupt_lock_context lock_context;
0898 
0899   /* Only flush if level 2 cache is active */
0900   if( ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) != 0 ) {
0901 
0902     /* ensure ordering with previous memory accesses */
0903     _ARM_Data_memory_barrier();
0904 
0905     rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
0906     l2cc->clean_inv_way = L2C_310_WAY_MASK;
0907 
0908     while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) {};
0909 
0910     /* Wait for the flush to complete */
0911     l2c_310_sync( l2cc );
0912 
0913     rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
0914   }
0915 }
0916 
0917 static inline void
0918 l2c_310_invalidate_1_line( const void *d_addr )
0919 {
0920   volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0921 
0922 
0923   l2cc->inv_pa = (uint32_t) d_addr;
0924   l2c_310_sync( l2cc );
0925 }
0926 
0927 static inline void
0928 l2c_310_invalidate_range( const void* d_addr, const size_t n_bytes )
0929 {
0930   /* Back starting address up to start of a line and invalidate until ADDR_LAST */
0931   uint32_t       adx               = (uint32_t)d_addr
0932     & ~L2C_310_DATA_LINE_MASK;
0933   const uint32_t ADDR_LAST         =
0934     (uint32_t)( (size_t)d_addr + n_bytes - 1 );
0935   volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0936 
0937   if ( n_bytes == 0 ) {
0938     return;
0939   }
0940 
0941   for (; adx <= ADDR_LAST; adx += CPU_DATA_CACHE_ALIGNMENT ) {
0942     /* Invalidate L2 cache line */
0943     l2cc->inv_pa = adx;
0944   }
0945 
0946   l2c_310_sync( l2cc );
0947 }
0948 
0949 
0950 static inline void
0951 l2c_310_invalidate_entire( void )
0952 {
0953   volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0954 
0955   /* Invalidate the caches */
0956 
0957   /* ensure ordering with previous memory accesses */
0958   _ARM_Data_memory_barrier();
0959 
0960   l2cc->inv_way = L2C_310_WAY_MASK;
0961 
0962   while ( l2cc->inv_way & L2C_310_WAY_MASK ) ;
0963 
0964   /* Wait for the invalidate to complete */
0965   l2c_310_sync( l2cc );
0966 }
0967 
0968 static inline void
0969 l2c_310_clean_and_invalidate_entire( void )
0970 {
0971   volatile L2CC               *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
0972   rtems_interrupt_lock_context lock_context;
0973 
0974   if( ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) != 0 ) {
0975     /* Invalidate the caches */
0976 
0977     /* ensure ordering with previous memory accesses */
0978     _ARM_Data_memory_barrier();
0979 
0980     rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
0981     l2cc->clean_inv_way = L2C_310_WAY_MASK;
0982 
0983     while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) ;
0984 
0985     /* Wait for the invalidate to complete */
0986     l2c_310_sync( l2cc );
0987 
0988     rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
0989   }
0990 }
0991 
0992 static inline void
0993 l2c_310_freeze( void )
0994 {
0995   /* To be implemented as needed, if supported
0996    by hardware at all */
0997 }
0998 
0999 static inline void
1000 l2c_310_unfreeze( void )
1001 {
1002   /* To be implemented as needed, if supported
1003    by hardware at all */
1004 }
1005 
1006 static inline size_t
1007 l2c_310_get_cache_size( void )
1008 {
1009   size_t         size       = 0;
1010   volatile L2CC *l2cc       = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1011   uint32_t       cache_type = l2cc->cache_type;
1012   uint32_t       way_size;
1013   uint32_t       num_ways;
1014 
1015   way_size = (cache_type & L2C_310_TYPE_SIZE_D_WAYS_MASK)
1016     >> L2C_310_TYPE_SIZE_D_WAYS_SHIFT;
1017   num_ways = (cache_type & L2C_310_TYPE_NUM_D_WAYS_MASK)
1018     >> L2C_310_TYPE_NUM_D_WAYS_SHIFT;
1019 
1020   assert( way_size <= 0x07 );
1021   assert( num_ways <= 0x01 );
1022   if(  way_size <= 0x07 && num_ways <= 0x01 ) {
1023     if( way_size == 0x00 ) {
1024       way_size = 16 * 1024;
1025     } else if( way_size == 0x07 ) {
1026       way_size = 512 * 1024;
1027     } else {
1028       way_size = (1 << (way_size - 1)) * 16 * 1024;
1029     }
1030     switch( num_ways ) {
1031       case 0:
1032         num_ways = 8;
1033         break;
1034       case 1:
1035         num_ways = 16;
1036         break;
1037       default:
1038         num_ways = 0;
1039         break;
1040     }
1041     size = way_size * num_ways;
1042   }
1043   return size;
1044 }
1045 
1046 static void l2c_310_unlock( volatile L2CC *l2cc )
1047 {
1048   l2cc->d_lockdown_0 = 0;
1049   l2cc->i_lockdown_0 = 0;
1050   l2cc->d_lockdown_1 = 0;
1051   l2cc->i_lockdown_1 = 0;
1052   l2cc->d_lockdown_2 = 0;
1053   l2cc->i_lockdown_2 = 0;
1054   l2cc->d_lockdown_3 = 0;
1055   l2cc->i_lockdown_3 = 0;
1056   l2cc->d_lockdown_4 = 0;
1057   l2cc->i_lockdown_4 = 0;
1058   l2cc->d_lockdown_5 = 0;
1059   l2cc->i_lockdown_5 = 0;
1060   l2cc->d_lockdown_6 = 0;
1061   l2cc->i_lockdown_6 = 0;
1062   l2cc->d_lockdown_7 = 0;
1063   l2cc->i_lockdown_7 = 0;
1064 }
1065 
1066 static void l2c_310_wait_for_background_ops( volatile L2CC *l2cc )
1067 {
1068   while ( l2cc->inv_way & L2C_310_WAY_MASK ) ;
1069 
1070   while ( l2cc->clean_way & L2C_310_WAY_MASK ) ;
1071 
1072   while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) ;
1073 }
1074 
1075 /* We support only the L2C-310 revisions r3p2 and r3p3 cache controller */
1076 
1077 #if (BSP_ARM_L2C_310_ID & L2C_310_ID_PART_MASK) \
1078   != L2C_310_ID_PART_L310
1079 #error "invalid L2-310 cache controller part number"
1080 #endif
1081 
1082 #if (BSP_ARM_L2C_310_RTL_RELEASE != L2C_310_RTL_RELEASE_R3_P2) \
1083   && (BSP_ARM_L2C_310_RTL_RELEASE != L2C_310_RTL_RELEASE_R3_P3)
1084 #error "invalid L2-310 cache controller RTL revision"
1085 #endif
1086 
1087 static inline void
1088 l2c_310_enable( void )
1089 {
1090   volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1091   uint32_t cache_id = l2cc->cache_id;
1092   uint32_t rtl_release = cache_id & L2C_310_ID_RTL_MASK;
1093   uint32_t id_mask = L2C_310_ID_IMPL_MASK | L2C_310_ID_PART_MASK;
1094   uint32_t ctrl;
1095 
1096   /*
1097    * Do we actually have an L2C-310 cache controller?  Has BSP_ARM_L2C_310_BASE
1098    * been configured correctly?
1099    */
1100   if (
1101     (BSP_ARM_L2C_310_ID & id_mask) != (cache_id & id_mask)
1102       || rtl_release < BSP_ARM_L2C_310_RTL_RELEASE
1103   ) {
1104     bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_ID );
1105   }
1106 
1107   l2c_310_check_errata( rtl_release );
1108 
1109   ctrl = l2cc->ctrl;
1110 
1111   if ( ( ctrl & L2C_310_CTRL_EXCL_CONFIG ) != 0 ) {
1112     bsp_fatal( ARM_FATAL_L2C_310_EXCLUSIVE_CONFIG );
1113   }
1114 
1115   /* Only enable if L2CC is currently disabled */
1116   if( ( ctrl & L2C_310_CTRL_ENABLE ) == 0 ) {
1117     uint32_t aux_ctrl;
1118     int ways;
1119 
1120     /* Make sure that I&D is not locked down when starting */
1121     l2c_310_unlock( l2cc );
1122 
1123     l2c_310_wait_for_background_ops( l2cc );
1124 
1125     aux_ctrl = l2cc->aux_ctrl;
1126 
1127     if ( (aux_ctrl & ( 1 << 16 )) != 0 ) {
1128       ways = 16;
1129     } else {
1130       ways = 8;
1131     }
1132 
1133     if ( ways != L2C_310_NUM_WAYS ) {
1134       bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_NUM_WAYS );
1135     }
1136 
1137     /* Set up the way size */
1138     aux_ctrl &= L2C_310_AUX_REG_ZERO_MASK; /* Set way_size to 0 */
1139     aux_ctrl |= L2C_310_AUX_REG_DEFAULT_MASK;
1140 
1141     l2cc->aux_ctrl = aux_ctrl;
1142 
1143     /* Set up the latencies */
1144     l2cc->tag_ram_ctrl  = L2C_310_TAG_RAM_DEFAULT_LAT;
1145     l2cc->data_ram_ctrl = L2C_310_DATA_RAM_DEFAULT_MASK;
1146 
1147     l2c_310_invalidate_entire();
1148 
1149     /* Clear the pending interrupts */
1150     l2cc->int_clr = l2cc->int_raw_status;
1151 
1152     /* Enable the L2CC */
1153     l2cc->ctrl = ctrl | L2C_310_CTRL_ENABLE;
1154   }
1155 }
1156 
1157 static inline void
1158 _CPU_cache_enable_data( void )
1159 {
1160   l2c_310_enable();
1161 }
1162 
1163 static inline void
1164 _CPU_cache_disable_data( void )
1165 {
1166   _Internal_error( INTERNAL_ERROR_CANNOT_DISABLE_DATA_CACHE );
1167 }
1168 
1169 static void l2c_310_enable_instruction( void *arg )
1170 {
1171   rtems_interrupt_level level;
1172 
1173   (void) arg;
1174 
1175   rtems_interrupt_local_disable(level);
1176   arm_cp15_set_control( arm_cp15_get_control() | ARM_CP15_CTRL_I );
1177   rtems_interrupt_local_enable(level);
1178 }
1179 
1180 static inline void
1181 _CPU_cache_enable_instruction( void )
1182 {
1183 #ifdef RTEMS_SMP
1184   rtems_interrupt_level level;
1185 
1186   rtems_interrupt_local_disable( level );
1187   _SMP_Broadcast_action( l2c_310_enable_instruction, NULL );
1188   rtems_interrupt_local_enable( level );
1189 #else
1190   l2c_310_enable_instruction( NULL );
1191 #endif
1192 }
1193 
1194 static void l2c_310_disable_instruction( void *arg )
1195 {
1196   rtems_interrupt_level level;
1197 
1198   (void) arg;
1199 
1200   rtems_interrupt_local_disable(level);
1201   arm_cp15_set_control( arm_cp15_get_control() & ~ARM_CP15_CTRL_I );
1202   rtems_interrupt_local_enable(level);
1203 
1204   arm_cache_l1_invalidate_entire_instruction();
1205 }
1206 
1207 static inline void
1208 _CPU_cache_disable_instruction( void )
1209 {
1210   l2c_310_flush_entire();
1211 
1212 #ifdef RTEMS_SMP
1213   rtems_interrupt_level level;
1214 
1215   rtems_interrupt_local_disable( level );
1216   _SMP_Broadcast_action( l2c_310_disable_instruction, NULL );
1217   rtems_interrupt_local_enable( level );
1218 #else
1219   l2c_310_disable_instruction( NULL );
1220 #endif
1221 }
1222 
1223 static inline void
1224 _CPU_cache_flush_data_range(
1225   const void *d_addr,
1226   size_t      n_bytes
1227 )
1228 {
1229   arm_cache_l1_flush_data_range(
1230     d_addr,
1231     n_bytes
1232   );
1233   l2c_310_flush_range(
1234     d_addr,
1235     n_bytes
1236   );
1237 }
1238 
1239 static inline void
1240 _CPU_cache_flush_entire_data( void )
1241 {
1242   arm_cache_l1_flush_entire_data();
1243   l2c_310_flush_entire();
1244 }
1245 
1246 static inline void
1247 _CPU_cache_invalidate_data_range(
1248   const void *addr_first,
1249   size_t     n_bytes
1250 )
1251 {
1252   l2c_310_invalidate_range(
1253     addr_first,
1254     n_bytes
1255   );
1256   arm_cache_l1_invalidate_data_range(
1257     addr_first,
1258     n_bytes
1259   );
1260 }
1261 
1262 static inline void
1263 _CPU_cache_invalidate_entire_data( void )
1264 {
1265   /* This is broadcast within the cluster */
1266   arm_cache_l1_flush_entire_data();
1267 
1268   /* forces the address out past level 2 */
1269   l2c_310_clean_and_invalidate_entire();
1270 
1271   /*This is broadcast within the cluster */
1272   arm_cache_l1_clean_and_invalidate_entire_data();
1273 }
1274 
1275 static inline void
1276 _CPU_cache_freeze_data( void )
1277 {
1278   arm_cache_l1_freeze_data();
1279   l2c_310_freeze();
1280 }
1281 
1282 static inline void
1283 _CPU_cache_unfreeze_data( void )
1284 {
1285   arm_cache_l1_unfreeze_data();
1286   l2c_310_unfreeze();
1287 }
1288 
1289 static inline void
1290 _CPU_cache_invalidate_instruction_range( const void *i_addr, size_t n_bytes)
1291 {
1292   arm_cache_l1_invalidate_instruction_range( i_addr, n_bytes );
1293 }
1294 
1295 static inline void
1296 _CPU_cache_invalidate_entire_instruction( void )
1297 {
1298   arm_cache_l1_invalidate_entire_instruction();
1299 }
1300 
1301 static inline void
1302 _CPU_cache_freeze_instruction( void )
1303 {
1304   arm_cache_l1_freeze_instruction();
1305   l2c_310_freeze();
1306 }
1307 
1308 static inline void
1309 _CPU_cache_unfreeze_instruction( void )
1310 {
1311   arm_cache_l1_unfreeze_instruction();
1312   l2c_310_unfreeze();
1313 }
1314 
1315 static inline size_t
1316 _CPU_cache_get_data_cache_size( const uint32_t level )
1317 {
1318   size_t size = 0;
1319 
1320   switch( level )
1321   {
1322     case 1:
1323       size = arm_cache_l1_get_data_cache_size();
1324     break;
1325     case 0:
1326     case 2:
1327       size = l2c_310_get_cache_size();
1328     break;
1329     default:
1330       size = 0;
1331     break;
1332   }
1333   return size;
1334 }
1335 
1336 static inline size_t
1337 _CPU_cache_get_instruction_cache_size( const uint32_t level )
1338 {
1339   size_t size = 0;
1340 
1341   switch( level )
1342   {
1343     case 1:
1344       size = arm_cache_l1_get_instruction_cache_size();
1345       break;
1346     case 0:
1347     case 2:
1348       size = l2c_310_get_cache_size();
1349       break;
1350     default:
1351       size = 0;
1352       break;
1353   }
1354   return size;
1355 }
1356 
1357 /** @} */
1358 
1359 #include "../../shared/cache/cacheimpl.h"