149 lines · 2.8 KB · Assembly
RawDownload
/* SPDX-License-Identifier: GPL-2.0 */#include <linux/linkage.h>#include <linux/kexec.h> #include <asm/assembly.h>#include <asm/asm-offsets.h>#include <asm/page.h>#include <asm/setup.h>#include <asm/psw.h> .level PA_ASM_LEVEL .macro	kexec_param name.align 8ENTRY(kexec\()_\name)#ifdef CONFIG_64BIT	.dword 0#else	.word 0#endif ENTRY(kexec\()_\name\()_offset)	.word kexec\()_\name - relocate_new_kernel.endm .text /* args: * r26 - kimage->head * r25 - start address of kernel * r24 - physical address of relocate code */ ENTRY_CFI(relocate_new_kernel)0:	copy	%arg1, %rp	/* disable I and Q bit, so we are allowed to execute RFI */	rsm PSW_SM_I, %r0	nop	nop	nop	nop	nop	nop	nop 	rsm PSW_SM_Q, %r0	nop	nop	nop	nop	nop	nop	nop 	/*	 * After return-from-interrupt, we want to run without Code/Data	 * translation enabled just like on a normal boot.	 */ 	/* calculate new physical execution address */	ldo	1f-0b(%arg2), %r1	mtctl	%r0, %cr17 /* IIASQ */	mtctl	%r0, %cr17 /* IIASQ */	mtctl	%r1, %cr18 /* IIAOQ */	ldo	4(%r1),%r1	mtctl	%r1, %cr18 /* IIAOQ */#ifdef CONFIG_64BIT	depdi,z	1, PSW_W_BIT, 1, %r1	mtctl	%r1, %cr22 /* IPSW */#else	mtctl	%r0, %cr22 /* IPSW */#endif	/* lets go... */	rfi1:	nop	nop .Lloop:	LDREG,ma	REG_SZ(%arg0), %r3	/* If crash kernel, no copy needed */	cmpib,COND(=),n 0,%r3,boot 	bb,<,n		%r3, 31 - IND_DONE_BIT, boot	bb,>=,n		%r3, 31 - IND_INDIRECTION_BIT, .Lnotind	/* indirection, load and restart */	movb		%r3, %arg0, .Lloop	depi		0, 31, PAGE_SHIFT, %arg0 .Lnotind:	bb,>=,n		%r3, 31 - IND_DESTINATION_BIT, .Lnotdest	b		.Lloop	copy		%r3, %r20 .Lnotdest:	bb,>=		%r3, 31 - IND_SOURCE_BIT, .Lloop	depi		0, 31, PAGE_SHIFT, %r3	copy		%r3, %r21 	/* copy page */	copy		%r0, %r18	zdepi		1, 31 - PAGE_SHIFT, 1, %r18	add		%r20, %r18, %r17 	depi		0, 31, PAGE_SHIFT, %r20.Lcopy:	copy		%r20, %r12	LDREG,ma	REG_SZ(%r21), %r8	LDREG,ma	REG_SZ(%r21), %r9	LDREG,ma	REG_SZ(%r21), %r10	LDREG,ma	REG_SZ(%r21), %r11	STREG,ma	%r8, REG_SZ(%r20)	STREG,ma	%r9, REG_SZ(%r20)	STREG,ma	%r10, REG_SZ(%r20)	STREG,ma	%r11, REG_SZ(%r20) #ifndef CONFIG_64BIT	LDREG,ma	REG_SZ(%r21), %r8	LDREG,ma	REG_SZ(%r21), %r9	LDREG,ma	REG_SZ(%r21), %r10	LDREG,ma	REG_SZ(%r21), %r11	STREG,ma	%r8, REG_SZ(%r20)	STREG,ma	%r9, REG_SZ(%r20)	STREG,ma	%r10, REG_SZ(%r20)	STREG,ma	%r11, REG_SZ(%r20)#endif 	fdc		%r0(%r12)	cmpb,COND(<<)	%r20,%r17,.Lcopy	fic		(%sr4, %r12)	b,n		.Lloop boot:	mtctl	%r0, %cr15 	LDREG	kexec_free_mem-0b(%arg2), %arg0	LDREG	kexec_cmdline-0b(%arg2), %arg1	LDREG	kexec_initrd_end-0b(%arg2), %arg3	LDREG	kexec_initrd_start-0b(%arg2), %arg2	bv,n %r0(%rp) ENDPROC_CFI(relocate_new_kernel); ENTRY(relocate_new_kernel_size)       .word relocate_new_kernel_size - relocate_new_kernel kexec_param cmdlinekexec_param initrd_startkexec_param initrd_endkexec_param free_mem