arch/riscv/kernel/kexec_relocate.S

Source file repositories/reference/linux-study-clean/arch/riscv/kernel/kexec_relocate.S

File Facts

System
Linux kernel
Corpus path
arch/riscv/kernel/kexec_relocate.S
Extension
.S
Size
4336 bytes
Lines
216
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: arch/riscv
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <asm/asm.h>	/* For RISCV_* and REG_* macros */
#include <asm/csr.h>	/* For CSR_* macros */
#include <asm/page.h>	/* For PAGE_SIZE */
#include <linux/linkage.h> /* For SYM_* macros */

.section ".rodata"
SYM_CODE_START(riscv_kexec_relocate)

	/*
	 * s0: Pointer to the current entry
	 * s1: (const) Phys address to jump to after relocation
	 * s2: (const) Phys address of the FDT image
	 * s3: (const) The hartid of the current hart
	 * s4: (const) kernel_map.va_pa_offset, used when switching MMU off
	 * s5: Pointer to the destination address for the relocation
	 * s6: (const) Physical address of the main loop
	 */
	mv	s0, a0
	mv	s1, a1
	mv	s2, a2
	mv	s3, a3
	mv	s4, a4
	mv	s5, zero
	mv	s6, zero

	/* Disable / cleanup interrupts */
	csrw	CSR_SIE, zero
	csrw	CSR_SIP, zero

	/*
	 * When we switch SATP.MODE to "Bare" we'll only
	 * play with physical addresses. However the first time
	 * we try to jump somewhere, the offset on the jump
	 * will be relative to pc which will still be on VA. To
	 * deal with this we set stvec to the physical address at
	 * the start of the loop below so that we jump there in
	 * any case.
	 */
	la	s6, 1f
	sub	s6, s6, s4
	csrw	CSR_STVEC, s6

	/*
	 * With C-extension, here we get 42 Bytes and the next
	 * .align directive would pad zeros here up to 44 Bytes.
	 * So manually put a nop here to avoid zeros padding.
	*/
	nop

	/* Process entries in a loop */
.align 2
1:
	REG_L	t0, 0(s0)		/* t0 = *image->entry */
	addi	s0, s0, RISCV_SZPTR	/* image->entry++ */

	/* IND_DESTINATION entry ? -> save destination address */
	andi	t1, t0, 0x1
	beqz	t1, 2f
	andi	s5, t0, ~0x1
	j	1b

2:
	/* IND_INDIRECTION entry ? -> update next entry ptr (PA) */
	andi	t1, t0, 0x2
	beqz	t1, 2f
	andi	s0, t0, ~0x2
	csrw	CSR_SATP, zero
	jr	s6

2:

Annotation

Implementation Notes