summaryrefslogtreecommitdiff
path: root/firmware/target/mips/mmu-mips.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/mmu-mips.c')
-rw-r--r--firmware/target/mips/mmu-mips.c92
1 files changed, 91 insertions, 1 deletions
diff --git a/firmware/target/mips/mmu-mips.c b/firmware/target/mips/mmu-mips.c
index 570b209e3a..2f7f19d3b3 100644
--- a/firmware/target/mips/mmu-mips.c
+++ b/firmware/target/mips/mmu-mips.c
@@ -112,7 +112,7 @@ void map_address(unsigned long virtual, unsigned long physical,
112 add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK); 112 add_wired_entry(entry0, entry1, entryhi, DEFAULT_PAGE_MASK);
113} 113}
114 114
115void tlb_init(void) 115void mmu_init(void)
116{ 116{
117 write_c0_pagemask(DEFAULT_PAGE_MASK); 117 write_c0_pagemask(DEFAULT_PAGE_MASK);
118 write_c0_wired(0); 118 write_c0_wired(0);
@@ -124,3 +124,93 @@ void tlb_init(void)
124 map_address(0x80004000, 0x80004000, MEM * 0x100000, K_CacheAttrC); 124 map_address(0x80004000, 0x80004000, MEM * 0x100000, K_CacheAttrC);
125*/ 125*/
126} 126}
127
128#define SYNC_WB() __asm__ __volatile__ ("sync")
129
130#define __CACHE_OP(op, addr) \
131 __asm__ __volatile__( \
132 " .set noreorder \n" \
133 " .set mips32\n\t \n" \
134 " cache %0, %1 \n" \
135 " .set mips0 \n" \
136 " .set reorder \n" \
137 : \
138 : "i" (op), "m" (*(unsigned char *)(addr)))
139
140void __flush_dcache_line(unsigned long addr)
141{
142 __CACHE_OP(DCHitWBInv, addr);
143 SYNC_WB();
144}
145
146void __icache_invalidate_all(void)
147{
148 unsigned int i;
149
150 asm volatile (".set noreorder \n"
151 ".set mips32 \n"
152 "mtc0 $0, $28 \n" /* TagLo */
153 "mtc0 $0, $29 \n" /* TagHi */
154 ".set mips0 \n"
155 ".set reorder \n"
156 );
157 for(i=A_K0BASE; i<A_K0BASE+CACHE_SIZE; i+=CACHE_LINE_SIZE)
158 __CACHE_OP(ICIndexStTag, i);
159
160 /* invalidate btb */
161 asm volatile (
162 ".set mips32 \n"
163 "mfc0 %0, $16, 7 \n"
164 "nop \n"
165 "ori %0, 2 \n"
166 "mtc0 %0, $16, 7 \n"
167 ".set mips0 \n"
168 :
169 : "r" (i));
170}
171
172void cpucache_invalidate(void)
173{
174 __icache_invalidate_all();
175}
176
177void __dcache_invalidate_all(void)
178{
179 unsigned int i;
180
181 asm volatile (".set noreorder \n"
182 ".set mips32 \n"
183 "mtc0 $0, $28 \n"
184 "mtc0 $0, $29 \n"
185 ".set mips0 \n"
186 ".set reorder \n"
187 );
188 for (i=A_K0BASE; i<A_K0BASE+CACHE_SIZE; i+=CACHE_LINE_SIZE)
189 __CACHE_OP(DCIndexStTag, i);
190}
191
192void __dcache_writeback_all(void)
193{
194 unsigned int i;
195 for(i=A_K0BASE; i<A_K0BASE+CACHE_SIZE; i+=CACHE_LINE_SIZE)
196 __CACHE_OP(DCIndexWBInv, i);
197
198 SYNC_WB();
199}
200
201void dma_cache_wback_inv(unsigned long addr, unsigned long size)
202{
203 unsigned long end, a;
204
205 if (size >= CACHE_SIZE)
206 __dcache_writeback_all();
207 else
208 {
209 unsigned long dc_lsize = CACHE_LINE_SIZE;
210
211 a = addr & ~(dc_lsize - 1);
212 end = (addr + size - 1) & ~(dc_lsize - 1);
213 for(; a < end; a += dc_lsize)
214 __flush_dcache_line(a);
215 }
216}