Linux Audio

Check our new training course

Loading...
v6.8
  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)
v6.13.7
  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, .long relocate_new_kernel_end - relocate_new_kernel)