xref: /linux/arch/parisc/kernel/relocate_kernel.S (revision 976e3645923bdd2fe7893aae33fd7a21098bfb28)
1*fc697dc0SSven Schnelle/* SPDX-License-Identifier: GPL-2.0 */
2*fc697dc0SSven Schnelle#include <linux/linkage.h>
3*fc697dc0SSven Schnelle#include <linux/kexec.h>
4*fc697dc0SSven Schnelle
5*fc697dc0SSven Schnelle#include <asm/assembly.h>
6*fc697dc0SSven Schnelle#include <asm/asm-offsets.h>
7*fc697dc0SSven Schnelle#include <asm/page.h>
8*fc697dc0SSven Schnelle#include <asm/setup.h>
9*fc697dc0SSven Schnelle#include <asm/psw.h>
10*fc697dc0SSven Schnelle
11*fc697dc0SSven Schnelle.level PA_ASM_LEVEL
12*fc697dc0SSven Schnelle
13*fc697dc0SSven Schnelle.macro	kexec_param name
14*fc697dc0SSven Schnelle.align 8
15*fc697dc0SSven SchnelleENTRY(kexec\()_\name)
16*fc697dc0SSven Schnelle#ifdef CONFIG_64BIT
17*fc697dc0SSven Schnelle	.dword 0
18*fc697dc0SSven Schnelle#else
19*fc697dc0SSven Schnelle	.word 0
20*fc697dc0SSven Schnelle#endif
21*fc697dc0SSven Schnelle
22*fc697dc0SSven SchnelleENTRY(kexec\()_\name\()_offset)
23*fc697dc0SSven Schnelle	.word kexec\()_\name - relocate_new_kernel
24*fc697dc0SSven Schnelle.endm
25*fc697dc0SSven Schnelle
26*fc697dc0SSven Schnelle.text
27*fc697dc0SSven Schnelle
28*fc697dc0SSven Schnelle/* args:
29*fc697dc0SSven Schnelle * r26 - kimage->head
30*fc697dc0SSven Schnelle * r25 - start address of kernel
31*fc697dc0SSven Schnelle * r24 - physical address of relocate code
32*fc697dc0SSven Schnelle */
33*fc697dc0SSven Schnelle
34*fc697dc0SSven SchnelleENTRY_CFI(relocate_new_kernel)
35*fc697dc0SSven Schnelle0:	copy	%arg1, %rp
36*fc697dc0SSven Schnelle	/* disable I and Q bit, so we are allowed to execute RFI */
37*fc697dc0SSven Schnelle	rsm PSW_SM_I, %r0
38*fc697dc0SSven Schnelle	nop
39*fc697dc0SSven Schnelle	nop
40*fc697dc0SSven Schnelle	nop
41*fc697dc0SSven Schnelle	nop
42*fc697dc0SSven Schnelle	nop
43*fc697dc0SSven Schnelle	nop
44*fc697dc0SSven Schnelle	nop
45*fc697dc0SSven Schnelle
46*fc697dc0SSven Schnelle	rsm PSW_SM_Q, %r0
47*fc697dc0SSven Schnelle	nop
48*fc697dc0SSven Schnelle	nop
49*fc697dc0SSven Schnelle	nop
50*fc697dc0SSven Schnelle	nop
51*fc697dc0SSven Schnelle	nop
52*fc697dc0SSven Schnelle	nop
53*fc697dc0SSven Schnelle	nop
54*fc697dc0SSven Schnelle
55*fc697dc0SSven Schnelle	/*
56*fc697dc0SSven Schnelle	 * After return-from-interrupt, we want to run without Code/Data
57*fc697dc0SSven Schnelle	 * translation enabled just like on a normal boot.
58*fc697dc0SSven Schnelle	 */
59*fc697dc0SSven Schnelle
60*fc697dc0SSven Schnelle	/* calculate new physical execution address */
61*fc697dc0SSven Schnelle	ldo	1f-0b(%arg2), %r1
62*fc697dc0SSven Schnelle	mtctl	%r0, %cr17 /* IIASQ */
63*fc697dc0SSven Schnelle	mtctl	%r0, %cr17 /* IIASQ */
64*fc697dc0SSven Schnelle	mtctl	%r1, %cr18 /* IIAOQ */
65*fc697dc0SSven Schnelle	ldo	4(%r1),%r1
66*fc697dc0SSven Schnelle	mtctl	%r1, %cr18 /* IIAOQ */
67*fc697dc0SSven Schnelle#ifdef CONFIG_64BIT
68*fc697dc0SSven Schnelle	depdi,z	1, PSW_W_BIT, 1, %r1
69*fc697dc0SSven Schnelle	mtctl	%r1, %cr22 /* IPSW */
70*fc697dc0SSven Schnelle#else
71*fc697dc0SSven Schnelle	mtctl	%r0, %cr22 /* IPSW */
72*fc697dc0SSven Schnelle#endif
73*fc697dc0SSven Schnelle	/* lets go... */
74*fc697dc0SSven Schnelle	rfi
75*fc697dc0SSven Schnelle1:	nop
76*fc697dc0SSven Schnelle	nop
77*fc697dc0SSven Schnelle
78*fc697dc0SSven Schnelle.Lloop:
79*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%arg0), %r3
80*fc697dc0SSven Schnelle	/* If crash kernel, no copy needed */
81*fc697dc0SSven Schnelle	cmpib,COND(=),n 0,%r3,boot
82*fc697dc0SSven Schnelle
83*fc697dc0SSven Schnelle	bb,<,n		%r3, 31 - IND_DONE_BIT, boot
84*fc697dc0SSven Schnelle	bb,>=,n		%r3, 31 - IND_INDIRECTION_BIT, .Lnotind
85*fc697dc0SSven Schnelle	/* indirection, load and restart */
86*fc697dc0SSven Schnelle	movb		%r3, %arg0, .Lloop
87*fc697dc0SSven Schnelle	depi		0, 31, PAGE_SHIFT, %arg0
88*fc697dc0SSven Schnelle
89*fc697dc0SSven Schnelle.Lnotind:
90*fc697dc0SSven Schnelle	bb,>=,n		%r3, 31 - IND_DESTINATION_BIT, .Lnotdest
91*fc697dc0SSven Schnelle	b		.Lloop
92*fc697dc0SSven Schnelle	copy		%r3, %r20
93*fc697dc0SSven Schnelle
94*fc697dc0SSven Schnelle.Lnotdest:
95*fc697dc0SSven Schnelle	bb,>=		%r3, 31 - IND_SOURCE_BIT, .Lloop
96*fc697dc0SSven Schnelle	depi		0, 31, PAGE_SHIFT, %r3
97*fc697dc0SSven Schnelle	copy		%r3, %r21
98*fc697dc0SSven Schnelle
99*fc697dc0SSven Schnelle	/* copy page */
100*fc697dc0SSven Schnelle	copy		%r0, %r18
101*fc697dc0SSven Schnelle	zdepi		1, 31 - PAGE_SHIFT, 1, %r18
102*fc697dc0SSven Schnelle	add		%r20, %r18, %r17
103*fc697dc0SSven Schnelle
104*fc697dc0SSven Schnelle	depi		0, 31, PAGE_SHIFT, %r20
105*fc697dc0SSven Schnelle.Lcopy:
106*fc697dc0SSven Schnelle	copy		%r20, %r12
107*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%r21), %r8
108*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%r21), %r9
109*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%r21), %r10
110*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%r21), %r11
111*fc697dc0SSven Schnelle	STREG,ma	%r8, REG_SZ(%r20)
112*fc697dc0SSven Schnelle	STREG,ma	%r9, REG_SZ(%r20)
113*fc697dc0SSven Schnelle	STREG,ma	%r10, REG_SZ(%r20)
114*fc697dc0SSven Schnelle	STREG,ma	%r11, REG_SZ(%r20)
115*fc697dc0SSven Schnelle
116*fc697dc0SSven Schnelle#ifndef CONFIG_64BIT
117*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%r21), %r8
118*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%r21), %r9
119*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%r21), %r10
120*fc697dc0SSven Schnelle	LDREG,ma	REG_SZ(%r21), %r11
121*fc697dc0SSven Schnelle	STREG,ma	%r8, REG_SZ(%r20)
122*fc697dc0SSven Schnelle	STREG,ma	%r9, REG_SZ(%r20)
123*fc697dc0SSven Schnelle	STREG,ma	%r10, REG_SZ(%r20)
124*fc697dc0SSven Schnelle	STREG,ma	%r11, REG_SZ(%r20)
125*fc697dc0SSven Schnelle#endif
126*fc697dc0SSven Schnelle
127*fc697dc0SSven Schnelle	fdc		%r0(%r12)
128*fc697dc0SSven Schnelle	cmpb,COND(<<)	%r20,%r17,.Lcopy
129*fc697dc0SSven Schnelle	fic		(%sr4, %r12)
130*fc697dc0SSven Schnelle	b,n		.Lloop
131*fc697dc0SSven Schnelle
132*fc697dc0SSven Schnelleboot:
133*fc697dc0SSven Schnelle	mtctl	%r0, %cr15
134*fc697dc0SSven Schnelle
135*fc697dc0SSven Schnelle	LDREG	kexec_free_mem-0b(%arg2), %arg0
136*fc697dc0SSven Schnelle	LDREG	kexec_cmdline-0b(%arg2), %arg1
137*fc697dc0SSven Schnelle	LDREG	kexec_initrd_end-0b(%arg2), %arg3
138*fc697dc0SSven Schnelle	LDREG	kexec_initrd_start-0b(%arg2), %arg2
139*fc697dc0SSven Schnelle	bv,n %r0(%rp)
140*fc697dc0SSven Schnelle
141*fc697dc0SSven SchnelleENDPROC_CFI(relocate_new_kernel);
142*fc697dc0SSven Schnelle
143*fc697dc0SSven SchnelleENTRY(relocate_new_kernel_size)
144*fc697dc0SSven Schnelle       .word relocate_new_kernel_size - relocate_new_kernel
145*fc697dc0SSven Schnelle
146*fc697dc0SSven Schnellekexec_param cmdline
147*fc697dc0SSven Schnellekexec_param initrd_start
148*fc697dc0SSven Schnellekexec_param initrd_end
149*fc697dc0SSven Schnellekexec_param free_mem
150