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

5
Last change on this file since fd10817 was fd10817, checked in by Alexei Pososin <m09123874@…>, on 05/11/17 at 13:33:10

Remove excessive locking from cache operations.

According to manual, the used operations (Clean Line by PA, Clean and
Invalidate Line by PA, Cache Sync) are atomic and do not require
locking.

Update #3007.

  • Property mode set to 100644
File size: 35.6 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 <bsp/fatal.h>
62#include <libcpu/arm-cp15.h>
63#include <rtems/rtems/intr.h>
64#include <bsp/arm-release-id.h>
65#include <bsp/arm-errata.h>
66#include "../include/arm-cache-l1.h"
67
68#ifdef __cplusplus
69extern "C" {
70#endif /* __cplusplus */
71
72/* These two defines also ensure that the rtems_cache_* functions have bodies */
73#define CPU_DATA_CACHE_ALIGNMENT ARM_CACHE_L1_CPU_DATA_ALIGNMENT
74#define CPU_INSTRUCTION_CACHE_ALIGNMENT ARM_CACHE_L1_CPU_INSTRUCTION_ALIGNMENT
75#if defined(__ARM_ARCH_7A__)
76/* Some/many ARM Cortex-A cores have L1 data line length 64 bytes */
77#define CPU_MAXIMAL_CACHE_ALIGNMENT 64
78#endif
79#define CPU_CACHE_SUPPORT_PROVIDES_RANGE_FUNCTIONS \
80  ARM_CACHE_L1_CPU_SUPPORT_PROVIDES_RANGE_FUNCTIONS
81#define CPU_CACHE_SUPPORT_PROVIDES_CACHE_SIZE_FUNCTIONS
82
83#define L2C_310_DATA_LINE_MASK ( CPU_DATA_CACHE_ALIGNMENT - 1 )
84#define L2C_310_INSTRUCTION_LINE_MASK \
85  ( CPU_INSTRUCTION_CACHE_ALIGNMENT \
86    - 1 )
87#define L2C_310_NUM_WAYS 8
88#define L2C_310_WAY_MASK ( ( 1 << L2C_310_NUM_WAYS ) - 1 )
89
90#define L2C_310_MIN( a, b ) \
91  ((a < b) ? (a) : (b))
92
93#define L2C_310_MAX_LOCKING_BYTES (4 * 1024)
94
95
96/* RTL release number as can be read from cache_id register */
97#define L2C_310_RTL_RELEASE_R0_P0 0x0
98#define L2C_310_RTL_RELEASE_R1_P0 0x2
99#define L2C_310_RTL_RELEASE_R2_P0 0x4
100#define L2C_310_RTL_RELEASE_R3_P0 0x5
101#define L2C_310_RTL_RELEASE_R3_P1 0x6
102#define L2C_310_RTL_RELEASE_R3_P2 0x8
103#define L2C_310_RTL_RELEASE_R3_P3 0x9
104
105#define BSP_ARM_L2C_310_RTL_RELEASE (BSP_ARM_L2C_310_ID & L2C_310_ID_RTL_MASK)
106
107/**
108 * @defgroup L2C-310_cache Cache Support
109 * @ingroup arm_shared
110 * @brief Cache Functions and Defitions
111 * @{
112 */
113
114
115/**
116 * @brief L2CC Register Offsets
117 */
118typedef struct {
119  /** @brief Cache ID */
120  uint32_t cache_id;
121#define L2C_310_ID_RTL_MASK 0x3f
122#define L2C_310_ID_PART_MASK ( 0xf << 6 )
123#define L2C_310_ID_PART_L210 ( 1 << 6 )
124#define L2C_310_ID_PART_L310 ( 3 << 6 )
125#define L2C_310_ID_IMPL_MASK ( 0xff << 24 )
126  /** @brief Cache type */
127  uint32_t cache_type;
128/** @brief 1 if data banking implemented, 0 if not */
129#define L2C_310_TYPE_DATA_BANKING_MASK 0x80000000
130/** @brief 11xy, where: x=1 if pl310_LOCKDOWN_BY_MASTER is defined, otherwise 0 */
131#define L2C_310_TYPE_CTYPE_MASK 0x1E000000
132/** @brief y=1 if pl310_LOCKDOWN_BY_LINE is defined, otherwise 0. */
133#define L2C_310_TYPE_CTYPE_SHIFT 25
134/** @brief 1 for Harvard architecture, 0 for unified architecture */
135#define L2C_310_TYPE_HARVARD_MASK 0x01000000
136/** @brief Data cache way size = 2 Exp(value + 2) KB */
137#define L2C_310_TYPE_SIZE_D_WAYS_MASK 0x00700000
138#define L2C_310_TYPE_SIZE_D_WAYS_SHIFT 20
139/** @brief Assoziativity aka number of data ways = (value * 8) + 8 */
140#define L2C_310_TYPE_NUM_D_WAYS_MASK 0x00040000
141#define L2C_310_TYPE_NUM_D_WAYS_SHIFT 18
142/** @brief Data cache line length 00 - 32 */
143#define L2C_310_TYPE_LENGTH_D_LINE_MASK 0x00003000
144#define L2C_310_TYPE_LENGTH_D_LINE_SHIFT 12
145#define L2C_310_TYPE_LENGTH_D_LINE_VAL_32 0x0
146/** @brief Instruction cache way size = 2 Exp(value + 2) KB */
147#define L2C_310_TYPE_SIZE_I_WAYS_MASK 0x00000700
148#define L2C_310_TYPE_SIZE_I_WAYS_SHIFT 8
149/** @brief Assoziativity aka number of instruction ways = (value * 8) + 8 */
150#define L2C_310_TYPE_NUM_I_WAYS_MASK 0x00000040
151#define L2C_310_TYPE_NUM_I_WAYS_SHIFT 6
152/** @brief Instruction cache line length 00 - 32 */
153#define L2C_310_TYPE_LENGTH_I_LINE_MASK 0x00000003
154#define L2C_310_TYPE_LENGTH_I_LINE_SHIFT 0
155#define L2C_310_TYPE_LENGTH_I_LINE_VAL_32 0x0
156
157  uint8_t reserved_8[0x100 - 8];
158  uint32_t ctrl; /* Control */
159/** @brief Enables the L2CC */
160#define L2C_310_CTRL_ENABLE 0x00000001
161
162#define L2C_310_CTRL_EXCL_CONFIG (1 << 12)
163
164  /** @brief Auxiliary control */
165  uint32_t aux_ctrl;
166
167/** @brief Early BRESP Enable */
168#define L2C_310_AUX_EBRESPE_MASK 0x40000000
169
170/** @brief Instruction Prefetch Enable */
171#define L2C_310_AUX_IPFE_MASK 0x20000000
172
173/** @brief Data Prefetch Enable */
174#define L2C_310_AUX_DPFE_MASK 0x10000000
175
176/** @brief Non-secure interrupt access control */
177#define L2C_310_AUX_NSIC_MASK 0x08000000
178
179/** @brief Non-secure lockdown enable */
180#define L2C_310_AUX_NSLE_MASK 0x04000000
181
182/** @brief Cache replacement policy */
183#define L2C_310_AUX_CRP_MASK 0x02000000
184
185/** @brief Force write allocate */
186#define L2C_310_AUX_FWE_MASK 0x01800000
187
188/** @brief Shared attribute override enable */
189#define L2C_310_AUX_SAOE_MASK 0x00400000
190
191/** @brief Parity enable */
192#define L2C_310_AUX_PE_MASK 0x00200000
193
194/** @brief Event monitor bus enable */
195#define L2C_310_AUX_EMBE_MASK 0x00100000
196
197/** @brief Way-size */
198#define L2C_310_AUX_WAY_SIZE_MASK 0x000E0000
199#define L2C_310_AUX_WAY_SIZE_SHIFT 17
200
201/** @brief Way-size */
202#define L2C_310_AUX_ASSOC_MASK 0x00010000
203
204/** @brief Shared attribute invalidate enable */
205#define L2C_310_AUX_SAIE_MASK 0x00002000
206
207/** @brief Exclusive cache configuration */
208#define L2C_310_AUX_EXCL_CACHE_MASK 0x00001000
209
210/** @brief Store buffer device limitation Enable */
211#define L2C_310_AUX_SBDLE_MASK 0x00000800
212
213/** @brief High Priority for SO and Dev Reads Enable */
214#define L2C_310_AUX_HPSODRE_MASK 0x00000400
215
216/** @brief Full line of zero enable */
217#define L2C_310_AUX_FLZE_MASK 0x00000001
218
219/** @brief Enable all prefetching, */
220#define L2C_310_AUX_REG_DEFAULT_MASK \
221  ( L2C_310_AUX_WAY_SIZE_MASK & ( 0x3 << L2C_310_AUX_WAY_SIZE_SHIFT ) ) \
222  | L2C_310_AUX_PE_MASK      /* Prefetch enable */ \
223  | L2C_310_AUX_SAOE_MASK    /* Shared attribute override enable */ \
224  | L2C_310_AUX_CRP_MASK     /* Cache replacement policy */ \
225  | L2C_310_AUX_DPFE_MASK    /* Data prefetch enable */ \
226  | L2C_310_AUX_IPFE_MASK    /* Instruction prefetch enable */ \
227  | L2C_310_AUX_EBRESPE_MASK /* Early BRESP enable */
228
229#define L2C_310_AUX_REG_ZERO_MASK 0xFFF1FFFF
230
231/** @brief 1 cycle of latency, there is no additional latency fot tag RAM */
232#define L2C_310_RAM_1_CYCLE_LAT_VAL 0x00000000
233/** @brief 2 cycles of latency for tag RAM */
234#define L2C_310_RAM_2_CYCLE_LAT_VAL 0x00000001
235/** @brief 3 cycles of latency for tag RAM */
236#define L2C_310_RAM_3_CYCLE_LAT_VAL 0x00000002
237/** @brief 4 cycles of latency for tag RAM */
238#define L2C_310_RAM_4_CYCLE_LAT_VAL 0x00000003
239/** @brief 5 cycles of latency for tag RAM */
240#define L2C_310_RAM_5_CYCLE_LAT_VAL 0x00000004
241/** @brief 6 cycles of latency for tag RAM */
242#define L2C_310_RAM_6_CYCLE_LAT_VAL 0x00000005
243/** @brief 7 cycles of latency for tag RAM */
244#define L2C_310_RAM_7_CYCLE_LAT_VAL 0x00000006
245/** @brief 8 cycles of latency for tag RAM */
246#define L2C_310_RAM_8_CYCLE_LAT_VAL 0x00000007
247/** @brief Shift left setup latency values by this value */
248#define L2C_310_RAM_SETUP_SHIFT 0x00000000
249/** @brief Shift left read latency values by this value */
250#define L2C_310_RAM_READ_SHIFT 0x00000004
251/** @brief Shift left write latency values by this value */
252#define L2C_310_RAM_WRITE_SHIFT 0x00000008
253/** @brief Mask for RAM setup latency */
254#define L2C_310_RAM_SETUP_LAT_MASK 0x00000007
255/** @brief Mask for RAM read latency */
256#define L2C_310_RAM_READ_LAT_MASK 0x00000070
257/** @brief Mask for RAM read latency */
258#define L2C_310_RAM_WRITE_LAT_MASK 0x00000700
259  /** @brief Latency for tag RAM */
260  uint32_t tag_ram_ctrl;
261/* @brief Latency for tag RAM */
262#define L2C_310_TAG_RAM_DEFAULT_LAT \
263  ( ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_SETUP_SHIFT ) \
264    | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_READ_SHIFT ) \
265    | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_WRITE_SHIFT ) )
266  /** @brief Latency for data RAM */
267  uint32_t data_ram_ctrl;
268/** @brief Latency for data RAM */
269#define L2C_310_DATA_RAM_DEFAULT_MASK \
270  ( ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_SETUP_SHIFT ) \
271    | ( L2C_310_RAM_3_CYCLE_LAT_VAL << L2C_310_RAM_READ_SHIFT ) \
272    | ( L2C_310_RAM_2_CYCLE_LAT_VAL << L2C_310_RAM_WRITE_SHIFT ) )
273
274  uint8_t reserved_110[0x200 - 0x110];
275
276  /** @brief Event counter control */
277  uint32_t ev_ctrl;
278
279  /** @brief Event counter 1 configuration */
280  uint32_t ev_cnt1_cfg;
281
282  /** @brief Event counter 0 configuration */
283  uint32_t ev_cnt0_cfg;
284
285  /** @brief Event counter 1 value */
286  uint32_t ev_cnt1;
287
288  /** @brief Event counter 0 value */
289  uint32_t ev_cnt0;
290
291  /** @brief Interrupt enable mask */
292  uint32_t int_mask;
293
294  /** @brief Masked   interrupt status (read-only)*/
295  uint32_t int_mask_status;
296
297  /** @brief Unmasked interrupt status */
298  uint32_t int_raw_status;
299
300  /** @brief Interrupt clear */
301  uint32_t int_clr;
302
303/**
304 * @name Interrupt bit masks
305 *
306 * @{
307 */
308
309/** @brief DECERR from L3 */
310#define L2C_310_INT_DECERR_MASK 0x00000100
311
312/** @brief SLVERR from L3 */
313#define L2C_310_INT_SLVERR_MASK 0x00000080
314
315/** @brief Error on L2 data RAM (Read) */
316#define L2C_310_INT_ERRRD_MASK 0x00000040
317
318/** @brief Error on L2 tag RAM (Read) */
319#define L2C_310_INT_ERRRT_MASK 0x00000020
320
321/** @brief Error on L2 data RAM (Write) */
322#define L2C_310_INT_ERRWD_MASK 0x00000010
323
324/** @brief Error on L2 tag RAM (Write) */
325#define L2C_310_INT_ERRWT_MASK 0x00000008
326
327/** @brief Parity Error on L2 data RAM (Read) */
328#define L2C_310_INT_PARRD_MASK 0x00000004
329
330/** @brief Parity Error on L2 tag RAM (Read) */
331#define L2C_310_INT_PARRT_MASK 0x00000002
332
333/** @brief Event Counter1/0 Overflow Increment */
334#define L2C_310_INT_ECNTR_MASK 0x00000001
335
336/** @} */
337
338  uint8_t reserved_224[0x730 - 0x224];
339
340  /** @brief Drain the STB */
341  uint32_t cache_sync;
342  uint8_t reserved_734[0x740 - 0x734];
343  /** @brief ARM Errata 753970 for pl310-r3p0 */
344  uint32_t dummy_cache_sync_reg;
345  uint8_t reserved_744[0x770 - 0x744];
346
347  /** @brief Invalidate line by PA */
348  uint32_t inv_pa;
349  uint8_t reserved_774[0x77c - 0x774];
350
351  /** @brief Invalidate by Way */
352  uint32_t inv_way;
353  uint8_t reserved_780[0x7b0 - 0x780];
354
355  /** @brief Clean Line by PA */
356  uint32_t clean_pa;
357  uint8_t reserved_7b4[0x7b8 - 0x7b4];
358
359  /** @brief Clean Line by Set/Way */
360  uint32_t clean_index;
361
362  /** @brief Clean by Way */
363  uint32_t clean_way;
364  uint8_t reserved_7c0[0x7f0 - 0x7c0];
365
366  /** @brief Clean and Invalidate Line by PA */
367  uint32_t clean_inv_pa;
368  uint8_t reserved_7f4[0x7f8 - 0x7f4];
369
370  /** @brief Clean and Invalidate Line by Set/Way */
371  uint32_t clean_inv_indx;
372
373  /** @brief Clean and Invalidate by Way */
374  uint32_t clean_inv_way;
375
376  /** @brief Data        lock down 0 */
377  uint32_t d_lockdown_0;
378
379  /** @brief Instruction lock down 0 */
380  uint32_t i_lockdown_0;
381
382  /** @brief Data        lock down 1 */
383  uint32_t d_lockdown_1;
384
385  /** @brief Instruction lock down 1 */
386  uint32_t i_lockdown_1;
387
388  /** @brief Data        lock down 2 */
389  uint32_t d_lockdown_2;
390
391  /** @brief Instruction lock down 2 */
392  uint32_t i_lockdown_2;
393
394  /** @brief Data        lock down 3 */
395  uint32_t d_lockdown_3;
396
397  /** @brief Instruction lock down 3 */
398  uint32_t i_lockdown_3;
399
400  /** @brief Data        lock down 4 */
401  uint32_t d_lockdown_4;
402
403  /** @brief Instruction lock down 4 */
404  uint32_t i_lockdown_4;
405
406  /** @brief Data        lock down 5 */
407  uint32_t d_lockdown_5;
408
409  /** @brief Instruction lock down 5 */
410  uint32_t i_lockdown_5;
411
412  /** @brief Data        lock down 6 */
413  uint32_t d_lockdown_6;
414
415  /** @brief Instruction lock down 6 */
416  uint32_t i_lockdown_6;
417
418  /** @brief Data        lock down 7 */
419  uint32_t d_lockdown_7;
420
421  /** @brief Instruction lock down 7 */
422  uint32_t i_lockdown_7;
423
424  uint8_t reserved_940[0x950 - 0x940];
425
426  /** @brief Lockdown by Line Enable */
427  uint32_t lock_line_en;
428
429  /** @brief Cache lockdown by way */
430  uint32_t unlock_way;
431
432  uint8_t reserved_958[0xc00 - 0x958];
433
434  /** @brief Address range redirect, part 1 */
435  uint32_t addr_filtering_start;
436
437  /** @brief Address range redirect, part 2 */
438  uint32_t addr_filtering_end;
439
440/** @brief Address filtering valid bits*/
441#define L2C_310_ADDR_FILTER_VALID_MASK 0xFFF00000
442
443/** @brief Address filtering enable bit*/
444#define L2C_310_ADDR_FILTER_ENABLE_MASK 0x00000001
445
446  uint8_t reserved_c08[0xf40 - 0xc08];
447
448  /** @brief Debug control */
449  uint32_t debug_ctrl;
450
451/** @brief Debug SPIDEN bit */
452#define L2C_310_DEBUG_SPIDEN_MASK 0x00000004
453
454/** @brief Debug DWB bit, forces write through */
455#define L2C_310_DEBUG_DWB_MASK 0x00000002
456
457/** @brief Debug DCL bit, disables cache line fill */
458#define L2C_310_DEBUG_DCL_MASK 0x00000002
459
460  uint8_t reserved_f44[0xf60 - 0xf44];
461
462  /** @brief Purpose prefetch enables */
463  uint32_t prefetch_ctrl;
464/** @brief Prefetch offset */
465#define L2C_310_PREFETCH_OFFSET_MASK 0x0000001F
466  uint8_t reserved_f64[0xf80 - 0xf64];
467
468  /** @brief Purpose power controls */
469  uint32_t power_ctrl;
470} L2CC;
471
472rtems_interrupt_lock l2c_310_lock = RTEMS_INTERRUPT_LOCK_INITIALIZER(
473  "L2-310 cache controller"
474);
475
476/* Errata table for the LC2 310 Level 2 cache from ARM.
477* Information taken from ARMs
478* "CoreLink controllers and peripherals
479* - System controllers
480* - L2C-310 Level 2 Cache Controller
481* - Revision r3p3
482* - Software Developer Errata Notice
483* - ARM CoreLink Level 2 Cache Controller (L2C-310 or PL310),
484*   r3 releases Software Developers Errata Notice"
485* Please see this document for more information on these erratas */
486#if BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R3_P0
487#define L2C_310_ERRATA_IS_APPLICABLE_753970
488#endif
489
490static bool l2c_310_errata_is_applicable_727913(
491  uint32_t rtl_release
492)
493{
494  bool is_applicable = false;
495
496  switch ( rtl_release ) {
497    case L2C_310_RTL_RELEASE_R3_P3:
498    case L2C_310_RTL_RELEASE_R3_P2:
499    case L2C_310_RTL_RELEASE_R3_P1:
500    case L2C_310_RTL_RELEASE_R2_P0:
501    case L2C_310_RTL_RELEASE_R1_P0:
502    case L2C_310_RTL_RELEASE_R0_P0:
503      is_applicable = false;
504      break;
505    case L2C_310_RTL_RELEASE_R3_P0:
506      is_applicable = true;
507      break;
508    default:
509      assert( 0 );
510      break;
511  }
512
513  return is_applicable;
514}
515
516static bool l2c_310_errata_is_applicable_727914(
517  uint32_t rtl_release
518)
519{
520  bool is_applicable = false;
521
522  switch ( rtl_release ) {
523    case L2C_310_RTL_RELEASE_R3_P3:
524    case L2C_310_RTL_RELEASE_R3_P2:
525    case L2C_310_RTL_RELEASE_R3_P1:
526    case L2C_310_RTL_RELEASE_R2_P0:
527    case L2C_310_RTL_RELEASE_R1_P0:
528    case L2C_310_RTL_RELEASE_R0_P0:
529      is_applicable = false;
530      break;
531    case L2C_310_RTL_RELEASE_R3_P0:
532      is_applicable = true;
533      break;
534    default:
535      assert( 0 );
536      break;
537  }
538
539  return is_applicable;
540}
541
542static bool l2c_310_errata_is_applicable_727915(
543  uint32_t rtl_release
544)
545{
546  bool is_applicable = false;
547
548  switch ( rtl_release ) {
549    case L2C_310_RTL_RELEASE_R3_P3:
550    case L2C_310_RTL_RELEASE_R3_P2:
551    case L2C_310_RTL_RELEASE_R3_P1:
552    case L2C_310_RTL_RELEASE_R1_P0:
553    case L2C_310_RTL_RELEASE_R0_P0:
554      is_applicable = false;
555      break;
556    case L2C_310_RTL_RELEASE_R3_P0:
557    case L2C_310_RTL_RELEASE_R2_P0:
558      is_applicable = true;
559      break;
560    default:
561      assert( 0 );
562      break;
563  }
564
565  return is_applicable;
566}
567
568static bool l2c_310_errata_is_applicable_729806(
569  uint32_t rtl_release
570)
571{
572  bool is_applicable = false;
573
574  switch ( rtl_release ) {
575    case L2C_310_RTL_RELEASE_R3_P3:
576    case L2C_310_RTL_RELEASE_R3_P2:
577    case L2C_310_RTL_RELEASE_R2_P0:
578    case L2C_310_RTL_RELEASE_R1_P0:
579    case L2C_310_RTL_RELEASE_R0_P0:
580      is_applicable = false;
581      break;
582    case L2C_310_RTL_RELEASE_R3_P1:
583    case L2C_310_RTL_RELEASE_R3_P0:
584      is_applicable = true;
585      break;
586    default:
587      assert( 0 );
588      break;
589  }
590
591  return is_applicable;
592}
593
594static bool l2c_310_errata_is_applicable_729815(
595  uint32_t rtl_release
596)
597{
598  bool is_applicable = false;
599
600  switch ( rtl_release ) {
601    case L2C_310_RTL_RELEASE_R3_P3:
602    case L2C_310_RTL_RELEASE_R1_P0:
603    case L2C_310_RTL_RELEASE_R0_P0:
604      is_applicable = false;
605      break;
606    case L2C_310_RTL_RELEASE_R3_P2:
607    case L2C_310_RTL_RELEASE_R3_P1:
608    case L2C_310_RTL_RELEASE_R3_P0:
609    case L2C_310_RTL_RELEASE_R2_P0:
610      is_applicable = true;
611      break;
612    default:
613      assert( 0 );
614      break;
615  }
616
617  return is_applicable;
618}
619
620static bool l2c_310_errata_is_applicable_742884(
621  uint32_t rtl_release
622)
623{
624  bool is_applicable = false;
625
626  switch ( rtl_release ) {
627    case L2C_310_RTL_RELEASE_R3_P3:
628    case L2C_310_RTL_RELEASE_R3_P2:
629    case L2C_310_RTL_RELEASE_R3_P0:
630    case L2C_310_RTL_RELEASE_R2_P0:
631    case L2C_310_RTL_RELEASE_R1_P0:
632    case L2C_310_RTL_RELEASE_R0_P0:
633      is_applicable = false;
634      break;
635    case L2C_310_RTL_RELEASE_R3_P1:
636      is_applicable = true;
637      break;
638    default:
639      assert( 0 );
640      break;
641  }
642
643  return is_applicable;
644}
645
646static bool l2c_310_errata_is_applicable_752271(
647  uint32_t rtl_release
648)
649{
650  bool is_applicable = false;
651
652  switch ( rtl_release ) {
653    case L2C_310_RTL_RELEASE_R3_P3:
654    case L2C_310_RTL_RELEASE_R3_P2:
655    case L2C_310_RTL_RELEASE_R2_P0:
656    case L2C_310_RTL_RELEASE_R1_P0:
657    case L2C_310_RTL_RELEASE_R0_P0:
658      is_applicable = false;
659      break;
660    case L2C_310_RTL_RELEASE_R3_P1:
661    case L2C_310_RTL_RELEASE_R3_P0:
662      is_applicable = true;
663      break;
664    default:
665      assert( 0 );
666      break;
667  }
668
669  return is_applicable;
670}
671
672static bool l2c_310_errata_is_applicable_765569(
673  uint32_t rtl_release
674)
675{
676  bool is_applicable = false;
677
678  switch ( rtl_release ) {
679    case L2C_310_RTL_RELEASE_R3_P3:
680    case L2C_310_RTL_RELEASE_R3_P2:
681    case L2C_310_RTL_RELEASE_R3_P1:
682    case L2C_310_RTL_RELEASE_R3_P0:
683    case L2C_310_RTL_RELEASE_R2_P0:
684    case L2C_310_RTL_RELEASE_R1_P0:
685    case L2C_310_RTL_RELEASE_R0_P0:
686      is_applicable = true;
687      break;
688    default:
689      assert( 0 );
690      break;
691  }
692
693  return is_applicable;
694}
695
696static bool l2c_310_errata_is_applicable_769419(
697  uint32_t rtl_release
698)
699{
700  bool is_applicable = false;
701
702  switch ( rtl_release ) {
703    case L2C_310_RTL_RELEASE_R3_P3:
704    case L2C_310_RTL_RELEASE_R3_P2:
705      is_applicable = false;
706      break;
707    case L2C_310_RTL_RELEASE_R3_P1:
708    case L2C_310_RTL_RELEASE_R3_P0:
709    case L2C_310_RTL_RELEASE_R2_P0:
710    case L2C_310_RTL_RELEASE_R1_P0:
711    case L2C_310_RTL_RELEASE_R0_P0:
712      is_applicable = true;
713      break;
714    default:
715      assert( 0 );
716      break;
717  }
718
719  return is_applicable;
720}
721
722#if BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R0_P0 \
723   || BSP_ARM_L2C_310_RTL_RELEASE == L2C_310_RTL_RELEASE_R1_P0
724#define L2C_310_ERRATA_IS_APPLICABLE_588369
725#endif
726
727#ifdef CACHE_ERRATA_CHECKS_FOR_IMPLEMENTED_ERRATAS
728static bool l2c_310_errata_is_applicable_754670(
729  uint32_t rtl_release
730)
731{
732  bool is_applicable = false;
733
734  switch ( rtl_release ) {
735    case L2C_310_RTL_RELEASE_R3_P3:
736    case L2C_310_RTL_RELEASE_R3_P2:
737    case L2C_310_RTL_RELEASE_R3_P1:
738    case L2C_310_RTL_RELEASE_R3_P0:
739    case L2C_310_RTL_RELEASE_R2_P0:
740    case L2C_310_RTL_RELEASE_R1_P0:
741    case L2C_310_RTL_RELEASE_R0_P0:
742      is_applicable = true;
743    break;
744    default:
745      assert( 0 );
746      break;
747  }
748
749  return is_applicable;
750}
751#endif /* CACHE_ERRATA_CHECKS_FOR_IMPLEMENTED_ERRATAS */
752
753/* The common workaround for this erratum would be to add a
754 * data synchronization barrier to the beginning of the abort handler.
755 * But for RTEMS a call of the abort handler means a fatal condition anyway.
756 * So there is no need to handle this erratum */
757#define CACHE_ARM_ERRATA_775420_HANDLER()                   \
758  if( arm_errata_is_applicable_processor_errata_775420 ) {  \
759  }                                                         \
760
761static void l2c_310_check_errata( uint32_t rtl_release )
762{
763  /* This erratum gets handled within the sources */
764  /* Unhandled erratum present: 588369 Errata 588369 says that clean + inv may
765   * keep the cache line if it was clean. See ARMs documentation on the erratum
766   * for a workaround */
767  /* assert( ! l2c_310_errata_is_applicable_588369( rtl_release ) ); */
768
769  /* Unhandled erratum present: 727913 Prefetch dropping feature can cause
770   * incorrect behavior when PL310 handles reads that cross cache line
771   * boundary */
772  assert( ! l2c_310_errata_is_applicable_727913( rtl_release ) );
773
774  /* Unhandled erratum present: 727914 Double linefill feature can cause
775   * deadlock */
776  assert( ! l2c_310_errata_is_applicable_727914( rtl_release ) );
777
778  /* Unhandled erratum present: 727915 Background Clean and Invalidate by Way
779   * operation can cause data corruption */
780  assert( ! l2c_310_errata_is_applicable_727915( rtl_release ) );
781
782  /* Unhandled erratum present: 729806 Speculative reads from the Cortex-A9
783   * MPCore processor can cause deadlock */
784  assert( ! l2c_310_errata_is_applicable_729806( rtl_release ) );
785
786  if( l2c_310_errata_is_applicable_729815( rtl_release ) )
787  {
788    volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
789
790    assert( 0 == ( l2cc->aux_ctrl & L2C_310_AUX_HPSODRE_MASK ) );
791
792    /* Erratum: 729815 The “High Priority for SO and Dev reads” feature can
793     * cause Quality of Service issues to cacheable read transactions*/
794
795    /* Conditions
796       This problem occurs when the following conditions are met:
797       1. Bit[10] “High Priority for SO and Dev reads enable” of the PL310
798          Auxiliary Control Register is set to 1.
799       2. PL310 receives a cacheable read that misses in the L2 cache.
800       3. PL310 receives a continuous flow of Strongly Ordered or Device
801          reads that take all address slots in the master interface.
802       Workaround
803       A workaround is only necessary in systems that are able to issue a
804       continuous flow of Strongly Ordered or Device reads. In such a case,
805       the workaround is to disable the “High Priority for SO and Dev reads”
806       feature. This is the default behavior.*/
807  }
808
809  /* Unhandled erratum present: 742884 Double linefill feature might introduce
810   * circular dependency and deadlock */
811  assert( ! l2c_310_errata_is_applicable_742884( rtl_release ) );
812
813  /* Unhandled erratum present: 752271 Double linefill feature can cause data
814   * corruption */
815  assert( ! l2c_310_errata_is_applicable_752271( rtl_release ) );
816
817  /* This erratum can not be worked around: 754670 A continuous write flow can
818   * stall a read targeting the same memory area
819   * But this erratum does not lead to any data corruption */
820  /* assert( ! l2c_310_errata_is_applicable_754670() ); */
821
822  if( l2c_310_errata_is_applicable_765569( rtl_release ) )
823  {
824    volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
825
826    assert( !( ( l2cc->aux_ctrl & L2C_310_AUX_IPFE_MASK
827                 || l2cc->aux_ctrl & L2C_310_AUX_DPFE_MASK )
828               && ( ( l2cc->prefetch_ctrl & L2C_310_PREFETCH_OFFSET_MASK )
829                    == 23 ) ) );
830
831    /* Unhandled erratum present: 765569 Prefetcher can cross 4KB boundary if
832     * offset is programmed with value 23 */
833
834    /* Conditions
835       This problem occurs when the following conditions are met:
836       1. One of the Prefetch Enable bits (bits [29:28] of the Auxiliary or
837          Prefetch Control Register) is set HIGH.
838       2. The prefetch offset bits are programmed with value 23 (5'b10111).
839       Workaround
840       A workaround for this erratum is to program the prefetch offset with any
841       value except 23.*/
842  }
843
844  /* Unhandled erratum present: 769419 No automatic Store Buffer drain,
845   * visibility of written data requires an explicit Cache */
846  assert( ! l2c_310_errata_is_applicable_769419( rtl_release ) );
847}
848
849static inline void
850l2c_310_sync( volatile L2CC *l2cc )
851{
852#ifdef L2C_310_ERRATA_IS_APPLICABLE_753970
853  l2cc->dummy_cache_sync_reg = 0;
854#else
855  l2cc->cache_sync = 0;
856#endif
857}
858
859static inline void
860l2c_310_flush_1_line( volatile L2CC *l2cc, uint32_t d_addr )
861{
862#ifdef L2C_310_ERRATA_IS_APPLICABLE_588369
863  /*
864  * Errata 588369 says that clean + inv may keep the
865  * cache line if it was clean, the recommended
866  * workaround is to clean then invalidate the cache
867  * line, with write-back and cache linefill disabled.
868  */
869  l2cc->clean_pa     = d_addr;
870  l2c_310_sync( l2cc );
871  l2cc->inv_pa       = d_addr;
872#else
873  l2cc->clean_inv_pa = d_addr;
874#endif
875}
876
877static inline void
878l2c_310_flush_range( const void* d_addr, const size_t n_bytes )
879{
880  /* Back starting address up to start of a line and invalidate until ADDR_LAST */
881  uint32_t       adx               = (uint32_t)d_addr
882    & ~L2C_310_DATA_LINE_MASK;
883  const uint32_t ADDR_LAST         =
884    (uint32_t)( (size_t)d_addr + n_bytes - 1 );
885  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
886
887  if ( n_bytes == 0 ) {
888    return;
889  }
890
891  for (; adx <= ADDR_LAST; adx += CPU_DATA_CACHE_ALIGNMENT ) {
892    l2c_310_flush_1_line( l2cc, adx );
893  }
894
895  l2c_310_sync( l2cc );
896}
897
898static inline void
899l2c_310_flush_entire( void )
900{
901  volatile L2CC               *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
902  rtems_interrupt_lock_context lock_context;
903
904  /* Only flush if level 2 cache is active */
905  if( ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) != 0 ) {
906
907    /* ensure ordering with previous memory accesses */
908    _ARM_Data_memory_barrier();
909
910    rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
911    l2cc->clean_inv_way = L2C_310_WAY_MASK;
912
913    while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) {};
914
915    /* Wait for the flush to complete */
916    l2c_310_sync( l2cc );
917
918    rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
919  }
920}
921
922static inline void
923l2c_310_invalidate_1_line( const void *d_addr )
924{
925  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
926
927
928  l2cc->inv_pa = (uint32_t) d_addr;
929  l2c_310_sync( l2cc );
930}
931
932static inline void
933l2c_310_invalidate_range( const void* d_addr, const size_t n_bytes )
934{
935  /* Back starting address up to start of a line and invalidate until ADDR_LAST */
936  uint32_t       adx               = (uint32_t)d_addr
937    & ~L2C_310_DATA_LINE_MASK;
938  const uint32_t ADDR_LAST         =
939    (uint32_t)( (size_t)d_addr + n_bytes - 1 );
940  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
941
942  if ( n_bytes == 0 ) {
943    return;
944  }
945
946  for (; adx <= ADDR_LAST; adx += CPU_DATA_CACHE_ALIGNMENT ) {
947    /* Invalidate L2 cache line */
948    l2cc->inv_pa = adx;
949  }
950
951  l2c_310_sync( l2cc );
952}
953
954
955static inline void
956l2c_310_invalidate_entire( void )
957{
958  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
959
960  /* Invalidate the caches */
961
962  /* ensure ordering with previous memory accesses */
963  _ARM_Data_memory_barrier();
964
965  l2cc->inv_way = L2C_310_WAY_MASK;
966
967  while ( l2cc->inv_way & L2C_310_WAY_MASK ) ;
968
969  /* Wait for the invalidate to complete */
970  l2c_310_sync( l2cc );
971}
972
973static inline void
974l2c_310_clean_and_invalidate_entire( void )
975{
976  volatile L2CC               *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
977  rtems_interrupt_lock_context lock_context;
978
979  if( ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) != 0 ) {
980    /* Invalidate the caches */
981
982    /* ensure ordering with previous memory accesses */
983    _ARM_Data_memory_barrier();
984
985    rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
986    l2cc->clean_inv_way = L2C_310_WAY_MASK;
987
988    while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) ;
989
990    /* Wait for the invalidate to complete */
991    l2c_310_sync( l2cc );
992
993    rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
994  }
995}
996
997static inline void
998l2c_310_freeze( void )
999{
1000  /* To be implemented as needed, if supported
1001   by hardware at all */
1002}
1003
1004static inline void
1005l2c_310_unfreeze( void )
1006{
1007  /* To be implemented as needed, if supported
1008   by hardware at all */
1009}
1010
1011static inline size_t
1012l2c_310_get_cache_size( void )
1013{
1014  size_t         size       = 0;
1015  volatile L2CC *l2cc       = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1016  uint32_t       cache_type = l2cc->cache_type;
1017  uint32_t       way_size;
1018  uint32_t       num_ways;
1019
1020  way_size = (cache_type & L2C_310_TYPE_SIZE_D_WAYS_MASK)
1021    >> L2C_310_TYPE_SIZE_D_WAYS_SHIFT;
1022  num_ways = (cache_type & L2C_310_TYPE_NUM_D_WAYS_MASK)
1023    >> L2C_310_TYPE_NUM_D_WAYS_SHIFT;
1024
1025  assert( way_size <= 0x07 );
1026  assert( num_ways <= 0x01 );
1027  if(  way_size <= 0x07 && num_ways <= 0x01 ) {
1028    if( way_size == 0x00 ) {
1029      way_size = 16 * 1024;
1030    } else if( way_size == 0x07 ) {
1031      way_size = 512 * 1024;
1032    } else {
1033      way_size = (1 << (way_size - 1)) * 16 * 1024;
1034    }
1035    switch( num_ways ) {
1036      case 0:
1037        num_ways = 8;
1038        break;
1039      case 1:
1040        num_ways = 16;
1041        break;
1042      default:
1043        num_ways = 0;
1044        break;
1045    }
1046    size = way_size * num_ways;
1047  }
1048  return size;
1049}
1050
1051static void l2c_310_unlock( volatile L2CC *l2cc )
1052{
1053  l2cc->d_lockdown_0 = 0;
1054  l2cc->i_lockdown_0 = 0;
1055  l2cc->d_lockdown_1 = 0;
1056  l2cc->i_lockdown_1 = 0;
1057  l2cc->d_lockdown_2 = 0;
1058  l2cc->i_lockdown_2 = 0;
1059  l2cc->d_lockdown_3 = 0;
1060  l2cc->i_lockdown_3 = 0;
1061  l2cc->d_lockdown_4 = 0;
1062  l2cc->i_lockdown_4 = 0;
1063  l2cc->d_lockdown_5 = 0;
1064  l2cc->i_lockdown_5 = 0;
1065  l2cc->d_lockdown_6 = 0;
1066  l2cc->i_lockdown_6 = 0;
1067  l2cc->d_lockdown_7 = 0;
1068  l2cc->i_lockdown_7 = 0;
1069}
1070
1071static void l2c_310_wait_for_background_ops( volatile L2CC *l2cc )
1072{
1073  while ( l2cc->inv_way & L2C_310_WAY_MASK ) ;
1074
1075  while ( l2cc->clean_way & L2C_310_WAY_MASK ) ;
1076
1077  while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) ;
1078}
1079
1080/* We support only the L2C-310 revisions r3p2 and r3p3 cache controller */
1081
1082#if (BSP_ARM_L2C_310_ID & L2C_310_ID_PART_MASK) \
1083  != L2C_310_ID_PART_L310
1084#error "invalid L2-310 cache controller part number"
1085#endif
1086
1087#if (BSP_ARM_L2C_310_RTL_RELEASE != L2C_310_RTL_RELEASE_R3_P2) \
1088  && (BSP_ARM_L2C_310_RTL_RELEASE != L2C_310_RTL_RELEASE_R3_P3)
1089#error "invalid L2-310 cache controller RTL revision"
1090#endif
1091
1092static inline void
1093l2c_310_enable( void )
1094{
1095  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1096  uint32_t cache_id = l2cc->cache_id;
1097  uint32_t rtl_release = cache_id & L2C_310_ID_RTL_MASK;
1098  uint32_t id_mask = L2C_310_ID_IMPL_MASK | L2C_310_ID_PART_MASK;
1099  uint32_t ctrl;
1100
1101  /*
1102   * Do we actually have an L2C-310 cache controller?  Has BSP_ARM_L2C_310_BASE
1103   * been configured correctly?
1104   */
1105  if (
1106    (BSP_ARM_L2C_310_ID & id_mask) != (cache_id & id_mask)
1107      || rtl_release < BSP_ARM_L2C_310_RTL_RELEASE
1108  ) {
1109    bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_ID );
1110  }
1111
1112  l2c_310_check_errata( rtl_release );
1113
1114  ctrl = l2cc->ctrl;
1115
1116  if ( ( ctrl & L2C_310_CTRL_EXCL_CONFIG ) != 0 ) {
1117    bsp_fatal( ARM_FATAL_L2C_310_EXCLUSIVE_CONFIG );
1118  }
1119
1120  /* Only enable if L2CC is currently disabled */
1121  if( ( ctrl & L2C_310_CTRL_ENABLE ) == 0 ) {
1122    uint32_t aux_ctrl;
1123    int ways;
1124
1125    /* Make sure that I&D is not locked down when starting */
1126    l2c_310_unlock( l2cc );
1127
1128    l2c_310_wait_for_background_ops( l2cc );
1129
1130    aux_ctrl = l2cc->aux_ctrl;
1131
1132    if ( (aux_ctrl & ( 1 << 16 )) != 0 ) {
1133      ways = 16;
1134    } else {
1135      ways = 8;
1136    }
1137
1138    if ( ways != L2C_310_NUM_WAYS ) {
1139      bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_NUM_WAYS );
1140    }
1141
1142    /* Set up the way size */
1143    aux_ctrl &= L2C_310_AUX_REG_ZERO_MASK; /* Set way_size to 0 */
1144    aux_ctrl |= L2C_310_AUX_REG_DEFAULT_MASK;
1145
1146    l2cc->aux_ctrl = aux_ctrl;
1147
1148    /* Set up the latencies */
1149    l2cc->tag_ram_ctrl  = L2C_310_TAG_RAM_DEFAULT_LAT;
1150    l2cc->data_ram_ctrl = L2C_310_DATA_RAM_DEFAULT_MASK;
1151
1152    l2c_310_invalidate_entire();
1153
1154    /* Clear the pending interrupts */
1155    l2cc->int_clr = l2cc->int_raw_status;
1156
1157    /* Enable the L2CC */
1158    l2cc->ctrl = ctrl | L2C_310_CTRL_ENABLE;
1159  }
1160}
1161
1162static inline void
1163l2c_310_disable( void )
1164{
1165  volatile L2CC               *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1166  rtems_interrupt_lock_context lock_context;
1167
1168  if ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) {
1169    /* Clean and Invalidate L2 Cache */
1170    l2c_310_flush_entire();
1171    rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
1172
1173    l2c_310_wait_for_background_ops( l2cc );
1174
1175    /* Disable the L2 cache */
1176    l2cc->ctrl &= ~L2C_310_CTRL_ENABLE;
1177    rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
1178  }
1179}
1180
1181static inline void
1182_CPU_cache_enable_data( void )
1183{
1184  l2c_310_enable();
1185}
1186
1187static inline void
1188_CPU_cache_disable_data( void )
1189{
1190  arm_cache_l1_disable_data();
1191  l2c_310_disable();
1192}
1193
1194static inline void
1195_CPU_cache_enable_instruction( void )
1196{
1197  l2c_310_enable();
1198}
1199
1200static inline void
1201_CPU_cache_disable_instruction( void )
1202{
1203  arm_cache_l1_disable_instruction();
1204  l2c_310_disable();
1205}
1206
1207static inline void
1208_CPU_cache_flush_data_range(
1209  const void *d_addr,
1210  size_t      n_bytes
1211)
1212{
1213  arm_cache_l1_flush_data_range(
1214    d_addr,
1215    n_bytes
1216  );
1217  l2c_310_flush_range(
1218    d_addr,
1219    n_bytes
1220  );
1221}
1222
1223static inline void
1224_CPU_cache_flush_entire_data( void )
1225{
1226  arm_cache_l1_flush_entire_data();
1227  l2c_310_flush_entire();
1228}
1229
1230static inline void
1231_CPU_cache_invalidate_data_range(
1232  const void *addr_first,
1233  size_t     n_bytes
1234)
1235{
1236  l2c_310_invalidate_range(
1237    addr_first,
1238    n_bytes
1239  );
1240  arm_cache_l1_invalidate_data_range(
1241    addr_first,
1242    n_bytes
1243  );
1244}
1245
1246static inline void
1247_CPU_cache_invalidate_entire_data( void )
1248{
1249  /* This is broadcast within the cluster */
1250  arm_cache_l1_flush_entire_data();
1251
1252  /* forces the address out past level 2 */
1253  l2c_310_clean_and_invalidate_entire();
1254
1255  /*This is broadcast within the cluster */
1256  arm_cache_l1_clean_and_invalidate_entire_data();
1257}
1258
1259static inline void
1260_CPU_cache_freeze_data( void )
1261{
1262  arm_cache_l1_freeze_data();
1263  l2c_310_freeze();
1264}
1265
1266static inline void
1267_CPU_cache_unfreeze_data( void )
1268{
1269  arm_cache_l1_unfreeze_data();
1270  l2c_310_unfreeze();
1271}
1272
1273static inline void
1274_CPU_cache_invalidate_instruction_range( const void *i_addr, size_t n_bytes)
1275{
1276  arm_cache_l1_invalidate_instruction_range( i_addr, n_bytes );
1277}
1278
1279static inline void
1280_CPU_cache_invalidate_entire_instruction( void )
1281{
1282  arm_cache_l1_invalidate_entire_instruction();
1283}
1284
1285static inline void
1286_CPU_cache_freeze_instruction( void )
1287{
1288  arm_cache_l1_freeze_instruction();
1289  l2c_310_freeze();
1290}
1291
1292static inline void
1293_CPU_cache_unfreeze_instruction( void )
1294{
1295  arm_cache_l1_unfreeze_instruction();
1296  l2c_310_unfreeze();
1297}
1298
1299static inline size_t
1300_CPU_cache_get_data_cache_size( const uint32_t level )
1301{
1302  size_t size = 0;
1303
1304  switch( level )
1305  {
1306    case 1:
1307      size = arm_cache_l1_get_data_cache_size();
1308    break;
1309    case 0:
1310    case 2:
1311      size = l2c_310_get_cache_size();
1312    break;
1313    default:
1314      size = 0;
1315    break;
1316  }
1317  return size;
1318}
1319
1320static inline size_t
1321_CPU_cache_get_instruction_cache_size( const uint32_t level )
1322{
1323  size_t size = 0;
1324
1325  switch( level )
1326  {
1327    case 1:
1328      size = arm_cache_l1_get_instruction_cache_size();
1329      break;
1330    case 0:
1331    case 2:
1332      size = l2c_310_get_cache_size();
1333      break;
1334    default:
1335      size = 0;
1336      break;
1337  }
1338  return size;
1339}
1340
1341
1342/** @} */
1343
1344#ifdef __cplusplus
1345}
1346#endif /* __cplusplus */
1347
1348#endif /* LIBBSP_ARM_SHARED_L2C_310_CACHE_H */
Note: See TracBrowser for help on using the repository browser.