source: rtems/c/src/lib/libbsp/arm/shared/arm-l2c-310/cache_.h @ 9fcd1b35

4.115
Last change on this file since 9fcd1b35 was 9fcd1b35, checked in by Ralf Kirchner <ralf.kirchner@…>, on 02/17/14 at 09:22:16

bsp/arm: Add handling for level 2 L2C-310 cache controller

arm-l2c-310/cache_.h contains the handling for the L2C-310
level 2 cache controller from arm. It references the arm
level 1 cache handling in the new file arm-cache-l1.h.

  • Property mode set to 100644
File size: 46.8 KB
Line 
1/**
2 * @file cache_.h
3 *
4 * @ingroup L2C-310_cache
5 *
6 * @brief Cache definitions and functions.
7 *
8 * This file implements handling for the ARM L2C-310 cache controller
9 */
10
11/*
12 * Authorship
13 * ----------
14 * This software was created by
15 *     R. Claus <claus@slac.stanford.edu>, 2013,
16 *       Stanford Linear Accelerator Center, Stanford University.
17 *
18 * Acknowledgement of sponsorship
19 * ------------------------------
20 * This software was produced by
21 *     the Stanford Linear Accelerator Center, Stanford University,
22 *     under Contract DE-AC03-76SFO0515 with the Department of Energy.
23 *
24 * Government disclaimer of liability
25 * ----------------------------------
26 * Neither the United States nor the United States Department of Energy,
27 * nor any of their employees, makes any warranty, express or implied, or
28 * assumes any legal liability or responsibility for the accuracy,
29 * completeness, or usefulness of any data, apparatus, product, or process
30 * disclosed, or represents that its use would not infringe privately owned
31 * rights.
32 *
33 * Stanford disclaimer of liability
34 * --------------------------------
35 * Stanford University makes no representations or warranties, express or
36 * implied, nor assumes any liability for the use of this software.
37 *
38 * Stanford disclaimer of copyright
39 * --------------------------------
40 * Stanford University, owner of the copyright, hereby disclaims its
41 * copyright and all other rights in this software.  Hence, anyone may
42 * freely use it for any purpose without restriction.
43 *
44 * Maintenance of notices
45 * ----------------------
46 * In the interest of clarity regarding the origin and status of this
47 * SLAC software, this and all the preceding Stanford University notices
48 * are to remain affixed to any copy or derivative of this software made
49 * or distributed by the recipient and are to be affixed to any copy of
50 * software made or distributed by the recipient that contains a copy or
51 * derivative of this software.
52 *
53 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
54 */
55
56#ifndef LIBBSP_ARM_SHARED_L2C_310_CACHE_H
57#define LIBBSP_ARM_SHARED_L2C_310_CACHE_H
58
59#include <assert.h>
60#include <bsp.h>
61#include <libcpu/arm-cp15.h>
62#include <bsp/arm-release-id.h>
63#include <bsp/arm-errata.h>
64#include "../include/arm-cache-l1.h"
65
66#ifdef __cplusplus
67extern "C" {
68#endif /* __cplusplus */
69
70/* These two defines also ensure that the rtems_cache_* functions have bodies */
71#define CPU_DATA_CACHE_ALIGNMENT ARM_CACHE_L1_CPU_DATA_ALIGNMENT
72#define CPU_INSTRUCTION_CACHE_ALIGNMENT ARM_CACHE_L1_CPU_INSTRUCTION_ALIGNMENT
73#define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS \
74  ARM_CACHE_L1_CPU_SUPPORT_PROVIDES_RANGE_FUNCTIONS
75
76#define CACHE_L2C_310_DATA_LINE_MASK ( CPU_DATA_CACHE_ALIGNMENT - 1 )
77#define CACHE_L2C_310_INSTRUCTION_LINE_MASK \
78  ( CPU_INSTRUCTION_CACHE_ALIGNMENT \
79    - 1 )
80#define CACHE_l2C_310_NUM_WAYS 8
81#define CACHE_l2C_310_WAY_MASK ( ( 1 << CACHE_l2C_310_NUM_WAYS ) - 1 )
82
83
84/* RTL release number as can be read from cache_id register */
85typedef enum {
86  CACHE_L2C_310_RTL_RELEASE_R0_P0 = 0x0,
87  CACHE_L2C_310_RTL_RELEASE_R1_P0 = 0x2,
88  CACHE_L2C_310_RTL_RELEASE_R2_P0 = 0x4,
89  CACHE_L2C_310_RTL_RELEASE_R3_P0 = 0x5,
90  CACHE_L2C_310_RTL_RELEASE_R3_P1 = 0x6,
91  CACHE_L2C_310_RTL_RELEASE_R3_P2 = 0x8,
92  CACHE_L2C_310_RTL_RELEASE_R3_P3 = 0x9
93} cache_l2c_310_rtl_release;
94
95/**
96 * @defgroup L2C-310_cache Cache Support
97 * @ingroup arm_shared
98 * @brief Cache Functions and Defitions
99 * @{
100 */
101
102
103/**
104 * @brief L2CC Register Offsets
105 */
106typedef struct {
107  /** @brief Cache ID */
108  uint32_t cache_id;
109#define CACHE_L2C_310_L2CC_ID_RTL_MASK 0x3f
110#define CACHE_L2C_310_L2CC_ID_PART_MASK ( 0xf << 6 )
111#define CACHE_L2C_310_L2CC_ID_PART_L210 ( 1 << 6 )
112#define CACHE_L2C_310_L2CC_ID_PART_L310 ( 3 << 6 )
113  /** @brief Cache type */
114  uint32_t cache_type;
115/** @brief 1 if data banking implemented, 0 if not */
116#define CACHE_L2C_310_L2CC_TYPE_DATA_BANKING_MASK 0x80000000
117/** @brief 11xy, where: x=1 if pl310_LOCKDOWN_BY_MASTER is defined, otherwise 0 */
118#define CACHE_L2C_310_L2CC_TYPE_CTYPE_MASK 0x1E000000
119/** @brief y=1 if pl310_LOCKDOWN_BY_LINE is defined, otherwise 0. */
120#define CACHE_L2C_310_L2CC_TYPE_CTYPE_SHIFT 25
121/** @brief 1 for Harvard architecture, 0 for unified architecture */
122#define CACHE_L2C_310_L2CC_TYPE_HARVARD_MASK 0x01000000
123/** @brief Data cache way size = 2 Exp(value + 2) KB */
124#define CACHE_L2C_310_L2CC_TYPE_SIZE_D_WAYS_MASK 0x00700000
125#define CACHE_L2C_310_L2CC_TYPE_SIZE_D_WAYS_SHIFT 20
126/** @brief Assoziativity aka number of data ways = (value * 8) + 8 */
127#define CACHE_L2C_310_L2CC_TYPE_NUM_D_WAYS_MASK 0x00040000
128#define CACHE_L2C_310_L2CC_TYPE_NUM_D_WAYS_SHIFT 18
129/** @brief Data cache line length 00 - 32 */
130#define CACHE_L2C_310_L2CC_TYPE_LENGTH_D_LINE_MASK 0x00003000
131#define CACHE_L2C_310_L2CC_TYPE_LENGTH_D_LINE_SHIFT 12
132#define CACHE_L2C_310_L2CC_TYPE_LENGTH_D_LINE_VAL_32 0x0
133/** @brief Instruction cache way size = 2 Exp(value + 2) KB */
134#define CACHE_L2C_310_L2CC_TYPE_SIZE_I_WAYS_MASK 0x00000700
135#define CACHE_L2C_310_L2CC_TYPE_SIZE_I_WAYS_SHIFT 8
136/** @brief Assoziativity aka number of instruction ways = (value * 8) + 8 */
137#define CACHE_L2C_310_L2CC_TYPE_NUM_I_WAYS_MASK 0x00000040
138#define CACHE_L2C_310_L2CC_TYPE_NUM_I_WAYS_SHIFT 6
139/** @brief Instruction cache line length 00 - 32 */
140#define CACHE_L2C_310_L2CC_TYPE_LENGTH_I_LINE_MASK 0x00000003
141#define CACHE_L2C_310_L2CC_TYPE_LENGTH_I_LINE_SHIFT 0
142#define CACHE_L2C_310_L2CC_TYPE_LENGTH_I_LINE_VAL_32 0x0
143
144  uint8_t reserved_8[0x100 - 8];
145  uint32_t ctrl; /* Control */
146/** @brief Enables the L2CC */
147#define CACHE_L2C_310_L2CC_ENABLE_MASK 0x00000001
148
149  /** @brief Auxiliary control */
150  uint32_t aux_ctrl;
151
152/** @brief Early BRESP Enable */
153#define CACHE_L2C_310_L2CC_AUX_EBRESPE_MASK 0x40000000
154
155/** @brief Instruction Prefetch Enable */
156#define CACHE_L2C_310_L2CC_AUX_IPFE_MASK 0x20000000
157
158/** @brief Data Prefetch Enable */
159#define CACHE_L2C_310_L2CC_AUX_DPFE_MASK 0x10000000
160
161/** @brief Non-secure interrupt access control */
162#define CACHE_L2C_310_L2CC_AUX_NSIC_MASK 0x08000000
163
164/** @brief Non-secure lockdown enable */
165#define CACHE_L2C_310_L2CC_AUX_NSLE_MASK 0x04000000
166
167/** @brief Cache replacement policy */
168#define CACHE_L2C_310_L2CC_AUX_CRP_MASK 0x02000000
169
170/** @brief Force write allocate */
171#define CACHE_L2C_310_L2CC_AUX_FWE_MASK 0x01800000
172
173/** @brief Shared attribute override enable */
174#define CACHE_L2C_310_L2CC_AUX_SAOE_MASK 0x00400000
175
176/** @brief Parity enable */
177#define CACHE_L2C_310_L2CC_AUX_PE_MASK 0x00200000
178
179/** @brief Event monitor bus enable */
180#define CACHE_L2C_310_L2CC_AUX_EMBE_MASK 0x00100000
181
182/** @brief Way-size */
183#define CACHE_L2C_310_L2CC_AUX_WAY_SIZE_MASK 0x000E0000
184#define CACHE_L2C_310_L2CC_AUX_WAY_SIZE_SHIFT 17
185
186/** @brief Way-size */
187#define CACHE_L2C_310_L2CC_AUX_ASSOC_MASK 0x00010000
188
189/** @brief Shared attribute invalidate enable */
190#define CACHE_L2C_310_L2CC_AUX_SAIE_MASK 0x00002000
191
192/** @brief Exclusive cache configuration */
193#define CACHE_L2C_310_L2CC_AUX_EXCL_CACHE_MASK 0x00001000
194
195/** @brief Store buffer device limitation Enable */
196#define CACHE_L2C_310_L2CC_AUX_SBDLE_MASK 0x00000800
197
198/** @brief High Priority for SO and Dev Reads Enable */
199#define CACHE_L2C_310_L2CC_AUX_HPSODRE_MASK 0x00000400
200
201/** @brief Full line of zero enable */
202#define CACHE_L2C_310_L2CC_AUX_FLZE_MASK 0x00000001
203
204/** @brief Enable all prefetching, */
205#define CACHE_L2C_310_L2CC_AUX_REG_DEFAULT_MASK \
206  ( CACHE_L2C_310_L2CC_AUX_WAY_SIZE_MASK & ( 0x3 << CACHE_L2C_310_L2CC_AUX_WAY_SIZE_SHIFT ) ) \
207  | CACHE_L2C_310_L2CC_AUX_PE_MASK      /* Prefetch enable */ \
208  | CACHE_L2C_310_L2CC_AUX_SAOE_MASK    /* Shared attribute override enable */ \
209  | CACHE_L2C_310_L2CC_AUX_CRP_MASK     /* Cache replacement policy */ \
210  | CACHE_L2C_310_L2CC_AUX_DPFE_MASK    /* Data prefetch enable */ \
211  | CACHE_L2C_310_L2CC_AUX_IPFE_MASK    /* Instruction prefetch enable */ \
212  | CACHE_L2C_310_L2CC_AUX_EBRESPE_MASK /* Early BRESP enable */
213
214#define CACHE_L2C_310_L2CC_AUX_REG_ZERO_MASK 0xFFF1FFFF
215
216/** @brief 1 cycle of latency, there is no additional latency fot tag RAM */
217#define CACHE_L2C_310_L2CC_RAM_1_CYCLE_LAT_VAL 0x00000000
218/** @brief 2 cycles of latency for tag RAM */
219#define CACHE_L2C_310_L2CC_RAM_2_CYCLE_LAT_VAL 0x00000001
220/** @brief 3 cycles of latency for tag RAM */
221#define CACHE_L2C_310_L2CC_RAM_3_CYCLE_LAT_VAL 0x00000002
222/** @brief 4 cycles of latency for tag RAM */
223#define CACHE_L2C_310_L2CC_RAM_4_CYCLE_LAT_VAL 0x00000003
224/** @brief 5 cycles of latency for tag RAM */
225#define CACHE_L2C_310_L2CC_RAM_5_CYCLE_LAT_VAL 0x00000004
226/** @brief 6 cycles of latency for tag RAM */
227#define CACHE_L2C_310_L2CC_RAM_6_CYCLE_LAT_VAL 0x00000005
228/** @brief 7 cycles of latency for tag RAM */
229#define CACHE_L2C_310_L2CC_RAM_7_CYCLE_LAT_VAL 0x00000006
230/** @brief 8 cycles of latency for tag RAM */
231#define CACHE_L2C_310_L2CC_RAM_8_CYCLE_LAT_VAL 0x00000007
232/** @brief Shift left setup latency values by this value */
233#define CACHE_L2C_310_L2CC_RAM_SETUP_SHIFT 0x00000000
234/** @brief Shift left read latency values by this value */
235#define CACHE_L2C_310_L2CC_RAM_READ_SHIFT 0x00000004
236/** @brief Shift left write latency values by this value */
237#define CACHE_L2C_310_L2CC_RAM_WRITE_SHIFT 0x00000008
238/** @brief Mask for RAM setup latency */
239#define CACHE_L2C_310_L2CC_RAM_SETUP_LAT_MASK 0x00000007
240/** @brief Mask for RAM read latency */
241#define CACHE_L2C_310_L2CC_RAM_READ_LAT_MASK 0x00000070
242/** @brief Mask for RAM read latency */
243#define CACHE_L2C_310_L2CC_RAM_WRITE_LAT_MASK 0x00000700
244  /** @brief Latency for tag RAM */
245  uint32_t tag_ram_ctrl;
246/* @brief Latency for tag RAM */
247#define CACHE_L2C_310_L2CC_TAG_RAM_DEFAULT_LAT \
248  ( ( CACHE_L2C_310_L2CC_RAM_2_CYCLE_LAT_VAL << CACHE_L2C_310_L2CC_RAM_SETUP_SHIFT ) \
249    | ( CACHE_L2C_310_L2CC_RAM_2_CYCLE_LAT_VAL << CACHE_L2C_310_L2CC_RAM_READ_SHIFT ) \
250    | ( CACHE_L2C_310_L2CC_RAM_2_CYCLE_LAT_VAL << CACHE_L2C_310_L2CC_RAM_WRITE_SHIFT ) )
251  /** @brief Latency for data RAM */
252  uint32_t data_ram_ctrl;
253/** @brief Latency for data RAM */
254#define CACHE_L2C_310_L2CC_DATA_RAM_DEFAULT_MASK \
255  ( ( CACHE_L2C_310_L2CC_RAM_2_CYCLE_LAT_VAL << CACHE_L2C_310_L2CC_RAM_SETUP_SHIFT ) \
256    | ( CACHE_L2C_310_L2CC_RAM_3_CYCLE_LAT_VAL << CACHE_L2C_310_L2CC_RAM_READ_SHIFT ) \
257    | ( CACHE_L2C_310_L2CC_RAM_2_CYCLE_LAT_VAL << CACHE_L2C_310_L2CC_RAM_WRITE_SHIFT ) )
258
259  uint8_t reserved_110[0x200 - 0x110];
260
261  /** @brief Event counter control */
262  uint32_t ev_ctrl;
263
264  /** @brief Event counter 1 configuration */
265  uint32_t ev_cnt1_cfg;
266
267  /** @brief Event counter 0 configuration */
268  uint32_t ev_cnt0_cfg;
269
270  /** @brief Event counter 1 value */
271  uint32_t ev_cnt1;
272
273  /** @brief Event counter 0 value */
274  uint32_t ev_cnt0;
275
276  /** @brief Interrupt enable mask */
277  uint32_t int_mask;
278
279  /** @brief Masked   interrupt status (read-only)*/
280  uint32_t int_mask_status;
281
282  /** @brief Unmasked interrupt status */
283  uint32_t int_raw_status;
284
285  /** @brief Interrupt clear */
286  uint32_t int_clr;
287
288/**
289 * @name Interrupt bit masks
290 *
291 * @{
292 */
293
294/** @brief DECERR from L3 */
295#define CACHE_L2C_310_L2CC_INT_DECERR_MASK 0x00000100
296
297/** @brief SLVERR from L3 */
298#define CACHE_L2C_310_L2CC_INT_SLVERR_MASK 0x00000080
299
300/** @brief Error on L2 data RAM (Read) */
301#define CACHE_L2C_310_L2CC_INT_ERRRD_MASK 0x00000040
302
303/** @brief Error on L2 tag RAM (Read) */
304#define CACHE_L2C_310_L2CC_INT_ERRRT_MASK 0x00000020
305
306/** @brief Error on L2 data RAM (Write) */
307#define CACHE_L2C_310_L2CC_INT_ERRWD_MASK 0x00000010
308
309/** @brief Error on L2 tag RAM (Write) */
310#define CACHE_L2C_310_L2CC_INT_ERRWT_MASK 0x00000008
311
312/** @brief Parity Error on L2 data RAM (Read) */
313#define CACHE_L2C_310_L2CC_INT_PARRD_MASK 0x00000004
314
315/** @brief Parity Error on L2 tag RAM (Read) */
316#define CACHE_L2C_310_L2CC_INT_PARRT_MASK 0x00000002
317
318/** @brief Event Counter1/0 Overflow Increment */
319#define CACHE_L2C_310_L2CC_INT_ECNTR_MASK 0x00000001
320
321/** @} */
322
323  uint8_t reserved_224[0x730 - 0x224];
324
325  /** @brief Drain the STB */
326  uint32_t cache_sync;
327  uint8_t reserved_734[0x740 - 0x734];
328  /** @brief ARM Errata 753970 for pl310-r3p0 */
329  uint32_t dummy_cache_sync_reg;
330  uint8_t reserved_744[0x770 - 0x744];
331
332  /** @brief Invalidate line by PA */
333  uint32_t inv_pa;
334  uint8_t reserved_774[0x77c - 0x774];
335
336  /** @brief Invalidate by Way */
337  uint32_t inv_way;
338  uint8_t reserved_780[0x7b0 - 0x780];
339
340  /** @brief Clean Line by PA */
341  uint32_t clean_pa;
342  uint8_t reserved_7b4[0x7b8 - 0x7b4];
343
344  /** @brief Clean Line by Set/Way */
345  uint32_t clean_index;
346
347  /** @brief Clean by Way */
348  uint32_t clean_way;
349  uint8_t reserved_7c0[0x7f0 - 0x7c0];
350
351  /** @brief Clean and Invalidate Line by PA */
352  uint32_t clean_inv_pa;
353  uint8_t reserved_7f4[0x7f8 - 0x7f4];
354
355  /** @brief Clean and Invalidate Line by Set/Way */
356  uint32_t clean_inv_indx;
357
358  /** @brief Clean and Invalidate by Way */
359  uint32_t clean_inv_way;
360
361  /** @brief Data        lock down 0 */
362  uint32_t d_lockdown_0;
363
364  /** @brief Instruction lock down 0 */
365  uint32_t i_lockdown_0;
366
367  /** @brief Data        lock down 1 */
368  uint32_t d_lockdown_1;
369
370  /** @brief Instruction lock down 1 */
371  uint32_t i_lockdown_1;
372
373  /** @brief Data        lock down 2 */
374  uint32_t d_lockdown_2;
375
376  /** @brief Instruction lock down 2 */
377  uint32_t i_lockdown_2;
378
379  /** @brief Data        lock down 3 */
380  uint32_t d_lockdown_3;
381
382  /** @brief Instruction lock down 3 */
383  uint32_t i_lockdown_3;
384
385  /** @brief Data        lock down 4 */
386  uint32_t d_lockdown_4;
387
388  /** @brief Instruction lock down 4 */
389  uint32_t i_lockdown_4;
390
391  /** @brief Data        lock down 5 */
392  uint32_t d_lockdown_5;
393
394  /** @brief Instruction lock down 5 */
395  uint32_t i_lockdown_5;
396
397  /** @brief Data        lock down 6 */
398  uint32_t d_lockdown_6;
399
400  /** @brief Instruction lock down 6 */
401  uint32_t i_lockdown_6;
402
403  /** @brief Data        lock down 7 */
404  uint32_t d_lockdown_7;
405
406  /** @brief Instruction lock down 7 */
407  uint32_t i_lockdown_7;
408
409  uint8_t reserved_940[0x950 - 0x940];
410
411  /** @brief Lockdown by Line Enable */
412  uint32_t lock_line_en;
413
414  /** @brief Cache lockdown by way */
415  uint32_t unlock_way;
416
417  uint8_t reserved_958[0xc00 - 0x958];
418
419  /** @brief Address range redirect, part 1 */
420  uint32_t addr_filtering_start;
421
422  /** @brief Address range redirect, part 2 */
423  uint32_t addr_filtering_end;
424
425/** @brief Address filtering valid bits*/
426#define CACHE_L2C_310_L2CC_ADDR_FILTER_VALID_MASK 0xFFF00000
427
428/** @brief Address filtering enable bit*/
429#define CACHE_L2C_310_L2CC_ADDR_FILTER_ENABLE_MASK 0x00000001
430
431  uint8_t reserved_c08[0xf40 - 0xc08];
432
433  /** @brief Debug control */
434  uint32_t debug_ctrl;
435
436/** @brief Debug SPIDEN bit */
437#define CACHE_L2C_310_L2CC_DEBUG_SPIDEN_MASK 0x00000004
438
439/** @brief Debug DWB bit, forces write through */
440#define CACHE_L2C_310_L2CC_DEBUG_DWB_MASK 0x00000002
441
442/** @brief Debug DCL bit, disables cache line fill */
443#define CACHE_L2C_310_L2CC_DEBUG_DCL_MASK 0x00000002
444
445  uint8_t reserved_f44[0xf60 - 0xf44];
446
447  /** @brief Purpose prefetch enables */
448  uint32_t prefetch_ctrl;
449/** @brief Prefetch offset */
450#define CACHE_L2C_310_L2CC_PREFETCH_OFFSET_MASK 0x0000001F
451  uint8_t reserved_f64[0xf80 - 0xf64];
452
453  /** @brief Purpose power controls */
454  uint32_t power_ctrl;
455} L2CC;
456
457/* Errata table for the LC2 310 Level 2 cache from ARM.
458* Information taken from ARMs
459* "CoreLink controllers and peripherals
460* - System controllers
461* - L2C-310 Level 2 Cache Controller
462* - Revision r3p3
463* - Software Developer Errata Notice
464* - ARM CoreLink Level 2 Cache Controller (L2C-310 or PL310),
465*   r3 releases Software Developers Errata Notice"
466* The corresponding link is:
467* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/BABJFIBA.html
468* Please see this document for more information on these erratas */
469static bool l2c_310_cache_errata_is_applicable_753970(
470  void
471)
472{
473  volatile L2CC                  *l2cc          =
474    (volatile L2CC *) BSP_ARM_L2CC_BASE;
475  const cache_l2c_310_rtl_release RTL_RELEASE   =
476    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
477  bool                            is_applicable = false;
478 
479  switch( RTL_RELEASE ) {
480    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
481    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
482    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
483    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
484    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
485    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
486      is_applicable = false;
487    break;
488    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
489      is_applicable = true;
490    break;
491    default:
492       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
493              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
494              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
495              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
496              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
497              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
498              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
499     break;
500  }
501 
502  return is_applicable;
503}
504
505
506
507static bool l2c_310_cache_errata_is_applicable_727913(
508  void
509)
510{
511  volatile L2CC                  *l2cc          =
512    (volatile L2CC *) BSP_ARM_L2CC_BASE;
513  const cache_l2c_310_rtl_release RTL_RELEASE   =
514    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
515  bool                            is_applicable = false;
516 
517  switch( RTL_RELEASE ) {
518    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
519    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
520    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
521    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
522    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
523    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
524      is_applicable = false;
525    break;
526    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
527      is_applicable = true;
528    break;
529    default:
530       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
531              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
532              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
533              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
534              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
535              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
536              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
537     break;
538  }
539 
540  return is_applicable;
541}
542
543static bool l2c_310_cache_errata_is_applicable_727914(
544  void
545)
546{
547  volatile L2CC                  *l2cc          =
548    (volatile L2CC *) BSP_ARM_L2CC_BASE;
549  const cache_l2c_310_rtl_release RTL_RELEASE   =
550    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
551  bool                            is_applicable = false;
552 
553  switch( RTL_RELEASE ) {
554    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
555    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
556    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
557    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
558    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
559    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
560      is_applicable = false;
561    break;
562    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
563      is_applicable = true;
564    break;
565    default:
566       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
567              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
568              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
569              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
570              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
571              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
572              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
573     break;
574  }
575 
576  return is_applicable;
577}
578
579static bool l2c_310_cache_errata_is_applicable_727915(
580  void
581)
582{
583  volatile L2CC                  *l2cc          =
584    (volatile L2CC *) BSP_ARM_L2CC_BASE;
585  const cache_l2c_310_rtl_release RTL_RELEASE   =
586    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
587  bool                            is_applicable = false;
588 
589  switch( RTL_RELEASE ) {
590    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
591    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
592    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
593    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
594    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
595      is_applicable = false;
596    break;
597    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
598    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
599      is_applicable = true;
600    break;
601    default:
602       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
603              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
604              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
605              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
606              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
607              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
608              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
609     break;
610  }
611 
612  return is_applicable;
613}
614
615static bool l2c_310_cache_errata_is_applicable_729806(
616  void
617)
618{
619  volatile L2CC                  *l2cc          =
620    (volatile L2CC *) BSP_ARM_L2CC_BASE;
621  const cache_l2c_310_rtl_release RTL_RELEASE   =
622    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
623  bool                            is_applicable = false;
624 
625  switch( RTL_RELEASE ) {
626    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
627    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
628    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
629    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
630    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
631      is_applicable = false;
632    break;
633    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
634    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
635      is_applicable = true;
636    break;
637    default:
638       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
639              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
640              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
641              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
642              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
643              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
644              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
645     break;
646  }
647 
648  return is_applicable;
649}
650
651static bool l2c_310_cache_errata_is_applicable_729815(
652  void
653)
654{
655  volatile L2CC                  *l2cc          =
656    (volatile L2CC *) BSP_ARM_L2CC_BASE;
657  const cache_l2c_310_rtl_release RTL_RELEASE   =
658    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
659  bool                            is_applicable = false;
660 
661  switch( RTL_RELEASE ) {
662    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
663    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
664    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
665      is_applicable = false;
666    break;
667    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
668    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
669    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
670    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
671      is_applicable = true;
672    break;
673    default:
674       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
675              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
676              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
677              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
678              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
679              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
680              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
681     break;
682  }
683 
684  return is_applicable;
685}
686
687static bool l2c_310_cache_errata_is_applicable_742884(
688  void
689)
690{
691  volatile L2CC                  *l2cc          =
692    (volatile L2CC *) BSP_ARM_L2CC_BASE;
693  const cache_l2c_310_rtl_release RTL_RELEASE   =
694    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
695  bool                            is_applicable = false;
696 
697  switch( RTL_RELEASE ) {
698    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
699    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
700    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
701    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
702    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
703    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
704      is_applicable = false;
705    break;
706    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
707      is_applicable = true;
708    break;
709    default:
710       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
711              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
712              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
713              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
714              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
715              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
716              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
717     break;
718  }
719 
720  return is_applicable;
721}
722
723static bool l2c_310_cache_errata_is_applicable_752271(
724  void
725)
726{
727  volatile L2CC                  *l2cc          =
728    (volatile L2CC *) BSP_ARM_L2CC_BASE;
729  const cache_l2c_310_rtl_release RTL_RELEASE   =
730    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
731  bool                            is_applicable = false;
732 
733  switch( RTL_RELEASE ) {
734    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
735    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
736    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
737    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
738    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
739      is_applicable = false;
740    break;
741    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
742    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
743      is_applicable = true;
744    break;
745    default:
746       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
747              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
748              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
749              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
750              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
751              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
752              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
753     break;
754  }
755 
756  return is_applicable;
757}
758
759static bool l2c_310_cache_errata_is_applicable_765569(
760  void
761)
762{
763  volatile L2CC                  *l2cc          =
764    (volatile L2CC *) BSP_ARM_L2CC_BASE;
765  const cache_l2c_310_rtl_release RTL_RELEASE   =
766    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
767  bool                            is_applicable = false;
768 
769  switch( RTL_RELEASE ) {
770    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
771    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
772    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
773    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
774    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
775    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
776    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
777      is_applicable = true;
778    break;
779    default:
780       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
781              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
782              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
783              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
784              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
785              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
786              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
787     break;
788  }
789 
790  return is_applicable;
791}
792
793static bool l2c_310_cache_errata_is_applicable_769419(
794  void
795)
796{
797  volatile L2CC                  *l2cc          =
798    (volatile L2CC *) BSP_ARM_L2CC_BASE;
799  const cache_l2c_310_rtl_release RTL_RELEASE   =
800    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
801  bool                            is_applicable = false;
802 
803  switch( RTL_RELEASE ) {
804    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
805    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
806      is_applicable = false;
807    break;
808    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
809    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
810    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
811    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
812    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
813      is_applicable = true;
814    break;
815    default:
816       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
817              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
818              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
819              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
820              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
821              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
822              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
823     break;
824  }
825 
826  return is_applicable;
827}
828
829static bool l2c_310_cache_errata_is_applicable_588369(
830  void
831)
832{
833  volatile L2CC                  *l2cc          =
834    (volatile L2CC *) BSP_ARM_L2CC_BASE;
835  const cache_l2c_310_rtl_release RTL_RELEASE   =
836    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
837  bool                            is_applicable = false;
838 
839  switch( RTL_RELEASE ) {
840    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
841    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
842    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
843    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
844    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
845      is_applicable = false;
846    break;
847    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
848    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
849      is_applicable = true;
850    break;
851    default:
852       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
853              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
854              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
855              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
856              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
857              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
858              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
859     break;
860  }
861 
862  return is_applicable;
863}
864
865#ifdef CACHE_ERRATA_CHECKS_FOR_IMPLEMENTED_ERRATAS
866static bool l2c_310_cache_errata_is_applicable_754670(
867  void
868)
869{
870  volatile L2CC                  *l2cc          =
871    (volatile L2CC *) BSP_ARM_L2CC_BASE;
872  const cache_l2c_310_rtl_release RTL_RELEASE   =
873    l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
874  bool                            is_applicable = false;
875 
876  switch( RTL_RELEASE ) {
877    case CACHE_L2C_310_RTL_RELEASE_R3_P3:
878    case CACHE_L2C_310_RTL_RELEASE_R3_P2:
879    case CACHE_L2C_310_RTL_RELEASE_R3_P1:
880    case CACHE_L2C_310_RTL_RELEASE_R3_P0:
881    case CACHE_L2C_310_RTL_RELEASE_R2_P0:
882    case CACHE_L2C_310_RTL_RELEASE_R1_P0:
883    case CACHE_L2C_310_RTL_RELEASE_R0_P0:
884      is_applicable = true;
885    break;
886    default:
887       assert(   RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
888              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
889              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
890              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
891              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
892              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
893              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
894     break;
895  }
896 
897  return is_applicable;
898}
899#endif /* CACHE_ERRATA_CHECKS_FOR_IMPLEMENTED_ERRATAS */
900
901/* Errata Handlers */
902#if ( defined( RTEMS_SMP ) )
903  #define CACHE_ARM_ERRATA_764369_HANDLER()                    \
904    if( arm_errata_is_applicable_processor_errata_764369() ) { \
905      _ARM_Data_synchronization_barrier();                     \
906    }                                           
907#else /* #if ( defined( RTEMS_SMP ) ) */
908  #define CACHE_ARM_ERRATA_764369_HANDLER()
909#endif /* #if ( defined( RTEMS_SMP ) ) */
910
911/* The common workaround for this erratum would be to add a
912 * data synchronization barrier to the beginning of the abort handler.
913 * But for RTEMS a call of the abort handler means a fatal condition anyway.
914 * So there is no need to handle this erratum */
915#define CACHE_ARM_ERRATA_775420_HANDLER()                   \
916  if( arm_errata_is_applicable_processor_errata_775420 ) {  \
917  }                                                         \
918
919static void l2c_310_cache_check_errata( void )
920{
921  /* This erratum gets handled within the sources */
922  /* Unhandled erratum present: 588369 Errata 588369 says that clean + inv may
923   * keep the cache line if it was clean. See ARMs documentation on the erratum
924   * for a workaround */
925  /* assert( ! l2c_310_cache_errata_is_applicable_588369() ); */
926
927  /* Unhandled erratum present: 727913 Prefetch dropping feature can cause
928   * incorrect behavior when PL310 handles reads that cross cache line
929   * boundary */
930  assert( ! l2c_310_cache_errata_is_applicable_727913() );
931
932  /* Unhandled erratum present: 727914 Double linefill feature can cause
933   * deadlock */
934  assert( ! l2c_310_cache_errata_is_applicable_727914() );
935 
936  /* Unhandled erratum present: 727915 Background Clean and Invalidate by Way
937   * operation can cause data corruption */
938  assert( ! l2c_310_cache_errata_is_applicable_727915() );
939
940  /* Unhandled erratum present: 729806 Speculative reads from the Cortex-A9
941   * MPCore processor can cause deadlock */
942  assert( ! l2c_310_cache_errata_is_applicable_729806() );
943
944  if( l2c_310_cache_errata_is_applicable_729815() )
945  {
946    volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
947
948    assert( 0 == ( l2cc->aux_ctrl & CACHE_L2C_310_L2CC_AUX_HPSODRE_MASK ) );
949
950    /* Erratum: 729815 The “High Priority for SO and Dev reads” feature can
951     * cause Quality of Service issues to cacheable read transactions*/
952
953    /* Conditions
954       This problem occurs when the following conditions are met:
955       1. Bit[10] “High Priority for SO and Dev reads enable” of the PL310
956          Auxiliary Control Register is set to 1.
957       2. PL310 receives a cacheable read that misses in the L2 cache.
958       3. PL310 receives a continuous flow of Strongly Ordered or Device
959          reads that take all address slots in the master interface.
960       Workaround
961       A workaround is only necessary in systems that are able to issue a
962       continuous flow of Strongly Ordered or Device reads. In such a case,
963       the workaround is to disable the “High Priority for SO and Dev reads”
964       feature. This is the default behavior.*/
965  }
966 
967  /* Unhandled erratum present: 742884 Double linefill feature might introduce
968   * circular dependency and deadlock */
969  assert( ! l2c_310_cache_errata_is_applicable_742884() );
970
971  /* Unhandled erratum present: 752271 Double linefill feature can cause data
972   * corruption */
973  assert( ! l2c_310_cache_errata_is_applicable_752271() );
974
975  /* This erratum gets handled with a workaround: 753970 The Cache Sync
976   * operation prevents further bufferable writes from merging in the store.
977     Search for 753970 in cache_.h for detailed information */
978
979  /* Conditions
980     This problem occurs when the following conditions are met:
981     1. PL310 receives a Cache Sync operation.
982     Workaround
983     The proposed workaround to avoid this erratum is to replace the normal
984     offset of Cache Sync operation (0x730) by another offset targeting an
985     unmapped PL310 register: 0x740.
986     More specifically, find below a pseudo code sequence illustrating the
987     workaround:
988     Replace
989     // PL310 Cache Sync operation
990     LDR r1,=PL310_BASE
991     STR r2,[r1,#0x730]
992     by
993     // Workaround for PL310 Cache Sync operation
994     LDR r1,=PL310_BASE
995     STR r2,[r1,#0x740] ; write to an unmapped register
996     This write has the same effect as the Cache Sync operation: store buffer
997     drained and waiting for all buffers empty.*/
998  /* assert( ! l2c_310_cache_errata_is_applicable_753970() ); */
999
1000  /* This erratum can not be worked around: 754670 A continuous write flow can
1001   * stall a read targeting the same memory area
1002   * But this erratum does not lead to any data corruption */
1003  /* assert( ! l2c_310_cache_errata_is_applicable_754670() ); */
1004
1005  if( l2c_310_cache_errata_is_applicable_765569() )
1006  {
1007    volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1008
1009    assert( !( ( l2cc->aux_ctrl & CACHE_L2C_310_L2CC_AUX_IPFE_MASK
1010                 || l2cc->aux_ctrl & CACHE_L2C_310_L2CC_AUX_DPFE_MASK )
1011               && ( ( l2cc->prefetch_ctrl & CACHE_L2C_310_L2CC_PREFETCH_OFFSET_MASK )
1012                    == 23 ) ) );
1013
1014    /* Unhandled erratum present: 765569 Prefetcher can cross 4KB boundary if
1015     * offset is programmed with value 23 */
1016
1017    /* Conditions
1018       This problem occurs when the following conditions are met:
1019       1. One of the Prefetch Enable bits (bits [29:28] of the Auxiliary or
1020          Prefetch Control Register) is set HIGH.
1021       2. The prefetch offset bits are programmed with value 23 (5'b10111).
1022       Workaround
1023       A workaround for this erratum is to program the prefetch offset with any
1024       value except 23.*/
1025  }
1026
1027  /* Unhandled erratum present: 769419 No automatic Store Buffer drain,
1028   * visibility of written data requires an explicit Cache */
1029  assert( ! l2c_310_cache_errata_is_applicable_769419() );
1030}
1031
1032static inline void
1033cache_l2c_310_sync( void )
1034{
1035  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1036
1037  if( l2c_310_cache_errata_is_applicable_753970() ) {
1038    l2cc->dummy_cache_sync_reg = 0;
1039  } else {
1040    l2cc->cache_sync           = 0;
1041  }
1042}
1043
1044static inline void
1045cache_l2c_310_flush_1_line( const void *d_addr )
1046{
1047  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1048
1049
1050  if( l2c_310_cache_errata_is_applicable_588369() ) {
1051    /*
1052    * Errata 588369 says that clean + inv may keep the
1053    * cache line if it was clean, the recommanded
1054    * workaround is to clean then invalidate the cache
1055    * line, with write-back and cache linefill disabled.
1056    */
1057    l2cc->clean_pa     = (uint32_t) d_addr;
1058    cache_l2c_310_sync();
1059    l2cc->inv_pa       = (uint32_t) d_addr;
1060  } else {
1061    l2cc->clean_inv_pa = (uint32_t) d_addr;
1062  }
1063
1064  cache_l2c_310_sync();
1065}
1066
1067static inline void
1068cache_l2c_310_flush_range( const void *addr, size_t n_bytes )
1069{
1070  if ( n_bytes != 0 ) {
1071    uint32_t       adx       = (uint32_t) addr
1072                               & ~CACHE_L2C_310_DATA_LINE_MASK;
1073    const uint32_t ADDR_LAST =
1074      ( (uint32_t) addr + n_bytes - 1 ) & ~CACHE_L2C_310_DATA_LINE_MASK;
1075    volatile L2CC *l2cc      = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1076
1077    CACHE_ARM_ERRATA_764369_HANDLER();
1078
1079    for (; adx <= ADDR_LAST; adx += CPU_DATA_CACHE_ALIGNMENT ) {
1080      l2cc->clean_pa = adx;
1081    }
1082    cache_l2c_310_sync();
1083  }
1084}
1085
1086static inline void
1087cache_l2c_310_flush_entire( void )
1088{
1089  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1090
1091  /* Only flush if level 2 cache is active */
1092  if( ( l2cc->ctrl & CACHE_L2C_310_L2CC_ENABLE_MASK ) != 0 ) {
1093
1094    /* ensure ordering with previous memory accesses */
1095    _ARM_Data_memory_barrier();
1096
1097    l2cc->clean_inv_way = CACHE_l2C_310_WAY_MASK;
1098
1099    while ( l2cc->clean_inv_way & CACHE_l2C_310_WAY_MASK ) {
1100    }
1101
1102    ;
1103
1104    /* Wait for the flush to complete */
1105    cache_l2c_310_sync();
1106  }
1107}
1108
1109static inline void
1110cache_l2c_310_invalidate_1_line( const void *d_addr )
1111{
1112  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1113
1114
1115  l2cc->inv_pa = (uint32_t) d_addr;
1116
1117  cache_l2c_310_sync();
1118}
1119
1120static inline void
1121cache_l2c_310_invalidate_range( const void *addr, size_t n_bytes )
1122{
1123  if ( n_bytes != 0 ) {
1124    uint32_t       adx  = (uint32_t) addr
1125                         & ~CACHE_L2C_310_INSTRUCTION_LINE_MASK;
1126    const uint32_t end  =
1127      ( adx + n_bytes ) & ~CACHE_L2C_310_INSTRUCTION_LINE_MASK;
1128    volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1129
1130    /* Back starting address up to start of a line and invalidate until end */
1131    for (;
1132         adx < end;
1133         adx += CPU_INSTRUCTION_CACHE_ALIGNMENT ) {
1134      /* Invalidate L2 cache line */
1135      l2cc->inv_pa = adx;
1136    }
1137    cache_l2c_310_sync();
1138  }
1139}
1140
1141static inline void
1142cache_l2c_310_invalidate_entire( void )
1143{
1144  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1145
1146  /* Invalidate the caches */
1147
1148  /* ensure ordering with previous memory accesses */
1149  _ARM_Data_memory_barrier();
1150
1151  l2cc->inv_way = CACHE_l2C_310_WAY_MASK;
1152
1153  while ( l2cc->inv_way & CACHE_l2C_310_WAY_MASK ) ;
1154
1155  /* Wait for the invalidate to complete */
1156  cache_l2c_310_sync();
1157}
1158
1159static inline void
1160cache_l2c_310_clean_and_invalidate_entire( void )
1161{
1162  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1163
1164
1165  if( ( l2cc->ctrl & CACHE_L2C_310_L2CC_ENABLE_MASK ) != 0 ) {
1166    /* Invalidate the caches */
1167
1168    /* ensure ordering with previous memory accesses */
1169    _ARM_Data_memory_barrier();
1170
1171    l2cc->clean_inv_way = CACHE_l2C_310_WAY_MASK;
1172
1173    while ( l2cc->clean_inv_way & CACHE_l2C_310_WAY_MASK ) ;
1174
1175    /* Wait for the invalidate to complete */
1176    cache_l2c_310_sync();
1177  }
1178}
1179
1180static inline void
1181cache_l2c_310_store( const void *d_addr )
1182{
1183  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1184
1185
1186  l2cc->clean_pa = (uint32_t) d_addr;
1187
1188  cache_l2c_310_sync();
1189}
1190
1191static inline void
1192cache_l2c_310_freeze( void )
1193{
1194  /* To be implemented as needed, if supported
1195   by hardware at all */
1196}
1197
1198static inline void
1199cache_l2c_310_unfreeze( void )
1200{
1201  /* To be implemented as needed, if supported
1202   by hardware at all */
1203}
1204
1205static void cache_l2c_310_unlock( void )
1206{
1207  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1208
1209
1210  l2cc->d_lockdown_0 = 0;
1211  l2cc->i_lockdown_0 = 0;
1212  l2cc->d_lockdown_1 = 0;
1213  l2cc->i_lockdown_1 = 0;
1214  l2cc->d_lockdown_2 = 0;
1215  l2cc->i_lockdown_2 = 0;
1216  l2cc->d_lockdown_3 = 0;
1217  l2cc->i_lockdown_3 = 0;
1218  l2cc->d_lockdown_4 = 0;
1219  l2cc->i_lockdown_4 = 0;
1220  l2cc->d_lockdown_5 = 0;
1221  l2cc->i_lockdown_5 = 0;
1222  l2cc->d_lockdown_6 = 0;
1223  l2cc->i_lockdown_6 = 0;
1224  l2cc->d_lockdown_7 = 0;
1225  l2cc->i_lockdown_7 = 0;
1226}
1227
1228static inline void
1229cache_l2c_310_enable( void )
1230{
1231  volatile L2CC *l2cc     = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1232  uint32_t       cache_id = l2cc->cache_id & CACHE_L2C_310_L2CC_ID_PART_MASK;
1233  int            ways     = 0;
1234
1235
1236  /* Do we actually have an L2C-310 cache controller?
1237   * Has BSP_ARM_L2CC_BASE been configured correctly? */
1238  switch ( cache_id ) {
1239    case CACHE_L2C_310_L2CC_ID_PART_L310:
1240    {
1241      const cache_l2c_310_rtl_release RTL_RELEASE =
1242        l2cc->cache_id & CACHE_L2C_310_L2CC_ID_RTL_MASK;
1243      /* If this assertion fails, you have a release of the
1244       * L2C-310 cache for which the l2c_310_cache_errata_is_applicable_ ...
1245       * methods are not yet implemented. This means you will get incorrect
1246       * errata handling */
1247      assert(    RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P3
1248              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P2
1249              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P1
1250              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R3_P0
1251              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R2_P0
1252              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R1_P0
1253              || RTL_RELEASE == CACHE_L2C_310_RTL_RELEASE_R0_P0 );
1254      if ( l2cc->aux_ctrl & ( 1 << 16 ) ) {
1255        ways = 16;
1256      } else {
1257        ways = 8;
1258      }
1259
1260      assert( ways == CACHE_l2C_310_NUM_WAYS );
1261    }
1262    break;
1263    case CACHE_L2C_310_L2CC_ID_PART_L210:
1264
1265      /* Invalid case */
1266
1267      /* Support for this type is not implemented in this driver.
1268       * Either support needs to get added or a seperate driver needs to get
1269       * implemented */
1270      assert( cache_id != CACHE_L2C_310_L2CC_ID_PART_L210 );
1271      break;
1272    default:
1273
1274      /* Unknown case */
1275      assert( cache_id == CACHE_L2C_310_L2CC_ID_PART_L310 );
1276      break;
1277  }
1278
1279  if ( ways > 0 ) {
1280    /* Only enable if L2CC is currently disabled */   
1281    if ( ways != 0
1282         && ( l2cc->ctrl & CACHE_L2C_310_L2CC_ENABLE_MASK ) == 0 ) {
1283      rtems_interrupt_level level;
1284      uint32_t              aux;
1285
1286      rtems_interrupt_disable( level );
1287
1288      /* Set up the way size */
1289      aux  = l2cc->aux_ctrl;
1290      aux &= CACHE_L2C_310_L2CC_AUX_REG_ZERO_MASK; /* Set way_size to 0 */
1291      aux |= CACHE_L2C_310_L2CC_AUX_REG_DEFAULT_MASK;
1292
1293      /* Make sure that I&D is not locked down when starting */
1294      cache_l2c_310_unlock();
1295
1296      /* Level 2 configuration and control registers must not get written while
1297       * background operations are pending */
1298      while ( l2cc->inv_way & CACHE_l2C_310_WAY_MASK ) ;
1299
1300      while ( l2cc->clean_way & CACHE_l2C_310_WAY_MASK ) ;
1301
1302      while ( l2cc->clean_inv_way & CACHE_l2C_310_WAY_MASK ) ;
1303
1304      l2cc->aux_ctrl = aux;
1305
1306      /* Set up the latencies */
1307      l2cc->tag_ram_ctrl  = CACHE_L2C_310_L2CC_TAG_RAM_DEFAULT_LAT;
1308      l2cc->data_ram_ctrl = CACHE_L2C_310_L2CC_DATA_RAM_DEFAULT_MASK;
1309
1310      cache_l2c_310_invalidate_entire();
1311
1312      /* Clear the pending interrupts */
1313      l2cc->int_clr = l2cc->int_raw_status;
1314
1315      l2c_310_cache_check_errata();
1316
1317      /* Enable the L2CC */
1318      l2cc->ctrl |= CACHE_L2C_310_L2CC_ENABLE_MASK;
1319
1320      rtems_interrupt_enable( level );
1321    }
1322  }
1323}
1324
1325static inline void
1326cache_l2c_310_disable( void )
1327{
1328  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2CC_BASE;
1329
1330
1331  if ( l2cc->ctrl & CACHE_L2C_310_L2CC_ENABLE_MASK ) {
1332    /* Clean and Invalidate L2 Cache */
1333    cache_l2c_310_flush_entire();
1334
1335    /* Level 2 configuration and control registers must not get written while
1336     * background operations are pending */
1337    while ( l2cc->inv_way & CACHE_l2C_310_WAY_MASK ) ;
1338
1339    while ( l2cc->clean_way & CACHE_l2C_310_WAY_MASK ) ;
1340
1341    while ( l2cc->clean_inv_way & CACHE_l2C_310_WAY_MASK ) ;
1342
1343    /* Disable the L2 cache */
1344    l2cc->ctrl &= ~CACHE_L2C_310_L2CC_ENABLE_MASK;
1345  }
1346}
1347
1348static inline void
1349_CPU_cache_enable_data( void )
1350{
1351  cache_l2c_310_enable();
1352  arm_cache_l1_enable_data();
1353}
1354
1355static inline void
1356_CPU_cache_disable_data( void )
1357{
1358  arm_cache_l1_disable_data();
1359  cache_l2c_310_disable();
1360}
1361
1362static inline void
1363_CPU_cache_enable_instruction( void )
1364{
1365  cache_l2c_310_enable();
1366  arm_cache_l1_enable_instruction();
1367}
1368
1369static inline void
1370_CPU_cache_disable_instruction( void )
1371{
1372  arm_cache_l1_disable_instruction();
1373  cache_l2c_310_disable();
1374}
1375
1376static inline void
1377_CPU_cache_flush_data_range(
1378  const void *d_addr,
1379  size_t      n_bytes
1380)
1381{
1382  if ( n_bytes != 0 ) {
1383    arm_cache_l1_flush_data_range(
1384      d_addr,
1385      n_bytes
1386    );
1387    cache_l2c_310_flush_range(
1388      d_addr,
1389      n_bytes
1390    );
1391  }
1392}
1393
1394static inline void
1395_CPU_cache_flush_entire_data( void )
1396{
1397  arm_cache_l1_flush_entire_data();
1398  cache_l2c_310_flush_entire();
1399}
1400
1401static inline void
1402_CPU_cache_invalidate_data_range(
1403  const void *addr_first,
1404  size_t     n_bytes
1405)
1406{
1407  if ( n_bytes > 0 ) {
1408    CACHE_ARM_ERRATA_764369_HANDLER();
1409   
1410    cache_l2c_310_invalidate_range(
1411      addr_first,
1412      n_bytes
1413    );
1414    arm_cache_l1_invalidate_data_range(
1415      addr_first,
1416      n_bytes
1417    );
1418    cache_l2c_310_invalidate_range(
1419      addr_first,
1420      n_bytes
1421    );
1422    arm_cache_l1_invalidate_data_range(
1423      addr_first,
1424      n_bytes
1425    );
1426  }
1427}
1428
1429static inline void
1430_CPU_cache_invalidate_entire_data( void )
1431{
1432  /* This is broadcast within the cluster */
1433  arm_cache_l1_flush_entire_data();
1434
1435  /* forces the address out past level 2 */
1436  cache_l2c_310_clean_and_invalidate_entire();
1437
1438  /*This is broadcast within the cluster */
1439  arm_cache_l1_clean_and_invalidate_entire_data();
1440}
1441
1442static inline void
1443_CPU_cache_store_data_line( const void *d_addr )
1444{
1445  const void *ADX =
1446    (const void *) ( (uint32_t) d_addr & ~CACHE_L2C_310_DATA_LINE_MASK );
1447
1448  arm_cache_l1_store_data( ADX );
1449  cache_l2c_310_store( ADX );
1450}
1451
1452static inline void
1453_CPU_cache_freeze_data( void )
1454{
1455  arm_cache_l1_freeze_data();
1456  cache_l2c_310_freeze();
1457}
1458
1459static inline void
1460_CPU_cache_unfreeze_data( void )
1461{
1462  arm_cache_l1_unfreeze_data();
1463  cache_l2c_310_unfreeze();
1464}
1465
1466static inline void
1467_CPU_cache_invalidate_instruction_range(
1468  const void *i_addr,
1469  size_t      n_bytes
1470)
1471{
1472  if ( n_bytes != 0 ) {
1473   CACHE_ARM_ERRATA_764369_HANDLER();
1474   
1475    /* Invalidate L2 cache lines */
1476    cache_l2c_310_invalidate_range(
1477      i_addr,
1478      n_bytes
1479    );
1480   
1481    arm_cache_l1_invalidate_instruction_range(
1482      i_addr,
1483      n_bytes
1484    );
1485  }
1486}
1487
1488static inline void
1489_CPU_cache_invalidate_entire_instruction( void )
1490{
1491  cache_l2c_310_invalidate_entire();
1492  arm_cache_l1_invalidate_entire_instruction();
1493}
1494
1495static inline void
1496_CPU_cache_freeze_instruction( void )
1497{
1498  arm_cache_l1_freeze_instruction();
1499  cache_l2c_310_freeze();
1500}
1501
1502static inline void
1503_CPU_cache_unfreeze_instruction( void )
1504{
1505  arm_cache_l1_unfreeze_instruction();
1506  cache_l2c_310_unfreeze();
1507}
1508
1509/** @} */
1510
1511#ifdef __cplusplus
1512}
1513#endif /* __cplusplus */
1514
1515#endif /* LIBBSP_ARM_SHARED_L2C_310_CACHE_H */
Note: See TracBrowser for help on using the repository browser.