diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/kernel/cps-vec.S | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/kernel/cps-vec.S')
-rw-r--r-- | arch/mips/kernel/cps-vec.S | 630 |
1 files changed, 630 insertions, 0 deletions
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S new file mode 100644 index 000000000..4db7ff055 --- /dev/null +++ b/arch/mips/kernel/cps-vec.S | |||
@@ -0,0 +1,630 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
2 | /* | ||
3 | * Copyright (C) 2013 Imagination Technologies | ||
4 | * Author: Paul Burton <paul.burton@mips.com> | ||
5 | */ | ||
6 | |||
7 | #include <asm/addrspace.h> | ||
8 | #include <asm/asm.h> | ||
9 | #include <asm/asm-offsets.h> | ||
10 | #include <asm/asmmacro.h> | ||
11 | #include <asm/cacheops.h> | ||
12 | #include <asm/eva.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/mipsmtregs.h> | ||
15 | #include <asm/pm.h> | ||
16 | |||
17 | #define GCR_CPC_BASE_OFS 0x0088 | ||
18 | #define GCR_CL_COHERENCE_OFS 0x2008 | ||
19 | #define GCR_CL_ID_OFS 0x2028 | ||
20 | |||
21 | #define CPC_CL_VC_STOP_OFS 0x2020 | ||
22 | #define CPC_CL_VC_RUN_OFS 0x2028 | ||
23 | |||
24 | .extern mips_cm_base | ||
25 | |||
26 | .set noreorder | ||
27 | |||
28 | #ifdef CONFIG_64BIT | ||
29 | # define STATUS_BITDEPS ST0_KX | ||
30 | #else | ||
31 | # define STATUS_BITDEPS 0 | ||
32 | #endif | ||
33 | |||
34 | #ifdef CONFIG_MIPS_CPS_NS16550 | ||
35 | |||
36 | #define DUMP_EXCEP(name) \ | ||
37 | PTR_LA a0, 8f; \ | ||
38 | jal mips_cps_bev_dump; \ | ||
39 | nop; \ | ||
40 | TEXT(name) | ||
41 | |||
42 | #else /* !CONFIG_MIPS_CPS_NS16550 */ | ||
43 | |||
44 | #define DUMP_EXCEP(name) | ||
45 | |||
46 | #endif /* !CONFIG_MIPS_CPS_NS16550 */ | ||
47 | |||
48 | /* | ||
49 | * Set dest to non-zero if the core supports the MT ASE, else zero. If | ||
50 | * MT is not supported then branch to nomt. | ||
51 | */ | ||
52 | .macro has_mt dest, nomt | ||
53 | mfc0 \dest, CP0_CONFIG, 1 | ||
54 | bgez \dest, \nomt | ||
55 | mfc0 \dest, CP0_CONFIG, 2 | ||
56 | bgez \dest, \nomt | ||
57 | mfc0 \dest, CP0_CONFIG, 3 | ||
58 | andi \dest, \dest, MIPS_CONF3_MT | ||
59 | beqz \dest, \nomt | ||
60 | nop | ||
61 | .endm | ||
62 | |||
63 | /* | ||
64 | * Set dest to non-zero if the core supports MIPSr6 multithreading | ||
65 | * (ie. VPs), else zero. If MIPSr6 multithreading is not supported then | ||
66 | * branch to nomt. | ||
67 | */ | ||
68 | .macro has_vp dest, nomt | ||
69 | mfc0 \dest, CP0_CONFIG, 1 | ||
70 | bgez \dest, \nomt | ||
71 | mfc0 \dest, CP0_CONFIG, 2 | ||
72 | bgez \dest, \nomt | ||
73 | mfc0 \dest, CP0_CONFIG, 3 | ||
74 | bgez \dest, \nomt | ||
75 | mfc0 \dest, CP0_CONFIG, 4 | ||
76 | bgez \dest, \nomt | ||
77 | mfc0 \dest, CP0_CONFIG, 5 | ||
78 | andi \dest, \dest, MIPS_CONF5_VP | ||
79 | beqz \dest, \nomt | ||
80 | nop | ||
81 | .endm | ||
82 | |||
83 | /* Calculate an uncached address for the CM GCRs */ | ||
84 | .macro cmgcrb dest | ||
85 | .set push | ||
86 | .set noat | ||
87 | MFC0 $1, CP0_CMGCRBASE | ||
88 | PTR_SLL $1, $1, 4 | ||
89 | PTR_LI \dest, UNCAC_BASE | ||
90 | PTR_ADDU \dest, \dest, $1 | ||
91 | .set pop | ||
92 | .endm | ||
93 | |||
94 | .section .text.cps-vec | ||
95 | .balign 0x1000 | ||
96 | |||
97 | LEAF(mips_cps_core_entry) | ||
98 | /* | ||
99 | * These first 4 bytes will be patched by cps_smp_setup to load the | ||
100 | * CCA to use into register s0. | ||
101 | */ | ||
102 | .word 0 | ||
103 | |||
104 | /* Check whether we're here due to an NMI */ | ||
105 | mfc0 k0, CP0_STATUS | ||
106 | and k0, k0, ST0_NMI | ||
107 | beqz k0, not_nmi | ||
108 | nop | ||
109 | |||
110 | /* This is an NMI */ | ||
111 | PTR_LA k0, nmi_handler | ||
112 | jr k0 | ||
113 | nop | ||
114 | |||
115 | not_nmi: | ||
116 | /* Setup Cause */ | ||
117 | li t0, CAUSEF_IV | ||
118 | mtc0 t0, CP0_CAUSE | ||
119 | |||
120 | /* Setup Status */ | ||
121 | li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS | ||
122 | mtc0 t0, CP0_STATUS | ||
123 | |||
124 | /* Skip cache & coherence setup if we're already coherent */ | ||
125 | cmgcrb v1 | ||
126 | lw s7, GCR_CL_COHERENCE_OFS(v1) | ||
127 | bnez s7, 1f | ||
128 | nop | ||
129 | |||
130 | /* Initialize the L1 caches */ | ||
131 | jal mips_cps_cache_init | ||
132 | nop | ||
133 | |||
134 | /* Enter the coherent domain */ | ||
135 | li t0, 0xff | ||
136 | sw t0, GCR_CL_COHERENCE_OFS(v1) | ||
137 | ehb | ||
138 | |||
139 | /* Set Kseg0 CCA to that in s0 */ | ||
140 | 1: mfc0 t0, CP0_CONFIG | ||
141 | ori t0, 0x7 | ||
142 | xori t0, 0x7 | ||
143 | or t0, t0, s0 | ||
144 | mtc0 t0, CP0_CONFIG | ||
145 | ehb | ||
146 | |||
147 | /* Jump to kseg0 */ | ||
148 | PTR_LA t0, 1f | ||
149 | jr t0 | ||
150 | nop | ||
151 | |||
152 | /* | ||
153 | * We're up, cached & coherent. Perform any EVA initialization necessary | ||
154 | * before we access memory. | ||
155 | */ | ||
156 | 1: eva_init | ||
157 | |||
158 | /* Retrieve boot configuration pointers */ | ||
159 | jal mips_cps_get_bootcfg | ||
160 | nop | ||
161 | |||
162 | /* Skip core-level init if we started up coherent */ | ||
163 | bnez s7, 1f | ||
164 | nop | ||
165 | |||
166 | /* Perform any further required core-level initialisation */ | ||
167 | jal mips_cps_core_init | ||
168 | nop | ||
169 | |||
170 | /* | ||
171 | * Boot any other VPEs within this core that should be online, and | ||
172 | * deactivate this VPE if it should be offline. | ||
173 | */ | ||
174 | move a1, t9 | ||
175 | jal mips_cps_boot_vpes | ||
176 | move a0, v0 | ||
177 | |||
178 | /* Off we go! */ | ||
179 | 1: PTR_L t1, VPEBOOTCFG_PC(v1) | ||
180 | PTR_L gp, VPEBOOTCFG_GP(v1) | ||
181 | PTR_L sp, VPEBOOTCFG_SP(v1) | ||
182 | jr t1 | ||
183 | nop | ||
184 | END(mips_cps_core_entry) | ||
185 | |||
186 | .org 0x200 | ||
187 | LEAF(excep_tlbfill) | ||
188 | DUMP_EXCEP("TLB Fill") | ||
189 | b . | ||
190 | nop | ||
191 | END(excep_tlbfill) | ||
192 | |||
193 | .org 0x280 | ||
194 | LEAF(excep_xtlbfill) | ||
195 | DUMP_EXCEP("XTLB Fill") | ||
196 | b . | ||
197 | nop | ||
198 | END(excep_xtlbfill) | ||
199 | |||
200 | .org 0x300 | ||
201 | LEAF(excep_cache) | ||
202 | DUMP_EXCEP("Cache") | ||
203 | b . | ||
204 | nop | ||
205 | END(excep_cache) | ||
206 | |||
207 | .org 0x380 | ||
208 | LEAF(excep_genex) | ||
209 | DUMP_EXCEP("General") | ||
210 | b . | ||
211 | nop | ||
212 | END(excep_genex) | ||
213 | |||
214 | .org 0x400 | ||
215 | LEAF(excep_intex) | ||
216 | DUMP_EXCEP("Interrupt") | ||
217 | b . | ||
218 | nop | ||
219 | END(excep_intex) | ||
220 | |||
221 | .org 0x480 | ||
222 | LEAF(excep_ejtag) | ||
223 | PTR_LA k0, ejtag_debug_handler | ||
224 | jr k0 | ||
225 | nop | ||
226 | END(excep_ejtag) | ||
227 | |||
228 | LEAF(mips_cps_core_init) | ||
229 | #ifdef CONFIG_MIPS_MT_SMP | ||
230 | /* Check that the core implements the MT ASE */ | ||
231 | has_mt t0, 3f | ||
232 | |||
233 | .set push | ||
234 | .set MIPS_ISA_LEVEL_RAW | ||
235 | .set mt | ||
236 | |||
237 | /* Only allow 1 TC per VPE to execute... */ | ||
238 | dmt | ||
239 | |||
240 | /* ...and for the moment only 1 VPE */ | ||
241 | dvpe | ||
242 | PTR_LA t1, 1f | ||
243 | jr.hb t1 | ||
244 | nop | ||
245 | |||
246 | /* Enter VPE configuration state */ | ||
247 | 1: mfc0 t0, CP0_MVPCONTROL | ||
248 | ori t0, t0, MVPCONTROL_VPC | ||
249 | mtc0 t0, CP0_MVPCONTROL | ||
250 | |||
251 | /* Retrieve the number of VPEs within the core */ | ||
252 | mfc0 t0, CP0_MVPCONF0 | ||
253 | srl t0, t0, MVPCONF0_PVPE_SHIFT | ||
254 | andi t0, t0, (MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT) | ||
255 | addiu ta3, t0, 1 | ||
256 | |||
257 | /* If there's only 1, we're done */ | ||
258 | beqz t0, 2f | ||
259 | nop | ||
260 | |||
261 | /* Loop through each VPE within this core */ | ||
262 | li ta1, 1 | ||
263 | |||
264 | 1: /* Operate on the appropriate TC */ | ||
265 | mtc0 ta1, CP0_VPECONTROL | ||
266 | ehb | ||
267 | |||
268 | /* Bind TC to VPE (1:1 TC:VPE mapping) */ | ||
269 | mttc0 ta1, CP0_TCBIND | ||
270 | |||
271 | /* Set exclusive TC, non-active, master */ | ||
272 | li t0, VPECONF0_MVP | ||
273 | sll t1, ta1, VPECONF0_XTC_SHIFT | ||
274 | or t0, t0, t1 | ||
275 | mttc0 t0, CP0_VPECONF0 | ||
276 | |||
277 | /* Set TC non-active, non-allocatable */ | ||
278 | mttc0 zero, CP0_TCSTATUS | ||
279 | |||
280 | /* Set TC halted */ | ||
281 | li t0, TCHALT_H | ||
282 | mttc0 t0, CP0_TCHALT | ||
283 | |||
284 | /* Next VPE */ | ||
285 | addiu ta1, ta1, 1 | ||
286 | slt t0, ta1, ta3 | ||
287 | bnez t0, 1b | ||
288 | nop | ||
289 | |||
290 | /* Leave VPE configuration state */ | ||
291 | 2: mfc0 t0, CP0_MVPCONTROL | ||
292 | xori t0, t0, MVPCONTROL_VPC | ||
293 | mtc0 t0, CP0_MVPCONTROL | ||
294 | |||
295 | 3: .set pop | ||
296 | #endif | ||
297 | jr ra | ||
298 | nop | ||
299 | END(mips_cps_core_init) | ||
300 | |||
301 | /** | ||
302 | * mips_cps_get_bootcfg() - retrieve boot configuration pointers | ||
303 | * | ||
304 | * Returns: pointer to struct core_boot_config in v0, pointer to | ||
305 | * struct vpe_boot_config in v1, VPE ID in t9 | ||
306 | */ | ||
307 | LEAF(mips_cps_get_bootcfg) | ||
308 | /* Calculate a pointer to this cores struct core_boot_config */ | ||
309 | cmgcrb t0 | ||
310 | lw t0, GCR_CL_ID_OFS(t0) | ||
311 | li t1, COREBOOTCFG_SIZE | ||
312 | mul t0, t0, t1 | ||
313 | PTR_LA t1, mips_cps_core_bootcfg | ||
314 | PTR_L t1, 0(t1) | ||
315 | PTR_ADDU v0, t0, t1 | ||
316 | |||
317 | /* Calculate this VPEs ID. If the core doesn't support MT use 0 */ | ||
318 | li t9, 0 | ||
319 | #if defined(CONFIG_CPU_MIPSR6) | ||
320 | has_vp ta2, 1f | ||
321 | |||
322 | /* | ||
323 | * Assume non-contiguous numbering. Perhaps some day we'll need | ||
324 | * to handle contiguous VP numbering, but no such systems yet | ||
325 | * exist. | ||
326 | */ | ||
327 | mfc0 t9, CP0_GLOBALNUMBER | ||
328 | andi t9, t9, MIPS_GLOBALNUMBER_VP | ||
329 | #elif defined(CONFIG_MIPS_MT_SMP) | ||
330 | has_mt ta2, 1f | ||
331 | |||
332 | /* Find the number of VPEs present in the core */ | ||
333 | mfc0 t1, CP0_MVPCONF0 | ||
334 | srl t1, t1, MVPCONF0_PVPE_SHIFT | ||
335 | andi t1, t1, MVPCONF0_PVPE >> MVPCONF0_PVPE_SHIFT | ||
336 | addiu t1, t1, 1 | ||
337 | |||
338 | /* Calculate a mask for the VPE ID from EBase.CPUNum */ | ||
339 | clz t1, t1 | ||
340 | li t2, 31 | ||
341 | subu t1, t2, t1 | ||
342 | li t2, 1 | ||
343 | sll t1, t2, t1 | ||
344 | addiu t1, t1, -1 | ||
345 | |||
346 | /* Retrieve the VPE ID from EBase.CPUNum */ | ||
347 | mfc0 t9, $15, 1 | ||
348 | and t9, t9, t1 | ||
349 | #endif | ||
350 | |||
351 | 1: /* Calculate a pointer to this VPEs struct vpe_boot_config */ | ||
352 | li t1, VPEBOOTCFG_SIZE | ||
353 | mul v1, t9, t1 | ||
354 | PTR_L ta3, COREBOOTCFG_VPECONFIG(v0) | ||
355 | PTR_ADDU v1, v1, ta3 | ||
356 | |||
357 | jr ra | ||
358 | nop | ||
359 | END(mips_cps_get_bootcfg) | ||
360 | |||
361 | LEAF(mips_cps_boot_vpes) | ||
362 | lw ta2, COREBOOTCFG_VPEMASK(a0) | ||
363 | PTR_L ta3, COREBOOTCFG_VPECONFIG(a0) | ||
364 | |||
365 | #if defined(CONFIG_CPU_MIPSR6) | ||
366 | |||
367 | has_vp t0, 5f | ||
368 | |||
369 | /* Find base address of CPC */ | ||
370 | cmgcrb t3 | ||
371 | PTR_L t1, GCR_CPC_BASE_OFS(t3) | ||
372 | PTR_LI t2, ~0x7fff | ||
373 | and t1, t1, t2 | ||
374 | PTR_LI t2, UNCAC_BASE | ||
375 | PTR_ADD t1, t1, t2 | ||
376 | |||
377 | /* Start any other VPs that ought to be running */ | ||
378 | PTR_S ta2, CPC_CL_VC_RUN_OFS(t1) | ||
379 | |||
380 | /* Ensure this VP stops running if it shouldn't be */ | ||
381 | not ta2 | ||
382 | PTR_S ta2, CPC_CL_VC_STOP_OFS(t1) | ||
383 | ehb | ||
384 | |||
385 | #elif defined(CONFIG_MIPS_MT) | ||
386 | |||
387 | /* If the core doesn't support MT then return */ | ||
388 | has_mt t0, 5f | ||
389 | |||
390 | /* Enter VPE configuration state */ | ||
391 | .set push | ||
392 | .set MIPS_ISA_LEVEL_RAW | ||
393 | .set mt | ||
394 | dvpe | ||
395 | .set pop | ||
396 | |||
397 | PTR_LA t1, 1f | ||
398 | jr.hb t1 | ||
399 | nop | ||
400 | 1: mfc0 t1, CP0_MVPCONTROL | ||
401 | ori t1, t1, MVPCONTROL_VPC | ||
402 | mtc0 t1, CP0_MVPCONTROL | ||
403 | ehb | ||
404 | |||
405 | /* Loop through each VPE */ | ||
406 | move t8, ta2 | ||
407 | li ta1, 0 | ||
408 | |||
409 | /* Check whether the VPE should be running. If not, skip it */ | ||
410 | 1: andi t0, ta2, 1 | ||
411 | beqz t0, 2f | ||
412 | nop | ||
413 | |||
414 | /* Operate on the appropriate TC */ | ||
415 | mfc0 t0, CP0_VPECONTROL | ||
416 | ori t0, t0, VPECONTROL_TARGTC | ||
417 | xori t0, t0, VPECONTROL_TARGTC | ||
418 | or t0, t0, ta1 | ||
419 | mtc0 t0, CP0_VPECONTROL | ||
420 | ehb | ||
421 | |||
422 | .set push | ||
423 | .set MIPS_ISA_LEVEL_RAW | ||
424 | .set mt | ||
425 | |||
426 | /* Skip the VPE if its TC is not halted */ | ||
427 | mftc0 t0, CP0_TCHALT | ||
428 | beqz t0, 2f | ||
429 | nop | ||
430 | |||
431 | /* Calculate a pointer to the VPEs struct vpe_boot_config */ | ||
432 | li t0, VPEBOOTCFG_SIZE | ||
433 | mul t0, t0, ta1 | ||
434 | addu t0, t0, ta3 | ||
435 | |||
436 | /* Set the TC restart PC */ | ||
437 | lw t1, VPEBOOTCFG_PC(t0) | ||
438 | mttc0 t1, CP0_TCRESTART | ||
439 | |||
440 | /* Set the TC stack pointer */ | ||
441 | lw t1, VPEBOOTCFG_SP(t0) | ||
442 | mttgpr t1, sp | ||
443 | |||
444 | /* Set the TC global pointer */ | ||
445 | lw t1, VPEBOOTCFG_GP(t0) | ||
446 | mttgpr t1, gp | ||
447 | |||
448 | /* Copy config from this VPE */ | ||
449 | mfc0 t0, CP0_CONFIG | ||
450 | mttc0 t0, CP0_CONFIG | ||
451 | |||
452 | /* | ||
453 | * Copy the EVA config from this VPE if the CPU supports it. | ||
454 | * CONFIG3 must exist to be running MT startup - just read it. | ||
455 | */ | ||
456 | mfc0 t0, CP0_CONFIG, 3 | ||
457 | and t0, t0, MIPS_CONF3_SC | ||
458 | beqz t0, 3f | ||
459 | nop | ||
460 | mfc0 t0, CP0_SEGCTL0 | ||
461 | mttc0 t0, CP0_SEGCTL0 | ||
462 | mfc0 t0, CP0_SEGCTL1 | ||
463 | mttc0 t0, CP0_SEGCTL1 | ||
464 | mfc0 t0, CP0_SEGCTL2 | ||
465 | mttc0 t0, CP0_SEGCTL2 | ||
466 | 3: | ||
467 | /* Ensure no software interrupts are pending */ | ||
468 | mttc0 zero, CP0_CAUSE | ||
469 | mttc0 zero, CP0_STATUS | ||
470 | |||
471 | /* Set TC active, not interrupt exempt */ | ||
472 | mftc0 t0, CP0_TCSTATUS | ||
473 | li t1, ~TCSTATUS_IXMT | ||
474 | and t0, t0, t1 | ||
475 | ori t0, t0, TCSTATUS_A | ||
476 | mttc0 t0, CP0_TCSTATUS | ||
477 | |||
478 | /* Clear the TC halt bit */ | ||
479 | mttc0 zero, CP0_TCHALT | ||
480 | |||
481 | /* Set VPE active */ | ||
482 | mftc0 t0, CP0_VPECONF0 | ||
483 | ori t0, t0, VPECONF0_VPA | ||
484 | mttc0 t0, CP0_VPECONF0 | ||
485 | |||
486 | /* Next VPE */ | ||
487 | 2: srl ta2, ta2, 1 | ||
488 | addiu ta1, ta1, 1 | ||
489 | bnez ta2, 1b | ||
490 | nop | ||
491 | |||
492 | /* Leave VPE configuration state */ | ||
493 | mfc0 t1, CP0_MVPCONTROL | ||
494 | xori t1, t1, MVPCONTROL_VPC | ||
495 | mtc0 t1, CP0_MVPCONTROL | ||
496 | ehb | ||
497 | evpe | ||
498 | |||
499 | .set pop | ||
500 | |||
501 | /* Check whether this VPE is meant to be running */ | ||
502 | li t0, 1 | ||
503 | sll t0, t0, a1 | ||
504 | and t0, t0, t8 | ||
505 | bnez t0, 2f | ||
506 | nop | ||
507 | |||
508 | /* This VPE should be offline, halt the TC */ | ||
509 | li t0, TCHALT_H | ||
510 | mtc0 t0, CP0_TCHALT | ||
511 | PTR_LA t0, 1f | ||
512 | 1: jr.hb t0 | ||
513 | nop | ||
514 | |||
515 | 2: | ||
516 | |||
517 | #endif /* CONFIG_MIPS_MT_SMP */ | ||
518 | |||
519 | /* Return */ | ||
520 | 5: jr ra | ||
521 | nop | ||
522 | END(mips_cps_boot_vpes) | ||
523 | |||
524 | LEAF(mips_cps_cache_init) | ||
525 | /* | ||
526 | * Clear the bits used to index the caches. Note that the architecture | ||
527 | * dictates that writing to any of TagLo or TagHi selects 0 or 2 should | ||
528 | * be valid for all MIPS32 CPUs, even those for which said writes are | ||
529 | * unnecessary. | ||
530 | */ | ||
531 | mtc0 zero, CP0_TAGLO, 0 | ||
532 | mtc0 zero, CP0_TAGHI, 0 | ||
533 | mtc0 zero, CP0_TAGLO, 2 | ||
534 | mtc0 zero, CP0_TAGHI, 2 | ||
535 | ehb | ||
536 | |||
537 | /* Primary cache configuration is indicated by Config1 */ | ||
538 | mfc0 v0, CP0_CONFIG, 1 | ||
539 | |||
540 | /* Detect I-cache line size */ | ||
541 | _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ | ||
542 | beqz t0, icache_done | ||
543 | li t1, 2 | ||
544 | sllv t0, t1, t0 | ||
545 | |||
546 | /* Detect I-cache size */ | ||
547 | _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ | ||
548 | xori t2, t1, 0x7 | ||
549 | beqz t2, 1f | ||
550 | li t3, 32 | ||
551 | addiu t1, t1, 1 | ||
552 | sllv t1, t3, t1 | ||
553 | 1: /* At this point t1 == I-cache sets per way */ | ||
554 | _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ | ||
555 | addiu t2, t2, 1 | ||
556 | mul t1, t1, t0 | ||
557 | mul t1, t1, t2 | ||
558 | |||
559 | li a0, CKSEG0 | ||
560 | PTR_ADD a1, a0, t1 | ||
561 | 1: cache Index_Store_Tag_I, 0(a0) | ||
562 | PTR_ADD a0, a0, t0 | ||
563 | bne a0, a1, 1b | ||
564 | nop | ||
565 | icache_done: | ||
566 | |||
567 | /* Detect D-cache line size */ | ||
568 | _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ | ||
569 | beqz t0, dcache_done | ||
570 | li t1, 2 | ||
571 | sllv t0, t1, t0 | ||
572 | |||
573 | /* Detect D-cache size */ | ||
574 | _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ | ||
575 | xori t2, t1, 0x7 | ||
576 | beqz t2, 1f | ||
577 | li t3, 32 | ||
578 | addiu t1, t1, 1 | ||
579 | sllv t1, t3, t1 | ||
580 | 1: /* At this point t1 == D-cache sets per way */ | ||
581 | _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ | ||
582 | addiu t2, t2, 1 | ||
583 | mul t1, t1, t0 | ||
584 | mul t1, t1, t2 | ||
585 | |||
586 | li a0, CKSEG0 | ||
587 | PTR_ADDU a1, a0, t1 | ||
588 | PTR_SUBU a1, a1, t0 | ||
589 | 1: cache Index_Store_Tag_D, 0(a0) | ||
590 | bne a0, a1, 1b | ||
591 | PTR_ADD a0, a0, t0 | ||
592 | dcache_done: | ||
593 | |||
594 | jr ra | ||
595 | nop | ||
596 | END(mips_cps_cache_init) | ||
597 | |||
598 | #if defined(CONFIG_MIPS_CPS_PM) && defined(CONFIG_CPU_PM) | ||
599 | |||
600 | /* Calculate a pointer to this CPUs struct mips_static_suspend_state */ | ||
601 | .macro psstate dest | ||
602 | .set push | ||
603 | .set noat | ||
604 | lw $1, TI_CPU(gp) | ||
605 | sll $1, $1, LONGLOG | ||
606 | PTR_LA \dest, __per_cpu_offset | ||
607 | addu $1, $1, \dest | ||
608 | lw $1, 0($1) | ||
609 | PTR_LA \dest, cps_cpu_state | ||
610 | addu \dest, \dest, $1 | ||
611 | .set pop | ||
612 | .endm | ||
613 | |||
614 | LEAF(mips_cps_pm_save) | ||
615 | /* Save CPU state */ | ||
616 | SUSPEND_SAVE_REGS | ||
617 | psstate t1 | ||
618 | SUSPEND_SAVE_STATIC | ||
619 | jr v0 | ||
620 | nop | ||
621 | END(mips_cps_pm_save) | ||
622 | |||
623 | LEAF(mips_cps_pm_restore) | ||
624 | /* Restore CPU state */ | ||
625 | psstate t1 | ||
626 | RESUME_RESTORE_STATIC | ||
627 | RESUME_RESTORE_REGS_RETURN | ||
628 | END(mips_cps_pm_restore) | ||
629 | |||
630 | #endif /* CONFIG_MIPS_CPS_PM && CONFIG_CPU_PM */ | ||