xref: /linux/arch/parisc/kernel/toc_asm.S (revision c717993dd76a1049093af5c262e751d901b8da10)
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