| @@ -1,352 +1,352 @@ | | | @@ -1,352 +1,352 @@ |
1 | /* $NetBSD: cpu.c,v 1.36 2021/03/05 07:11:24 rin Exp $ */ | | 1 | /* $NetBSD: cpu.c,v 1.37 2021/03/30 02:27:00 rin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 2001 Wasabi Systems, Inc. | | 4 | * Copyright 2001 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc. | | 7 | * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in the | | 15 | * notice, this list of conditions and the following disclaimer in the |
16 | * documentation and/or other materials provided with the distribution. | | 16 | * documentation and/or other materials provided with the distribution. |
17 | * 3. All advertising materials mentioning features or use of this software | | 17 | * 3. All advertising materials mentioning features or use of this software |
18 | * must display the following acknowledgement: | | 18 | * must display the following acknowledgement: |
19 | * This product includes software developed for the NetBSD Project by | | 19 | * This product includes software developed for the NetBSD Project by |
20 | * Wasabi Systems, Inc. | | 20 | * Wasabi Systems, Inc. |
21 | * 4. The name of Wasabi Systems, Inc. may not be used to endorse | | 21 | * 4. The name of Wasabi Systems, Inc. may not be used to endorse |
22 | * or promote products derived from this software without specific prior | | 22 | * or promote products derived from this software without specific prior |
23 | * written permission. | | 23 | * written permission. |
24 | * | | 24 | * |
25 | * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND | | 25 | * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND |
26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
27 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 27 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
28 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC | | 28 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC |
29 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 29 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
30 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 30 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
31 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 31 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
35 | * POSSIBILITY OF SUCH DAMAGE. | | 35 | * POSSIBILITY OF SUCH DAMAGE. |
36 | */ | | 36 | */ |
37 | | | 37 | |
38 | #include <sys/cdefs.h> | | 38 | #include <sys/cdefs.h> |
39 | __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.36 2021/03/05 07:11:24 rin Exp $"); | | 39 | __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.37 2021/03/30 02:27:00 rin Exp $"); |
40 | | | 40 | |
41 | #include <sys/param.h> | | 41 | #include <sys/param.h> |
42 | #include <sys/systm.h> | | 42 | #include <sys/systm.h> |
43 | #include <sys/device.h> | | 43 | #include <sys/device.h> |
44 | #include <sys/evcnt.h> | | 44 | #include <sys/evcnt.h> |
45 | #include <sys/cpu.h> | | 45 | #include <sys/cpu.h> |
46 | | | 46 | |
47 | #include <uvm/uvm_extern.h> | | 47 | #include <uvm/uvm_extern.h> |
48 | | | 48 | |
49 | #include <prop/proplib.h> | | 49 | #include <prop/proplib.h> |
50 | | | 50 | |
51 | #include <powerpc/ibm4xx/cpu.h> | | 51 | #include <powerpc/ibm4xx/cpu.h> |
52 | #include <powerpc/ibm4xx/dev/plbvar.h> | | 52 | #include <powerpc/ibm4xx/dev/plbvar.h> |
53 | | | 53 | |
54 | struct cputab { | | 54 | struct cputab { |
55 | u_int version; | | 55 | u_int version; |
56 | u_int mask; | | 56 | u_int mask; |
57 | const char *name; | | 57 | const char *name; |
58 | struct cache_info ci; | | 58 | struct cache_info ci; |
59 | }; | | 59 | }; |
60 | | | 60 | |
61 | static const struct cputab models[] = { | | 61 | static const struct cputab models[] = { |
62 | { | | 62 | { |
63 | .version = PVR_401A1, | | 63 | .version = PVR_401A1, |
64 | .mask = 0xffff0000, | | 64 | .mask = 0xffff0000, |
65 | .name = "401A1", | | 65 | .name = "401A1", |
66 | .ci = { | | 66 | .ci = { |
67 | .dcache_size = 1024, | | 67 | .dcache_size = 1024, |
68 | .dcache_line_size = 16, | | 68 | .dcache_line_size = 16, |
69 | .icache_size = 2848, | | 69 | .icache_size = 2848, |
70 | .icache_line_size = 16, | | 70 | .icache_line_size = 16, |
71 | } | | 71 | } |
72 | }, { | | 72 | }, { |
73 | .version = PVR_401B2, | | 73 | .version = PVR_401B2, |
74 | .mask = 0xffff0000, | | 74 | .mask = 0xffff0000, |
75 | .name = "401B21", | | 75 | .name = "401B21", |
76 | .ci = { | | 76 | .ci = { |
77 | .dcache_size = 8192, | | 77 | .dcache_size = 8192, |
78 | .dcache_line_size = 16, | | 78 | .dcache_line_size = 16, |
79 | .icache_size = 16384, | | 79 | .icache_size = 16384, |
80 | .icache_line_size = 16, | | 80 | .icache_line_size = 16, |
81 | } | | 81 | } |
82 | }, { | | 82 | }, { |
83 | .version = PVR_401C2, | | 83 | .version = PVR_401C2, |
84 | .mask = 0xffff0000, | | 84 | .mask = 0xffff0000, |
85 | .name = "401C2", | | 85 | .name = "401C2", |
86 | .ci = { | | 86 | .ci = { |
87 | .dcache_size = 8192, | | 87 | .dcache_size = 8192, |
88 | .dcache_line_size = 16, | | 88 | .dcache_line_size = 16, |
89 | .icache_size = 0, | | 89 | .icache_size = 0, |
90 | .icache_line_size = 16, | | 90 | .icache_line_size = 16, |
91 | } | | 91 | } |
92 | }, { | | 92 | }, { |
93 | .version = PVR_401D2, | | 93 | .version = PVR_401D2, |
94 | .mask = 0xffff0000, | | 94 | .mask = 0xffff0000, |
95 | .name = "401D2", | | 95 | .name = "401D2", |
96 | .ci = { | | 96 | .ci = { |
97 | .dcache_size = 2848, | | 97 | .dcache_size = 2848, |
98 | .dcache_line_size = 16, | | 98 | .dcache_line_size = 16, |
99 | .icache_size = 4096, | | 99 | .icache_size = 4096, |
100 | .icache_line_size = 16, | | 100 | .icache_line_size = 16, |
101 | } | | 101 | } |
102 | }, { | | 102 | }, { |
103 | .version = PVR_401E2, | | 103 | .version = PVR_401E2, |
104 | .mask = 0xffff0000, | | 104 | .mask = 0xffff0000, |
105 | .name = "401E2", | | 105 | .name = "401E2", |
106 | .ci = { | | 106 | .ci = { |
107 | .dcache_size = 0, | | 107 | .dcache_size = 0, |
108 | .dcache_line_size = 16, | | 108 | .dcache_line_size = 16, |
109 | .icache_size = 0, | | 109 | .icache_size = 0, |
110 | .icache_line_size = 16, | | 110 | .icache_line_size = 16, |
111 | } | | 111 | } |
112 | }, { | | 112 | }, { |
113 | .version = PVR_401F2, | | 113 | .version = PVR_401F2, |
114 | .mask = 0xffff0000, | | 114 | .mask = 0xffff0000, |
115 | .name = "401F2", | | 115 | .name = "401F2", |
116 | .ci = { | | 116 | .ci = { |
117 | .dcache_size = 2048, | | 117 | .dcache_size = 2048, |
118 | .dcache_line_size = 16, | | 118 | .dcache_line_size = 16, |
119 | .icache_size = 2848, | | 119 | .icache_size = 2848, |
120 | .icache_line_size = 16, | | 120 | .icache_line_size = 16, |
121 | } | | 121 | } |
122 | }, { | | 122 | }, { |
123 | .version = PVR_401G2, | | 123 | .version = PVR_401G2, |
124 | .mask = 0xffff0000, | | 124 | .mask = 0xffff0000, |
125 | .name = "401G2", | | 125 | .name = "401G2", |
126 | .ci = { | | 126 | .ci = { |
127 | .dcache_size = 2848, | | 127 | .dcache_size = 2848, |
128 | .dcache_line_size = 16, | | 128 | .dcache_line_size = 16, |
129 | .icache_size = 8192, | | 129 | .icache_size = 8192, |
130 | .icache_line_size = 16, | | 130 | .icache_line_size = 16, |
131 | } | | 131 | } |
132 | }, { | | 132 | }, { |
133 | .version = PVR_403GA, /* XXX no MMU */ | | 133 | .version = PVR_403GA, /* XXX no MMU */ |
134 | .mask = 0xffffff00, | | 134 | .mask = 0xffffff00, |
135 | .name = "403GA", | | 135 | .name = "403GA", |
136 | .ci = { | | 136 | .ci = { |
137 | .dcache_size = 1024, | | 137 | .dcache_size = 1024, |
138 | .dcache_line_size = 16, | | 138 | .dcache_line_size = 16, |
139 | .icache_size = 2048, | | 139 | .icache_size = 2048, |
140 | .icache_line_size = 16, | | 140 | .icache_line_size = 16, |
141 | } | | 141 | } |
142 | }, { | | 142 | }, { |
143 | .version = PVR_403GB, /* XXX no MMU */ | | 143 | .version = PVR_403GB, /* XXX no MMU */ |
144 | .mask = 0xffffff00, | | 144 | .mask = 0xffffff00, |
145 | .name = "403GB", | | 145 | .name = "403GB", |
146 | .ci = { | | 146 | .ci = { |
147 | .dcache_size = 1024, | | 147 | .dcache_size = 1024, |
148 | .dcache_line_size = 16, | | 148 | .dcache_line_size = 16, |
149 | .icache_size = 2048, | | 149 | .icache_size = 2048, |
150 | .icache_line_size = 16, | | 150 | .icache_line_size = 16, |
151 | } | | 151 | } |
152 | }, { | | 152 | }, { |
153 | .version = PVR_403GC, | | 153 | .version = PVR_403GC, |
154 | .mask = 0xffffff00, | | 154 | .mask = 0xffffff00, |
155 | .name = "403GC", | | 155 | .name = "403GC", |
156 | .ci = { | | 156 | .ci = { |
157 | .dcache_size = 1024, | | 157 | .dcache_size = 1024, |
158 | .dcache_line_size = 16, | | 158 | .dcache_line_size = 16, |
159 | .icache_size = 2048, | | 159 | .icache_size = 2048, |
160 | .icache_line_size = 16, | | 160 | .icache_line_size = 16, |
161 | } | | 161 | } |
162 | }, { | | 162 | }, { |
163 | .version = PVR_403GCX, | | 163 | .version = PVR_403GCX, |
164 | .mask = 0xffffff00, | | 164 | .mask = 0xffffff00, |
165 | .name = "403GCX", | | 165 | .name = "403GCX", |
166 | .ci = { | | 166 | .ci = { |
167 | .dcache_size = 8192, | | 167 | .dcache_size = 8192, |
168 | .dcache_line_size = 16, | | 168 | .dcache_line_size = 16, |
169 | .icache_size = 16384, | | 169 | .icache_size = 16384, |
170 | .icache_line_size = 16, | | 170 | .icache_line_size = 16, |
171 | } | | 171 | } |
172 | }, { | | 172 | }, { |
173 | .version = PVR_405GP, | | 173 | .version = PVR_405GP, |
174 | .mask = 0xffff0000, | | 174 | .mask = 0xffff0000, |
175 | .name = "405GP", | | 175 | .name = "405GP", |
176 | .ci = { | | 176 | .ci = { |
177 | .dcache_size = 8192, | | 177 | .dcache_size = 8192, |
178 | .dcache_line_size = 32, | | 178 | .dcache_line_size = 32, |
179 | .icache_size = 8192, | | 179 | .icache_size = 16384, |
180 | .icache_line_size = 32, | | 180 | .icache_line_size = 32, |
181 | } | | 181 | } |
182 | }, { | | 182 | }, { |
183 | .version = PVR_405GPR, | | 183 | .version = PVR_405GPR, |
184 | .mask = 0xffff0000, | | 184 | .mask = 0xffff0000, |
185 | .name = "405GPr", | | 185 | .name = "405GPr", |
186 | .ci = { | | 186 | .ci = { |
187 | .dcache_size = 16384, | | 187 | .dcache_size = 16384, |
188 | .dcache_line_size = 32, | | 188 | .dcache_line_size = 32, |
189 | .icache_size = 16384, | | 189 | .icache_size = 16384, |
190 | .icache_line_size = 32, | | 190 | .icache_line_size = 32, |
191 | } | | 191 | } |
192 | }, { | | 192 | }, { |
193 | .version = PVR_405D5X1, | | 193 | .version = PVR_405D5X1, |
194 | .mask = 0xfffff000, | | 194 | .mask = 0xfffff000, |
195 | .name = "Xilinx Virtex II Pro", | | 195 | .name = "Xilinx Virtex II Pro", |
196 | .ci = { | | 196 | .ci = { |
197 | .dcache_size = 16384, | | 197 | .dcache_size = 16384, |
198 | .dcache_line_size = 32, | | 198 | .dcache_line_size = 32, |
199 | .icache_size = 16384, | | 199 | .icache_size = 16384, |
200 | .icache_line_size = 32, | | 200 | .icache_line_size = 32, |
201 | } | | 201 | } |
202 | }, { | | 202 | }, { |
203 | .version = PVR_405D5X2, | | 203 | .version = PVR_405D5X2, |
204 | .mask = 0xfffff000, | | 204 | .mask = 0xfffff000, |
205 | .name = "Xilinx Virtex 4 FX", | | 205 | .name = "Xilinx Virtex 4 FX", |
206 | .ci = { | | 206 | .ci = { |
207 | .dcache_size = 16384, | | 207 | .dcache_size = 16384, |
208 | .dcache_line_size = 32, | | 208 | .dcache_line_size = 32, |
209 | .icache_size = 16384, | | 209 | .icache_size = 16384, |
210 | .icache_line_size = 32, | | 210 | .icache_line_size = 32, |
211 | } | | 211 | } |
212 | }, { | | 212 | }, { |
213 | .version = PVR_405EX, | | 213 | .version = PVR_405EX, |
214 | .mask = 0xffff0000, | | 214 | .mask = 0xffff0000, |
215 | .name = "405EX", | | 215 | .name = "405EX", |
216 | .ci = { | | 216 | .ci = { |
217 | .dcache_size = 16384, | | 217 | .dcache_size = 16384, |
218 | .dcache_line_size = 32, | | 218 | .dcache_line_size = 32, |
219 | .icache_size = 16384, | | 219 | .icache_size = 16384, |
220 | .icache_line_size = 32, | | 220 | .icache_line_size = 32, |
221 | } | | 221 | } |
222 | }, { | | 222 | }, { |
223 | .version = 0, | | 223 | .version = 0, |
224 | .mask = 0, | | 224 | .mask = 0, |
225 | .name = NULL, | | 225 | .name = NULL, |
226 | .ci = { | | 226 | .ci = { |
227 | /* | | 227 | /* |
228 | * Unknown CPU type. For safety we'll specify a | | 228 | * Unknown CPU type. For safety we'll specify a |
229 | * cache with a 4-byte line size. That way cache | | 229 | * cache with a 4-byte line size. That way cache |
230 | * flush routines won't miss any lines. | | 230 | * flush routines won't miss any lines. |
231 | */ | | 231 | */ |
232 | .dcache_line_size = 4, | | 232 | .dcache_line_size = 4, |
233 | .icache_line_size = 4, | | 233 | .icache_line_size = 4, |
234 | }, | | 234 | }, |
235 | }, | | 235 | }, |
236 | }; | | 236 | }; |
237 | | | 237 | |
238 | static int cpumatch(device_t, cfdata_t, void *); | | 238 | static int cpumatch(device_t, cfdata_t, void *); |
239 | static void cpuattach(device_t, device_t, void *); | | 239 | static void cpuattach(device_t, device_t, void *); |
240 | | | 240 | |
241 | CFATTACH_DECL_NEW(cpu, 0, cpumatch, cpuattach, NULL, NULL); | | 241 | CFATTACH_DECL_NEW(cpu, 0, cpumatch, cpuattach, NULL, NULL); |
242 | | | 242 | |
243 | int ncpus; | | 243 | int ncpus; |
244 | | | 244 | |
245 | struct cpu_info cpu_info[1] = { | | 245 | struct cpu_info cpu_info[1] = { |
246 | { | | 246 | { |
247 | /* XXX add more ci_ev_* as we teach 4xx about them */ | | 247 | /* XXX add more ci_ev_* as we teach 4xx about them */ |
248 | .ci_ev_clock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR, | | 248 | .ci_ev_clock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR, |
249 | NULL, "cpu0", "clock"), | | 249 | NULL, "cpu0", "clock"), |
250 | .ci_ev_statclock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR, | | 250 | .ci_ev_statclock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR, |
251 | NULL, "cpu0", "stat clock"), | | 251 | NULL, "cpu0", "stat clock"), |
252 | .ci_curlwp = &lwp0, | | 252 | .ci_curlwp = &lwp0, |
253 | } | | 253 | } |
254 | }; | | 254 | }; |
255 | | | 255 | |
256 | bool cpufound; | | 256 | bool cpufound; |
257 | | | 257 | |
258 | static int | | 258 | static int |
259 | cpumatch(device_t parent, cfdata_t cf, void *aux) | | 259 | cpumatch(device_t parent, cfdata_t cf, void *aux) |
260 | { | | 260 | { |
261 | struct plb_attach_args *paa = aux; | | 261 | struct plb_attach_args *paa = aux; |
262 | | | 262 | |
263 | /* make sure that we're looking for a CPU */ | | 263 | /* make sure that we're looking for a CPU */ |
264 | if (strcmp(paa->plb_name, cf->cf_name) != 0) | | 264 | if (strcmp(paa->plb_name, cf->cf_name) != 0) |
265 | return (0); | | 265 | return (0); |
266 | | | 266 | |
267 | return !cpufound; | | 267 | return !cpufound; |
268 | } | | 268 | } |
269 | | | 269 | |
270 | static void | | 270 | static void |
271 | cpuattach(device_t parent, device_t self, void *aux) | | 271 | cpuattach(device_t parent, device_t self, void *aux) |
272 | { | | 272 | { |
273 | struct cpu_info * const ci = curcpu(); | | 273 | struct cpu_info * const ci = curcpu(); |
274 | const struct cputab *cp; | | 274 | const struct cputab *cp; |
275 | u_int processor_freq; | | 275 | u_int processor_freq; |
276 | prop_number_t freq; | | 276 | prop_number_t freq; |
277 | | | 277 | |
278 | freq = prop_dictionary_get(board_properties, "processor-frequency"); | | 278 | freq = prop_dictionary_get(board_properties, "processor-frequency"); |
279 | KASSERT(freq != NULL); | | 279 | KASSERT(freq != NULL); |
280 | processor_freq = (unsigned int) prop_number_integer_value(freq); | | 280 | processor_freq = (unsigned int) prop_number_integer_value(freq); |
281 | | | 281 | |
282 | cpufound = true; | | 282 | cpufound = true; |
283 | ncpus++; | | 283 | ncpus++; |
284 | | | 284 | |
285 | const u_int pvr = mfpvr(); | | 285 | const u_int pvr = mfpvr(); |
286 | for (cp = models; cp->name != NULL; cp++) { | | 286 | for (cp = models; cp->name != NULL; cp++) { |
287 | if ((pvr & cp->mask) == cp->version) { | | 287 | if ((pvr & cp->mask) == cp->version) { |
288 | cpu_setmodel("%s", cp->name); | | 288 | cpu_setmodel("%s", cp->name); |
289 | break; | | 289 | break; |
290 | } | | 290 | } |
291 | } | | 291 | } |
292 | if (__predict_false(cp->name == NULL)) | | 292 | if (__predict_false(cp->name == NULL)) |
293 | cpu_setmodel("Version 0x%x", pvr); | | 293 | cpu_setmodel("Version 0x%x", pvr); |
294 | | | 294 | |
295 | aprint_normal(": %uMHz %s (PVR 0x%08x)\n", | | 295 | aprint_normal(": %uMHz %s (PVR 0x%08x)\n", |
296 | (processor_freq + 500000) / 1000000, | | 296 | (processor_freq + 500000) / 1000000, |
297 | (cp->name != NULL ? cpu_getmodel() : "unknown model"), | | 297 | (cp->name != NULL ? cpu_getmodel() : "unknown model"), |
298 | pvr); | | 298 | pvr); |
299 | | | 299 | |
300 | cpu_probe_cache(); | | 300 | cpu_probe_cache(); |
301 | | | 301 | |
302 | /* We would crash later on anyway so just make the reason obvious */ | | 302 | /* We would crash later on anyway so just make the reason obvious */ |
303 | if (ci->ci_ci.icache_size == 0 && ci->ci_ci.dcache_size == 0) | | 303 | if (ci->ci_ci.icache_size == 0 && ci->ci_ci.dcache_size == 0) |
304 | panic("%s: %s: could not detect cache size", | | 304 | panic("%s: %s: could not detect cache size", |
305 | __func__, device_xname(self)); | | 305 | __func__, device_xname(self)); |
306 | | | 306 | |
307 | aprint_normal_dev(self, "%uKB/%uB L1 instruction cache\n", | | 307 | aprint_normal_dev(self, "%uKB/%uB L1 instruction cache\n", |
308 | ci->ci_ci.icache_size / 1024, ci->ci_ci.icache_line_size); | | 308 | ci->ci_ci.icache_size / 1024, ci->ci_ci.icache_line_size); |
309 | aprint_normal_dev(self, "%uKB/%uB L1 data cache\n", | | 309 | aprint_normal_dev(self, "%uKB/%uB L1 data cache\n", |
310 | ci->ci_ci.dcache_size / 1024, ci->ci_ci.dcache_line_size); | | 310 | ci->ci_ci.dcache_size / 1024, ci->ci_ci.dcache_line_size); |
311 | } | | 311 | } |
312 | | | 312 | |
313 | /* | | 313 | /* |
314 | * This routine must be explicitly called to initialize the | | 314 | * This routine must be explicitly called to initialize the |
315 | * CPU cache information so cache flushe and memcpy operation | | 315 | * CPU cache information so cache flushe and memcpy operation |
316 | * work. | | 316 | * work. |
317 | */ | | 317 | */ |
318 | void | | 318 | void |
319 | cpu_probe_cache(void) | | 319 | cpu_probe_cache(void) |
320 | { | | 320 | { |
321 | struct cpu_info * const ci = curcpu(); | | 321 | struct cpu_info * const ci = curcpu(); |
322 | const struct cputab *cp = models; | | 322 | const struct cputab *cp = models; |
323 | | | 323 | |
324 | const u_int pvr = mfpvr(); | | 324 | const u_int pvr = mfpvr(); |
325 | for (cp = models; cp->name != NULL; cp++) { | | 325 | for (cp = models; cp->name != NULL; cp++) { |
326 | if ((pvr & cp->mask) == cp->version) | | 326 | if ((pvr & cp->mask) == cp->version) |
327 | break; | | 327 | break; |
328 | } | | 328 | } |
329 | | | 329 | |
330 | /* | | 330 | /* |
331 | * Copy the cache from the cputab into cpu_info. | | 331 | * Copy the cache from the cputab into cpu_info. |
332 | */ | | 332 | */ |
333 | ci->ci_ci = cp->ci; | | 333 | ci->ci_ci = cp->ci; |
334 | } | | 334 | } |
335 | | | 335 | |
336 | /* | | 336 | /* |
337 | * These small routines may have to be replaced, | | 337 | * These small routines may have to be replaced, |
338 | * if/when we support processors other that the 604. | | 338 | * if/when we support processors other that the 604. |
339 | */ | | 339 | */ |
340 | | | 340 | |
341 | void | | 341 | void |
342 | dcache_wbinv_page(vaddr_t va) | | 342 | dcache_wbinv_page(vaddr_t va) |
343 | { | | 343 | { |
344 | const size_t dcache_line_size = curcpu()->ci_ci.dcache_line_size; | | 344 | const size_t dcache_line_size = curcpu()->ci_ci.dcache_line_size; |
345 | | | 345 | |
346 | if (dcache_line_size) { | | 346 | if (dcache_line_size) { |
347 | for (size_t i = 0; i < PAGE_SIZE; i += dcache_line_size) { | | 347 | for (size_t i = 0; i < PAGE_SIZE; i += dcache_line_size) { |
348 | __asm volatile("dcbf %0,%1" : : "b" (va), "r" (i)); | | 348 | __asm volatile("dcbf %0,%1" : : "b" (va), "r" (i)); |
349 | } | | 349 | } |
350 | __asm volatile("sync; isync" : : ); | | 350 | __asm volatile("sync; isync" : : ); |
351 | } | | 351 | } |
352 | } | | 352 | } |