]> git.sur5r.net Git - freertos/blob
8633e92bcfd5ca2c91c3caa06393d40fa80d622a
[freertos] /
1 /******************************************************************************
2 *
3 * Copyright (C) 2010 - 2014 Xilinx, Inc.  All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 *
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
30 *
31 ******************************************************************************/
32 /*****************************************************************************/
33 /**
34 *
35 * @file xil_cache.c
36 *
37 * Contains required functions for the ARM cache functionality.
38 *
39 * <pre>
40 * MODIFICATION HISTORY:
41 *
42 * Ver    Who Date     Changes
43 * ----- ---- -------- -----------------------------------------------
44 * 1.00a  ecm 01/29/10 First release
45 * 1.00a  ecm 06/24/10 Moved the L1 and L2 specific function prototypes
46 *                     to xil_cache_mach.h to give access to sophisticated users
47 * 3.02a  sdm 04/07/11 Updated Flush/InvalidateRange APIs to flush/invalidate
48 *                     L1 and L2 caches in a single loop and used dsb, L2 sync
49 *                     at the end of the loop.
50 * 3.04a  sdm 01/02/12 Remove redundant dsb/dmb instructions in cache maintenance
51 *                     APIs.
52 * 3.07a  asa 07/16/12 Corrected the L1 and L2 cache invalidation order.
53 * 3.07a  sgd 09/18/12 Corrected the L2 cache enable and disable sequence.
54 * 3.10a  srt 04/18/13 Implemented ARM Erratas. Please refer to file
55 *                     'xil_errata.h' for errata description
56 * 3.10a  asa 05/13/13 Modified cache disable APIs. The L2 cache disable
57 *                         operation was being done with L1 Data cache disabled. This is
58 *                         fixed so that L2 cache disable operation happens independent of
59 *                         L1 cache disable operation. This fixes CR #706464.
60 *                         Changes are done to do a L2 cache sync (poll reg7_?cache_?sync).
61 *                         This is done to fix the CR #700542.
62 * 3.11a  asa 09/23/13 Modified the Xil_DCacheFlushRange and
63 *                        Xil_DCacheInvalidateRange to fix potential issues. Fixed other
64 *                        relevant cache APIs to disable and enable back the interrupts.
65 *                        This fixes CR #663885.
66 * 3.11a  asa 09/28/13 Made changes for L2 cache sync operation. It is found
67 *                        out that for L2 cache flush/clean/invalidation by cache lines
68 *                        does not need a cache sync as these are atomic nature. Similarly
69 *                        figured out that for complete L2 cache flush/invalidation by way
70 *                        we need to wait for some more time in a loop till the status
71 *                        shows that the cache operation is completed.
72 * 4.00   pkp 24/01/14 Modified Xil_DCacheInvalidateRange to fix the bug. Few
73 *                        cache lines were missed to invalidate when unaligned address
74 *                        invalidation was accommodated. That fixes CR #766768.
75 *                        Also in Xil_L1DCacheInvalidate, while invalidating all L1D cache
76 *                        stack memory which contains return address was invalidated. So
77 *                        stack memory was flushed first and then L1D cache is invalidated.
78 *                        This is done to fix CR #763829
79 * 4.01   asa 05/09/14 Made changes in cortexa9/xil_cache.c to fix CR# 798230.
80 * </pre>
81 *
82 ******************************************************************************/
83
84 /***************************** Include Files *********************************/
85
86 #include "xil_cache.h"
87 #include "xil_cache_l.h"
88 #include "xil_io.h"
89 #include "xpseudo_asm.h"
90 #include "xparameters.h"
91 #include "xreg_cortexa9.h"
92 #include "xl2cc.h"
93 #include "xil_errata.h"
94 #include "xil_exception.h"
95
96 /************************** Function Prototypes ******************************/
97
98 /************************** Variable Definitions *****************************/
99
100 #define IRQ_FIQ_MASK 0xC0       /* Mask IRQ and FIQ interrupts in cpsr */
101
102 #ifdef __GNUC__
103         extern int  _stack_end;
104         extern int  _stack;
105 #endif
106
107 /****************************************************************************
108 *
109 * Access L2 Debug Control Register.
110 *
111 * @param        Value, value to be written to Debug Control Register.
112 *
113 * @return       None.
114 *
115 * @note         None.
116 *
117 ****************************************************************************/
118 #ifdef __GNUC__
119 static inline void Xil_L2WriteDebugCtrl(u32 Value)
120 #else
121 static void Xil_L2WriteDebugCtrl(u32 Value)
122 #endif
123 {
124 #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
125         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_DEBUG_CTRL_OFFSET, Value);
126 #else
127         (void)(Value);
128 #endif
129 }
130
131 /****************************************************************************
132 *
133 * Perform L2 Cache Sync Operation.
134 *
135 * @param        None.
136 *
137 * @return       None.
138 *
139 * @note         None.
140 *
141 ****************************************************************************/
142 #ifdef __GNUC__
143 static inline void Xil_L2CacheSync(void)
144 #else
145 static void Xil_L2CacheSync(void)
146 #endif
147 {
148 #ifdef CONFIG_PL310_ERRATA_753970
149         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_DUMMY_CACHE_SYNC_OFFSET, 0x0);
150 #else
151         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_SYNC_OFFSET, 0x0);
152 #endif
153 }
154
155 /****************************************************************************
156 *
157 * Enable the Data cache.
158 *
159 * @param        None.
160 *
161 * @return       None.
162 *
163 * @note         None.
164 *
165 ****************************************************************************/
166 void Xil_DCacheEnable(void)
167 {
168         Xil_L1DCacheEnable();
169         Xil_L2CacheEnable();
170 }
171
172 /****************************************************************************
173 *
174 * Disable the Data cache.
175 *
176 * @param        None.
177 *
178 * @return       None.
179 *
180 * @note         None.
181 *
182 ****************************************************************************/
183 void Xil_DCacheDisable(void)
184 {
185         Xil_L2CacheDisable();
186         Xil_L1DCacheDisable();
187 }
188
189 /****************************************************************************
190 *
191 * Invalidate the entire Data cache.
192 *
193 * @param        None.
194 *
195 * @return       None.
196 *
197 * @note         None.
198 *
199 ****************************************************************************/
200 void Xil_DCacheInvalidate(void)
201 {
202         unsigned int currmask;
203
204         currmask = mfcpsr();
205         mtcpsr(currmask | IRQ_FIQ_MASK);
206
207         Xil_L2CacheInvalidate();
208         Xil_L1DCacheInvalidate();
209
210         mtcpsr(currmask);
211 }
212
213 /****************************************************************************
214 *
215 * Invalidate a Data cache line. If the byte specified by the address (adr)
216 * is cached by the Data cache, the cacheline containing that byte is
217 * invalidated.  If the cacheline is modified (dirty), the modified contents
218 * are lost and are NOT written to system memory before the line is
219 * invalidated.
220 *
221 * @param        Address to be flushed.
222 *
223 * @return       None.
224 *
225 * @note         The bottom 4 bits are set to 0, forced by architecture.
226 *
227 ****************************************************************************/
228 void Xil_DCacheInvalidateLine(unsigned int adr)
229 {
230         unsigned int currmask;
231
232         currmask = mfcpsr();
233         mtcpsr(currmask | IRQ_FIQ_MASK);
234
235         Xil_L2CacheInvalidateLine(adr);
236         Xil_L1DCacheInvalidateLine(adr);
237
238         mtcpsr(currmask);
239 }
240
241 /****************************************************************************
242 *
243 * Invalidate the Data cache for the given address range.
244 * If the bytes specified by the address (adr) are cached by the Data cache,
245 * the cacheline containing that byte is invalidated.    If the cacheline
246 * is modified (dirty), the modified contents are lost and are NOT
247 * written to system memory before the line is invalidated.
248 *
249 * @param        Start address of range to be invalidated.
250 * @param        Length of range to be invalidated in bytes.
251 *
252 * @return       None.
253 *
254 * @note         None.
255 *
256 ****************************************************************************/
257 void Xil_DCacheInvalidateRange(unsigned int adr, unsigned len)
258 {
259         const unsigned cacheline = 32;
260         unsigned int end;
261         unsigned int tempadr = adr;
262         unsigned int tempend;
263         unsigned int currmask;
264         volatile u32 *L2CCOffset = (volatile u32 *) (XPS_L2CC_BASEADDR +
265                                     XPS_L2CC_CACHE_INVLD_PA_OFFSET);
266
267         currmask = mfcpsr();
268         mtcpsr(currmask | IRQ_FIQ_MASK);
269
270         if (len != 0) {
271                 end = tempadr + len;
272                 tempend = end;
273                 /* Select L1 Data cache in CSSR */
274                 mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
275
276                 if (tempadr & (cacheline-1)) {
277                         tempadr &= ~(cacheline - 1);
278
279                         Xil_L1DCacheFlushLine(tempadr);
280                         /* Disable Write-back and line fills */
281                         Xil_L2WriteDebugCtrl(0x3);
282                         Xil_L2CacheFlushLine(tempadr);
283                         /* Enable Write-back and line fills */
284                         Xil_L2WriteDebugCtrl(0x0);
285                         Xil_L2CacheSync();
286                         tempadr += cacheline;
287                 }
288                 if (tempend & (cacheline-1)) {
289                         tempend &= ~(cacheline - 1);
290
291                         Xil_L1DCacheFlushLine(tempend);
292                         /* Disable Write-back and line fills */
293                         Xil_L2WriteDebugCtrl(0x3);
294                         Xil_L2CacheFlushLine(tempend);
295                         /* Enable Write-back and line fills */
296                         Xil_L2WriteDebugCtrl(0x0);
297                         Xil_L2CacheSync();
298                 }
299
300                 while (tempadr < tempend) {
301                         /* Invalidate L2 cache line */
302                         *L2CCOffset = tempadr;
303                         dsb();
304 #ifdef __GNUC__
305                         /* Invalidate L1 Data cache line */
306                         __asm__ __volatile__("mcr " \
307                         XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (tempadr));
308 #else
309                         { volatile register unsigned int Reg
310                                 __asm(XREG_CP15_INVAL_DC_LINE_MVA_POC);
311                           Reg = tempadr; }
312 #endif
313                         tempadr += cacheline;
314                 }
315         }
316
317         dsb();
318         mtcpsr(currmask);
319 }
320
321 /****************************************************************************
322 *
323 * Flush the entire Data cache.
324 *
325 * @param        None.
326 *
327 * @return       None.
328 *
329 * @note         None.
330 *
331 ****************************************************************************/
332 void Xil_DCacheFlush(void)
333 {
334         unsigned int currmask;
335
336         currmask = mfcpsr();
337         mtcpsr(currmask | IRQ_FIQ_MASK);
338         Xil_L1DCacheFlush();
339         Xil_L2CacheFlush();
340
341         mtcpsr(currmask);
342 }
343
344 /****************************************************************************
345 *
346 * Flush a Data cache line. If the byte specified by the address (adr)
347 * is cached by the Data cache, the cacheline containing that byte is
348 * invalidated.  If the cacheline is modified (dirty), the entire
349 * contents of the cacheline are written to system memory before the
350 * line is invalidated.
351 *
352 * @param        Address to be flushed.
353 *
354 * @return       None.
355 *
356 * @note         The bottom 4 bits are set to 0, forced by architecture.
357 *
358 ****************************************************************************/
359 void Xil_DCacheFlushLine(unsigned int adr)
360 {
361         unsigned int currmask;
362
363         currmask = mfcpsr();
364         mtcpsr(currmask | IRQ_FIQ_MASK);
365         Xil_L1DCacheFlushLine(adr);
366
367         /* Disable Write-back and line fills */
368         Xil_L2WriteDebugCtrl(0x3);
369
370         Xil_L2CacheFlushLine(adr);
371
372         /* Enable Write-back and line fills */
373         Xil_L2WriteDebugCtrl(0x0);
374         Xil_L2CacheSync();
375         mtcpsr(currmask);
376 }
377
378 /****************************************************************************
379 * Flush the Data cache for the given address range.
380 * If the bytes specified by the address (adr) are cached by the Data cache,
381 * the cacheline containing that byte is invalidated.    If the cacheline
382 * is modified (dirty), the written to system memory first before the
383 * before the line is invalidated.
384 *
385 * @param        Start address of range to be flushed.
386 * @param        Length of range to be flushed in bytes.
387 *
388 * @return       None.
389 *
390 * @note         None.
391 *
392 ****************************************************************************/
393 void Xil_DCacheFlushRange(unsigned int adr, unsigned len)
394 {
395         const unsigned cacheline = 32;
396         unsigned int end;
397         unsigned int currmask;
398         volatile u32 *L2CCOffset = (volatile u32 *) (XPS_L2CC_BASEADDR +
399                                     XPS_L2CC_CACHE_INV_CLN_PA_OFFSET);
400
401         currmask = mfcpsr();
402         mtcpsr(currmask | IRQ_FIQ_MASK);
403
404         if (len != 0) {
405                 /* Back the starting address up to the start of a cache line
406                  * perform cache operations until adr+len
407                  */
408                 end = adr + len;
409                 adr &= ~(cacheline - 1);
410
411                 while (adr < end) {
412 #ifdef __GNUC__
413                         /* Flush L1 Data cache line */
414                         __asm__ __volatile__("mcr " \
415                         XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (adr));
416 #else
417                         { volatile register unsigned int Reg
418                                 __asm(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC);
419                           Reg = adr; }
420 #endif
421                         /* Flush L2 cache line */
422                         *L2CCOffset = adr;
423                         dsb();
424                         adr += cacheline;
425                 }
426         }
427         dsb();
428         mtcpsr(currmask);
429 }
430 /****************************************************************************
431 *
432 * Store a Data cache line. If the byte specified by the address (adr)
433 * is cached by the Data cache and the cacheline is modified (dirty),
434 * the entire contents of the cacheline are written to system memory.
435 * After the store completes, the cacheline is marked as unmodified
436 * (not dirty).
437 *
438 * @param        Address to be stored.
439 *
440 * @return       None.
441 *
442 * @note         The bottom 4 bits are set to 0, forced by architecture.
443 *
444 ****************************************************************************/
445 void Xil_DCacheStoreLine(unsigned int adr)
446 {
447         unsigned int currmask;
448
449         currmask = mfcpsr();
450         mtcpsr(currmask | IRQ_FIQ_MASK);
451
452         Xil_L1DCacheStoreLine(adr);
453         Xil_L2CacheStoreLine(adr);
454         mtcpsr(currmask);
455 }
456
457 /****************************************************************************
458 *
459 * Enable the instruction cache.
460 *
461 * @param        None.
462 *
463 * @return       None.
464 *
465 * @note         None.
466 *
467 ****************************************************************************/
468 void Xil_ICacheEnable(void)
469 {
470         Xil_L1ICacheEnable();
471         Xil_L2CacheEnable();
472 }
473
474 /****************************************************************************
475 *
476 * Disable the instruction cache.
477 *
478 * @param        None.
479 *
480 * @return       None.
481 *
482 * @note         None.
483 *
484 ****************************************************************************/
485 void Xil_ICacheDisable(void)
486 {
487         Xil_L2CacheDisable();
488         Xil_L1ICacheDisable();
489 }
490
491 /****************************************************************************
492 *
493 * Invalidate the entire instruction cache.
494 *
495 * @param        None.
496 *
497 * @return       None.
498 *
499 * @note         None.
500 *
501 ****************************************************************************/
502 void Xil_ICacheInvalidate(void)
503 {
504         unsigned int currmask;
505
506         currmask = mfcpsr();
507         mtcpsr(currmask | IRQ_FIQ_MASK);
508
509         Xil_L2CacheInvalidate();
510         Xil_L1ICacheInvalidate();
511
512         mtcpsr(currmask);
513 }
514
515 /****************************************************************************
516 *
517 * Invalidate an instruction cache line. If the instruction specified by the
518 * parameter adr is cached by the instruction cache, the cacheline containing
519 * that instruction is invalidated.
520 *
521 * @param        None.
522 *
523 * @return       None.
524 *
525 * @note         The bottom 4 bits are set to 0, forced by architecture.
526 *
527 ****************************************************************************/
528 void Xil_ICacheInvalidateLine(unsigned int adr)
529 {
530         unsigned int currmask;
531
532         currmask = mfcpsr();
533         mtcpsr(currmask | IRQ_FIQ_MASK);
534         Xil_L2CacheInvalidateLine(adr);
535         Xil_L1ICacheInvalidateLine(adr);
536         mtcpsr(currmask);
537 }
538
539 /****************************************************************************
540 *
541 * Invalidate the instruction cache for the given address range.
542 * If the bytes specified by the address (adr) are cached by the Data cache,
543 * the cacheline containing that byte is invalidated. If the cacheline
544 * is modified (dirty), the modified contents are lost and are NOT
545 * written to system memory before the line is invalidated.
546 *
547 * @param        Start address of range to be invalidated.
548 * @param        Length of range to be invalidated in bytes.
549 *
550 * @return       None.
551 *
552 * @note         None.
553 *
554 ****************************************************************************/
555 void Xil_ICacheInvalidateRange(unsigned int adr, unsigned len)
556 {
557         const unsigned cacheline = 32;
558         unsigned int end;
559         volatile u32 *L2CCOffset = (volatile u32 *) (XPS_L2CC_BASEADDR +
560                                     XPS_L2CC_CACHE_INVLD_PA_OFFSET);
561
562         unsigned int currmask;
563
564         currmask = mfcpsr();
565         mtcpsr(currmask | IRQ_FIQ_MASK);
566         if (len != 0) {
567                 /* Back the starting address up to the start of a cache line
568                  * perform cache operations until adr+len
569                  */
570                 end = adr + len;
571                 adr = adr & ~(cacheline - 1);
572
573                 /* Select cache L0 I-cache in CSSR */
574                 mtcp(XREG_CP15_CACHE_SIZE_SEL, 1);
575
576                 while (adr < end) {
577                 /* Invalidate L2 cache line */
578                 *L2CCOffset = adr;
579                 dsb();
580 #ifdef __GNUC__
581                         /* Invalidate L1 I-cache line */
582                         __asm__ __volatile__("mcr " \
583                         XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (adr));
584 #else
585                         { volatile register unsigned int Reg
586                                 __asm(XREG_CP15_INVAL_IC_LINE_MVA_POU);
587                           Reg = adr; }
588 #endif
589
590                         adr += cacheline;
591                 }
592         }
593
594         /* Wait for L1 and L2 invalidate to complete */
595         dsb();
596         mtcpsr(currmask);
597 }
598
599 /****************************************************************************
600 *
601 * Enable the level 1 Data cache.
602 *
603 * @param        None.
604 *
605 * @return       None.
606 *
607 * @note         None.
608 *
609 ****************************************************************************/
610 void Xil_L1DCacheEnable(void)
611 {
612         register unsigned int CtrlReg;
613
614         /* enable caches only if they are disabled */
615 #ifdef __GNUC__
616         CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
617 #else
618         { volatile register unsigned int Reg __asm(XREG_CP15_SYS_CONTROL);
619           CtrlReg = Reg; }
620 #endif
621         if (CtrlReg & XREG_CP15_CONTROL_C_BIT) {
622                 return;
623         }
624
625         /* clean and invalidate the Data cache */
626         Xil_L1DCacheInvalidate();
627
628         /* enable the Data cache */
629         CtrlReg |= (XREG_CP15_CONTROL_C_BIT);
630
631         mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
632 }
633
634 /****************************************************************************
635 *
636 * Disable the level 1 Data cache.
637 *
638 * @param        None.
639 *
640 * @return       None.
641 *
642 * @note         None.
643 *
644 ****************************************************************************/
645 void Xil_L1DCacheDisable(void)
646 {
647         register unsigned int CtrlReg;
648
649         /* clean and invalidate the Data cache */
650         Xil_L1DCacheFlush();
651
652 #ifdef __GNUC__
653         /* disable the Data cache */
654         CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
655 #else
656         { volatile register unsigned int Reg __asm(XREG_CP15_SYS_CONTROL);
657           CtrlReg = Reg; }
658 #endif
659
660         CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT);
661
662         mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
663 }
664
665 /****************************************************************************
666 *
667 * Invalidate the level 1 Data cache.
668 *
669 * @param        None.
670 *
671 * @return       None.
672 *
673 * @note         In Cortex A9, there is no cp instruction for invalidating
674 *               the whole D-cache. This function invalidates each line by
675 *               set/way.
676 *
677 ****************************************************************************/
678 void Xil_L1DCacheInvalidate(void)
679 {
680         register unsigned int CsidReg, C7Reg;
681         unsigned int CacheSize, LineSize, NumWays;
682         unsigned int Way, WayIndex, Set, SetIndex, NumSet;
683         unsigned int currmask;
684
685 #ifdef __GNUC__
686         unsigned int stack_start,stack_end,stack_size;
687 #endif
688
689         currmask = mfcpsr();
690         mtcpsr(currmask | IRQ_FIQ_MASK);
691
692 #ifdef __GNUC__
693         stack_end = (unsigned int )&_stack_end;
694         stack_start = (unsigned int )&_stack;
695         stack_size=stack_start-stack_end;
696
697         /*Flush stack memory to save return address*/
698         Xil_DCacheFlushRange(stack_end, stack_size);
699 #endif
700
701         /* Select cache level 0 and D cache in CSSR */
702         mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
703
704 #ifdef __GNUC__
705         CsidReg = mfcp(XREG_CP15_CACHE_SIZE_ID);
706 #else
707         { volatile register unsigned int Reg __asm(XREG_CP15_CACHE_SIZE_ID);
708           CsidReg = Reg; }
709 #endif
710         /* Determine Cache Size */
711         CacheSize = (CsidReg >> 13) & 0x1FF;
712         CacheSize +=1;
713         CacheSize *=128;    /* to get number of bytes */
714
715         /* Number of Ways */
716         NumWays = (CsidReg & 0x3ff) >> 3;
717         NumWays += 1;
718
719         /* Get the cacheline size, way size, index size from csidr */
720         LineSize = (CsidReg & 0x07) + 4;
721
722         NumSet = CacheSize/NumWays;
723         NumSet /= (1 << LineSize);
724
725         Way = 0UL;
726         Set = 0UL;
727
728         /* Invalidate all the cachelines */
729         for (WayIndex =0; WayIndex < NumWays; WayIndex++) {
730                 for (SetIndex =0; SetIndex < NumSet; SetIndex++) {
731                         C7Reg = Way | Set;
732 #ifdef __GNUC__
733                         /* Invalidate by Set/Way */
734                         __asm__ __volatile__("mcr " \
735                         XREG_CP15_INVAL_DC_LINE_SW :: "r" (C7Reg));
736 #else
737                         //mtcp(XREG_CP15_INVAL_DC_LINE_SW, C7Reg);
738                         { volatile register unsigned int Reg
739                                 __asm(XREG_CP15_INVAL_DC_LINE_SW);
740                           Reg = C7Reg; }
741 #endif
742                         Set += (1 << LineSize);
743                 }
744                 Set=0UL;
745                 Way += 0x40000000;
746         }
747
748         /* Wait for L1 invalidate to complete */
749         dsb();
750         mtcpsr(currmask);
751 }
752
753 /****************************************************************************
754 *
755 * Invalidate a level 1 Data cache line. If the byte specified by the address
756 * (Addr) is cached by the Data cache, the cacheline containing that byte is
757 * invalidated.  If the cacheline is modified (dirty), the modified contents
758 * are lost and are NOT written to system memory before the line is
759 * invalidated.
760 *
761 * @param        Address to be flushed.
762 *
763 * @return       None.
764 *
765 * @note         The bottom 5 bits are set to 0, forced by architecture.
766 *
767 ****************************************************************************/
768 void Xil_L1DCacheInvalidateLine(unsigned int adr)
769 {
770         mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
771         mtcp(XREG_CP15_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F)));
772
773         /* Wait for L1 invalidate to complete */
774         dsb();
775 }
776
777 /****************************************************************************
778 *
779 * Invalidate the level 1 Data cache for the given address range.
780 * If the bytes specified by the address (adr) are cached by the Data cache,
781 * the cacheline containing that byte is invalidated. If the cacheline
782 * is modified (dirty), the modified contents are lost and are NOT
783 * written to system memory before the line is invalidated.
784 *
785 * @param        Start address of range to be invalidated.
786 * @param        Length of range to be invalidated in bytes.
787 *
788 * @return       None.
789 *
790 * @note         None.
791 *
792 ****************************************************************************/
793 void Xil_L1DCacheInvalidateRange(unsigned int adr, unsigned len)
794 {
795         const unsigned cacheline = 32;
796         unsigned int end;
797         unsigned int currmask;
798
799         currmask = mfcpsr();
800         mtcpsr(currmask | IRQ_FIQ_MASK);
801
802         if (len != 0) {
803                 /* Back the starting address up to the start of a cache line
804                  * perform cache operations until adr+len
805                  */
806                 end = adr + len;
807                 adr = adr & ~(cacheline - 1);
808
809                 /* Select cache L0 D-cache in CSSR */
810                 mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
811
812                 while (adr < end) {
813 #ifdef __GNUC__
814                         __asm__ __volatile__("mcr " \
815                         XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (adr));
816 #else
817                         { volatile register unsigned int Reg
818                                 __asm(XREG_CP15_INVAL_DC_LINE_MVA_POC);
819                           Reg = adr; }
820 #endif
821                         adr += cacheline;
822                 }
823         }
824
825         /* Wait for L1 invalidate to complete */
826         dsb();
827         mtcpsr(currmask);
828 }
829
830 /****************************************************************************
831 *
832 * Flush the level 1 Data cache.
833 *
834 * @param        None.
835 *
836 * @return       None.
837 *
838 * @note         In Cortex A9, there is no cp instruction for flushing
839 *               the whole D-cache. Need to flush each line.
840 *
841 ****************************************************************************/
842 void Xil_L1DCacheFlush(void)
843 {
844         register unsigned int CsidReg, C7Reg;
845         unsigned int CacheSize, LineSize, NumWays;
846         unsigned int Way, WayIndex, Set, SetIndex, NumSet;
847         unsigned int currmask;
848
849         currmask = mfcpsr();
850         mtcpsr(currmask | IRQ_FIQ_MASK);
851
852         /* Select cache level 0 and D cache in CSSR */
853         mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
854
855 #ifdef __GNUC__
856         CsidReg = mfcp(XREG_CP15_CACHE_SIZE_ID);
857 #else
858         { volatile register unsigned int Reg __asm(XREG_CP15_CACHE_SIZE_ID);
859           CsidReg = Reg; }
860 #endif
861
862         /* Determine Cache Size */
863
864         CacheSize = (CsidReg >> 13) & 0x1FF;
865         CacheSize +=1;
866         CacheSize *=128;    /* to get number of bytes */
867
868         /* Number of Ways */
869         NumWays = (CsidReg & 0x3ff) >> 3;
870         NumWays += 1;
871
872         /* Get the cacheline size, way size, index size from csidr */
873         LineSize = (CsidReg & 0x07) + 4;
874
875         NumSet = CacheSize/NumWays;
876         NumSet /= (1 << LineSize);
877
878         Way = 0UL;
879         Set = 0UL;
880
881         /* Invalidate all the cachelines */
882         for (WayIndex =0; WayIndex < NumWays; WayIndex++) {
883                 for (SetIndex =0; SetIndex < NumSet; SetIndex++) {
884                         C7Reg = Way | Set;
885                         /* Flush by Set/Way */
886 #ifdef __GNUC__
887                         __asm__ __volatile__("mcr " \
888                         XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (C7Reg));
889 #else
890                         { volatile register unsigned int Reg
891                                 __asm(XREG_CP15_CLEAN_INVAL_DC_LINE_SW);
892                           Reg = C7Reg; }
893 #endif
894                         Set += (1 << LineSize);
895                 }
896                 Set = 0UL;
897                 Way += 0x40000000;
898         }
899
900         /* Wait for L1 flush to complete */
901         dsb();
902         mtcpsr(currmask);
903 }
904
905 /****************************************************************************
906 *
907 * Flush a level 1 Data cache line. If the byte specified by the address (adr)
908 * is cached by the Data cache, the cacheline containing that byte is
909 * invalidated.  If the cacheline is modified (dirty), the entire
910 * contents of the cacheline are written to system memory before the
911 * line is invalidated.
912 *
913 * @param        Address to be flushed.
914 *
915 * @return       None.
916 *
917 * @note         The bottom 5 bits are set to 0, forced by architecture.
918 *
919 ****************************************************************************/
920 void Xil_L1DCacheFlushLine(unsigned int adr)
921 {
922         mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
923         mtcp(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F)));
924
925         /* Wait for L1 flush to complete */
926         dsb();
927 }
928
929 /****************************************************************************
930 * Flush the level 1  Data cache for the given address range.
931 * If the bytes specified by the address (adr) are cached by the Data cache,
932 * the cacheline containing that byte is invalidated.    If the cacheline
933 * is modified (dirty), the written to system memory first before the
934 * before the line is invalidated.
935 *
936 * @param        Start address of range to be flushed.
937 * @param        Length of range to be flushed in bytes.
938 *
939 * @return       None.
940 *
941 * @note         None.
942 *
943 ****************************************************************************/
944 void Xil_L1DCacheFlushRange(unsigned int adr, unsigned len)
945 {
946         const unsigned cacheline = 32;
947         unsigned int end;
948         unsigned int currmask;
949
950         currmask = mfcpsr();
951         mtcpsr(currmask | IRQ_FIQ_MASK);
952
953         if (len != 0) {
954                 /* Back the starting address up to the start of a cache line
955                  * perform cache operations until adr+len
956                  */
957                 end = adr + len;
958                 adr = adr & ~(cacheline - 1);
959
960                 /* Select cache L0 D-cache in CSSR */
961                 mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
962
963                 while (adr < end) {
964 #ifdef __GNUC__
965                         __asm__ __volatile__("mcr " \
966                         XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (adr));
967 #else
968                         { volatile register unsigned int Reg
969                                 __asm(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC);
970                           Reg = adr; }
971 #endif
972                         adr += cacheline;
973                 }
974         }
975
976         /* Wait for L1 flush to complete */
977         dsb();
978         mtcpsr(currmask);
979 }
980
981 /****************************************************************************
982 *
983 * Store a level 1  Data cache line. If the byte specified by the address (adr)
984 * is cached by the Data cache and the cacheline is modified (dirty),
985 * the entire contents of the cacheline are written to system memory.
986 * After the store completes, the cacheline is marked as unmodified
987 * (not dirty).
988 *
989 * @param        Address to be stored.
990 *
991 * @return       None.
992 *
993 * @note         The bottom 5 bits are set to 0, forced by architecture.
994 *
995 ****************************************************************************/
996 void Xil_L1DCacheStoreLine(unsigned int adr)
997 {
998         mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
999         mtcp(XREG_CP15_CLEAN_DC_LINE_MVA_POC, (adr & (~0x1F)));
1000
1001         /* Wait for L1 store to complete */
1002         dsb();
1003 }
1004
1005 /****************************************************************************
1006 *
1007 * Enable the level 1 instruction cache.
1008 *
1009 * @param        None.
1010 *
1011 * @return       None.
1012 *
1013 * @note         None.
1014 *
1015 ****************************************************************************/
1016 void Xil_L1ICacheEnable(void)
1017 {
1018         register unsigned int CtrlReg;
1019
1020         /* enable caches only if they are disabled */
1021 #ifdef __GNUC__
1022         CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
1023 #else
1024         { volatile register unsigned int Reg __asm(XREG_CP15_SYS_CONTROL);
1025           CtrlReg = Reg; }
1026 #endif
1027         if (CtrlReg & XREG_CP15_CONTROL_I_BIT) {
1028                 return;
1029         }
1030
1031         /* invalidate the instruction cache */
1032         mtcp(XREG_CP15_INVAL_IC_POU, 0);
1033
1034         /* enable the instruction cache */
1035         CtrlReg |= (XREG_CP15_CONTROL_I_BIT);
1036
1037         mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
1038 }
1039
1040 /****************************************************************************
1041 *
1042 * Disable level 1 the instruction cache.
1043 *
1044 * @param        None.
1045 *
1046 * @return       None.
1047 *
1048 * @note         None.
1049 *
1050 ****************************************************************************/
1051 void Xil_L1ICacheDisable(void)
1052 {
1053         register unsigned int CtrlReg;
1054
1055         dsb();
1056
1057         /* invalidate the instruction cache */
1058         mtcp(XREG_CP15_INVAL_IC_POU, 0);
1059
1060         /* disable the instruction cache */
1061 #ifdef __GNUC__
1062         CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
1063 #else
1064         { volatile register unsigned int Reg __asm(XREG_CP15_SYS_CONTROL);
1065           CtrlReg = Reg; }
1066 #endif
1067         CtrlReg &= ~(XREG_CP15_CONTROL_I_BIT);
1068
1069         mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
1070 }
1071
1072 /****************************************************************************
1073 *
1074 * Invalidate the entire level 1 instruction cache.
1075 *
1076 * @param        None.
1077 *
1078 * @return       None.
1079 *
1080 * @note         None.
1081 *
1082 ****************************************************************************/
1083 void Xil_L1ICacheInvalidate(void)
1084 {
1085         mtcp(XREG_CP15_CACHE_SIZE_SEL, 1);
1086         /* invalidate the instruction cache */
1087         mtcp(XREG_CP15_INVAL_IC_POU, 0);
1088
1089         /* Wait for L1 invalidate to complete */
1090         dsb();
1091 }
1092
1093 /****************************************************************************
1094 *
1095 * Invalidate a level 1  instruction cache line. If the instruction specified by
1096 * the parameter adr is cached by the instruction cache, the cacheline containing
1097 * that instruction is invalidated.
1098 *
1099 * @param        None.
1100 *
1101 * @return       None.
1102 *
1103 * @note         The bottom 5 bits are set to 0, forced by architecture.
1104 *
1105 ****************************************************************************/
1106 void Xil_L1ICacheInvalidateLine(unsigned int adr)
1107 {
1108         mtcp(XREG_CP15_CACHE_SIZE_SEL, 1);
1109         mtcp(XREG_CP15_INVAL_IC_LINE_MVA_POU, (adr & (~0x1F)));
1110
1111         /* Wait for L1 invalidate to complete */
1112         dsb();
1113 }
1114
1115 /****************************************************************************
1116 *
1117 * Invalidate the level 1 instruction cache for the given address range.
1118 * If the bytes specified by the address (adr) are cached by the Data cache,
1119 * the cacheline containing that byte is invalidated.    If the cacheline
1120 * is modified (dirty), the modified contents are lost and are NOT
1121 * written to system memory before the line is invalidated.
1122 *
1123 * @param        Start address of range to be invalidated.
1124 * @param        Length of range to be invalidated in bytes.
1125 *
1126 * @return       None.
1127 *
1128 * @note         None.
1129 *
1130 ****************************************************************************/
1131 void Xil_L1ICacheInvalidateRange(unsigned int adr, unsigned len)
1132 {
1133         const unsigned cacheline = 32;
1134         unsigned int end;
1135         unsigned int currmask;
1136
1137         currmask = mfcpsr();
1138         mtcpsr(currmask | IRQ_FIQ_MASK);
1139
1140         if (len != 0) {
1141                 /* Back the starting address up to the start of a cache line
1142                  * perform cache operations until adr+len
1143                  */
1144                 end = adr + len;
1145                 adr = adr & ~(cacheline - 1);
1146
1147                 /* Select cache L0 I-cache in CSSR */
1148                 mtcp(XREG_CP15_CACHE_SIZE_SEL, 1);
1149
1150                 while (adr < end) {
1151 #ifdef __GNUC__
1152                         __asm__ __volatile__("mcr " \
1153                         XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (adr));
1154 #else
1155                         { volatile register unsigned int Reg
1156                                 __asm(XREG_CP15_INVAL_IC_LINE_MVA_POU);
1157                           Reg = adr; }
1158 #endif
1159                         adr += cacheline;
1160                 }
1161         }
1162
1163         /* Wait for L1 invalidate to complete */
1164         dsb();
1165         mtcpsr(currmask);
1166 }
1167
1168 /****************************************************************************
1169 *
1170 * Enable the L2 cache.
1171 *
1172 * @param        None.
1173 *
1174 * @return       None.
1175 *
1176 * @note         None.
1177 *
1178 ****************************************************************************/
1179 void Xil_L2CacheEnable(void)
1180 {
1181         register unsigned int L2CCReg;
1182
1183         L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET);
1184
1185         /* only enable if L2CC is currently disabled */
1186         if ((L2CCReg & 0x01) == 0) {
1187                 /* set up the way size and latencies */
1188                 L2CCReg = Xil_In32(XPS_L2CC_BASEADDR +
1189                                    XPS_L2CC_AUX_CNTRL_OFFSET);
1190                 L2CCReg &= XPS_L2CC_AUX_REG_ZERO_MASK;
1191                 L2CCReg |= XPS_L2CC_AUX_REG_DEFAULT_MASK;
1192                 Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_AUX_CNTRL_OFFSET,
1193                           L2CCReg);
1194                 Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_TAG_RAM_CNTRL_OFFSET,
1195                           XPS_L2CC_TAG_RAM_DEFAULT_MASK);
1196                 Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_DATA_RAM_CNTRL_OFFSET,
1197                           XPS_L2CC_DATA_RAM_DEFAULT_MASK);
1198
1199                 /* Clear the pending interrupts */
1200                 L2CCReg = Xil_In32(XPS_L2CC_BASEADDR +
1201                                    XPS_L2CC_ISR_OFFSET);
1202                 Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_IAR_OFFSET, L2CCReg);
1203
1204                 Xil_L2CacheInvalidate();
1205                 /* Enable the L2CC */
1206                 L2CCReg = Xil_In32(XPS_L2CC_BASEADDR +
1207                                    XPS_L2CC_CNTRL_OFFSET);
1208                 Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET,
1209                           (L2CCReg | (0x01)));
1210
1211         Xil_L2CacheSync();
1212         /* synchronize the processor */
1213             dsb();
1214
1215     }
1216 }
1217
1218 /****************************************************************************
1219 *
1220 * Disable the L2 cache.
1221 *
1222 * @param        None.
1223 *
1224 * @return       None.
1225 *
1226 * @note         None.
1227 *
1228 ****************************************************************************/
1229 void Xil_L2CacheDisable(void)
1230 {
1231     register unsigned int L2CCReg;
1232
1233         L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET);
1234
1235     if(L2CCReg & 0x1) {
1236
1237         /* Clean and Invalidate L2 Cache */
1238         Xil_L2CacheFlush();
1239
1240             /* Disable the L2CC */
1241         L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET);
1242             Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET,
1243                       (L2CCReg & (~0x01)));
1244                 /* Wait for the cache operations to complete */
1245
1246                 dsb();
1247     }
1248 }
1249
1250 /****************************************************************************
1251 *
1252 * Invalidate the L2 cache. If the byte specified by the address (adr)
1253 * is cached by the Data cache, the cacheline containing that byte is
1254 * invalidated.  If the cacheline is modified (dirty), the modified contents
1255 * are lost and are NOT written to system memory before the line is
1256 * invalidated.
1257 *
1258 * @param        Address to be flushed.
1259 *
1260 * @return       None.
1261 *
1262 * @note         The bottom 4 bits are set to 0, forced by architecture.
1263 *
1264 ****************************************************************************/
1265 void Xil_L2CacheInvalidate(void)
1266 {
1267         /* Invalidate the caches */
1268         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_WAY_OFFSET,
1269                   0x0000FFFF);
1270         while((Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_WAY_OFFSET))
1271                                                                                                                                 & 0x0000FFFF);
1272
1273         /* Wait for the invalidate to complete */
1274         Xil_L2CacheSync();
1275
1276         /* synchronize the processor */
1277         dsb();
1278 }
1279
1280 /****************************************************************************
1281 *
1282 * Invalidate a level 2 cache line. If the byte specified by the address (adr)
1283 * is cached by the Data cache, the cacheline containing that byte is
1284 * invalidated.  If the cacheline is modified (dirty), the modified contents
1285 * are lost and are NOT written to system memory before the line is
1286 * invalidated.
1287 *
1288 * @param        Address to be flushed.
1289 *
1290 * @return       None.
1291 *
1292 * @note         The bottom 4 bits are set to 0, forced by architecture.
1293 *
1294 ****************************************************************************/
1295 void Xil_L2CacheInvalidateLine(unsigned int adr)
1296 {
1297         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_PA_OFFSET, adr);
1298         /* synchronize the processor */
1299         dsb();
1300 }
1301
1302 /****************************************************************************
1303 *
1304 * Invalidate the level 2 cache for the given address range.
1305 * If the bytes specified by the address (adr) are cached by the Data cache,
1306 * the cacheline containing that byte is invalidated.    If the cacheline
1307 * is modified (dirty), the modified contents are lost and are NOT
1308 * written to system memory before the line is invalidated.
1309 *
1310 * @param        Start address of range to be invalidated.
1311 * @param        Length of range to be invalidated in bytes.
1312 *
1313 * @return       None.
1314 *
1315 * @note         None.
1316 *
1317 ****************************************************************************/
1318 void Xil_L2CacheInvalidateRange(unsigned int adr, unsigned len)
1319 {
1320         const unsigned cacheline = 32;
1321         unsigned int end;
1322         volatile u32 *L2CCOffset = (volatile u32 *) (XPS_L2CC_BASEADDR +
1323                                     XPS_L2CC_CACHE_INVLD_PA_OFFSET);
1324
1325         unsigned int currmask;
1326
1327         currmask = mfcpsr();
1328         mtcpsr(currmask | IRQ_FIQ_MASK);
1329
1330         if (len != 0) {
1331                 /* Back the starting address up to the start of a cache line
1332                  * perform cache operations until adr+len
1333                  */
1334                 end = adr + len;
1335                 adr = adr & ~(cacheline - 1);
1336
1337                 /* Disable Write-back and line fills */
1338                 Xil_L2WriteDebugCtrl(0x3);
1339
1340                 while (adr < end) {
1341                         *L2CCOffset = adr;
1342                         adr += cacheline;
1343                 }
1344
1345                 /* Enable Write-back and line fills */
1346                 Xil_L2WriteDebugCtrl(0x0);
1347         }
1348
1349         /* synchronize the processor */
1350         dsb();
1351         mtcpsr(currmask);
1352 }
1353
1354 /****************************************************************************
1355 *
1356 * Flush the L2 cache. If the byte specified by the address (adr)
1357 * is cached by the Data cache, the cacheline containing that byte is
1358 * invalidated. If the cacheline is modified (dirty), the entire
1359 * contents of the cacheline are written to system memory before the
1360 * line is invalidated.
1361 *
1362 * @param        Address to be flushed.
1363 *
1364 * @return       None.
1365 *
1366 * @note         The bottom 4 bits are set to 0, forced by architecture.
1367 *
1368 ****************************************************************************/
1369 void Xil_L2CacheFlush(void)
1370 {
1371
1372         /* Flush the caches */
1373
1374         /* Disable Write-back and line fills */
1375         Xil_L2WriteDebugCtrl(0x3);
1376
1377         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET,
1378                   0x0000FFFF);
1379
1380         while((Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET))
1381                                                                                                                         & 0x0000FFFF);
1382
1383         Xil_L2CacheSync();
1384         /* Enable Write-back and line fills */
1385         Xil_L2WriteDebugCtrl(0x0);
1386
1387         /* synchronize the processor */
1388         dsb();
1389 }
1390
1391 /****************************************************************************
1392 *
1393 * Flush a level 2 cache line. If the byte specified by the address (adr)
1394 * is cached by the Data cache, the cacheline containing that byte is
1395 * invalidated. If the cacheline is modified (dirty), the entire
1396 * contents of the cacheline are written to system memory before the
1397 * line is invalidated.
1398 *
1399 * @param        Address to be flushed.
1400 *
1401 * @return       None.
1402 *
1403 * @note         The bottom 4 bits are set to 0, forced by architecture.
1404 *
1405 ****************************************************************************/
1406 void Xil_L2CacheFlushLine(unsigned int adr)
1407 {
1408 #ifdef CONFIG_PL310_ERRATA_588369
1409         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_CLEAN_PA_OFFSET, adr);
1410         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_PA_OFFSET, adr);
1411 #else
1412         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_PA_OFFSET, adr);
1413 #endif
1414         /* synchronize the processor */
1415         dsb();
1416 }
1417
1418 /****************************************************************************
1419 * Flush the level 2 cache for the given address range.
1420 * If the bytes specified by the address (adr) are cached by the Data cache,
1421 * the cacheline containing that byte is invalidated.    If the cacheline
1422 * is modified (dirty), the written to system memory first before the
1423 * before the line is invalidated.
1424 *
1425 * @param        Start address of range to be flushed.
1426 * @param        Length of range to be flushed in bytes.
1427 *
1428 * @return       None.
1429 *
1430 * @note         None.
1431 *
1432 ****************************************************************************/
1433 void Xil_L2CacheFlushRange(unsigned int adr, unsigned len)
1434 {
1435         const unsigned cacheline = 32;
1436         unsigned int end;
1437         volatile u32 *L2CCOffset = (volatile u32 *) (XPS_L2CC_BASEADDR +
1438                                     XPS_L2CC_CACHE_INV_CLN_PA_OFFSET);
1439
1440         unsigned int currmask;
1441
1442         currmask = mfcpsr();
1443         mtcpsr(currmask | IRQ_FIQ_MASK);
1444         if (len != 0) {
1445                 /* Back the starting address up to the start of a cache line
1446                  * perform cache operations until adr+len
1447                  */
1448                 end = adr + len;
1449                 adr = adr & ~(cacheline - 1);
1450
1451                 /* Disable Write-back and line fills */
1452                 Xil_L2WriteDebugCtrl(0x3);
1453
1454                 while (adr < end) {
1455                         *L2CCOffset = adr;
1456                         Xil_L2CacheSync();
1457                         adr += cacheline;
1458                 }
1459
1460                 /* Enable Write-back and line fills */
1461                 Xil_L2WriteDebugCtrl(0x0);
1462         }
1463         /* synchronize the processor */
1464         dsb();
1465         mtcpsr(currmask);
1466 }
1467
1468 /****************************************************************************
1469 *
1470 * Store a level 2 cache line. If the byte specified by the address (adr)
1471 * is cached by the Data cache and the cacheline is modified (dirty),
1472 * the entire contents of the cacheline are written to system memory.
1473 * After the store completes, the cacheline is marked as unmodified
1474 * (not dirty).
1475 *
1476 * @param        Address to be stored.
1477 *
1478 * @return       None.
1479 *
1480 * @note         The bottom 4 bits are set to 0, forced by architecture.
1481 *
1482 ****************************************************************************/
1483 void Xil_L2CacheStoreLine(unsigned int adr)
1484 {
1485         Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_CLEAN_PA_OFFSET, adr);
1486         /* synchronize the processor */
1487         dsb();
1488 }