Root/target/linux/lantiq/patches-3.3/0018-cache-split.patch

1From d38bc3854ee2fb9d3e6080b89dd6774dd5d39c2b Mon Sep 17 00:00:00 2001
2From: John Crispin <blogic@openwrt.org>
3Date: Thu, 29 Sep 2011 20:31:54 +0200
4Subject: [PATCH 18/25] cache split
5
6---
7 arch/mips/Kconfig | 22 ++++++
8 arch/mips/kernel/vpe.c | 66 ++++++++++++++++++
9 arch/mips/mm/c-r4k.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++++
10 3 files changed, 260 insertions(+), 0 deletions(-)
11
12diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
13index e152c85..39e698f 100644
14--- a/arch/mips/Kconfig
15+++ b/arch/mips/Kconfig
16@@ -1955,6 +1955,28 @@ config IFX_VPE_EXT
17     help
18       IFX included extensions in APRP
19 
20+config IFX_VPE_CACHE_SPLIT
21+ bool "IFX Cache Split Ways"
22+ depends on IFX_VPE_EXT
23+ help
24+ IFX extension for reserving (splitting) cache ways among VPEs. You must
25+ give kernel command line arguments vpe_icache_shared=0 or
26+ vpe_dcache_shared=0 to enable splitting of icache or dcache
27+ respectively. Then you can specify which cache ways should be
28+ assigned to which VPE. There are total 8 cache ways, 4 each
29+ for dcache and icache: dcache_way0, dcache_way1,dcache_way2,
30+ dcache_way3 and icache_way0,icache_way1, icache_way2,icache_way3.
31+
32+ For example, if you specify vpe_icache_shared=0 and icache_way2=1,
33+ then the 3rd icache way will be assigned to VPE0 and denied in VPE1.
34+
35+ For icache, software is required to make at least one cache way available
36+ for a VPE at all times i.e., one can't assign all the icache ways to one
37+ VPE.
38+
39+ By default, vpe_dcache_shared and vpe_icache_shared are set to 1
40+ (i.e., both icache and dcache are shared among VPEs)
41+
42 config PERFCTRS
43     bool "34K Performance counters"
44     depends on MIPS_MT && PROC_FS
45diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
46index e338ba5..0511d11 100644
47--- a/arch/mips/kernel/vpe.c
48+++ b/arch/mips/kernel/vpe.c
49@@ -127,6 +127,13 @@ __setup("vpe1_wdog_timeout=", wdog_timeout);
50 EXPORT_SYMBOL(vpe1_wdog_timeout);
51 
52 #endif
53+
54+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT /* Code for splitting the cache ways among VPEs. */
55+extern int vpe_icache_shared,vpe_dcache_shared;
56+extern int icache_way0,icache_way1,icache_way2,icache_way3;
57+extern int dcache_way0,dcache_way1,dcache_way2,dcache_way3;
58+#endif
59+
60 /* grab the likely amount of memory we will need. */
61 #ifdef CONFIG_MIPS_VPE_LOADER_TOM
62 #define P_SIZE (2 * 1024 * 1024)
63@@ -865,6 +872,65 @@ static int vpe_run(struct vpe * v)
64     /* enable this VPE */
65     write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
66 
67+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT
68+ if ( (!vpe_icache_shared) || (!vpe_dcache_shared) ) {
69+
70+ /* PCP bit must be 1 to split the cache */
71+ if(read_c0_mvpconf0() & MVPCONF0_PCP) {
72+
73+ if ( !vpe_icache_shared ){
74+ write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0()) & ~VPECONF0_ICS);
75+
76+ /*
77+ * If any cache way is 1, then that way is denied
78+ * in VPE1. Otherwise assign that way to VPE1.
79+ */
80+ if (!icache_way0)
81+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX0 );
82+ else
83+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX0 );
84+ if (!icache_way1)
85+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX1 );
86+ else
87+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX1 );
88+ if (!icache_way2)
89+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX2 );
90+ else
91+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX2 );
92+ if (!icache_way3)
93+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_IWX3 );
94+ else
95+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_IWX3 );
96+ }
97+
98+ if ( !vpe_dcache_shared ) {
99+ write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0()) & ~VPECONF0_DCS);
100+
101+ /*
102+ * If any cache way is 1, then that way is denied
103+ * in VPE1. Otherwise assign that way to VPE1.
104+ */
105+ if (!dcache_way0)
106+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX0 );
107+ else
108+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX0 );
109+ if (!dcache_way1)
110+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX1 );
111+ else
112+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX1 );
113+ if (!dcache_way2)
114+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX2 );
115+ else
116+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX2 );
117+ if (!dcache_way3)
118+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() | VPEOPT_DWX3 );
119+ else
120+ write_vpe_c0_vpeopt(read_vpe_c0_vpeopt() & ~VPEOPT_DWX3 );
121+ }
122+ }
123+ }
124+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
125+
126     /* clear out any left overs from a previous program */
127     write_vpe_c0_status(0);
128     write_vpe_c0_cause(0);
129diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
130index de3475e..41aee8b 100644
131--- a/arch/mips/mm/c-r4k.c
132+++ b/arch/mips/mm/c-r4k.c
133@@ -1389,6 +1389,106 @@ static int __init setcoherentio(char *str)
134 __setup("coherentio", setcoherentio);
135 #endif
136 
137+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT /* Code for splitting the cache ways among VPEs. */
138+
139+#include <asm/mipsmtregs.h>
140+
141+/*
142+ * By default, vpe_icache_shared and vpe_dcache_shared
143+ * values are 1 i.e., both icache and dcache are shared
144+ * among the VPEs.
145+ */
146+
147+int vpe_icache_shared = 1;
148+static int __init vpe_icache_shared_val(char *str)
149+{
150+ get_option(&str, &vpe_icache_shared);
151+ return 1;
152+}
153+__setup("vpe_icache_shared=", vpe_icache_shared_val);
154+EXPORT_SYMBOL(vpe_icache_shared);
155+
156+int vpe_dcache_shared = 1;
157+static int __init vpe_dcache_shared_val(char *str)
158+{
159+ get_option(&str, &vpe_dcache_shared);
160+ return 1;
161+}
162+__setup("vpe_dcache_shared=", vpe_dcache_shared_val);
163+EXPORT_SYMBOL(vpe_dcache_shared);
164+
165+/*
166+ * Software is required to make atleast one icache
167+ * way available for a VPE at all times i.e., one
168+ * can't assign all the icache ways to one VPE.
169+ */
170+
171+int icache_way0 = 0;
172+static int __init icache_way0_val(char *str)
173+{
174+ get_option(&str, &icache_way0);
175+ return 1;
176+}
177+__setup("icache_way0=", icache_way0_val);
178+
179+int icache_way1 = 0;
180+static int __init icache_way1_val(char *str)
181+{
182+ get_option(&str, &icache_way1);
183+ return 1;
184+}
185+__setup("icache_way1=", icache_way1_val);
186+
187+int icache_way2 = 0;
188+static int __init icache_way2_val(char *str)
189+{
190+ get_option(&str, &icache_way2);
191+ return 1;
192+}
193+__setup("icache_way2=", icache_way2_val);
194+
195+int icache_way3 = 0;
196+static int __init icache_way3_val(char *str)
197+{
198+ get_option(&str, &icache_way3);
199+ return 1;
200+}
201+__setup("icache_way3=", icache_way3_val);
202+
203+int dcache_way0 = 0;
204+static int __init dcache_way0_val(char *str)
205+{
206+ get_option(&str, &dcache_way0);
207+ return 1;
208+}
209+__setup("dcache_way0=", dcache_way0_val);
210+
211+int dcache_way1 = 0;
212+static int __init dcache_way1_val(char *str)
213+{
214+ get_option(&str, &dcache_way1);
215+ return 1;
216+}
217+__setup("dcache_way1=", dcache_way1_val);
218+
219+int dcache_way2 = 0;
220+static int __init dcache_way2_val(char *str)
221+{
222+ get_option(&str, &dcache_way2);
223+ return 1;
224+}
225+__setup("dcache_way2=", dcache_way2_val);
226+
227+int dcache_way3 = 0;
228+static int __init dcache_way3_val(char *str)
229+{
230+ get_option(&str, &dcache_way3);
231+ return 1;
232+}
233+__setup("dcache_way3=", dcache_way3_val);
234+
235+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
236+
237 void __cpuinit r4k_cache_init(void)
238 {
239     extern void build_clear_page(void);
240@@ -1408,6 +1508,78 @@ void __cpuinit r4k_cache_init(void)
241         break;
242     }
243 
244+#ifdef CONFIG_IFX_VPE_CACHE_SPLIT
245+ /*
246+ * We split the cache ways appropriately among the VPEs
247+ * based on cache ways values we received as command line
248+ * arguments
249+ */
250+ if ( (!vpe_icache_shared) || (!vpe_dcache_shared) ){
251+
252+ /* PCP bit must be 1 to split the cache */
253+ if(read_c0_mvpconf0() & MVPCONF0_PCP) {
254+
255+ /* Set CPA bit which enables us to modify VPEOpt register */
256+ write_c0_mvpcontrol((read_c0_mvpcontrol()) | MVPCONTROL_CPA);
257+
258+ if ( !vpe_icache_shared ){
259+ write_c0_vpeconf0((read_c0_vpeconf0()) & ~VPECONF0_ICS);
260+ /*
261+ * If any cache way is 1, then that way is denied
262+ * in VPE0. Otherwise assign that way to VPE0.
263+ */
264+ printk(KERN_DEBUG "icache is split\n");
265+ printk(KERN_DEBUG "icache_way0=%d icache_way1=%d icache_way2=%d icache_way3=%d\n",
266+ icache_way0, icache_way1,icache_way2, icache_way3);
267+ if (icache_way0)
268+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX0 );
269+ else
270+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX0 );
271+ if (icache_way1)
272+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX1 );
273+ else
274+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX1 );
275+ if (icache_way2)
276+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX2 );
277+ else
278+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX2 );
279+ if (icache_way3)
280+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_IWX3 );
281+ else
282+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_IWX3 );
283+ }
284+
285+ if ( !vpe_dcache_shared ) {
286+ /*
287+ * If any cache way is 1, then that way is denied
288+ * in VPE0. Otherwise assign that way to VPE0.
289+ */
290+ printk(KERN_DEBUG "dcache is split\n");
291+ printk(KERN_DEBUG "dcache_way0=%d dcache_way1=%d dcache_way2=%d dcache_way3=%d\n",
292+ dcache_way0, dcache_way1, dcache_way2, dcache_way3);
293+ write_c0_vpeconf0((read_c0_vpeconf0()) & ~VPECONF0_DCS);
294+ if (dcache_way0)
295+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX0 );
296+ else
297+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX0 );
298+ if (dcache_way1)
299+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX1 );
300+ else
301+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX1 );
302+ if (dcache_way2)
303+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX2 );
304+ else
305+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX2 );
306+ if (dcache_way3)
307+ write_c0_vpeopt(read_c0_vpeopt() | VPEOPT_DWX3 );
308+ else
309+ write_c0_vpeopt(read_c0_vpeopt() & ~VPEOPT_DWX3 );
310+ }
311+ }
312+ }
313+
314+#endif /* endif CONFIG_IFX_VPE_CACHE_SPLIT */
315+
316     probe_pcache();
317     setup_scache();
318 
319--
3201.7.9.1
321
322

Archive Download this file



interactive