1 /* $Id: cache.c,v 1.4 2000/01/25 00:11:38 prumpf Exp $
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
7 * Copyright (C) 1999 Helge Deller (07-13-1999)
8 * Copyright (C) 1999 SuSE GmbH Nuernberg
9 * Copyright (C) 2000 Philipp Rumpf (prumpf@tux.org)
11 * Cache and TLB management
15 #include <linux/init.h>
16 #include <linux/kernel.h>
20 #include <asm/cache.h>
21 #include <asm/system.h>
23 #include <asm/pgalloc.h>
25 struct pdc_cache_info cache_info
;
27 static struct pdc_btlb_info btlb_info
;
31 void __flush_page_to_ram(unsigned long address
)
33 __flush_dcache_range(address
, PAGE_SIZE
);
34 __flush_icache_range(address
, PAGE_SIZE
);
39 void flush_data_cache(void)
41 register unsigned long base
= cache_info
.dc_base
;
42 register unsigned long count
= cache_info
.dc_count
;
43 register unsigned long loop
= cache_info
.dc_loop
;
44 register unsigned long stride
= cache_info
.dc_stride
;
45 register unsigned long addr
;
48 for(i
=0,addr
=base
; i
<count
; i
++,addr
+=stride
)
53 static inline void flush_data_tlb_space(void)
55 unsigned long base
= cache_info
.dt_off_base
;
56 unsigned long count
= cache_info
.dt_off_count
;
57 unsigned long stride
= cache_info
.dt_off_stride
;
58 unsigned long loop
= cache_info
.dt_loop
;
63 for(i
=0,addr
=base
; i
<count
; i
++,addr
+=stride
)
70 void flush_data_tlb(void)
72 unsigned long base
= cache_info
.dt_sp_base
;
73 unsigned long count
= cache_info
.dt_sp_count
;
74 unsigned long stride
= cache_info
.dt_sp_stride
;
76 unsigned long old_sr1
;
81 for(i
=0,space
=base
; i
<count
; i
++, space
+=stride
) {
83 flush_data_tlb_space();
89 static inline void flush_instruction_tlb_space(void)
91 unsigned long base
= cache_info
.it_off_base
;
92 unsigned long count
= cache_info
.it_off_count
;
93 unsigned long stride
= cache_info
.it_off_stride
;
94 unsigned long loop
= cache_info
.it_loop
;
99 for(i
=0,addr
=base
; i
<count
; i
++,addr
+=stride
)
100 for(j
=0; j
<loop
; j
++)
104 void flush_instruction_tlb(void)
106 unsigned long base
= cache_info
.it_sp_base
;
107 unsigned long count
= cache_info
.it_sp_count
;
108 unsigned long stride
= cache_info
.it_sp_stride
;
110 unsigned long old_sr1
;
115 for(i
=0,space
=base
; i
<count
; i
++, space
+=stride
) {
117 flush_instruction_tlb_space();
124 void __flush_tlb_space(unsigned long space
)
126 unsigned long old_sr1
;
131 flush_data_tlb_space();
132 flush_instruction_tlb_space();
138 void flush_instruction_cache(void)
140 register unsigned long base
= cache_info
.ic_base
;
141 register unsigned long count
= cache_info
.ic_count
;
142 register unsigned long loop
= cache_info
.ic_loop
;
143 register unsigned long stride
= cache_info
.ic_stride
;
144 register unsigned long addr
;
146 unsigned long old_sr1
;
152 * Note: fice instruction has 3 bit space field, so one must
153 * be specified (otherwise you are justing using whatever
154 * happens to be in sr0).
157 for(i
=0,addr
=base
; i
<count
; i
++,addr
+=stride
)
158 for(j
=0; j
<loop
; j
++)
164 /* not yet ... fdc() needs to be implemented in cache.h !
165 void flush_datacache_range( unsigned int base, unsigned int end )
167 register long offset,offset_add;
168 offset_add = ( (1<<(cache_info.dc_conf.cc_block-1)) *
169 cache_info.dc_conf.cc_line ) << 4;
170 for (offset=base; offset<=end; offset+=offset_add)
176 /* flushes code and data-cache */
177 void flush_all_caches(void)
179 flush_instruction_cache();
182 flush_instruction_tlb();
185 asm volatile("sync");
186 asm volatile("syncdma");
187 asm volatile("sync");
190 int get_cache_info(char *buffer
)
194 p
+= sprintf(p
, "I-cache\t\t: %ld KB\n",
195 cache_info
.ic_size
/1024 );
196 p
+= sprintf(p
, "D-cache\t\t: %ld KB (%s)%s\n",
197 cache_info
.dc_size
/1024,
198 (cache_info
.dc_conf
.cc_wt
? "WT":"WB"),
199 (cache_info
.dc_conf
.cc_sh
? " - shared I/D":"")
202 p
+= sprintf(p
, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
205 cache_info
.dt_conf
.tc_sh
? " - shared with ITLB":""
209 /* BTLB - Block TLB */
210 if (btlb_info
.max_size
==0) {
211 p
+= sprintf(p
, "BTLB\t\t: not supported\n" );
214 "BTLB fixed\t: max. %d pages, pagesize=%d (%dMB)\n"
215 "BTLB fix-entr.\t: %d instruction, %d data (%d combined)\n"
216 "BTLB var-entr.\t: %d instruction, %d data (%d combined)\n",
217 btlb_info
.max_size
, (int)4096,
218 btlb_info
.max_size
>>8,
219 btlb_info
.fixed_range_info
.num_i
,
220 btlb_info
.fixed_range_info
.num_d
,
221 btlb_info
.fixed_range_info
.num_comb
,
222 btlb_info
.variable_range_info
.num_i
,
223 btlb_info
.variable_range_info
.num_d
,
224 btlb_info
.variable_range_info
.num_comb
236 if(pdc_cache_info(&cache_info
)<0)
237 panic("cache_init: pdc_cache_info failed");
240 printk("ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",
244 sizeof (struct pdc_cache_info
) / sizeof (long),
245 sizeof (struct pdc_cache_cf
)
249 if(pdc_btlb_info(&btlb_info
)<0) {
250 memset(&btlb_info
, 0, sizeof btlb_info
);