Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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	/*
 19	 * a0: EFI boot flag for the new kernel
 20	 * a1: Command line pointer for the new kernel
 21	 * a2: System table pointer for the new kernel
 22	 * a3: Start address to jump to after relocation
 23	 * a4: Pointer to the current indirection page entry
 24	 */
 25	move		s0, a4
 26
 27	/*
 28	 * In case of a kdump/crash kernel, the indirection page is not
 29	 * populated as the kernel is directly copied to a reserved location
 30	 */
 31	beqz		s0, done
 32
 33process_entry:
 34	PTR_L		s1, s0, 0
 35	PTR_ADDI	s0, s0, SZREG
 36
 37	/* destination page */
 38	andi		s2, s1, IND_DESTINATION
 39	beqz		s2, 1f
 40	li.w		t0, ~0x1
 41	and		s3, s1, t0	/* store destination addr in s3 */
 42	b		process_entry
 43
 441:
 45	/* indirection page, update s0	*/
 46	andi		s2, s1, IND_INDIRECTION
 47	beqz		s2, 1f
 48	li.w		t0, ~0x2
 49	and		s0, s1, t0
 50	b		process_entry
 51
 521:
 53	/* done page */
 54	andi		s2, s1, IND_DONE
 55	beqz		s2, 1f
 56	b		done
 57
 581:
 59	/* source page */
 60	andi		s2, s1, IND_SOURCE
 61	beqz		s2, process_entry
 62	li.w		t0, ~0x8
 63	and		s1, s1, t0
 64	li.w		s5, (1 << _PAGE_SHIFT) / SZREG
 65
 66copy_word:
 67	/* copy page word by word */
 68	REG_L		s4, s1, 0
 69	REG_S		s4, s3, 0
 70	PTR_ADDI	s3, s3, SZREG
 71	PTR_ADDI	s1, s1, SZREG
 72	LONG_ADDI	s5, s5, -1
 73	beqz		s5, process_entry
 74	b		copy_word
 75
 76done:
 77	ibar		0
 78	dbar		0
 79
 80	/*
 81	 * Jump to the new kernel,
 82	 * make sure the values of a0, a1, a2 and a3 are not changed.
 83	 */
 84	jr		a3
 85SYM_CODE_END(relocate_new_kernel)
 86
 87#ifdef CONFIG_SMP
 88/*
 89 * Other CPUs should wait until code is relocated and
 90 * then start at the entry point from LOONGARCH_IOCSR_MBUF0.
 91 */
 92SYM_CODE_START(kexec_smp_wait)
 931:	li.w		t0, 0x100			/* wait for init loop */
 942:	addi.w		t0, t0, -1			/* limit mailbox access */
 95	bnez		t0, 2b
 96	li.w		t1, LOONGARCH_IOCSR_MBUF0
 97	iocsrrd.w	s0, t1				/* check PC as an indicator */
 98	beqz		s0, 1b
 99	iocsrrd.d	s0, t1				/* get PC via mailbox */
100
101	li.d		t0, CACHE_BASE
102	or		s0, s0, t0			/* s0 = TO_CACHE(s0) */
103	jr		s0				/* jump to initial PC */
104SYM_CODE_END(kexec_smp_wait)
105#endif
106
107relocate_new_kernel_end:
108
109SYM_DATA_START(relocate_new_kernel_size)
110	PTR		relocate_new_kernel_end - relocate_new_kernel
111SYM_DATA_END(relocate_new_kernel_size)