1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | |
3 | /* TOC (Transfer of Control) handler. */ |
4 | |
5 | .level 1.1 |
6 | |
7 | #include <asm/assembly.h> |
8 | #include <linux/threads.h> |
9 | #include <linux/linkage.h> |
10 | |
11 | .text |
12 | .import toc_intr,code |
13 | .import toc_stack,data |
14 | .align 16 |
15 | ENTRY_CFI(toc_handler) |
16 | load32 PA(toc_stack),%sp |
17 | |
18 | #ifdef CONFIG_SMP |
19 | /* get per-cpu toc_stack address. */ |
20 | mfctl %cr30, %r1 |
21 | tophys %r1,%r2 /* task_struct */ |
22 | LDREG TASK_TI_CPU(%r2),%r4 /* cpu */ |
23 | load32 PA(__per_cpu_offset),%r1 |
24 | LDREGX %r4(%r1),%r4 |
25 | add %r4,%sp,%sp |
26 | #endif |
27 | |
28 | /* |
29 | * setup pt_regs on stack and save the |
30 | * floating point registers. PIM_TOC doesn't |
31 | * save fp registers, so we're doing it here. |
32 | */ |
33 | copy %sp,%arg0 |
34 | ldo PT_SZ_ALGN(%sp), %sp |
35 | |
36 | /* clear pt_regs */ |
37 | copy %arg0,%r1 |
38 | 0: cmpb,<<,n %r1,%sp,0b |
39 | stw,ma %r0,4(%r1) |
40 | |
41 | ldo PT_FR0(%arg0),%r25 |
42 | save_fp %r25 |
43 | |
44 | /* go virtual */ |
45 | load32 PA(swapper_pg_dir),%r4 |
46 | mtctl %r4,%cr24 |
47 | mtctl %r4,%cr25 |
48 | |
49 | /* Clear sr4-sr7 */ |
50 | mtsp %r0, %sr4 |
51 | mtsp %r0, %sr5 |
52 | mtsp %r0, %sr6 |
53 | mtsp %r0, %sr7 |
54 | |
55 | tovirt_r1 %sp |
56 | tovirt_r1 %arg0 |
57 | virt_map |
58 | |
59 | loadgp |
60 | |
61 | #ifdef CONFIG_64BIT |
62 | ldo -16(%sp),%r29 |
63 | #endif |
64 | load32 toc_intr,%r1 |
65 | be 0(%sr7,%r1) |
66 | nop |
67 | ENDPROC_CFI(toc_handler) |
68 | |
69 | /* |
70 | * keep this checksum here, as it is part of the toc_handler |
71 | * spanned by toc_handler_size (all words in toc_handler are |
72 | * added in PDC and the sum must equal to zero. |
73 | */ |
74 | SYM_DATA(toc_handler_csum, .long 0) |
75 | SYM_DATA(toc_handler_size, .long . - toc_handler) |
76 | |