1 /*
2 * File : cache.c
3 * COPYRIGHT (C) 2008 - 2016, RT-Thread Development Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Change Logs:
20 * Date Author Notes
21 */
22
23 #include "../xburst/cache.h"
24
25 #include <board.h>
26
27 #define CACHE_SIZE 16*1024
28 #define CACHE_LINE_SIZE 32
29 #define KSEG0 0x80000000
30
31 #define K0_TO_K1() \
32 do { \
33 unsigned long __k0_addr; \
34 \
35 __asm__ __volatile__( \
36 "la %0, 1f\n\t" \
37 "or %0, %0, %1\n\t" \
38 "jr %0\n\t" \
39 "nop\n\t" \
40 "1: nop\n" \
41 : "=&r"(__k0_addr) \
42 : "r" (0x20000000) ); \
43 } while(0)
44
45 #define K1_TO_K0() \
46 do { \
47 unsigned long __k0_addr; \
48 __asm__ __volatile__( \
49 "nop;nop;nop;nop;nop;nop;nop\n\t" \
50 "la %0, 1f\n\t" \
51 "jr %0\n\t" \
52 "nop\n\t" \
53 "1: nop\n" \
54 : "=&r" (__k0_addr)); \
55 } while (0)
56
57 #define INVALIDATE_BTB() \
58 do { \
59 unsigned long tmp; \
60 __asm__ __volatile__( \
61 ".set mips32\n\t" \
62 "mfc0 %0, $16, 7\n\t" \
63 "nop\n\t" \
64 "ori %0, 2\n\t" \
65 "mtc0 %0, $16, 7\n\t" \
66 "nop\n\t" \
67 ".set mips2\n\t" \
68 : "=&r" (tmp)); \
69 } while (0)
70
71 #define SYNC_WB() __asm__ __volatile__ ("sync")
72
73 #define cache_op(op,addr) \
74 __asm__ __volatile__( \
75 " .set noreorder \n" \
76 " .set mips32\n\t \n" \
77 " cache %0, %1 \n" \
78 " .set mips0 \n" \
79 " .set reorder" \
80 : \
81 : "i" (op), "m" (*(unsigned char *)(addr)))
82
__icache_invalidate_all(void)83 void __icache_invalidate_all(void)
84 {
85 unsigned int i;
86
87 K0_TO_K1();
88
89 asm volatile (".set noreorder\n"
90 ".set mips32\n\t"
91 "mtc0\t$0,$28\n\t"
92 "mtc0\t$0,$29\n"
93 ".set mips0\n"
94 ".set reorder\n");
95 for (i=KSEG0;i<KSEG0+CACHE_SIZE;i+=CACHE_LINE_SIZE)
96 cache_op(Index_Store_Tag_I, i);
97
98 K1_TO_K0();
99
100 INVALIDATE_BTB();
101 }
102
__dcache_writeback_all(void)103 void __dcache_writeback_all(void)
104 {
105 unsigned int i;
106
107 for (i=KSEG0;i<KSEG0+CACHE_SIZE;i+=CACHE_LINE_SIZE)
108 cache_op(Index_Writeback_Inv_D, i);
109
110 SYNC_WB();
111 }
112
rt_hw_cache_init(void)113 void rt_hw_cache_init(void)
114 {
115 __dcache_writeback_all();
116 __icache_invalidate_all();
117 }
118
119