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

Last change on this file since 612297e8 was 612297e8, checked in by Joel Sherrill <joel@…>, on Jul 12, 2016 at 10:44:17 AM

Misc: Spell length correctly

  • Property mode set to 100644
File size: 36.5 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  uint32_t       block_end         =
886    L2C_310_MIN( ADDR_LAST, adx + L2C_310_MAX_LOCKING_BYTES );
887  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
888
889  if ( n_bytes == 0 ) {
890    return;
891  }
892
893  for (;
894       adx      <= ADDR_LAST;
895       adx       = block_end + 1,
896       block_end = L2C_310_MIN( ADDR_LAST, adx + L2C_310_MAX_LOCKING_BYTES )) {
897    rtems_interrupt_lock_context lock_context;
898
899    rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
900
901    for (; adx <= block_end; adx += CPU_DATA_CACHE_ALIGNMENT ) {
902      l2c_310_flush_1_line( l2cc, adx );
903    }
904
905    l2c_310_sync( l2cc );
906
907    rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
908  }
909}
910
911static inline void
912l2c_310_flush_entire( void )
913{
914  volatile L2CC               *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
915  rtems_interrupt_lock_context lock_context;
916
917  /* Only flush if level 2 cache is active */
918  if( ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) != 0 ) {
919
920    /* ensure ordering with previous memory accesses */
921    _ARM_Data_memory_barrier();
922
923    rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
924    l2cc->clean_inv_way = L2C_310_WAY_MASK;
925
926    while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) {};
927
928    /* Wait for the flush to complete */
929    l2c_310_sync( l2cc );
930
931    rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
932  }
933}
934
935static inline void
936l2c_310_invalidate_1_line( const void *d_addr )
937{
938  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
939
940
941  l2cc->inv_pa = (uint32_t) d_addr;
942  l2c_310_sync( l2cc );
943}
944
945static inline void
946l2c_310_invalidate_range( const void* d_addr, const size_t n_bytes )
947{
948  /* Back starting address up to start of a line and invalidate until ADDR_LAST */
949  uint32_t       adx               = (uint32_t)d_addr
950    & ~L2C_310_DATA_LINE_MASK;
951  const uint32_t ADDR_LAST         =
952    (uint32_t)( (size_t)d_addr + n_bytes - 1 );
953  uint32_t       block_end         =
954    L2C_310_MIN( ADDR_LAST, adx + L2C_310_MAX_LOCKING_BYTES );
955  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
956
957  if ( n_bytes == 0 ) {
958    return;
959  }
960
961  for (;
962       adx      <= ADDR_LAST;
963       adx       = block_end + 1,
964       block_end = L2C_310_MIN( ADDR_LAST, adx + L2C_310_MAX_LOCKING_BYTES )) {
965    rtems_interrupt_lock_context lock_context;
966
967    rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
968
969    for (; adx <= block_end; adx += CPU_DATA_CACHE_ALIGNMENT ) {
970      /* Invalidate L2 cache line */
971      l2cc->inv_pa = adx;
972    }
973
974    l2c_310_sync( l2cc );
975
976    rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
977  }
978}
979
980
981static inline void
982l2c_310_invalidate_entire( void )
983{
984  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
985
986  /* Invalidate the caches */
987
988  /* ensure ordering with previous memory accesses */
989  _ARM_Data_memory_barrier();
990
991  l2cc->inv_way = L2C_310_WAY_MASK;
992
993  while ( l2cc->inv_way & L2C_310_WAY_MASK ) ;
994
995  /* Wait for the invalidate to complete */
996  l2c_310_sync( l2cc );
997}
998
999static inline void
1000l2c_310_clean_and_invalidate_entire( void )
1001{
1002  volatile L2CC               *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1003  rtems_interrupt_lock_context lock_context;
1004
1005  if( ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) != 0 ) {
1006    /* Invalidate the caches */
1007
1008    /* ensure ordering with previous memory accesses */
1009    _ARM_Data_memory_barrier();
1010
1011    rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
1012    l2cc->clean_inv_way = L2C_310_WAY_MASK;
1013
1014    while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) ;
1015
1016    /* Wait for the invalidate to complete */
1017    l2c_310_sync( l2cc );
1018
1019    rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
1020  }
1021}
1022
1023static inline void
1024l2c_310_freeze( void )
1025{
1026  /* To be implemented as needed, if supported
1027   by hardware at all */
1028}
1029
1030static inline void
1031l2c_310_unfreeze( void )
1032{
1033  /* To be implemented as needed, if supported
1034   by hardware at all */
1035}
1036
1037static inline size_t
1038l2c_310_get_cache_size( void )
1039{
1040  size_t         size       = 0;
1041  volatile L2CC *l2cc       = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1042  uint32_t       cache_type = l2cc->cache_type;
1043  uint32_t       way_size;
1044  uint32_t       num_ways;
1045
1046  way_size = (cache_type & L2C_310_TYPE_SIZE_D_WAYS_MASK)
1047    >> L2C_310_TYPE_SIZE_D_WAYS_SHIFT;
1048  num_ways = (cache_type & L2C_310_TYPE_NUM_D_WAYS_MASK)
1049    >> L2C_310_TYPE_NUM_D_WAYS_SHIFT;
1050
1051  assert( way_size <= 0x07 );
1052  assert( num_ways <= 0x01 );
1053  if(  way_size <= 0x07 && num_ways <= 0x01 ) {
1054    if( way_size == 0x00 ) {
1055      way_size = 16 * 1024;
1056    } else if( way_size == 0x07 ) {
1057      way_size = 512 * 1024;
1058    } else {
1059      way_size = (1 << (way_size - 1)) * 16 * 1024;
1060    }
1061    switch( num_ways ) {
1062      case 0:
1063        num_ways = 8;
1064        break;
1065      case 1:
1066        num_ways = 16;
1067        break;
1068      default:
1069        num_ways = 0;
1070        break;
1071    }
1072    size = way_size * num_ways;
1073  }
1074  return size;
1075}
1076
1077static void l2c_310_unlock( volatile L2CC *l2cc )
1078{
1079  l2cc->d_lockdown_0 = 0;
1080  l2cc->i_lockdown_0 = 0;
1081  l2cc->d_lockdown_1 = 0;
1082  l2cc->i_lockdown_1 = 0;
1083  l2cc->d_lockdown_2 = 0;
1084  l2cc->i_lockdown_2 = 0;
1085  l2cc->d_lockdown_3 = 0;
1086  l2cc->i_lockdown_3 = 0;
1087  l2cc->d_lockdown_4 = 0;
1088  l2cc->i_lockdown_4 = 0;
1089  l2cc->d_lockdown_5 = 0;
1090  l2cc->i_lockdown_5 = 0;
1091  l2cc->d_lockdown_6 = 0;
1092  l2cc->i_lockdown_6 = 0;
1093  l2cc->d_lockdown_7 = 0;
1094  l2cc->i_lockdown_7 = 0;
1095}
1096
1097static void l2c_310_wait_for_background_ops( volatile L2CC *l2cc )
1098{
1099  while ( l2cc->inv_way & L2C_310_WAY_MASK ) ;
1100
1101  while ( l2cc->clean_way & L2C_310_WAY_MASK ) ;
1102
1103  while ( l2cc->clean_inv_way & L2C_310_WAY_MASK ) ;
1104}
1105
1106/* We support only the L2C-310 revisions r3p2 and r3p3 cache controller */
1107
1108#if (BSP_ARM_L2C_310_ID & L2C_310_ID_PART_MASK) \
1109  != L2C_310_ID_PART_L310
1110#error "invalid L2-310 cache controller part number"
1111#endif
1112
1113#if (BSP_ARM_L2C_310_RTL_RELEASE != L2C_310_RTL_RELEASE_R3_P2) \
1114  && (BSP_ARM_L2C_310_RTL_RELEASE != L2C_310_RTL_RELEASE_R3_P3)
1115#error "invalid L2-310 cache controller RTL revision"
1116#endif
1117
1118static inline void
1119l2c_310_enable( void )
1120{
1121  volatile L2CC *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1122  uint32_t cache_id = l2cc->cache_id;
1123  uint32_t rtl_release = cache_id & L2C_310_ID_RTL_MASK;
1124  uint32_t id_mask = L2C_310_ID_IMPL_MASK | L2C_310_ID_PART_MASK;
1125  uint32_t ctrl;
1126
1127  /*
1128   * Do we actually have an L2C-310 cache controller?  Has BSP_ARM_L2C_310_BASE
1129   * been configured correctly?
1130   */
1131  if (
1132    (BSP_ARM_L2C_310_ID & id_mask) != (cache_id & id_mask)
1133      || rtl_release < BSP_ARM_L2C_310_RTL_RELEASE
1134  ) {
1135    bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_ID );
1136  }
1137
1138  l2c_310_check_errata( rtl_release );
1139
1140  ctrl = l2cc->ctrl;
1141
1142  if ( ( ctrl & L2C_310_CTRL_EXCL_CONFIG ) != 0 ) {
1143    bsp_fatal( ARM_FATAL_L2C_310_EXCLUSIVE_CONFIG );
1144  }
1145
1146  /* Only enable if L2CC is currently disabled */
1147  if( ( ctrl & L2C_310_CTRL_ENABLE ) == 0 ) {
1148    uint32_t aux_ctrl;
1149    int ways;
1150
1151    /* Make sure that I&D is not locked down when starting */
1152    l2c_310_unlock( l2cc );
1153
1154    l2c_310_wait_for_background_ops( l2cc );
1155
1156    aux_ctrl = l2cc->aux_ctrl;
1157
1158    if ( (aux_ctrl & ( 1 << 16 )) != 0 ) {
1159      ways = 16;
1160    } else {
1161      ways = 8;
1162    }
1163
1164    if ( ways != L2C_310_NUM_WAYS ) {
1165      bsp_fatal( ARM_FATAL_L2C_310_UNEXPECTED_NUM_WAYS );
1166    }
1167
1168    /* Set up the way size */
1169    aux_ctrl &= L2C_310_AUX_REG_ZERO_MASK; /* Set way_size to 0 */
1170    aux_ctrl |= L2C_310_AUX_REG_DEFAULT_MASK;
1171
1172    l2cc->aux_ctrl = aux_ctrl;
1173
1174    /* Set up the latencies */
1175    l2cc->tag_ram_ctrl  = L2C_310_TAG_RAM_DEFAULT_LAT;
1176    l2cc->data_ram_ctrl = L2C_310_DATA_RAM_DEFAULT_MASK;
1177
1178    l2c_310_invalidate_entire();
1179
1180    /* Clear the pending interrupts */
1181    l2cc->int_clr = l2cc->int_raw_status;
1182
1183    /* Enable the L2CC */
1184    l2cc->ctrl = ctrl | L2C_310_CTRL_ENABLE;
1185  }
1186}
1187
1188static inline void
1189l2c_310_disable( void )
1190{
1191  volatile L2CC               *l2cc = (volatile L2CC *) BSP_ARM_L2C_310_BASE;
1192  rtems_interrupt_lock_context lock_context;
1193
1194  if ( l2cc->ctrl & L2C_310_CTRL_ENABLE ) {
1195    /* Clean and Invalidate L2 Cache */
1196    l2c_310_flush_entire();
1197    rtems_interrupt_lock_acquire( &l2c_310_lock, &lock_context );
1198
1199    l2c_310_wait_for_background_ops( l2cc );
1200
1201    /* Disable the L2 cache */
1202    l2cc->ctrl &= ~L2C_310_CTRL_ENABLE;
1203    rtems_interrupt_lock_release( &l2c_310_lock, &lock_context );
1204  }
1205}
1206
1207static inline void
1208_CPU_cache_enable_data( void )
1209{
1210  l2c_310_enable();
1211}
1212
1213static inline void
1214_CPU_cache_disable_data( void )
1215{
1216  arm_cache_l1_disable_data();
1217  l2c_310_disable();
1218}
1219
1220static inline void
1221_CPU_cache_enable_instruction( void )
1222{
1223  l2c_310_enable();
1224}
1225
1226static inline void
1227_CPU_cache_disable_instruction( void )
1228{
1229  arm_cache_l1_disable_instruction();
1230  l2c_310_disable();
1231}
1232
1233static inline void
1234_CPU_cache_flush_data_range(
1235  const void *d_addr,
1236  size_t      n_bytes
1237)
1238{
1239  arm_cache_l1_flush_data_range(
1240    d_addr,
1241    n_bytes
1242  );
1243  l2c_310_flush_range(
1244    d_addr,
1245    n_bytes
1246  );
1247}
1248
1249static inline void
1250_CPU_cache_flush_entire_data( void )
1251{
1252  arm_cache_l1_flush_entire_data();
1253  l2c_310_flush_entire();
1254}
1255
1256static inline void
1257_CPU_cache_invalidate_data_range(
1258  const void *addr_first,
1259  size_t     n_bytes
1260)
1261{
1262  l2c_310_invalidate_range(
1263    addr_first,
1264    n_bytes
1265  );
1266  arm_cache_l1_invalidate_data_range(
1267    addr_first,
1268    n_bytes
1269  );
1270}
1271
1272static inline void
1273_CPU_cache_invalidate_entire_data( void )
1274{
1275  /* This is broadcast within the cluster */
1276  arm_cache_l1_flush_entire_data();
1277
1278  /* forces the address out past level 2 */
1279  l2c_310_clean_and_invalidate_entire();
1280
1281  /*This is broadcast within the cluster */
1282  arm_cache_l1_clean_and_invalidate_entire_data();
1283}
1284
1285static inline void
1286_CPU_cache_freeze_data( void )
1287{
1288  arm_cache_l1_freeze_data();
1289  l2c_310_freeze();
1290}
1291
1292static inline void
1293_CPU_cache_unfreeze_data( void )
1294{
1295  arm_cache_l1_unfreeze_data();
1296  l2c_310_unfreeze();
1297}
1298
1299static inline void
1300_CPU_cache_invalidate_instruction_range( const void *i_addr, size_t n_bytes)
1301{
1302  arm_cache_l1_invalidate_instruction_range( i_addr, n_bytes );
1303}
1304
1305static inline void
1306_CPU_cache_invalidate_entire_instruction( void )
1307{
1308  arm_cache_l1_invalidate_entire_instruction();
1309}
1310
1311static inline void
1312_CPU_cache_freeze_instruction( void )
1313{
1314  arm_cache_l1_freeze_instruction();
1315  l2c_310_freeze();
1316}
1317
1318static inline void
1319_CPU_cache_unfreeze_instruction( void )
1320{
1321  arm_cache_l1_unfreeze_instruction();
1322  l2c_310_unfreeze();
1323}
1324
1325static inline size_t
1326_CPU_cache_get_data_cache_size( const uint32_t level )
1327{
1328  size_t size = 0;
1329
1330  switch( level )
1331  {
1332    case 1:
1333      size = arm_cache_l1_get_data_cache_size();
1334    break;
1335    case 0:
1336    case 2:
1337      size = l2c_310_get_cache_size();
1338    break;
1339    default:
1340      size = 0;
1341    break;
1342  }
1343  return size;
1344}
1345
1346static inline size_t
1347_CPU_cache_get_instruction_cache_size( const uint32_t level )
1348{
1349  size_t size = 0;
1350
1351  switch( level )
1352  {
1353    case 1:
1354      size = arm_cache_l1_get_instruction_cache_size();
1355      break;
1356    case 0:
1357    case 2:
1358      size = l2c_310_get_cache_size();
1359      break;
1360    default:
1361      size = 0;
1362      break;
1363  }
1364  return size;
1365}
1366
1367
1368/** @} */
1369
1370#ifdef __cplusplus
1371}
1372#endif /* __cplusplus */
1373
1374#endif /* LIBBSP_ARM_SHARED_L2C_310_CACHE_H */
Note: See TracBrowser for help on using the repository browser.