File Index
Files and directories
Sign in
FILE

relocate_kernel.S

File preview with syntax highlighting.

linux-6.19.14/arch/loongarch/kernel/relocate_kernel.S S
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 * relocate_kernel.S for kexec
  4 *
  5 * Copyright (C) 2022 Loongson Technology Corporation Limited
  6 */
  7
  8#include <linux/kexec.h>
  9
 10#include <asm/asm.h>
 11#include <asm/asmmacro.h>
 12#include <asm/regdef.h>
 13#include <asm/loongarch.h>
 14#include <asm/stackframe.h>
 15#include <asm/addrspace.h>
 16
 17SYM_CODE_START(relocate_new_kernel)
 18	UNWIND_HINT_UNDEFINED
 19	/*
 20	 * a0: EFI boot flag for the new kernel
 21	 * a1: Command line pointer for the new kernel
 22	 * a2: System table pointer for the new kernel
 23	 * a3: Start address to jump to after relocation
 24	 * a4: Pointer to the current indirection page entry
 25	 */
 26	move		s0, a4
 27
 28	/*
 29	 * In case of a kdump/crash kernel, the indirection page is not
 30	 * populated as the kernel is directly copied to a reserved location
 31	 */
 32	beqz		s0, done
 33
 34process_entry:
 35	PTR_L		s1, s0, 0
 36	PTR_ADDI	s0, s0, SZREG
 37
 38	/* destination page */
 39	andi		s2, s1, IND_DESTINATION
 40	beqz		s2, 1f
 41	li.w		t0, ~0x1
 42	and		s3, s1, t0	/* store destination addr in s3 */
 43	b		process_entry
 44
 451:
 46	/* indirection page, update s0	*/
 47	andi		s2, s1, IND_INDIRECTION
 48	beqz		s2, 1f
 49	li.w		t0, ~0x2
 50	and		s0, s1, t0
 51	b		process_entry
 52
 531:
 54	/* done page */
 55	andi		s2, s1, IND_DONE
 56	beqz		s2, 1f
 57	b		done
 58
 591:
 60	/* source page */
 61	andi		s2, s1, IND_SOURCE
 62	beqz		s2, process_entry
 63	li.w		t0, ~0x8
 64	and		s1, s1, t0
 65	li.w		s5, (1 << _PAGE_SHIFT) / SZREG
 66
 67copy_word:
 68	/* copy page word by word */
 69	REG_L		s4, s1, 0
 70	REG_S		s4, s3, 0
 71	PTR_ADDI	s3, s3, SZREG
 72	PTR_ADDI	s1, s1, SZREG
 73	LONG_ADDI	s5, s5, -1
 74	beqz		s5, process_entry
 75	b		copy_word
 76
 77done:
 78	ibar		0
 79	dbar		0
 80
 81	/*
 82	 * Jump to the new kernel,
 83	 * make sure the values of a0, a1, a2 and a3 are not changed.
 84	 */
 85	jr		a3
 86SYM_CODE_END(relocate_new_kernel)
 87
 88#ifdef CONFIG_SMP
 89/*
 90 * Other CPUs should wait until code is relocated and
 91 * then start at the entry point from LOONGARCH_IOCSR_MBUF0.
 92 */
 93SYM_CODE_START(kexec_smp_wait)
 94	UNWIND_HINT_UNDEFINED
 951:	li.w		t0, 0x100			/* wait for init loop */
 962:	addi.w		t0, t0, -1			/* limit mailbox access */
 97	bnez		t0, 2b
 98	li.w		t1, LOONGARCH_IOCSR_MBUF0
 99	iocsrrd.w	s0, t1				/* check PC as an indicator */
100	beqz		s0, 1b
101	iocsrrd.d	s0, t1				/* get PC via mailbox */
102
103	li.d		t0, CACHE_BASE
104	or		s0, s0, t0			/* s0 = TO_CACHE(s0) */
105	jr		s0				/* jump to initial PC */
106SYM_CODE_END(kexec_smp_wait)
107#endif
108
109relocate_new_kernel_end:
110
111	.section ".data"
112SYM_DATA(relocate_new_kernel_size, .quad relocate_new_kernel_end - relocate_new_kernel)
~/ Read-only file preview.